Remove unused file
The file nimscriptsupport.nim is no longer used in favor of the newer version nimscriptwrapper.nim. Related to #680
This commit is contained in:
parent
bfc4f25548
commit
1eb9f0f01c
1 changed files with 0 additions and 708 deletions
|
|
@ -1,708 +0,0 @@
|
|||
# Copyright (C) Andreas Rumpf. All rights reserved.
|
||||
# BSD License. Look at license.txt for more info.
|
||||
|
||||
## Implements the new configuration system for Nimble. Uses Nim as a
|
||||
## scripting language.
|
||||
|
||||
import
|
||||
compiler/ast, compiler/modules, compiler/passes, compiler/condsyms,
|
||||
compiler/sem, compiler/llstream, compiler/vm, compiler/vmdef, compiler/idents,
|
||||
compiler/nimconf, compiler/nversion
|
||||
|
||||
from compiler/astalgo import strTableGet
|
||||
import compiler/options as compiler_options
|
||||
|
||||
import common, version, options, cli, tools
|
||||
import os, strutils, tables, times, osproc, sets, pegs
|
||||
|
||||
when not declared(resetAllModulesHard):
|
||||
import compiler/modulegraphs
|
||||
|
||||
type
|
||||
Flags = TableRef[string, seq[string]]
|
||||
ExecutionResult*[T] = object
|
||||
success*: bool
|
||||
command*: string
|
||||
arguments*: seq[string]
|
||||
flags*: Flags
|
||||
retVal*: T
|
||||
|
||||
const
|
||||
internalCmd = "NimbleInternal"
|
||||
nimscriptApi = staticRead("nimscriptapi.nim")
|
||||
|
||||
proc raiseVariableError(ident, typ: string) {.noinline.} =
|
||||
raise newException(NimbleError,
|
||||
"NimScript's variable '" & ident & "' needs a value of type '" & typ & "'.")
|
||||
|
||||
proc isStrLit(n: PNode): bool = n.kind in {nkStrLit..nkTripleStrLit}
|
||||
|
||||
when declared(NimCompilerApiVersion):
|
||||
const finalApi = NimCompilerApiVersion >= 2
|
||||
|
||||
when NimCompilerApiVersion >= 3:
|
||||
import compiler / pathutils
|
||||
else:
|
||||
const finalApi = false
|
||||
|
||||
proc getGlobal(g: ModuleGraph; ident: PSym): string =
|
||||
when finalApi:
|
||||
let n = vm.getGlobalValue(PCtx g.vm, ident)
|
||||
else:
|
||||
let n = vm.globalCtx.getGlobalValue(ident)
|
||||
if n.isStrLit:
|
||||
result = n.strVal
|
||||
else:
|
||||
raiseVariableError(ident.name.s, "string")
|
||||
|
||||
proc getGlobalAsSeq(g: ModuleGraph; ident: PSym): seq[string] =
|
||||
when finalApi:
|
||||
let n = vm.getGlobalValue(PCtx g.vm, ident)
|
||||
else:
|
||||
let n = vm.globalCtx.getGlobalValue(ident)
|
||||
result = @[]
|
||||
if n.kind == nkBracket:
|
||||
for x in n:
|
||||
if x.isStrLit:
|
||||
result.add x.strVal
|
||||
else:
|
||||
raiseVariableError(ident.name.s, "seq[string]")
|
||||
else:
|
||||
raiseVariableError(ident.name.s, "seq[string]")
|
||||
|
||||
proc extractRequires(g: ModuleGraph; ident: PSym, result: var seq[PkgTuple]) =
|
||||
when finalApi:
|
||||
let n = vm.getGlobalValue(PCtx g.vm, ident)
|
||||
else:
|
||||
let n = vm.globalCtx.getGlobalValue(ident)
|
||||
if n.kind == nkBracket:
|
||||
for x in n:
|
||||
if x.kind == nkPar and x.len == 2 and x[0].isStrLit and x[1].isStrLit:
|
||||
result.add(parseRequires(x[0].strVal & x[1].strVal))
|
||||
elif x.isStrLit:
|
||||
result.add(parseRequires(x.strVal))
|
||||
else:
|
||||
raiseVariableError("requiresData", "seq[(string, VersionReq)]")
|
||||
else:
|
||||
raiseVariableError("requiresData", "seq[(string, VersionReq)]")
|
||||
|
||||
when declared(newIdentCache):
|
||||
var identCache = newIdentCache()
|
||||
|
||||
proc setupVM(graph: ModuleGraph; module: PSym; scriptName: string, flags: Flags): PEvalContext =
|
||||
## This procedure is exported in the compiler sources, but its implementation
|
||||
## is too Nim-specific to be used by Nimble.
|
||||
## Specifically, the implementation of ``switch`` is problematic. Sooo
|
||||
## I simply copied it here and edited it :)
|
||||
when declared(NimCompilerApiVersion):
|
||||
result = newCtx(module, identCache, graph)
|
||||
elif declared(newIdentCache):
|
||||
result = newCtx(module, identCache)
|
||||
else:
|
||||
result = newCtx(module)
|
||||
result.mode = emRepl
|
||||
registerAdditionalOps(result)
|
||||
|
||||
# captured vars:
|
||||
let conf = graph.config
|
||||
var errorMsg: string
|
||||
var vthisDir = scriptName.splitFile.dir
|
||||
|
||||
proc listDirs(a: VmArgs, filter: set[PathComponent]) =
|
||||
let dir = getString(a, 0)
|
||||
var res: seq[string] = @[]
|
||||
for kind, path in walkDir(dir):
|
||||
if kind in filter: res.add path
|
||||
setResult(a, res)
|
||||
|
||||
template cbconf(name, body) {.dirty.} =
|
||||
result.registerCallback "stdlib.system." & astToStr(name),
|
||||
proc (a: VmArgs) =
|
||||
body
|
||||
|
||||
template cbos(name, body) {.dirty.} =
|
||||
result.registerCallback "stdlib.system." & astToStr(name),
|
||||
proc (a: VmArgs) =
|
||||
try:
|
||||
body
|
||||
except OSError:
|
||||
errorMsg = getCurrentExceptionMsg()
|
||||
|
||||
# Idea: Treat link to file as a file, but ignore link to directory to prevent
|
||||
# endless recursions out of the box.
|
||||
cbos listFiles:
|
||||
listDirs(a, {pcFile, pcLinkToFile})
|
||||
cbos listDirs:
|
||||
listDirs(a, {pcDir})
|
||||
cbos removeDir:
|
||||
os.removeDir getString(a, 0)
|
||||
cbos removeFile:
|
||||
os.removeFile getString(a, 0)
|
||||
cbos createDir:
|
||||
os.createDir getString(a, 0)
|
||||
cbos getOsError:
|
||||
setResult(a, errorMsg)
|
||||
cbos setCurrentDir:
|
||||
os.setCurrentDir getString(a, 0)
|
||||
cbos getCurrentDir:
|
||||
setResult(a, os.getCurrentDir())
|
||||
cbos moveFile:
|
||||
os.moveFile(getString(a, 0), getString(a, 1))
|
||||
cbos copyFile:
|
||||
os.copyFile(getString(a, 0), getString(a, 1))
|
||||
cbos getLastModificationTime:
|
||||
setResult(a, toUnix(getLastModificationTime(getString(a, 0))))
|
||||
cbos findExe:
|
||||
setResult(a, os.findExe(getString(a, 0)))
|
||||
|
||||
cbos rawExec:
|
||||
setResult(a, osproc.execCmd getString(a, 0))
|
||||
|
||||
cbconf getEnv:
|
||||
setResult(a, os.getEnv(a.getString 0))
|
||||
cbconf existsEnv:
|
||||
setResult(a, os.existsEnv(a.getString 0))
|
||||
cbconf dirExists:
|
||||
setResult(a, os.dirExists(a.getString 0))
|
||||
cbconf fileExists:
|
||||
setResult(a, os.fileExists(a.getString 0))
|
||||
|
||||
cbconf thisDir:
|
||||
setResult(a, vthisDir)
|
||||
cbconf put:
|
||||
when declared(NimCompilerApiVersion):
|
||||
compiler_options.setConfigVar(conf, getString(a, 0), getString(a, 1))
|
||||
else:
|
||||
compiler_options.setConfigVar(getString(a, 0), getString(a, 1))
|
||||
cbconf get:
|
||||
when declared(NimCompilerApiVersion):
|
||||
setResult(a, compiler_options.getConfigVar(conf, a.getString 0))
|
||||
else:
|
||||
setResult(a, compiler_options.getConfigVar(a.getString 0))
|
||||
cbconf exists:
|
||||
when declared(NimCompilerApiVersion):
|
||||
setResult(a, compiler_options.existsConfigVar(conf, a.getString 0))
|
||||
else:
|
||||
setResult(a, compiler_options.existsConfigVar(a.getString 0))
|
||||
cbconf nimcacheDir:
|
||||
when declared(NimCompilerApiVersion):
|
||||
setResult(a, compiler_options.getNimcacheDir(conf))
|
||||
else:
|
||||
setResult(a, compiler_options.getNimcacheDir())
|
||||
cbconf paramStr:
|
||||
setResult(a, os.paramStr(int a.getInt 0))
|
||||
cbconf paramCount:
|
||||
setResult(a, os.paramCount())
|
||||
cbconf cmpIgnoreStyle:
|
||||
setResult(a, strutils.cmpIgnoreStyle(a.getString 0, a.getString 1))
|
||||
cbconf cmpIgnoreCase:
|
||||
setResult(a, strutils.cmpIgnoreCase(a.getString 0, a.getString 1))
|
||||
cbconf setCommand:
|
||||
when declared(NimCompilerApiVersion):
|
||||
conf.command = a.getString 0
|
||||
let arg = a.getString 1
|
||||
if arg.len > 0:
|
||||
conf.projectName = arg
|
||||
when NimCompilerApiVersion >= 3:
|
||||
try:
|
||||
conf.projectFull = canonicalizePath(conf,
|
||||
conf.projectPath / RelativeFile(conf.projectName))
|
||||
except OSError:
|
||||
conf.projectFull = AbsoluteFile conf.projectName
|
||||
else:
|
||||
try:
|
||||
conf.projectFull = canonicalizePath(conf, conf.projectPath / conf.projectName)
|
||||
except OSError:
|
||||
conf.projectFull = conf.projectName
|
||||
else:
|
||||
compiler_options.command = a.getString 0
|
||||
let arg = a.getString 1
|
||||
if arg.len > 0:
|
||||
gProjectName = arg
|
||||
try:
|
||||
gProjectFull = canonicalizePath(gProjectPath / gProjectName)
|
||||
except OSError:
|
||||
gProjectFull = gProjectName
|
||||
cbconf getCommand:
|
||||
when declared(NimCompilerApiVersion):
|
||||
setResult(a, conf.command)
|
||||
else:
|
||||
setResult(a, compiler_options.command)
|
||||
cbconf switch:
|
||||
if not flags.isNil:
|
||||
let
|
||||
key = a.getString 0
|
||||
value = a.getString 1
|
||||
if flags.hasKey(key):
|
||||
flags[key].add(value)
|
||||
else:
|
||||
flags[key] = @[value]
|
||||
|
||||
proc isValidLibPath(lib: string): bool =
|
||||
return fileExists(lib / "system.nim")
|
||||
|
||||
proc getNimPrefixDir(options: Options): string =
|
||||
let env = getEnv("NIM_LIB_PREFIX")
|
||||
if env != "":
|
||||
let msg = "Using env var NIM_LIB_PREFIX: " & env
|
||||
display("Warning:", msg, Warning, HighPriority)
|
||||
return env
|
||||
|
||||
if options.config.nimLibPrefix != "":
|
||||
result = options.config.nimLibPrefix
|
||||
let msg = "Using Nim stdlib prefix from Nimble config file: " & result
|
||||
display("Warning:", msg, Warning, HighPriority)
|
||||
return
|
||||
|
||||
result = splitPath(findExe("nim")).head.parentDir
|
||||
# The above heuristic doesn't work for 'choosenim' proxies. Thankfully in
|
||||
# that case the `nimble` binary is beside the `nim` binary so things should
|
||||
# just work.
|
||||
if not dirExists(result / "lib"):
|
||||
# By specifying an empty string we instruct the Nim compiler to use
|
||||
# getAppDir().head as the prefix dir. See compiler/options module for
|
||||
# the code responsible for this.
|
||||
result = ""
|
||||
|
||||
proc getLibVersion(lib: string): Version =
|
||||
## This is quite a hacky procedure, but there is no other way to extract
|
||||
## this out of the ``system`` module. We could evaluate it, but that would
|
||||
## cause an error if the stdlib is out of date. The purpose of this
|
||||
## proc is to give a nice error message to the user instead of a confusing
|
||||
## Nim compile error.
|
||||
let systemPath = lib / "system.nim"
|
||||
if not fileExists(systemPath):
|
||||
raiseNimbleError("system module not found in stdlib path: " & lib)
|
||||
|
||||
let systemFile = readFile(systemPath)
|
||||
let majorPeg = peg"'NimMajor' @ '=' \s* {\d*}"
|
||||
let minorPeg = peg"'NimMinor' @ '=' \s* {\d*}"
|
||||
let patchPeg = peg"'NimPatch' @ '=' \s* {\d*}"
|
||||
|
||||
var majorMatches: array[1, string]
|
||||
let major = find(systemFile, majorPeg, majorMatches)
|
||||
var minorMatches: array[1, string]
|
||||
let minor = find(systemFile, minorPeg, minorMatches)
|
||||
var patchMatches: array[1, string]
|
||||
let patch = find(systemFile, patchPeg, patchMatches)
|
||||
|
||||
if major != -1 and minor != -1 and patch != -1:
|
||||
return newVersion(majorMatches[0] & "." & minorMatches[0] & "." & patchMatches[0])
|
||||
else:
|
||||
return system.NimVersion.newVersion()
|
||||
|
||||
when finalApi:
|
||||
var graph = newModuleGraph(identCache, newConfigRef())
|
||||
|
||||
elif declared(ModuleGraph):
|
||||
var graph = newModuleGraph()
|
||||
|
||||
proc execScript(scriptName: string, flags: Flags, options: Options): PSym =
|
||||
## Executes the specified script. Returns the script's module symbol.
|
||||
##
|
||||
## No clean up is performed and must be done manually!
|
||||
when finalApi:
|
||||
graph = newModuleGraph(graph.cache, graph.config)
|
||||
else:
|
||||
graph = newModuleGraph(graph.config)
|
||||
|
||||
let conf = graph.config
|
||||
when declared(NimCompilerApiVersion):
|
||||
if "nimblepkg/nimscriptapi" notin conf.implicitImports:
|
||||
conf.implicitImports.add("nimblepkg/nimscriptapi")
|
||||
elif declared(resetAllModulesHard):
|
||||
# for compatibility with older Nim versions:
|
||||
if "nimblepkg/nimscriptapi" notin compiler_options.implicitIncludes:
|
||||
compiler_options.implicitIncludes.add("nimblepkg/nimscriptapi")
|
||||
else:
|
||||
if "nimblepkg/nimscriptapi" notin compiler_options.implicitImports:
|
||||
compiler_options.implicitImports.add("nimblepkg/nimscriptapi")
|
||||
|
||||
# Ensure the compiler can find its standard library #220.
|
||||
when declared(NimCompilerApiVersion):
|
||||
when NimCompilerApiVersion >= 3:
|
||||
conf.prefixDir = AbsoluteDir getNimPrefixDir(options)
|
||||
display("Setting", "Nim stdlib prefix to " & conf.prefixDir.string,
|
||||
priority=LowPriority)
|
||||
|
||||
template myLibPath(): untyped = conf.libpath.string
|
||||
|
||||
else:
|
||||
conf.prefixDir = getNimPrefixDir(options)
|
||||
display("Setting", "Nim stdlib prefix to " & conf.prefixDir,
|
||||
priority=LowPriority)
|
||||
|
||||
template myLibPath(): untyped = conf.libpath
|
||||
|
||||
# Verify that lib path points to existing stdlib.
|
||||
setDefaultLibpath(conf)
|
||||
else:
|
||||
compiler_options.gPrefixDir = getNimPrefixDir(options)
|
||||
display("Setting", "Nim stdlib prefix to " & compiler_options.gPrefixDir,
|
||||
priority=LowPriority)
|
||||
|
||||
template myLibPath(): untyped = compiler_options.libpath
|
||||
|
||||
# Verify that lib path points to existing stdlib.
|
||||
compiler_options.setDefaultLibpath()
|
||||
|
||||
display("Setting", "Nim stdlib path to " & myLibPath(),
|
||||
priority=LowPriority)
|
||||
if not isValidLibPath(myLibPath()):
|
||||
let msg = "Nimble cannot find Nim's standard library.\nLast try in:\n - $1" %
|
||||
myLibPath()
|
||||
let hint = "Nimble does its best to find Nim's standard library, " &
|
||||
"sometimes this fails. You can set the environment variable " &
|
||||
"NIM_LIB_PREFIX to where Nim's `lib` directory is located as " &
|
||||
"a workaround. " &
|
||||
"See https://github.com/nim-lang/nimble#troubleshooting for " &
|
||||
"more info."
|
||||
raiseNimbleError(msg, hint)
|
||||
|
||||
# Verify that the stdlib that was found isn't older than the stdlib that Nimble
|
||||
# was compiled with.
|
||||
let libVersion = getLibVersion(myLibPath())
|
||||
if NimVersion.newVersion() > libVersion:
|
||||
let msg = ("Nimble cannot use an older stdlib than the one it was compiled " &
|
||||
"with.\n Stdlib in '$#' has version: $#.\n Nimble needs at least: $#.") %
|
||||
[myLibPath(), $libVersion, NimVersion]
|
||||
let hint = "You may be running a newer version of Nimble than you intended " &
|
||||
"to. Run an older version of Nimble that is compatible with " &
|
||||
"the stdlib that Nimble is attempting to use or set the environment variable " &
|
||||
"NIM_LIB_PREFIX to where a different stdlib's `lib` directory is located as " &
|
||||
"a workaround." &
|
||||
"See https://github.com/nim-lang/nimble#troubleshooting for " &
|
||||
"more info."
|
||||
raiseNimbleError(msg, hint)
|
||||
|
||||
# Ensure that "nimblepkg/nimscriptapi" is in the PATH.
|
||||
block:
|
||||
let t = getNimbleUserTempDir() / "nimblecache"
|
||||
let tmpNimscriptApiPath = t / "nimblepkg" / "nimscriptapi.nim"
|
||||
createDir(tmpNimscriptApiPath.splitFile.dir)
|
||||
writeFile(tmpNimscriptApiPath, nimscriptApi)
|
||||
when declared(NimCompilerApiVersion):
|
||||
when NimCompilerApiVersion >= 3:
|
||||
conf.searchPaths.add(AbsoluteDir t)
|
||||
else:
|
||||
conf.searchPaths.add(t)
|
||||
else:
|
||||
searchPaths.add(t)
|
||||
|
||||
when declared(NimCompilerApiVersion):
|
||||
initDefines(conf.symbols)
|
||||
when NimCompilerApiVersion >= 2:
|
||||
loadConfigs(DefaultConfig, graph.cache, conf)
|
||||
else:
|
||||
loadConfigs(DefaultConfig, conf)
|
||||
passes.gIncludeFile = includeModule
|
||||
passes.gImportModule = importModule
|
||||
|
||||
defineSymbol(conf.symbols, "nimscript")
|
||||
defineSymbol(conf.symbols, "nimconfig")
|
||||
defineSymbol(conf.symbols, "nimble")
|
||||
when NimCompilerApiVersion >= 2:
|
||||
registerPass(graph, semPass)
|
||||
registerPass(graph, evalPass)
|
||||
else:
|
||||
registerPass(semPass)
|
||||
registerPass(evalPass)
|
||||
|
||||
conf.searchPaths.add(conf.libpath)
|
||||
else:
|
||||
initDefines()
|
||||
loadConfigs(DefaultConfig)
|
||||
passes.gIncludeFile = includeModule
|
||||
passes.gImportModule = importModule
|
||||
|
||||
defineSymbol("nimscript")
|
||||
defineSymbol("nimconfig")
|
||||
defineSymbol("nimble")
|
||||
registerPass(semPass)
|
||||
registerPass(evalPass)
|
||||
|
||||
searchPaths.add(compiler_options.libpath)
|
||||
|
||||
when declared(resetAllModulesHard):
|
||||
result = makeModule(scriptName)
|
||||
else:
|
||||
result = graph.makeModule(scriptName)
|
||||
|
||||
incl(result.flags, sfMainModule)
|
||||
when finalApi:
|
||||
graph.vm = setupVM(graph, result, scriptName, flags)
|
||||
|
||||
# Setup builtins defined in nimscriptapi.nim
|
||||
template cbApi(name, body) {.dirty.} =
|
||||
PCtx(graph.vm).registerCallback "nimscriptapi." & astToStr(name),
|
||||
proc (a: VmArgs) =
|
||||
body
|
||||
|
||||
else:
|
||||
vm.globalCtx = setupVM(graph, result, scriptName, flags)
|
||||
|
||||
# Setup builtins defined in nimscriptapi.nim
|
||||
template cbApi(name, body) {.dirty.} =
|
||||
vm.globalCtx.registerCallback "nimscriptapi." & astToStr(name),
|
||||
proc (a: VmArgs) =
|
||||
body
|
||||
|
||||
cbApi getPkgDir:
|
||||
setResult(a, scriptName.splitFile.dir)
|
||||
|
||||
when finalApi:
|
||||
graph.compileSystemModule()
|
||||
when NimCompilerApiVersion >= 3:
|
||||
graph.processModule(result, llStreamOpen(AbsoluteFile scriptName, fmRead))
|
||||
else:
|
||||
graph.processModule(result, llStreamOpen(scriptName, fmRead))
|
||||
elif declared(newIdentCache):
|
||||
graph.compileSystemModule(identCache)
|
||||
graph.processModule(result, llStreamOpen(scriptName, fmRead), nil, identCache)
|
||||
else:
|
||||
compileSystemModule()
|
||||
processModule(result, llStreamOpen(scriptName, fmRead), nil)
|
||||
|
||||
proc cleanup() =
|
||||
# ensure everything can be called again:
|
||||
when declared(NimCompilerApiVersion):
|
||||
let conf = graph.config
|
||||
conf.projectName = ""
|
||||
conf.command = ""
|
||||
else:
|
||||
compiler_options.gProjectName = ""
|
||||
compiler_options.command = ""
|
||||
when declared(NimCompilerApiVersion):
|
||||
resetSystemArtifacts(graph)
|
||||
elif declared(resetAllModulesHard):
|
||||
resetAllModulesHard()
|
||||
else:
|
||||
resetSystemArtifacts()
|
||||
when finalApi:
|
||||
clearPasses(graph)
|
||||
else:
|
||||
clearPasses()
|
||||
when declared(NimCompilerApiVersion):
|
||||
conf.errorMax = 1
|
||||
when NimCompilerApiVersion >= 2:
|
||||
conf.writeLnHook = nil
|
||||
graph.vm = nil
|
||||
else:
|
||||
msgs.writeLnHook = nil
|
||||
vm.globalCtx = nil
|
||||
initDefines(conf.symbols)
|
||||
else:
|
||||
msgs.gErrorMax = 1
|
||||
msgs.writeLnHook = nil
|
||||
vm.globalCtx = nil
|
||||
initDefines()
|
||||
|
||||
proc readPackageInfoFromNims*(scriptName: string, options: Options,
|
||||
result: var PackageInfo) =
|
||||
## Executes the `scriptName` nimscript file. Reads the package information
|
||||
## that it populates.
|
||||
|
||||
# Setup custom error handling.
|
||||
when declared(NimCompilerApiVersion):
|
||||
let conf = graph.config
|
||||
conf.errorMax = high(int)
|
||||
else:
|
||||
msgs.gErrorMax = high(int)
|
||||
|
||||
template errCounter(): int =
|
||||
when declared(NimCompilerApiVersion): conf.errorCounter
|
||||
else: msgs.gErrorCounter
|
||||
|
||||
var previousMsg = ""
|
||||
|
||||
proc writelnHook(output: string) =
|
||||
# The error counter is incremented after the writeLnHook is invoked.
|
||||
if errCounter() > 0:
|
||||
raise newException(NimbleError, previousMsg)
|
||||
elif previousMsg.len > 0:
|
||||
display("Info", previousMsg, priority = MediumPriority)
|
||||
if output.normalize.startsWith("error"):
|
||||
raise newException(NimbleError, output)
|
||||
previousMsg = output
|
||||
|
||||
when finalApi:
|
||||
conf.writelnHook = writelnHook
|
||||
else:
|
||||
msgs.writeLnHook = writelnHook
|
||||
|
||||
when declared(NimCompilerApiVersion):
|
||||
conf.command = internalCmd
|
||||
else:
|
||||
compiler_options.command = internalCmd
|
||||
|
||||
# Execute the nimscript file.
|
||||
let thisModule = execScript(scriptName, nil, options)
|
||||
|
||||
when declared(resetAllModulesHard):
|
||||
let apiModule = thisModule
|
||||
else:
|
||||
var apiModule: PSym
|
||||
for i in 0..<graph.modules.len:
|
||||
if graph.modules[i] != nil and
|
||||
graph.modules[i].name.s == "nimscriptapi":
|
||||
apiModule = graph.modules[i]
|
||||
break
|
||||
doAssert apiModule != nil
|
||||
|
||||
# Check whether an error has occurred.
|
||||
if errCounter() > 0:
|
||||
raise newException(NimbleError, previousMsg)
|
||||
|
||||
# Extract all the necessary fields populated by the nimscript file.
|
||||
proc getSym(apiModule: PSym, ident: string): PSym =
|
||||
result = apiModule.tab.strTableGet(getIdent(identCache, ident))
|
||||
if result.isNil:
|
||||
raise newException(NimbleError, "Ident not found: " & ident)
|
||||
|
||||
template trivialField(field) =
|
||||
result.field = getGlobal(graph, getSym(apiModule, astToStr field))
|
||||
|
||||
template trivialFieldSeq(field) =
|
||||
result.field.add getGlobalAsSeq(graph, getSym(apiModule, astToStr field))
|
||||
|
||||
# keep reasonable default:
|
||||
let name = getGlobal(graph, apiModule.tab.strTableGet(getIdent(identCache, "packageName")))
|
||||
if name.len > 0: result.name = name
|
||||
|
||||
trivialField version
|
||||
trivialField author
|
||||
trivialField description
|
||||
trivialField license
|
||||
trivialField srcdir
|
||||
trivialField bindir
|
||||
trivialFieldSeq skipDirs
|
||||
trivialFieldSeq skipFiles
|
||||
trivialFieldSeq skipExt
|
||||
trivialFieldSeq installDirs
|
||||
trivialFieldSeq installFiles
|
||||
trivialFieldSeq installExt
|
||||
trivialFieldSeq foreignDeps
|
||||
|
||||
extractRequires(graph, getSym(apiModule, "requiresData"), result.requires)
|
||||
|
||||
let binSeq = getGlobalAsSeq(graph, getSym(apiModule, "bin"))
|
||||
for i in binSeq:
|
||||
result.bin.add(i.addFileExt(ExeExt))
|
||||
|
||||
let backend = getGlobal(graph, getSym(apiModule, "backend"))
|
||||
if backend.len == 0:
|
||||
result.backend = "c"
|
||||
elif cmpIgnoreStyle(backend, "javascript") == 0:
|
||||
result.backend = "js"
|
||||
else:
|
||||
result.backend = backend.toLowerAscii()
|
||||
|
||||
# Grab all the global procs
|
||||
for i in thisModule.tab.data:
|
||||
if not i.isNil():
|
||||
let name = i.name.s.normalize()
|
||||
if name.endsWith("before"):
|
||||
result.preHooks.incl(name[0 .. ^7])
|
||||
if name.endsWith("after"):
|
||||
result.postHooks.incl(name[0 .. ^6])
|
||||
|
||||
cleanup()
|
||||
|
||||
when declared(NimCompilerApiVersion):
|
||||
template nimCommand(): untyped = conf.command
|
||||
template nimProjectName(): untyped = conf.projectName
|
||||
else:
|
||||
template nimCommand(): untyped = compiler_options.command
|
||||
template nimProjectName(): untyped = compiler_options.gProjectName
|
||||
|
||||
proc execTask*(scriptName, taskName: string,
|
||||
options: Options): ExecutionResult[void] =
|
||||
## Executes the specified task in the specified script.
|
||||
##
|
||||
## `scriptName` should be a filename pointing to the nimscript file.
|
||||
result.success = true
|
||||
result.flags = newTable[string, seq[string]]()
|
||||
when declared(NimCompilerApiVersion):
|
||||
let conf = graph.config
|
||||
nimCommand() = internalCmd
|
||||
display("Executing", "task $# in $#" % [taskName, scriptName],
|
||||
priority = HighPriority)
|
||||
|
||||
let thisModule = execScript(scriptName, result.flags, options)
|
||||
let prc = thisModule.tab.strTableGet(getIdent(identCache, taskName & "Task"))
|
||||
if prc.isNil:
|
||||
# Procedure not defined in the NimScript module.
|
||||
result.success = false
|
||||
cleanup()
|
||||
return
|
||||
when finalApi:
|
||||
discard vm.execProc(PCtx(graph.vm), prc, [])
|
||||
else:
|
||||
discard vm.globalCtx.execProc(prc, [])
|
||||
|
||||
# Read the command, arguments and flags set by the executed task.
|
||||
result.command = nimCommand()
|
||||
result.arguments = @[]
|
||||
for arg in nimProjectName().split():
|
||||
result.arguments.add(arg)
|
||||
|
||||
cleanup()
|
||||
|
||||
proc execHook*(scriptName, actionName: string, before: bool,
|
||||
options: Options): ExecutionResult[bool] =
|
||||
## Executes the specified action's hook. Depending on ``before``, either
|
||||
## the "before" or the "after" hook.
|
||||
##
|
||||
## `scriptName` should be a filename pointing to the nimscript file.
|
||||
when declared(NimCompilerApiVersion):
|
||||
let conf = graph.config
|
||||
result.success = true
|
||||
result.flags = newTable[string, seq[string]]()
|
||||
nimCommand() = internalCmd
|
||||
let hookName =
|
||||
if before: actionName.toLowerAscii & "Before"
|
||||
else: actionName.toLowerAscii & "After"
|
||||
display("Attempting", "to execute hook $# in $#" % [hookName, scriptName],
|
||||
priority = MediumPriority)
|
||||
|
||||
let thisModule = execScript(scriptName, result.flags, options)
|
||||
# Explicitly execute the task procedure, instead of relying on hack.
|
||||
let prc = thisModule.tab.strTableGet(getIdent(identCache, hookName))
|
||||
if prc.isNil:
|
||||
# Procedure not defined in the NimScript module.
|
||||
result.success = false
|
||||
cleanup()
|
||||
return
|
||||
when finalApi:
|
||||
let returnVal = vm.execProc(PCtx(graph.vm), prc, [])
|
||||
else:
|
||||
let returnVal = vm.globalCtx.execProc(prc, [])
|
||||
case returnVal.kind
|
||||
of nkCharLit..nkUInt64Lit:
|
||||
result.retVal = returnVal.intVal == 1
|
||||
else: assert false
|
||||
|
||||
# Read the command, arguments and flags set by the executed task.
|
||||
result.command = nimCommand()
|
||||
result.arguments = @[]
|
||||
for arg in nimProjectName().split():
|
||||
result.arguments.add(arg)
|
||||
|
||||
cleanup()
|
||||
|
||||
proc setNimScriptCommand(command: string) =
|
||||
when declared(NimCompilerApiVersion):
|
||||
let conf = graph.config
|
||||
nimCommand() = command
|
||||
|
||||
proc hasTaskRequestedCommand*(execResult: ExecutionResult): bool =
|
||||
## Determines whether the last executed task used ``setCommand``
|
||||
return execResult.command != internalCmd
|
||||
|
||||
proc listTasks*(scriptName: string, options: Options) =
|
||||
setNimScriptCommand("help")
|
||||
|
||||
discard execScript(scriptName, nil, options)
|
||||
# TODO (#402): Make the 'task' template generate explicit data structure
|
||||
# containing all the task names + descriptions.
|
||||
cleanup()
|
||||
Loading…
Add table
Add a link
Reference in a new issue