mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 05:23:20 +00:00
Atlas: add atlas tag command (#21936)
* Initial structure, `GitTags` → `GitRefsTags` * Determine if we should use v prefix * get tag from latest tag, patch nimble file * Just do tags for now * atlas tag now tags and pushes * Improve UX of `atlas tag` * better description for `tag` * Small fixup * Consistent naming * strip after checking status * Take major/minor/patch as arg for `atlas tag` * undo testing comment * Fix for `v` prefixed versions * Avoid useless assignment * Remove uselss enum assignment * Consistent parameter seperation * Add error handling for non-semver tags * Use `assert` to quit on error * Update tools/atlas/atlas.nim Co-authored-by: Andreas Rumpf <rumpf_a@web.de> * Don't push tags if errors occurred * Allow `atlas tag [tag]` again * Add atlas tag `a..z` for fields > 3 * Document the three input options * Take up less lines in help * Less or in help * One last doc pass * Check args length * clarify last tag * consistency/order --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
@@ -43,6 +43,10 @@ Command:
|
||||
updateDeps [filter]
|
||||
update every dependency that has a remote
|
||||
URL that matches `filter` if a filter is given
|
||||
tag [major|minor|patch]
|
||||
add and push a new tag, input must be one of:
|
||||
['major'|'minor'|'patch'] or a SemVer tag like ['1.0.3']
|
||||
or a letter ['a'..'z']: a.b.c.d.e.f.g
|
||||
build|test|doc|tasks currently delegates to `nimble build|test|doc`
|
||||
task <taskname> currently delegates to `nimble <taskname>`
|
||||
|
||||
@@ -83,6 +87,9 @@ type
|
||||
DepRelation = enum
|
||||
normal, strictlyLess, strictlyGreater
|
||||
|
||||
SemVerField = enum
|
||||
major, minor, patch
|
||||
|
||||
Dependency = object
|
||||
name: PackageName
|
||||
url, commit: string
|
||||
@@ -116,9 +123,12 @@ const
|
||||
type
|
||||
Command = enum
|
||||
GitDiff = "git diff",
|
||||
GitTag = "git tag",
|
||||
GitTags = "git show-ref --tags",
|
||||
GitLastTaggedRef = "git rev-list --tags --max-count=1",
|
||||
GitRevParse = "git rev-parse",
|
||||
GitCheckout = "git checkout",
|
||||
GitPush = "git push origin",
|
||||
GitPull = "git pull",
|
||||
GitCurrentCommit = "git log -n 1 --format=%H"
|
||||
GitMergeBase = "git merge-base"
|
||||
@@ -143,7 +153,7 @@ proc exec(c: var AtlasContext; cmd: Command; args: openArray[string]): (string,
|
||||
when MockupRun:
|
||||
assert TestLog[c.step].cmd == cmd, $(TestLog[c.step].cmd, cmd)
|
||||
case cmd
|
||||
of GitDiff, GitTags, GitRevParse, GitPull, GitCurrentCommit:
|
||||
of GitDiff, GitTag, GitTags, GitLastTaggedRef, GitRevParse, GitPush, GitPull, GitCurrentCommit:
|
||||
result = (TestLog[c.step].output, TestLog[c.step].exitCode)
|
||||
of GitCheckout:
|
||||
assert args[0] == TestLog[c.step].output
|
||||
@@ -209,6 +219,9 @@ proc message(c: var AtlasContext; category: string; p: PackageName; args: vararg
|
||||
msg.add a
|
||||
stdout.writeLine msg
|
||||
|
||||
proc info(c: var AtlasContext; p: PackageName; args: varargs[string]) =
|
||||
message(c, "[Info] ", p, args)
|
||||
|
||||
proc warn(c: var AtlasContext; p: PackageName; args: varargs[string]) =
|
||||
message(c, "[Warning] ", p, args)
|
||||
inc c.errors
|
||||
@@ -217,9 +230,6 @@ proc error(c: var AtlasContext; p: PackageName; args: varargs[string]) =
|
||||
message(c, "[Error] ", p, args)
|
||||
inc c.errors
|
||||
|
||||
proc info(c: var AtlasContext; p: PackageName; args: varargs[string]) =
|
||||
message(c, "[Info] ", p, args)
|
||||
|
||||
proc sameVersionAs(tag, ver: string): bool =
|
||||
const VersionChars = {'0'..'9', '.'}
|
||||
|
||||
@@ -270,6 +280,62 @@ proc gitPull(c: var AtlasContext; p: PackageName) =
|
||||
if status != 0:
|
||||
error(c, p, "could not 'git pull'")
|
||||
|
||||
proc gitTag(c: var AtlasContext; tag: string) =
|
||||
let (_, status) = exec(c, GitTag, [tag])
|
||||
if status != 0:
|
||||
error(c, c.projectDir.PackageName, "could not 'git tag " & tag & "'")
|
||||
|
||||
proc pushTag(c: var AtlasContext; tag: string) =
|
||||
let (outp, status) = exec(c, GitPush, [tag])
|
||||
if status != 0:
|
||||
error(c, c.projectDir.PackageName, "could not 'git push " & tag & "'")
|
||||
elif outp.strip() == "Everything up-to-date":
|
||||
info(c, c.projectDir.PackageName, "is up-to-date")
|
||||
else:
|
||||
info(c, c.projectDir.PackageName, "successfully pushed tag: " & tag)
|
||||
|
||||
proc incrementTag(lastTag: string; field: Natural): string =
|
||||
var startPos =
|
||||
if lastTag[0] in {'0'..'9'}: 0
|
||||
else: 1
|
||||
var endPos = lastTag.find('.', startPos)
|
||||
if field >= 1:
|
||||
for i in 1 .. field:
|
||||
assert endPos != -1, "the last tag '" & lastTag & "' is missing . periods"
|
||||
startPos = endPos + 1
|
||||
endPos = lastTag.find('.', startPos)
|
||||
if endPos == -1:
|
||||
endPos = len(lastTag)
|
||||
let patchNumber = parseInt(lastTag[startPos..<endPos])
|
||||
lastTag[0..<startPos] & $(patchNumber + 1) & lastTag[endPos..^1]
|
||||
|
||||
proc incrementLastTag(c: var AtlasContext; field: Natural): string =
|
||||
let (ltr, status) = exec(c, GitLastTaggedRef, [])
|
||||
if status == 0:
|
||||
let
|
||||
lastTaggedRef = ltr.strip()
|
||||
(lt, _) = osproc.execCmdEx("git describe --tags " & lastTaggedRef)
|
||||
lastTag = lt.strip()
|
||||
(cc, _) = exec(c, GitCurrentCommit, [])
|
||||
currentCommit = cc.strip()
|
||||
|
||||
if lastTaggedRef == currentCommit:
|
||||
info c, c.projectDir.PackageName, "the current commit '" & currentCommit & "' is already tagged '" & lastTag & "'"
|
||||
lastTag
|
||||
else:
|
||||
incrementTag(lastTag, field)
|
||||
else: "v0.0.1" # assuming no tags have been made yet
|
||||
|
||||
proc tag(c: var AtlasContext; tag: string) =
|
||||
gitTag(c, tag)
|
||||
pushTag(c, tag)
|
||||
|
||||
proc tag(c: var AtlasContext; field: Natural) =
|
||||
let oldErrors = c.errors
|
||||
let newTag = incrementLastTag(c, field)
|
||||
if c.errors == oldErrors:
|
||||
tag(c, newTag)
|
||||
|
||||
proc updatePackages(c: var AtlasContext) =
|
||||
if dirExists(c.workspace / PackagesDir):
|
||||
withDir(c, c.workspace / PackagesDir):
|
||||
@@ -839,6 +905,20 @@ proc main =
|
||||
echo toJson(extractRequiresInfo(args[0]))
|
||||
else:
|
||||
error "File does not exist: " & args[0]
|
||||
of "tag":
|
||||
projectCmd()
|
||||
if args.len == 0:
|
||||
tag(c, ord(patch))
|
||||
elif args[0].len == 1 and args[0][0] in {'a'..'z'}:
|
||||
let field = ord(args[0][0]) - ord('a')
|
||||
tag(c, field)
|
||||
elif '.' in args[0]:
|
||||
tag(c, args[0])
|
||||
else:
|
||||
var field: SemVerField
|
||||
try: field = parseEnum[SemVerField](args[0])
|
||||
except: error "tag command takes one of 'patch' 'minor' 'major', a SemVer tag, or a letter from 'a' to 'z'"
|
||||
tag(c, ord(field))
|
||||
of "build", "test", "doc", "tasks":
|
||||
projectCmd()
|
||||
nimbleExec(action, args)
|
||||
|
||||
Reference in New Issue
Block a user