Improvements to API of nimscriptsupport module.
* setCommand "nop" no longer needed. * Recursive setCommand supported. * Explicit execTask procedure which executes the task explicitly instead of setting global compiler variables.
This commit is contained in:
parent
9b75a95459
commit
36273f1166
2 changed files with 73 additions and 19 deletions
|
|
@ -10,7 +10,7 @@ import nimblepkg/packageinfo, nimblepkg/version, nimblepkg/tools,
|
||||||
nimblepkg/download, nimblepkg/config, nimblepkg/nimbletypes,
|
nimblepkg/download, nimblepkg/config, nimblepkg/nimbletypes,
|
||||||
nimblepkg/publish
|
nimblepkg/publish
|
||||||
|
|
||||||
import compiler/options as compiler_options
|
import nimblepkg/nimscriptsupport
|
||||||
|
|
||||||
when not defined(windows):
|
when not defined(windows):
|
||||||
from posix import getpid
|
from posix import getpid
|
||||||
|
|
@ -223,7 +223,7 @@ proc parseCmdLine(): Options =
|
||||||
case kind
|
case kind
|
||||||
of cmdArgument:
|
of cmdArgument:
|
||||||
if result.action.typ == actionNil:
|
if result.action.typ == actionNil:
|
||||||
compiler_options.command = key
|
setNimScriptCommand(key)
|
||||||
result.action.typ = parseActionType(key)
|
result.action.typ = parseActionType(key)
|
||||||
initAction(result, key)
|
initAction(result, key)
|
||||||
else:
|
else:
|
||||||
|
|
@ -1017,14 +1017,9 @@ proc doAction(options: Options) =
|
||||||
if not existsDir(options.getPkgsDir):
|
if not existsDir(options.getPkgsDir):
|
||||||
createDir(options.getPkgsDir)
|
createDir(options.getPkgsDir)
|
||||||
|
|
||||||
# The nimscript file may use `setCommand` to set the command so we need to
|
var command = getNimScriptCommand().parseActionType()
|
||||||
# re-read it from the compiler.
|
# The loop is necessary to support tasks using `setCommand`.
|
||||||
# TODO: It doesn't appear that this actually happens, can we just remove this?
|
while true:
|
||||||
var command = compiler_options.command.parseActionType()
|
|
||||||
var doLoop = true
|
|
||||||
while doLoop:
|
|
||||||
doLoop = false
|
|
||||||
let cmd = compiler_options.command.normalize
|
|
||||||
case command
|
case command
|
||||||
of actionUpdate:
|
of actionUpdate:
|
||||||
update(options)
|
update(options)
|
||||||
|
|
@ -1050,11 +1045,22 @@ proc doAction(options: Options) =
|
||||||
publish(pkgInfo)
|
publish(pkgInfo)
|
||||||
of actionDump:
|
of actionDump:
|
||||||
dump(options)
|
dump(options)
|
||||||
of actionNil: discard "assuming nimscript 'nop' command here"
|
of actionNil:
|
||||||
|
assert false
|
||||||
of actionCustom:
|
of actionCustom:
|
||||||
# calls Nimscript as a side effect :-/
|
# Custom command. Attempt to call a NimScript task.
|
||||||
discard getPkgInfo(getCurrentDir())
|
let (isNimScript, nimbleFile) = findNimbleFile(getCurrentDir(), true)
|
||||||
doLoop = cmd != compiler_options.command.normalize
|
if not isNimScript:
|
||||||
|
writeHelp()
|
||||||
|
let oldCmd = getNimScriptCommand()
|
||||||
|
if not execTask(nimbleFile, oldCmd):
|
||||||
|
echo("FAILURE: Could not find task ", oldCmd, " in ", nimbleFile)
|
||||||
|
writeHelp()
|
||||||
|
if getNimScriptCommand().normalize == "nop":
|
||||||
|
echo("WARNING: Using `setCommand 'nop'` is not necessary.")
|
||||||
|
break
|
||||||
|
command = getNimScriptCommand().parseActionType()
|
||||||
|
if not hasTaskRequestedCommand(): break
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
when defined(release):
|
when defined(release):
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,15 @@ import
|
||||||
compiler/msgs, compiler/magicsys, compiler/lists
|
compiler/msgs, compiler/magicsys, compiler/lists
|
||||||
|
|
||||||
from compiler/scriptconfig import setupVM
|
from compiler/scriptconfig import setupVM
|
||||||
|
from compiler/idents import getIdent
|
||||||
|
from compiler/astalgo import strTableGet, `$`
|
||||||
|
|
||||||
import nimbletypes, version
|
import nimbletypes, version
|
||||||
import os, strutils
|
import os, strutils
|
||||||
|
|
||||||
|
const
|
||||||
|
internalCmd = "NimbleInternal"
|
||||||
|
|
||||||
proc raiseVariableError(ident, typ: string) {.noinline.} =
|
proc raiseVariableError(ident, typ: string) {.noinline.} =
|
||||||
raise newException(NimbleError,
|
raise newException(NimbleError,
|
||||||
"NimScript's variable '" & ident & "' needs a value of type '" & typ & "'.")
|
"NimScript's variable '" & ident & "' needs a value of type '" & typ & "'.")
|
||||||
|
|
@ -53,7 +58,10 @@ proc extractRequires(result: var seq[PkgTuple]) =
|
||||||
else:
|
else:
|
||||||
raiseVariableError("requiresData", "seq[(string, VersionReq)]")
|
raiseVariableError("requiresData", "seq[(string, VersionReq)]")
|
||||||
|
|
||||||
proc readPackageInfoFromNims*(scriptName: string; result: var PackageInfo) =
|
proc execScript(scriptName: string) =
|
||||||
|
## Executes the specified script.
|
||||||
|
##
|
||||||
|
## No clean up is performed and must be done manually!
|
||||||
setDefaultLibpath()
|
setDefaultLibpath()
|
||||||
passes.gIncludeFile = includeModule
|
passes.gIncludeFile = includeModule
|
||||||
passes.gImportModule = importModule
|
passes.gImportModule = importModule
|
||||||
|
|
@ -74,6 +82,21 @@ proc readPackageInfoFromNims*(scriptName: string; result: var PackageInfo) =
|
||||||
compileSystemModule()
|
compileSystemModule()
|
||||||
processModule(m, llStreamOpen(scriptName, fmRead), nil)
|
processModule(m, llStreamOpen(scriptName, fmRead), nil)
|
||||||
|
|
||||||
|
proc cleanup() =
|
||||||
|
# ensure everything can be called again:
|
||||||
|
resetAllModulesHard()
|
||||||
|
clearPasses()
|
||||||
|
vm.globalCtx = nil
|
||||||
|
initDefines()
|
||||||
|
|
||||||
|
proc readPackageInfoFromNims*(scriptName: string; result: var PackageInfo) =
|
||||||
|
## Executes the `scriptName` nimscript file. Reads the package information
|
||||||
|
## that it populates.
|
||||||
|
|
||||||
|
# Execute the nimscript file.
|
||||||
|
execScript(scriptName)
|
||||||
|
|
||||||
|
# Extract all the necessary fields populated by the nimscript file.
|
||||||
template trivialField(field) =
|
template trivialField(field) =
|
||||||
result.field = getGlobal(astToStr field)
|
result.field = getGlobal(astToStr field)
|
||||||
|
|
||||||
|
|
@ -111,7 +134,32 @@ proc readPackageInfoFromNims*(scriptName: string; result: var PackageInfo) =
|
||||||
else:
|
else:
|
||||||
result.backend = backend.toLower()
|
result.backend = backend.toLower()
|
||||||
|
|
||||||
# ensure everything can be called again:
|
cleanup()
|
||||||
resetAllModulesHard()
|
|
||||||
vm.globalCtx = nil
|
proc execTask*(scriptName, taskName: string): bool =
|
||||||
initDefines()
|
## Executes the specified task in the specified script.
|
||||||
|
##
|
||||||
|
## `scriptName` should be a filename pointing to the nimscript file.
|
||||||
|
result = true
|
||||||
|
options.command = internalCmd
|
||||||
|
echo("Executing task ", taskName, " in ", scriptName)
|
||||||
|
|
||||||
|
execScript(scriptName)
|
||||||
|
# Explicitly execute the task procedure, instead of relying on hack.
|
||||||
|
assert vm.globalCtx.module.kind == skModule
|
||||||
|
let prc = vm.globalCtx.module.tab.strTableGet(getIdent(taskName & "Task"))
|
||||||
|
if prc.isNil:
|
||||||
|
# Procedure not defined in the NimScript module.
|
||||||
|
return false
|
||||||
|
discard vm.globalCtx.execProc(prc, [])
|
||||||
|
cleanup()
|
||||||
|
|
||||||
|
proc getNimScriptCommand*(): string =
|
||||||
|
options.command
|
||||||
|
|
||||||
|
proc setNimScriptCommand*(command: string) =
|
||||||
|
options.command = command
|
||||||
|
|
||||||
|
proc hasTaskRequestedCommand*(): bool =
|
||||||
|
## Determines whether the last executed task used ``setCommand``
|
||||||
|
return getNimScriptCommand() != internalCmd
|
||||||
Loading…
Add table
Add a link
Reference in a new issue