diff --git a/src/babel.nim b/src/babel.nim index 386bfc1..8a96312 100644 --- a/src/babel.nim +++ b/src/babel.nim @@ -6,8 +6,8 @@ import httpclient, parseopt, os, strutils, osproc, pegs, tables, parseutils, from sequtils import toSeq -import babelpkg/packageinfo, babelpkg/version, babelpkg/tools, - babelpkg/download, babelpkg/config, babelpkg/compat +import nimblepkg/packageinfo, nimblepkg/version, nimblepkg/tools, + nimblepkg/download, nimblepkg/config, nimblepkg/compat when not defined(windows): from posix import getpid @@ -18,7 +18,7 @@ type queryVersions: bool action: TAction config: TConfig - babelData: PJsonNode ## Babeldata.json + nimbleData: PJsonNode ## Nimbledata.json TActionType = enum ActionNil, ActionUpdate, ActionInit, ActionInstall, ActionSearch, @@ -43,11 +43,11 @@ type const help = """ -Usage: babel COMMAND [opts] +Usage: nimble COMMAND [opts] Commands: install [pkgname, ...] Installs a list of packages. - init [pkgname] Initializes a new Babel project. + init [pkgname] Initializes a new Nimble project. uninstall [pkgname, ...] Uninstalls a list of packages. build Builds a package. update [url] Updates package list. A package list URL can @@ -66,7 +66,7 @@ Options: --ver Query remote server for package version information when searching or listing packages """ - babelVersion = "0.4.0" + nimbleVersion = "0.4.0" defaultPackageURL = "https://github.com/nimrod-code/packages/raw/master/packages.json" proc writeHelp() = @@ -74,17 +74,51 @@ proc writeHelp() = quit(QuitSuccess) proc writeVersion() = - echo("babel v$# compiled at $# $#" % [babelVersion, CompileDate, CompileTime]) + echo("nimble v$# compiled at $# $#" % [nimbleVersion, CompileDate, CompileTime]) quit(QuitSuccess) -proc getBabelDir(options: TOptions): string = - options.config.babelDir +proc getNimbleDir(options: TOptions): string = + options.config.nimbleDir proc getPkgsDir(options: TOptions): string = - options.config.babelDir / "pkgs" + options.config.nimbleDir / "pkgs" proc getBinDir(options: TOptions): string = - options.config.babelDir / "bin" + options.config.nimbleDir / "bin" + +proc prompt(options: TOptions, question: string): bool = + ## Asks an interactive question and returns the result. + ## + ## The proc will return immediately without asking the user if the global + ## forcePrompts has a value different than DontForcePrompt. + case options.forcePrompts + of ForcePromptYes: + echo(question & " -> [forced yes]") + return true + of ForcePromptNo: + echo(question & " -> [forced no]") + return false + of DontForcePrompt: + echo(question & " [y/N]") + let yn = stdin.readLine() + case yn.normalize + of "y", "yes": + return true + of "n", "no": + return false + else: + return false + +proc renameBabelToNimble(options: TOptions) {.deprecated.} = + let babelDir = getHomeDir() / ".babel" + let nimbleDir = getHomeDir() / ".nimble" + if dirExists(babelDir): + if options.prompt("Found deprecated babel package directory, would you like to rename it to nimble?"): + copyDir(babelDir, nimbleDir) + removeDir(babelDir) + + copyFile(nimbleDir / "babeldata.json", nimbleDir / "nimbledata.json") + removeFile(nimbleDir / "babeldata.json") proc parseCmdLine(): TOptions = result.action.typ = ActionNil @@ -136,7 +170,7 @@ proc parseCmdLine(): TOptions = result.action.search.add(key) of ActionInit: if result.action.projName != "": - raise newException(EBabel, "Can only initialize one package at a time.") + raise newException(ENimble, "Can only initialize one package at a time.") result.action.projName = key of ActionList, ActionBuild: writeHelp() @@ -151,35 +185,15 @@ proc parseCmdLine(): TOptions = if result.action.typ == ActionNil: writeHelp() - # Load babeldata.json - let babeldataFilename = result.getBabelDir() / "babeldata.json" - if fileExists(babeldataFilename): - result.babelData = parseFile(babeldataFilename) - else: - result.babelData = %{"reverseDeps": newJObject()} + # Rename deprecated babel dir. + renameBabelToNimble(result) -proc prompt(options: TOptions, question: string): bool = - ## Asks an interactive question and returns the result. - ## - ## The proc will return immediately without asking the user if the global - ## forcePrompts has a value different than DontForcePrompt. - case options.forcePrompts - of ForcePromptYes: - echo(question & " -> [forced yes]") - return true - of ForcePromptNo: - echo(question & " -> [forced no]") - return false - of DontForcePrompt: - echo(question & " [y/N]") - let yn = stdin.readLine() - case yn.normalize - of "y", "yes": - return true - of "n", "no": - return false - else: - return false + # Load nimbledata.json + let nimbledataFilename = result.getNimbleDir() / "nimbledata.json" + if fileExists(nimbledataFilename): + result.nimbleData = parseFile(nimbledataFilename) + else: + result.nimbleData = %{"reverseDeps": newJObject()} proc update(options: TOptions) = ## Downloads the package list from the specified URL. @@ -192,7 +206,7 @@ proc update(options: TOptions) = else: defaultPackageURL echo("Downloading package list from " & url) - downloadFile(url, options.getBabelDir() / "packages.json") + downloadFile(url, options.getNimbleDir() / "packages.json") echo("Done.") proc checkInstallFile(pkgInfo: TPackageInfo, @@ -201,8 +215,8 @@ proc checkInstallFile(pkgInfo: TPackageInfo, ## ``True`` means file should be skipped. for ignoreFile in pkgInfo.skipFiles: - if ignoreFile.endswith("babel"): - raise newException(EBabel, ignoreFile & " must be installed.") + if ignoreFile.endswith("nimble"): + raise newException(ENimble, ignoreFile & " must be installed.") if samePaths(file, origDir / ignoreFile): result = true break @@ -244,7 +258,7 @@ proc copyWithExt(origDir, currentDir, dest: string, proc copyFilesRec(origDir, currentDir, dest: string, options: TOptions, pkgInfo: TPackageInfo): TSet[string] = - ## Copies all the required files, skips files specified in the .babel file + ## Copies all the required files, skips files specified in the .nimble file ## (TPackageInfo). ## Returns a list of filepaths to files which have been installed. result = initSet[string]() @@ -294,19 +308,19 @@ proc copyFilesRec(origDir, currentDir, dest: string, result.incl copyFileD(pkgInfo.mypath, changeRoot(pkgInfo.mypath.splitFile.dir, dest, pkgInfo.mypath)) -proc saveBabelData(options: TOptions) = +proc saveNimbleData(options: TOptions) = # TODO: This file should probably be locked. - writeFile(options.getBabelDir() / "babeldata.json", pretty(options.babelData)) + writeFile(options.getNimbleDir() / "nimbledata.json", pretty(options.nimbleData)) proc addRevDep(options: TOptions, dep: tuple[name, version: string], pkg: TPackageInfo) = let depNameVer = dep.name & '-' & dep.version - if not options.babelData["reverseDeps"].hasKey(dep.name): - options.babelData["reverseDeps"][dep.name] = newJObject() - if not options.babelData["reverseDeps"][dep.name].hasKey(dep.version): - options.babelData["reverseDeps"][dep.name][dep.version] = newJArray() + if not options.nimbleData["reverseDeps"].hasKey(dep.name): + options.nimbleData["reverseDeps"][dep.name] = newJObject() + if not options.nimbleData["reverseDeps"][dep.name].hasKey(dep.version): + options.nimbleData["reverseDeps"][dep.name][dep.version] = newJArray() let revDep = %{ "name": %pkg.name, "version": %pkg.version} - let thisDep = options.babelData["reverseDeps"][dep.name][dep.version] + let thisDep = options.nimbleData["reverseDeps"][dep.name][dep.version] if revDep notin thisDep: thisDep.add revDep @@ -326,16 +340,16 @@ proc removeRevDep(options: TOptions, pkg: TPackageInfo) = for depTup in pkg.requires: if depTup.name.isURL(): # We sadly must go through everything in this case... - for key, val in options.babelData["reverseDeps"]: + for key, val in options.nimbleData["reverseDeps"]: options.remove(pkg, depTup, val) else: - let thisDep = options.babelData["reverseDeps"][depTup.name] + let thisDep = options.nimbleData["reverseDeps"][depTup.name] if thisDep.isNil: continue options.remove(pkg, depTup, thisDep) # Clean up empty objects/arrays var newData = newJObject() - for key, val in options.babelData["reverseDeps"]: + for key, val in options.nimbleData["reverseDeps"]: if val.len != 0: var newVal = newJObject() for ver, elem in val: @@ -343,9 +357,9 @@ proc removeRevDep(options: TOptions, pkg: TPackageInfo) = newVal[ver] = elem if newVal.len != 0: newData[key] = newVal - options.babelData["reverseDeps"] = newData + options.nimbleData["reverseDeps"] = newData - saveBabelData(options) + saveNimbleData(options) proc install(packages: seq[TPkgTuple], options: TOptions, @@ -384,7 +398,7 @@ proc processDeps(pkginfo: TPackageInfo, options: TOptions): seq[string] = for p in result: let (name, version) = getNameVersion(p) if pkgsInPath.hasKey(name) and pkgsInPath[name] != version: - raise newException(EBabel, + raise newException(ENimble, "Cannot satisfy the dependency on $1 $2 and $1 $3" % [name, version, pkgsInPath[name]]) pkgsInPath[name] = version @@ -394,7 +408,7 @@ proc processDeps(pkginfo: TPackageInfo, options: TOptions): seq[string] = # (unsatisfiable dependendencies). for i in reverseDeps: addRevDep(options, i, pkginfo) - saveBabelData(options) + saveNimbleData(options) proc buildFromDir(pkgInfo: TPackageInfo, paths: seq[string]) = ## Builds a package as specified by ``pkgInfo``. @@ -404,36 +418,36 @@ proc buildFromDir(pkgInfo: TPackageInfo, paths: seq[string]) = for bin in pkgInfo.bin: echo("Building ", pkginfo.name, "/", bin, " using ", pkgInfo.backend, " backend...") - doCmd(getNimBin() & " $# -d:release --noBabelPath $# \"$#\"" % + doCmd(getNimBin() & " $# -d:release --noNimblePath $# \"$#\"" % [pkgInfo.backend, args, realDir / bin.changeFileExt("nim")]) -proc saveBabelMeta(pkgDestDir, url: string, filesInstalled: TSet[string]) = - var babelmeta = %{"url": %url} - babelmeta["files"] = newJArray() +proc saveNimbleMeta(pkgDestDir, url: string, filesInstalled: TSet[string]) = + var nimblemeta = %{"url": %url} + nimblemeta["files"] = newJArray() for file in filesInstalled: - babelmeta["files"].add(%changeRoot(pkgDestDir, "", file)) - writeFile(pkgDestDir / "babelmeta.json", $babelmeta) + nimblemeta["files"].add(%changeRoot(pkgDestDir, "", file)) + writeFile(pkgDestDir / "nimblemeta.json", $nimblemeta) proc removePkgDir(dir: string, options: TOptions) = ## Removes files belonging to the package in ``dir``. try: - var babelmeta = parseFile(dir / "babelmeta.json") - if not babelmeta.hasKey("files"): + var nimblemeta = parseFile(dir / "nimblemeta.json") + if not nimblemeta.hasKey("files"): raise newException(EJsonParsingError, "Meta data does not contain required info.") - for file in babelmeta["files"]: + for file in nimblemeta["files"]: removeFile(dir / file.str) - removeFile(dir / "babelmeta.json") + removeFile(dir / "nimblemeta.json") # If there are no files left in the directory, remove the directory. if toSeq(walkDirRec(dir)).len == 0: removeDir(dir) else: echo("WARNING: Cannot completely remove " & dir & - ". Files not installed by babel are present.") + ". Files not installed by nimble are present.") except EOS, EJsonParsingError: - echo("Error: Unable to read babelmeta.json: ", getCurrentExceptionMsg()) + echo("Error: Unable to read nimblemeta.json: ", getCurrentExceptionMsg()) if not options.prompt("Would you like to COMPLETELY remove ALL files " & "in " & dir & "?"): quit(QuitSuccess) @@ -460,7 +474,7 @@ proc installFromDir(dir: string, latest: bool, options: TOptions, let versionStr = (if latest: "" else: '-' & pkgInfo.version) let pkgDestDir = pkgsDir / (pkgInfo.name & versionStr) - if existsDir(pkgDestDir) and existsFile(pkgDestDir / "babelmeta.json"): + if existsDir(pkgDestDir) and existsFile(pkgDestDir / "nimblemeta.json"): if not options.prompt(pkgInfo.name & versionStr & " already exists. Overwrite?"): quit(QuitSuccess) removePkgDir(pkgDestDir, options) @@ -482,7 +496,7 @@ proc installFromDir(dir: string, latest: bool, options: TOptions, filesInstalled = copyFilesRec(realDir, realDir, pkgDestDir, options, pkgInfo) # Set file permissions to +x for all binaries built, - # and symlink them on *nix OS' to $babelDir/bin/ + # and symlink them on *nix OS' to $nimbleDir/bin/ for bin in pkgInfo.bin: if not existsFile(pkgDestDir / bin): filesInstalled.incl copyFileD(realDir / bin, pkgDestDir / bin) @@ -506,8 +520,8 @@ proc installFromDir(dir: string, latest: bool, options: TOptions, filesInstalled = copyFilesRec(realDir, realDir, pkgDestDir, options, pkgInfo) - # Save a babelmeta.json file. - saveBabelMeta(pkgDestDir, url, filesInstalled) + # Save a nimblemeta.json file. + saveNimbleMeta(pkgDestDir, url, filesInstalled) # Return the paths to the dependencies of this package. result.paths.add pkgDestDir @@ -515,14 +529,14 @@ proc installFromDir(dir: string, latest: bool, options: TOptions, echo(pkgInfo.name & " installed successfully.") -proc getBabelTempDir(): string = +proc getNimbleTempDir(): string = ## Returns a path to a temporary directory. ## ## The returned path will be the same for the duration of the process but ## different for different runs of it. You have to make sure to create it - ## first. In release builds the directory will be removed when babel finishes + ## first. In release builds the directory will be removed when nimble finishes ## its work. - result = getTempDir() / "babel_" + result = getTempDir() / "nimble_" when defined(windows): proc GetCurrentProcessId(): int32 {.stdcall, dynlib: "kernel32", importc: "GetCurrentProcessId".} @@ -532,14 +546,14 @@ proc getBabelTempDir(): string = proc downloadPkg(url: string, verRange: PVersionRange, downMethod: TDownloadMethod): string = - let downloadDir = (getBabelTempDir() / getDownloadDirName(url, verRange)) + let downloadDir = (getNimbleTempDir() / getDownloadDirName(url, verRange)) createDir(downloadDir) echo("Downloading ", url, " into ", downloadDir, " using ", downMethod, "...") doDownload(url, downloadDir, verRange, downMethod) result = downloadDir proc downloadPkg(pkg: TPackage, verRange: PVersionRange): string = - let downloadDir = (getBabelTempDir() / getDownloadDirName(pkg, verRange)) + let downloadDir = (getNimbleTempDir() / getDownloadDirName(pkg, verRange)) let downMethod = pkg.downloadMethod.getDownloadMethod() createDir(downloadDir) echo("Downloading ", pkg.name, " into ", downloadDir, " using ", downMethod, "...") @@ -553,12 +567,12 @@ proc install(packages: seq[TPkgTuple], result = installFromDir(getCurrentDir(), false, options, "") else: # If packages.json is not present ask the user if they want to download it. - if not existsFile(options.getBabelDir / "packages.json"): + if not existsFile(options.getNimbleDir / "packages.json"): if doPrompt and options.prompt("Local packages.json not found, download it from internet?"): update(options) else: - quit("Please run babel update.", QuitFailure) + quit("Please run nimble update.", QuitFailure) # Install each package. for pv in packages: @@ -568,7 +582,7 @@ proc install(packages: seq[TPkgTuple], result = installFromDir(downloadDir, false, options, pv.name) else: var pkg: TPackage - if getPackage(pv.name, options.getBabelDir() / "packages.json", pkg): + if getPackage(pv.name, options.getNimbleDir() / "packages.json", pkg): let downloadDir = downloadPkg(pkg, pv.ver) result = installFromDir(downloadDir, false, options, pkg.url) else: @@ -579,7 +593,7 @@ proc install(packages: seq[TPkgTuple], update(options) result = install(@[pv], options, false) else: - raise newException(EBabel, "Package not found.") + raise newException(ENimble, "Package not found.") proc build(options: TOptions) = var pkgInfo = getPkgInfo(getCurrentDir()) @@ -592,10 +606,10 @@ proc search(options: TOptions) = ## Searches are done in a case insensitive way making all strings lower case. assert options.action.typ == ActionSearch if options.action.search == @[]: - raise newException(EBabel, "Please specify a search string.") - if not existsFile(options.getBabelDir() / "packages.json"): - raise newException(EBabel, "Please run babel update.") - let pkgList = getPackageList(options.getBabelDir() / "packages.json") + raise newException(ENimble, "Please specify a search string.") + if not existsFile(options.getNimbleDir() / "packages.json"): + raise newException(ENimble, "Please run nimble update.") + let pkgList = getPackageList(options.getNimbleDir() / "packages.json") var found = false template onFound: stmt = echoPackage(pkg) @@ -619,9 +633,9 @@ proc search(options: TOptions) = echo("No package found.") proc list(options: TOptions) = - if not existsFile(options.getBabelDir() / "packages.json"): - raise newException(EBabel, "Please run babel update.") - let pkgList = getPackageList(options.getBabelDir() / "packages.json") + if not existsFile(options.getNimbleDir() / "packages.json"): + raise newException(ENimble, "Please run nimble update.") + let pkgList = getPackageList(options.getNimbleDir() / "packages.json") for pkg in pkgList: echoPackage(pkg) if options.queryVersions: @@ -647,15 +661,15 @@ proc listPaths(options: TOptions) = if kind != pcDir or not path.startsWith(options.getPkgsDir / name): continue - let babelFile = path / name.addFileExt("babel") - if existsFile(babelFile): + let nimbleFile = path / name.addFileExt("nimble") + if existsFile(nimbleFile): var pkgInfo = getPkgInfo(path) var v: VersionAndPath v.version = newVersion(pkgInfo.version) v.path = options.getPkgsDir / (pkgInfo.name & '-' & pkgInfo.version) installed.add(v) else: - echo "Warning: No .babel file found for ", path + echo "Warning: No .nimble file found for ", path if installed.len > 0: sort(installed, system.cmp[VersionAndPath], Descending) @@ -664,36 +678,36 @@ proc listPaths(options: TOptions) = echo "Warning: Package '" & name & "' not installed" errors += 1 if errors > 0: - raise newException(EBabel, "At least one of the specified packages was not found") + raise newException(ENimble, "At least one of the specified packages was not found") proc init(options: TOptions) = - echo("Initializing new Babel project!") + echo("Initializing new Nimble project!") var pkgName, fName: string = "" outFile: TFile if (options.action.projName != ""): pkgName = options.action.projName - fName = pkgName & ".babel" + fName = pkgName & ".nimble" if ( existsFile( os.getCurrentDir() / fName ) ): - raise newException(EBabel, "Already have a babel file.") + raise newException(ENimble, "Already have a nimble file.") else: echo("Enter a project name for this (blank to use working directory), Ctrl-C to abort:") pkgName = readline(stdin) if (pkgName == ""): pkgName = os.getCurrentDir().splitPath.tail if (pkgName == ""): - raise newException(EBabel, "Could not get default file path.") - fName = pkgName & ".babel" + raise newException(ENimble, "Could not get default file path.") + fName = pkgName & ".nimble" - # Now need to write out .babel file with projName and other details + # Now need to write out .nimble file with projName and other details if (not existsFile(os.getCurrentDir() / fName) and open(f=outFile, filename = fName, mode = fmWrite)): outFile.writeln("[Package]") outFile.writeln("name = \"" & pkgName & "\"") outFile.writeln("version = \"0.01\"") outFile.writeln("author = \"Anonymous\"") - outFile.writeln("description = \"New Babel project for Nimrod\"") + outFile.writeln("description = \"New Nimble project for Nimrod\"") outFile.writeln("license = \"BSD\"") outFile.writeln("") outFile.writeln("[Deps]") @@ -701,7 +715,7 @@ proc init(options: TOptions) = close(outFile) else: - raise newException(EBabel, "Unable to open file " & fName & " for writing: " & osErrorMsg()) + raise newException(ENimble, "Unable to open file " & fName & " for writing: " & osErrorMsg()) proc uninstall(options: TOptions) = var pkgsToDelete: seq[TPackageInfo] = @[] @@ -711,14 +725,14 @@ proc uninstall(options: TOptions) = let installedPkgs = getInstalledPkgs(options.getPkgsDir()) var pkgList = findAllPkgs(installedPkgs, pkgTup) if pkgList.len == 0: - raise newException(EBabel, "Package not found") + raise newException(ENimble, "Package not found") echo("Checking reverse dependencies...") var errors: seq[string] = @[] for pkg in pkgList: # Check whether any packages depend on the ones the user is trying to # uninstall. - let thisPkgsDep = options.babelData["reverseDeps"]{pkg.name}{pkg.version} + let thisPkgsDep = options.nimbleData["reverseDeps"]{pkg.name}{pkg.version} if not thisPkgsDep.isNil: var reason = "" if thisPkgsDep.len == 1: @@ -737,7 +751,7 @@ proc uninstall(options: TOptions) = pkgsToDelete.add pkg if pkgsToDelete.len == 0: - raise newException(EBabel, "\n " & errors.join("\n ")) + raise newException(ENimble, "\n " & errors.join("\n ")) var pkgNames = "" for i in 0 .. = 5): - when not defined(`{}`): - proc `{}`*(node: PJsonNode, key: string): PJsonNode = - ## Transverses the node and gets the given value. If any of the - ## names does not exist, returns nil - result = node - if isNil(node): return nil - result = result[key] - - when not defined(`{}=`): - proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) = - ## Transverses the node and tries to set the value at the given location - ## to `value` If any of the names are missing, they are added - var node = node - for i in 0..(names.len-2): - if isNil(node[names[i]]): - node[names[i]] = newJObject() - node = node[names[i]] - node[names[names.len-1]] = value diff --git a/src/nimblepkg/compat.nim b/src/nimblepkg/compat.nim new file mode 100644 index 0000000..f0b8db1 --- /dev/null +++ b/src/nimblepkg/compat.nim @@ -0,0 +1,29 @@ +# Copyright (C) Dominik Picheta. All rights reserved. +# BSD License. Look at license.txt for more info. + +## This module contains additional code from the development version of +## Nimrod's standard library. These procs are required to be able to compile +## against the last stable release 0.9.4. Once 0.9.6 is release these procs +## will disappear. + +import json +when false: + when not (NimrodPatch >= 5): + when not defined(`{}`): + proc `{}`*(node: PJsonNode, key: string): PJsonNode = + ## Transverses the node and gets the given value. If any of the + ## names does not exist, returns nil + result = node + if isNil(node): return nil + result = result[key] + + when not defined(`{}=`): + proc `{}=`*(node: PJsonNode, names: varargs[string], value: PJsonNode) = + ## Transverses the node and tries to set the value at the given location + ## to `value` If any of the names are missing, they are added + var node = node + for i in 0..(names.len-2): + if isNil(node[names[i]]): + node[names[i]] = newJObject() + node = node[names[i]] + node[names[names.len-1]] = value diff --git a/src/babelpkg/config.nim b/src/nimblepkg/config.nim similarity index 55% rename from src/babelpkg/config.nim rename to src/nimblepkg/config.nim index 3e42476..b24825a 100644 --- a/src/babelpkg/config.nim +++ b/src/nimblepkg/config.nim @@ -6,16 +6,23 @@ import tools type TConfig* = object - babelDir*: string + nimbleDir*: string proc initConfig(): TConfig = - result.babelDir = getHomeDir() / ".babel" + result.nimbleDir = getHomeDir() / ".nimble" proc parseConfig*(): TConfig = result = initConfig() - let confFile = getConfigDir() / "babel" / "babel.ini" + var confFile = getConfigDir() / "nimble" / "nimble.ini" var f = newFileStream(confFile, fmRead) + if f == nil: + # Try the old deprecated babel.ini + confFile = getConfigDir() / "babel" / "babel.ini" + f = newFileStream(confFile, fmRead) + if f != nil: + echo("[Warning] Using deprecated config file at ", confFile) + if f != nil: echo("Reading from config file at ", confFile) var p: TCfgParser @@ -28,11 +35,11 @@ proc parseConfig*(): TConfig = of cfgSectionStart: discard of cfgKeyValuePair, cfgOption: case e.key.normalize - of "babeldir": - result.babelDir = e.value + of "nimbledir": + result.nimbleDir = e.value else: - raise newException(EBabel, "Unable to parse config file:" & + raise newException(ENimble, "Unable to parse config file:" & " Unknown key: " & e.key) of cfgError: - raise newException(EBabel, "Unable to parse config file: " & e.msg) + raise newException(ENimble, "Unable to parse config file: " & e.msg) close(p) diff --git a/src/babelpkg/download.nim b/src/nimblepkg/download.nim similarity index 97% rename from src/babelpkg/download.nim rename to src/nimblepkg/download.nim index 9562edb..230ecde 100644 --- a/src/babelpkg/download.nim +++ b/src/nimblepkg/download.nim @@ -111,7 +111,7 @@ proc getDownloadMethod*(meth: string): TDownloadMethod = of "git": return TDownloadMethod.Git of "hg", "mercurial": return TDownloadMethod.Hg else: - raise newException(EBabel, "Invalid download method: " & meth) + raise newException(ENimble, "Invalid download method: " & meth) proc getHeadName*(meth: TDownloadMethod): string = ## Returns the name of the download method specific head. i.e. for git @@ -127,7 +127,7 @@ proc checkUrlType*(url: string): TDownloadMethod = elif doCmdEx("hg identify " & url).exitCode == QuitSuccess: return TDownloadMethod.Hg else: - raise newException(EBabel, "Unable to identify url.") + raise newException(ENimble, "Unable to identify url.") proc isURL*(name: string): bool = name.startsWith(peg" @'://' ") @@ -143,7 +143,7 @@ proc doDownload*(url: string, downloadDir: string, verRange: PVersionRange, # If no tagged versions satisfy our range latest.tag will be "". # We still clone in that scenario because we want to try HEAD in that case. - # https://github.com/nimrod-code/babel/issues/22 + # https://github.com/nimrod-code/nimble/issues/22 meth proc verifyClone() = @@ -151,7 +151,7 @@ proc doDownload*(url: string, downloadDir: string, verRange: PVersionRange, ## version range. let pkginfo = getPkgInfo(downloadDir) if pkginfo.version.newVersion notin verRange: - raise newException(EBabel, + raise newException(ENimble, "Downloaded package's version does not satisfy requested version " & "range: wanted $1 got $2." % [$verRange, $pkginfo.version]) diff --git a/src/babelpkg/packageinfo.nim b/src/nimblepkg/packageinfo.nim similarity index 81% rename from src/babelpkg/packageinfo.nim rename to src/nimblepkg/packageinfo.nim index ad56d8c..8b3056e 100644 --- a/src/babelpkg/packageinfo.nim +++ b/src/nimblepkg/packageinfo.nim @@ -7,7 +7,7 @@ type TPkgTuple* = tuple[name: string, ver: PVersionRange] TPackageInfo* = object - mypath*: string ## The path of this .babel file + mypath*: string ## The path of this .nimble file name*: string version*: string author*: string @@ -60,25 +60,25 @@ proc initPackageInfo(): TPackageInfo = proc validatePackageInfo(pkgInfo: TPackageInfo, path: string) = if pkgInfo.name == "": - raise newException(EBabel, "Incorrect .babel file: " & path & + raise newException(ENimble, "Incorrect .nimble file: " & path & " does not contain a name field.") if pkgInfo.version == "": - raise newException(EBabel, "Incorrect .babel file: " & path & + raise newException(ENimble, "Incorrect .nimble file: " & path & " does not contain a version field.") if pkgInfo.author == "": - raise newException(EBabel, "Incorrect .babel file: " & path & + raise newException(ENimble, "Incorrect .nimble file: " & path & " does not contain an author field.") if pkgInfo.description == "": - raise newException(EBabel, "Incorrect .babel file: " & path & + raise newException(ENimble, "Incorrect .nimble file: " & path & " does not contain a description field.") if pkgInfo.license == "": - raise newException(EBabel, "Incorrect .babel file: " & path & + raise newException(ENimble, "Incorrect .nimble file: " & path & " does not contain a license field.") if pkgInfo.backend notin ["c", "cc", "objc", "cpp", "js"]: - raise newException(EBabel, "'" & pkgInfo.backend & "' is an invalid backend.") + raise newException(ENimble, "'" & pkgInfo.backend & "' is an invalid backend.") for c in pkgInfo.version: if c notin ({'.'} + Digits): - raise newException(EBabel, + raise newException(ENimble, "Version may only consist of numbers and the '.' character " & "but found '" & c & "'.") @@ -96,7 +96,7 @@ proc parseRequires(req: string): TPkgTuple = result.name = req.strip result.ver = PVersionRange(kind: verAny) except EParseVersion: - raise newException(EBabel, "Unable to parse dependency version range: " & + raise newException(ENimble, "Unable to parse dependency version range: " & getCurrentExceptionMsg()) proc multiSplit(s: string): seq[string] = @@ -160,18 +160,18 @@ proc readPackageInfo*(path: string): TPackageInfo = case result.backend.normalize of "javascript": result.backend = "js" else: - raise newException(EBabel, "Invalid field: " & ev.key) + raise newException(ENimble, "Invalid field: " & ev.key) of "deps", "dependencies": case ev.key.normalize of "requires": for v in ev.value.multiSplit: result.requires.add(parseRequires(v.strip)) else: - raise newException(EBabel, "Invalid field: " & ev.key) - else: raise newException(EBabel, "Invalid section: " & currentSection) - of cfgOption: raise newException(EBabel, "Invalid package info, should not contain --" & ev.value) + raise newException(ENimble, "Invalid field: " & ev.key) + else: raise newException(ENimble, "Invalid section: " & currentSection) + of cfgOption: raise newException(ENimble, "Invalid package info, should not contain --" & ev.value) of cfgError: - raise newException(EBabel, "Error parsing .babel file: " & ev.msg) + raise newException(ENimble, "Error parsing .nimble file: " & ev.msg) close(p) else: raise newException(EInvalidValue, "Cannot open package info: " & path) @@ -187,7 +187,7 @@ proc optionalField(obj: PJsonNode, name: string, default = ""): string = if obj[name].kind == JString: return obj[name].str else: - raise newException(EBabel, "Corrupted packages.json file. " & name & " field is of unexpected type.") + raise newException(ENimble, "Corrupted packages.json file. " & name & " field is of unexpected type.") else: return default proc requiredField(obj: PJsonNode, name: string): string = @@ -196,7 +196,7 @@ proc requiredField(obj: PJsonNode, name: string): string = ## Aborts execution if the field does not exist or is of invalid json type. result = optionalField(obj, name, nil) if result == nil: - raise newException(EBabel, + raise newException(ENimble, "Package in packages.json file does not contain a " & name & " field.") proc fromJson(obj: PJSonNode): TPackage = @@ -216,14 +216,18 @@ proc fromJson(obj: PJSonNode): TPackage = result.web = obj.optionalField("web") proc readMetadata*(path: string): TMetadata = - ## Reads the metadata present in ``~/.babel/pkgs/pkg-0.1/babelmeta.json`` - let bmeta = path / "babelmeta.json" + ## Reads the metadata present in ``~/.nimble/pkgs/pkg-0.1/nimblemeta.json`` + var bmeta = path / "nimblemeta.json" + if not existsFile(bmeta): + bmeta = path / "babelmeta.json" + if existsFile(bmeta): + echo("WARNING: using deprecated babelmeta.json file in " & path) if not existsFile(bmeta): result.url = "" - echo("WARNING: No babelmeta.json file found in " & path) + echo("WARNING: No nimblemeta.json file found in " & path) return # TODO: Make this an error. - let cont = readFile(path / "babelmeta.json") + let cont = readFile(bmeta) let jsonmeta = parseJson(cont) result.url = jsonmeta["url"].str @@ -247,35 +251,35 @@ proc getPackageList*(packagesPath: string): seq[TPackage] = let pkg: TPackage = p.fromJson() result.add(pkg) -proc findBabelFile*(dir: string): string = +proc findNimbleFile*(dir: string): string = result = "" for kind, path in walkDir(dir): - if kind == pcFile and path.splitFile.ext == ".babel": + if kind == pcFile and path.splitFile.ext in [".babel", ".nimble"]: if result != "": - raise newException(EBabel, "Only one .babel file should be present in " & dir) + raise newException(ENimble, "Only one .nimble file should be present in " & dir) result = path proc getPkgInfo*(dir: string): TPackageInfo = - ## Find the .babel file in ``dir`` and parses it, returning a TPackageInfo. - let babelFile = findBabelFile(dir) - if babelFile == "": - raise newException(EBabel, "Specified directory does not contain a .babel file.") - result = readPackageInfo(babelFile) + ## Find the .nimble file in ``dir`` and parses it, returning a TPackageInfo. + let nimbleFile = findNimbleFile(dir) + if nimbleFile == "": + raise newException(ENimble, "Specified directory does not contain a .nimble file.") + result = readPackageInfo(nimbleFile) proc getInstalledPkgs*(libsDir: string): seq[tuple[pkginfo: TPackageInfo, meta: TMetaData]] = ## Gets a list of installed packages. ## - ## ``libsDir`` is in most cases: ~/.babel/pkgs/ + ## ``libsDir`` is in most cases: ~/.nimble/pkgs/ result = @[] for kind, path in walkDir(libsDir): if kind == pcDir: - let babelFile = findBabelFile(path) - if babelFile != "": + let nimbleFile = findNimbleFile(path) + if nimbleFile != "": let meta = readMetadata(path) - result.add((readPackageInfo(babelFile), meta)) + result.add((readPackageInfo(nimbleFile), meta)) else: # TODO: Abstract logging. - echo("WARNING: No .babel file found for ", path) + echo("WARNING: No .nimble file found for ", path) proc findPkg*(pkglist: seq[tuple[pkginfo: TPackageInfo, meta: TMetaData]], dep: TPkgTuple, @@ -315,7 +319,7 @@ proc getRealDir*(pkgInfo: TPackageInfo): string = result = pkgInfo.mypath.splitFile.dir proc getNameVersion*(pkgpath: string): tuple[name, version: string] = - ## Splits ``pkgpath`` in the format ``/home/user/.babel/pkgs/package-0.1`` + ## Splits ``pkgpath`` in the format ``/home/user/.nimble/pkgs/package-0.1`` ## into ``(packagea, 0.1)`` result.name = "" result.version = "" @@ -347,5 +351,5 @@ proc getDownloadDirName*(pkg: TPackage, verRange: PVersionRange): string = result.add verSimple when isMainModule: - doAssert getNameVersion("/home/user/.babel/libs/packagea-0.1") == ("packagea", "0.1") - doAssert getNameVersion("/home/user/.babel/libs/package-a-0.1") == ("package-a", "0.1") + doAssert getNameVersion("/home/user/.nimble/libs/packagea-0.1") == ("packagea", "0.1") + doAssert getNameVersion("/home/user/.nimble/libs/package-a-0.1") == ("package-a", "0.1") diff --git a/src/babelpkg/tools.nim b/src/nimblepkg/tools.nim similarity index 93% rename from src/babelpkg/tools.nim rename to src/nimblepkg/tools.nim index 0381aff..295c0bb 100644 --- a/src/babelpkg/tools.nim +++ b/src/nimblepkg/tools.nim @@ -6,21 +6,21 @@ import osproc, pegs, strutils, os, parseurl, sets, json import version, packageinfo type - EBabel* = object of EBase + ENimble* = object of EBase proc doCmd*(cmd: string) = let bin = cmd.split(' ')[0] if findExe(bin) == "": - raise newException(EBabel, "'" & bin & "' not in PATH.") + raise newException(ENimble, "'" & bin & "' not in PATH.") let exitCode = execCmd(cmd) if exitCode != QuitSuccess: - raise newException(EBabel, "Execution failed with exit code " & $exitCode) + raise newException(ENimble, "Execution failed with exit code " & $exitCode) proc doCmdEx*(cmd: string): tuple[output: TaintedString, exitCode: int] = let bin = cmd.split(' ')[0] if findExe(bin) == "": - raise newException(EBabel, "'" & bin & "' not in PATH.") + raise newException(ENimble, "'" & bin & "' not in PATH.") return execCmdEx(cmd) template cd*(dir: string, body: stmt) = diff --git a/src/nimblepkg/version b/src/nimblepkg/version new file mode 100755 index 0000000..c152294 Binary files /dev/null and b/src/nimblepkg/version differ diff --git a/src/babelpkg/version.nim b/src/nimblepkg/version.nim similarity index 99% rename from src/babelpkg/version.nim rename to src/nimblepkg/version.nim index bec66d7..8cc4cd0 100644 --- a/src/babelpkg/version.nim +++ b/src/nimblepkg/version.nim @@ -279,6 +279,5 @@ when isMainModule: var sp = parseVersionRange("#ab26sgdt362") doAssert newSpecial("ab26sgdt362") in sp doAssert newSpecial("ab26saggdt362") notin sp - echo("Everything works!")