From dbd478bc20170b898d0967ffcdedfa775579603c Mon Sep 17 00:00:00 2001 From: Dominik Picheta Date: Wed, 23 Dec 2015 20:48:05 +0000 Subject: [PATCH] The .nimble extension is now used for both ini and nims .nimble files. This is done by parsing the .nimble file using the ini parser first, then if that fails evaluating it using nimscript. --- src/nimble.nim | 11 +++--- src/nimblepkg/nimbletypes.nim | 1 + src/nimblepkg/nimscriptsupport.nim | 10 +++++ src/nimblepkg/packageinfo.nim | 59 +++++++++++++++++++++++------- 4 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/nimble.nim b/src/nimble.nim index ef5d5c7..b06268e 100644 --- a/src/nimble.nim +++ b/src/nimble.nim @@ -892,6 +892,7 @@ proc guessAuthor(): string = return "Anonymous" proc join(x: seq[PkgTuple]; y: string): string = + if x.len == 0: return "" result = x[0][0] & " " & $x[0][1] for i in 1 ..< x.len: result.add y @@ -899,7 +900,7 @@ proc join(x: seq[PkgTuple]; y: string): string = proc dump(options: Options) = let proj = addFileExt(options.action.projName, NimsExt) - let p = if fileExists(proj): readPackageInfo((true, proj)) + let p = if fileExists(proj): readPackageInfo(proj) else: getPkgInfo(os.getCurrentDir()) echo "name: ", p.name.escape echo "version: ", p.version.escape @@ -1017,9 +1018,7 @@ proc uninstall(options: Options) = echo("Removed ", pkg.name, " (", $pkg.version, ")") proc listTasks(options: Options) = - let (isNimScript, nimbleFile) = findNimbleFile(getCurrentDir(), true) - if not isNimScript: - echo("No tasks defined (Found Nimble file, but no NimScript file)") + let nimbleFile = findNimbleFile(getCurrentDir(), true) nimscriptsupport.listTasks(nimbleFile) proc doAction(options: Options) = @@ -1064,8 +1063,8 @@ proc doAction(options: Options) = assert false of actionCustom: # Custom command. Attempt to call a NimScript task. - let (isNimScript, nimbleFile) = findNimbleFile(getCurrentDir(), true) - if not isNimScript: + let nimbleFile = findNimbleFile(getCurrentDir(), true) + if not nimbleFile.isNimScript(): writeHelp() let oldCmd = getNimScriptCommand() if not execTask(nimbleFile, oldCmd): diff --git a/src/nimblepkg/nimbletypes.nim b/src/nimblepkg/nimbletypes.nim index c02a5d7..c5ad669 100644 --- a/src/nimblepkg/nimbletypes.nim +++ b/src/nimblepkg/nimbletypes.nim @@ -11,6 +11,7 @@ type PackageInfo* = object mypath*: string ## The path of this .nimble file + isNimScript*: bool ## Determines if this pkg info was read from a nims file name*: string version*: string author*: string diff --git a/src/nimblepkg/nimscriptsupport.nim b/src/nimblepkg/nimscriptsupport.nim index f6298f8..7a343e8 100644 --- a/src/nimblepkg/nimscriptsupport.nim +++ b/src/nimblepkg/nimscriptsupport.nim @@ -93,6 +93,16 @@ proc readPackageInfoFromNims*(scriptName: string; result: var PackageInfo) = ## Executes the `scriptName` nimscript file. Reads the package information ## that it populates. + # Setup custom error handling. + msgs.gErrorMax = high(int) + var previousMsg = "" + msgs.writeLnHook = + proc (output: string) = + # The error counter is incremented after the writeLnHook is invoked. + if msgs.gErrorCounter > 0: + raise newException(NimbleError, previousMsg) + previousMsg = output + # Execute the nimscript file. execScript(scriptName) diff --git a/src/nimblepkg/packageinfo.nim b/src/nimblepkg/packageinfo.nim index 089a02d..71d4c92 100644 --- a/src/nimblepkg/packageinfo.nim +++ b/src/nimblepkg/packageinfo.nim @@ -26,7 +26,7 @@ type MetaData* = object url*: string - NimbleFile* = tuple[isNimScript: bool; file: string] + NimbleFile* = string proc initPackageInfo(path: string): PackageInfo = result.mypath = path @@ -73,6 +73,12 @@ proc validatePackageInfo(pkgInfo: PackageInfo, path: string) = "Version may only consist of numbers and the '.' character " & "but found '" & c & "'.") + if not pkgInfo.isNimScript: + # TODO: Turn this into a warning. + # TODO: Add a URL explaining more. + echo("NOTE: The .nimble file for this project could make use of " & + "additional features, if converted into the new NimScript format.") + proc multiSplit(s: string): seq[string] = ## Returns ``s`` split by newline and comma characters. ## @@ -169,17 +175,42 @@ proc getNameVersion*(pkgpath: string): tuple[name, version: string] = break proc readPackageInfo*(nf: NimbleFile; onlyMinimalInfo=false): PackageInfo = - result = initPackageInfo(nf.file) - if nf.isNimScript: + ## Reads package info from the specifed Nimble file. + ## + ## Attempts to read it using the "old" Nimble ini format first, if that + ## fails attempts to evaluate it as a nimscript file. + ## + ## If both fail then returns an error. + result = initPackageInfo(nf) + + var success = false + var iniError: ref NimbleError + # Attempt ini-format first. + try: + readPackageInfoFromNimble(nf, result) + success = true + result.isNimScript = false + except NimbleError: + iniError = (ref NimbleError)(getCurrentException()) + + if not success: if onlyMinimalInfo: - let tmp = getNameVersion(nf.file) + let tmp = getNameVersion(nf) result.name = tmp.name result.version = tmp.version else: - readPackageInfoFromNims(nf.file, result) - else: - readPackageInfoFromNimble(nf.file, result) - validatePackageInfo(result, nf.file) + try: + readPackageInfoFromNims(nf, result) + result.isNimScript = true + except NimbleError: + let msg = "Could not read package info file in " & nf & ";\n" & + " Reading as ini file failed with: \n" & + " " & iniError.msg & ".\n" & + " Evaluating as NimScript file failed with: \n" & + " " & getCurrentExceptionMsg() & "." + raise newException(NimbleError, msg) + + validatePackageInfo(result, nf) proc optionalField(obj: JsonNode, name: string, default = ""): string = ## Queries ``obj`` for the optional ``name`` string. @@ -257,17 +288,14 @@ proc getPackageList*(packagesPath: string): seq[Package] = result.add(pkg) proc findNimbleFile*(dir: string; error: bool): NimbleFile = - result = (false, "") + result = "" var hits = 0 for kind, path in walkDir(dir): if kind == pcFile: let ext = path.splitFile.ext case ext of ".babel", ".nimble": - result = (false, path) - inc hits - of NimsExt: - result = (true, path) + result = path inc hits else: discard if hits >= 2: @@ -295,7 +323,7 @@ proc getInstalledPkgs*(libsDir: string): for kind, path in walkDir(libsDir): if kind == pcDir: let nimbleFile = findNimbleFile(path, false) - if nimbleFile.file != "": + if nimbleFile != "": let meta = readMetaData(path) result.add((readPackageInfo(nimbleFile, true), meta)) @@ -359,6 +387,9 @@ proc getDownloadDirName*(pkg: Package, verRange: VersionRange): string = result.add "_" result.add verSimple +proc isNimScript*(nf: NimbleFile): bool = + readPackageInfo(nf).isNimScript + when isMainModule: doAssert getNameVersion("/home/user/.nimble/libs/packagea-0.1") == ("packagea", "0.1")