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")