diff --git a/update_version.nim b/update_version.nim index 2f824a5..d49076b 100644 --- a/update_version.nim +++ b/update_version.nim @@ -11,6 +11,9 @@ const USAGE = """Usage: Options: + -d, --dir Use the given directory as the project root (defaults + to the current working directory). + -l, --lang Choose the language/ecosystem to consider. Valid values are: 'nim' or 'node'. If not provided, this is auto-detected by the presence of either a *.nimble @@ -64,13 +67,14 @@ type SemVerParts = enum major, minor, patch, prerelease, buildmetadata type PackageVersion = object - packageFile: Path + file: Path version: string name: string case lang: LangType of lNim: - discard + lines: seq[string] + versionLine: int of lNode: nodePackage: JsonNode @@ -85,27 +89,29 @@ let SemVerPattern = re"^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:-(?P(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" proc parseNimblePackage(dir: Path): PackageVersion = + result = PackageVersion(lang: lNim) + for fe in walkDir(dir): if fe.kind == pcFile and fe.path.splitFile.ext == ".nimble": - let content = readFile($fe.path) - for v in content.splitLines: - if v.startsWith("version"): - return PackageVersion( - lang: lNim, - packageFile: fe.path, - version: v.split("=")[^1].strip(chars = {' ', '"'}), - name: $fe.path.splitFile.name) - + result.lines = readFile($fe.path).splitLines + for idx, l in result.lines: + if l.startsWith("version"): + result.versionLine = idx + result.version = l.split("=")[^1].strip(chars = {' ', '"'}) + result.name = $fe.path.splitFile.name + result.file = fe.path + return result raise newException(IOError, "No valid .nimble file found in $#" % [$dir]) proc parseNodePackage(dir: Path): PackageVersion = - result.packageFile = dir / Path("package.json") - result.lang = lNode - result.nodePackage = parseFile($result.packageFile) + result = PackageVersion( + file: dir / Path("package.json"), + lang: lNode, + nodePackage: parseFile($result.file)) if not result.nodePackage.hasKey("name") or not result.nodePackage.hasKey("version") or @@ -118,6 +124,28 @@ proc parseNodePackage(dir: Path): PackageVersion = result.version = result.nodePackage{"version"}.getStr +proc detectAndParsePackage(dir: Path): PackageVersion = + try: result = parseNimblePackage(dir) + except: + let nimEx = getCurrentException() + try: result = parseNodePackage(dir) + except: + let nodeEx = getCurrentException() + stderr.writeLine( + "Unable to find a package definitions file. Errors:\n\t$#\n\t$#" % + [nimEx.msg, nodeEx.msg]) + + +proc writePackage(pkg: PackageVersion) = + if pkg.lang == lNim: + var lines = pkg.lines + lines[pkg.versionLine] = "version = \"$#\"" % pkg.version + writeFile($pkg.file, lines.join("\p")) + elif pkg.lang == lNode: + pkg.nodePackage["version"] = %pkg.version + writeFile($pkg.file, pkg.nodePackage.pretty) + + proc incrementLastVersionPart(version: string): string = let versionParts = toSeq(findIter(version, re"([^\d.]+)?\.?(\d+)")) let lastVersionPartMatch = versionParts[^1] @@ -178,15 +206,7 @@ proc incrementSemverPart( when isMainModule: let args = docopt(USAGE, version = UV_VERSION) - if args["bump"]: - discard - elif args["set"]: - discard - elif args["get"]: - discard - elif args["interactive"]: - discard - elif args["test"]: + if args["test"]: # incrementLastVersionPart assert incrementLastVersionPart("1.0.0") == "1.0.1" @@ -206,3 +226,55 @@ when isMainModule: assert incrementSemverPart("1.5.10", buildmetadata) == "1.5.10+build.0" echo "All tests passed." + quit(QuitSuccess) + + + let dir = + if args["--dir"]: Path($args["--dir"]) + else: Path(".") + + var pkg = + if args["--lang"] and $args["--lang"] == "nim": + parseNimblePackage(dir) + elif args["--lang"] and $args["--lang"] == "node": + parseNodePackage(dir) + else: + detectAndParsePackage(dir) + + if args["bump"]: + if $args[""] == "last": + pkg.version = incrementLastVersionPart(pkg.version) + else: + let part = parseEnum[SemVerParts]($args[""]) + pkg.version = incrementSemverPart(pkg.version, part) + + writePackage(pkg) + echo pkg.version + + elif args["set"]: + pkg.version = $args[""] + writePackage(pkg) + echo pkg.version + + elif args["get"]: echo pkg.version + + elif args["interactive"]: + var acceptNewVersion = false + var newVersion = pkg.version + while not acceptNewVersion: + stdout.writeLine "Current version is " & pkg.version + stdout.write "New version? " + newVersion = stdin.readLine + + stdout.write "New version will be set to '" & pkg.version & "'. Is this correct (yes/no)? " + let isCorrect = stdin.readLine + let acceptNewVersion = "yes".startsWith(isCorrect.toLower) + + pkg.version = newVersion + echo "Updating version definition in " & $pkg.file + writePackage(pkg) + + # TODO: + # for f in filesToUpdate: + # echo "Updating version definition in " & $f + # updateVersionInFile(f) diff --git a/update_version.nimble b/update_version.nimble index 3796f44..132d34b 100644 --- a/update_version.nimble +++ b/update_version.nimble @@ -1,6 +1,6 @@ # Package -version = "1.0.0" +version = "1.0.1" author = "Jonathan Bernard" description = "Small util to update version consistently for nim and node packages." license = "MIT"