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.
This commit is contained in:
Dominik Picheta 2015-12-23 20:48:05 +00:00
commit dbd478bc20
4 changed files with 61 additions and 20 deletions

View file

@ -892,6 +892,7 @@ proc guessAuthor(): string =
return "Anonymous" return "Anonymous"
proc join(x: seq[PkgTuple]; y: string): string = proc join(x: seq[PkgTuple]; y: string): string =
if x.len == 0: return ""
result = x[0][0] & " " & $x[0][1] result = x[0][0] & " " & $x[0][1]
for i in 1 ..< x.len: for i in 1 ..< x.len:
result.add y result.add y
@ -899,7 +900,7 @@ proc join(x: seq[PkgTuple]; y: string): string =
proc dump(options: Options) = proc dump(options: Options) =
let proj = addFileExt(options.action.projName, NimsExt) 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()) else: getPkgInfo(os.getCurrentDir())
echo "name: ", p.name.escape echo "name: ", p.name.escape
echo "version: ", p.version.escape echo "version: ", p.version.escape
@ -1017,9 +1018,7 @@ proc uninstall(options: Options) =
echo("Removed ", pkg.name, " (", $pkg.version, ")") echo("Removed ", pkg.name, " (", $pkg.version, ")")
proc listTasks(options: Options) = proc listTasks(options: Options) =
let (isNimScript, nimbleFile) = findNimbleFile(getCurrentDir(), true) let nimbleFile = findNimbleFile(getCurrentDir(), true)
if not isNimScript:
echo("No tasks defined (Found Nimble file, but no NimScript file)")
nimscriptsupport.listTasks(nimbleFile) nimscriptsupport.listTasks(nimbleFile)
proc doAction(options: Options) = proc doAction(options: Options) =
@ -1064,8 +1063,8 @@ proc doAction(options: Options) =
assert false assert false
of actionCustom: of actionCustom:
# Custom command. Attempt to call a NimScript task. # Custom command. Attempt to call a NimScript task.
let (isNimScript, nimbleFile) = findNimbleFile(getCurrentDir(), true) let nimbleFile = findNimbleFile(getCurrentDir(), true)
if not isNimScript: if not nimbleFile.isNimScript():
writeHelp() writeHelp()
let oldCmd = getNimScriptCommand() let oldCmd = getNimScriptCommand()
if not execTask(nimbleFile, oldCmd): if not execTask(nimbleFile, oldCmd):

View file

@ -11,6 +11,7 @@ type
PackageInfo* = object PackageInfo* = object
mypath*: string ## The path of this .nimble file mypath*: string ## The path of this .nimble file
isNimScript*: bool ## Determines if this pkg info was read from a nims file
name*: string name*: string
version*: string version*: string
author*: string author*: string

View file

@ -93,6 +93,16 @@ proc readPackageInfoFromNims*(scriptName: string; result: var PackageInfo) =
## Executes the `scriptName` nimscript file. Reads the package information ## Executes the `scriptName` nimscript file. Reads the package information
## that it populates. ## 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. # Execute the nimscript file.
execScript(scriptName) execScript(scriptName)

View file

@ -26,7 +26,7 @@ type
MetaData* = object MetaData* = object
url*: string url*: string
NimbleFile* = tuple[isNimScript: bool; file: string] NimbleFile* = string
proc initPackageInfo(path: string): PackageInfo = proc initPackageInfo(path: string): PackageInfo =
result.mypath = path result.mypath = path
@ -73,6 +73,12 @@ proc validatePackageInfo(pkgInfo: PackageInfo, path: string) =
"Version may only consist of numbers and the '.' character " & "Version may only consist of numbers and the '.' character " &
"but found '" & c & "'.") "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] = proc multiSplit(s: string): seq[string] =
## Returns ``s`` split by newline and comma characters. ## Returns ``s`` split by newline and comma characters.
## ##
@ -169,17 +175,42 @@ proc getNameVersion*(pkgpath: string): tuple[name, version: string] =
break break
proc readPackageInfo*(nf: NimbleFile; onlyMinimalInfo=false): PackageInfo = proc readPackageInfo*(nf: NimbleFile; onlyMinimalInfo=false): PackageInfo =
result = initPackageInfo(nf.file) ## Reads package info from the specifed Nimble file.
if nf.isNimScript: ##
## 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: if onlyMinimalInfo:
let tmp = getNameVersion(nf.file) let tmp = getNameVersion(nf)
result.name = tmp.name result.name = tmp.name
result.version = tmp.version result.version = tmp.version
else: else:
readPackageInfoFromNims(nf.file, result) try:
else: readPackageInfoFromNims(nf, result)
readPackageInfoFromNimble(nf.file, result) result.isNimScript = true
validatePackageInfo(result, nf.file) 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 = proc optionalField(obj: JsonNode, name: string, default = ""): string =
## Queries ``obj`` for the optional ``name`` string. ## Queries ``obj`` for the optional ``name`` string.
@ -257,17 +288,14 @@ proc getPackageList*(packagesPath: string): seq[Package] =
result.add(pkg) result.add(pkg)
proc findNimbleFile*(dir: string; error: bool): NimbleFile = proc findNimbleFile*(dir: string; error: bool): NimbleFile =
result = (false, "") result = ""
var hits = 0 var hits = 0
for kind, path in walkDir(dir): for kind, path in walkDir(dir):
if kind == pcFile: if kind == pcFile:
let ext = path.splitFile.ext let ext = path.splitFile.ext
case ext case ext
of ".babel", ".nimble": of ".babel", ".nimble":
result = (false, path) result = path
inc hits
of NimsExt:
result = (true, path)
inc hits inc hits
else: discard else: discard
if hits >= 2: if hits >= 2:
@ -295,7 +323,7 @@ proc getInstalledPkgs*(libsDir: string):
for kind, path in walkDir(libsDir): for kind, path in walkDir(libsDir):
if kind == pcDir: if kind == pcDir:
let nimbleFile = findNimbleFile(path, false) let nimbleFile = findNimbleFile(path, false)
if nimbleFile.file != "": if nimbleFile != "":
let meta = readMetaData(path) let meta = readMetaData(path)
result.add((readPackageInfo(nimbleFile, true), meta)) result.add((readPackageInfo(nimbleFile, true), meta))
@ -359,6 +387,9 @@ proc getDownloadDirName*(pkg: Package, verRange: VersionRange): string =
result.add "_" result.add "_"
result.add verSimple result.add verSimple
proc isNimScript*(nf: NimbleFile): bool =
readPackageInfo(nf).isNimScript
when isMainModule: when isMainModule:
doAssert getNameVersion("/home/user/.nimble/libs/packagea-0.1") == doAssert getNameVersion("/home/user/.nimble/libs/packagea-0.1") ==
("packagea", "0.1") ("packagea", "0.1")