diff options
author | Timothee Cour <timothee.cour2@gmail.com> | 2018-08-30 04:52:32 -0700 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-08-30 13:52:32 +0200 |
commit | ed0cb7b85d8d48bcebb63a5e90a45a4e29bcb673 (patch) | |
tree | a89177259a1fb42477adbafa09c1790c5fe50535 /compiler | |
parent | 01211ced1d5c3252c88e61bbbb6bb78dcc5575f0 (diff) | |
download | Nim-ed0cb7b85d8d48bcebb63a5e90a45a4e29bcb673.tar.gz |
make config.nims behave like nim.cfg in terms of where these scripts are searched / run (#8682)
* run project config.nims if exists, then inputfile.nims if exists * ~/.config/nim/config.nims can now be used * also check in getSystemConfigPath for config.nims * refactor handleCmdLine for nim and nimsuggest
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/cmdlinehelper.nim | 85 | ||||
-rw-r--r-- | compiler/commands.nim | 2 | ||||
-rw-r--r-- | compiler/nim.nim | 96 | ||||
-rw-r--r-- | compiler/nimconf.nim | 7 | ||||
-rw-r--r-- | compiler/options.nim | 9 | ||||
-rw-r--r-- | compiler/scriptconfig.nim | 2 |
6 files changed, 131 insertions, 70 deletions
diff --git a/compiler/cmdlinehelper.nim b/compiler/cmdlinehelper.nim new file mode 100644 index 000000000..9d2334af5 --- /dev/null +++ b/compiler/cmdlinehelper.nim @@ -0,0 +1,85 @@ +## Helpers for binaries that use compiler passes, eg: nim, nimsuggest, nimfix + +# TODO: nimfix should use this; currently out of sync + +import + compiler/[options, idents, nimconf, scriptconfig, extccomp, commands, msgs, lineinfos, modulegraphs, condsyms], + std/os + +type + NimProg* = ref object + suggestMode*: bool + supportsStdinFile*: bool + processCmdLine*: proc(pass: TCmdLinePass, cmd: string; config: ConfigRef) + mainCommand*: proc(graph: ModuleGraph) + +proc initDefinesProg*(self: NimProg, conf: ConfigRef, name: string) = + condsyms.initDefines(conf.symbols) + defineSymbol conf.symbols, name + +proc processCmdLineAndProjectPath*(self: NimProg, conf: ConfigRef) = + self.processCmdLine(passCmd1, "", conf) + if self.supportsStdinFile and conf.projectName == "-": + conf.projectName = "stdinfile" + conf.projectFull = "stdinfile" + conf.projectPath = canonicalizePath(conf, getCurrentDir()) + conf.projectIsStdin = true + elif conf.projectName != "": + try: + conf.projectFull = canonicalizePath(conf, conf.projectName) + except OSError: + conf.projectFull = conf.projectName + let p = splitFile(conf.projectFull) + let dir = if p.dir.len > 0: p.dir else: getCurrentDir() + conf.projectPath = canonicalizePath(conf, dir) + conf.projectName = p.name + else: + conf.projectPath = canonicalizePath(conf, getCurrentDir()) + +proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: ConfigRef): bool = + loadConfigs(DefaultConfig, cache, conf) # load all config files + if self.suggestMode: + conf.command = "nimsuggest" + + proc runNimScriptIfExists(path: string)= + if fileExists(path): + runNimScript(cache, path, freshDefines = false, conf) + + # Caution: make sure this stays in sync with `loadConfigs` + if optSkipSystemConfigFile notin conf.globalOptions: + runNimScriptIfExists(getSystemConfigPath(conf, DefaultConfigNims)) + + if optSkipUserConfigFile notin conf.globalOptions: + runNimScriptIfExists(getUserConfigPath(DefaultConfigNims)) + + if optSkipParentConfigFiles notin conf.globalOptions: + for dir in parentDirs(conf.projectPath, fromRoot = true, inclusive = false): + runNimScriptIfExists(dir / DefaultConfigNims) + + if optSkipProjConfigFile notin conf.globalOptions: + runNimScriptIfExists(conf.projectPath / DefaultConfigNims) + block: + let scriptFile = conf.projectFull.changeFileExt("nims") + if not self.suggestMode: + runNimScriptIfExists(scriptFile) + # 'nim foo.nims' means to just run the NimScript file and do nothing more: + if fileExists(scriptFile) and scriptFile.cmpPaths(conf.projectFull) == 0: + return false + else: + if scriptFile.cmpPaths(conf.projectFull) != 0: + runNimScriptIfExists(scriptFile) + else: + # 'nimsuggest foo.nims' means to just auto-complete the NimScript file + discard + + # now process command line arguments again, because some options in the + # command line can overwite the config file's settings + extccomp.initVars(conf) + self.processCmdLine(passCmd2, "", conf) + if conf.command == "": + rawMessage(conf, errGenerated, "command missing") + + let graph = newModuleGraph(cache, conf) + graph.suggestMode = self.suggestMode + self.mainCommand(graph) + return true diff --git a/compiler/commands.nim b/compiler/commands.nim index 8165fa5d4..b47ccf610 100644 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -651,7 +651,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo; else: localError(conf, info, "invalid option for --symbolFiles: " & arg) of "skipcfg": expectNoArg(conf, switch, arg, pass, info) - incl(conf.globalOptions, optSkipConfigFile) + incl(conf.globalOptions, optSkipSystemConfigFile) of "skipprojcfg": expectNoArg(conf, switch, arg, pass, info) incl(conf.globalOptions, optSkipProjConfigFile) diff --git a/compiler/nim.nim b/compiler/nim.nim index 90049bdfb..0fed72dc7 100644 --- a/compiler/nim.nim +++ b/compiler/nim.nim @@ -21,7 +21,7 @@ when defined(i386) and defined(windows) and defined(vcc): import commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes, extccomp, strutils, os, osproc, platform, main, parseopt, - nodejs, scriptconfig, idents, modulegraphs, lineinfos + nodejs, scriptconfig, idents, modulegraphs, lineinfos, cmdlinehelper when hasTinyCBackend: import tccgen @@ -57,69 +57,43 @@ proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) = rawMessage(config, errGenerated, errArgsNeedRunOption) proc handleCmdLine(cache: IdentCache; conf: ConfigRef) = - condsyms.initDefines(conf.symbols) + let self = NimProg( + supportsStdinFile: true, + processCmdLine: processCmdLine, + mainCommand: mainCommand + ) + self.initDefinesProg(conf, "nim_compiler") if paramCount() == 0: writeCommandLineUsage(conf, conf.helpWritten) - else: - # Process command line arguments: - processCmdLine(passCmd1, "", conf) - if conf.projectName == "-": - conf.projectName = "stdinfile" - conf.projectFull = "stdinfile" - conf.projectPath = canonicalizePath(conf, getCurrentDir()) - conf.projectIsStdin = true - elif conf.projectName != "": - try: - conf.projectFull = canonicalizePath(conf, conf.projectName) - except OSError: - conf.projectFull = conf.projectName - let p = splitFile(conf.projectFull) - let dir = if p.dir.len > 0: p.dir else: getCurrentDir() - conf.projectPath = canonicalizePath(conf, dir) - conf.projectName = p.name + return + + self.processCmdLineAndProjectPath(conf) + if not self.loadConfigsAndRunMainCommand(cache, conf): return + if optHints in conf.options and hintGCStats in conf.notes: echo(GC_getStatistics()) + #echo(GC_getStatistics()) + if conf.errorCounter != 0: return + when hasTinyCBackend: + if conf.cmd == cmdRun: + tccgen.run(conf.arguments) + if optRun in conf.globalOptions: + if conf.cmd == cmdCompileToJS: + var ex: string + if conf.outFile.len > 0: + ex = conf.outFile.prependCurDir.quoteShell + else: + ex = quoteShell( + completeCFilePath(conf, changeFileExt(conf.projectFull, "js").prependCurDir)) + execExternalProgram(conf, findNodeJs() & " " & ex & ' ' & conf.arguments) else: - conf.projectPath = canonicalizePath(conf, getCurrentDir()) - loadConfigs(DefaultConfig, cache, conf) # load all config files - let scriptFile = conf.projectFull.changeFileExt("nims") - if fileExists(scriptFile): - runNimScript(cache, scriptFile, freshDefines=false, conf) - # 'nim foo.nims' means to just run the NimScript file and do nothing more: - if scriptFile == conf.projectFull: return - elif fileExists(conf.projectPath / "config.nims"): - # directory wide NimScript file - runNimScript(cache, conf.projectPath / "config.nims", freshDefines=false, conf) - # now process command line arguments again, because some options in the - # command line can overwite the config file's settings - extccomp.initVars(conf) - processCmdLine(passCmd2, "", conf) - if conf.command == "": - rawMessage(conf, errGenerated, "command missing") - mainCommand(newModuleGraph(cache, conf)) - if optHints in conf.options and hintGCStats in conf.notes: echo(GC_getStatistics()) - #echo(GC_getStatistics()) - if conf.errorCounter == 0: - when hasTinyCBackend: - if conf.cmd == cmdRun: - tccgen.run(conf.arguments) - if optRun in conf.globalOptions: - if conf.cmd == cmdCompileToJS: - var ex: string - if conf.outFile.len > 0: - ex = conf.outFile.prependCurDir.quoteShell - else: - ex = quoteShell( - completeCFilePath(conf, changeFileExt(conf.projectFull, "js").prependCurDir)) - execExternalProgram(conf, findNodeJs() & " " & ex & ' ' & conf.arguments) - else: - var binPath: string - if conf.outFile.len > 0: - # If the user specified an outFile path, use that directly. - binPath = conf.outFile.prependCurDir - else: - # Figure out ourselves a valid binary name. - binPath = changeFileExt(conf.projectFull, ExeExt).prependCurDir - var ex = quoteShell(binPath) - execExternalProgram(conf, ex & ' ' & conf.arguments) + var binPath: string + if conf.outFile.len > 0: + # If the user specified an outFile path, use that directly. + binPath = conf.outFile.prependCurDir + else: + # Figure out ourselves a valid binary name. + binPath = changeFileExt(conf.projectFull, ExeExt).prependCurDir + var ex = quoteShell(binPath) + execExternalProgram(conf, ex & ' ' & conf.arguments) when declared(GC_setMaxPause): GC_setMaxPause 2_000 diff --git a/compiler/nimconf.nim b/compiler/nimconf.nim index 96b9a3841..5f6889a6f 100644 --- a/compiler/nimconf.nim +++ b/compiler/nimconf.nim @@ -219,10 +219,10 @@ proc readConfigFile( closeLexer(L) return true -proc getUserConfigPath(filename: string): string = +proc getUserConfigPath*(filename: string): string = result = joinPath([getConfigDir(), "nim", filename]) -proc getSystemConfigPath(conf: ConfigRef; filename: string): string = +proc getSystemConfigPath*(conf: ConfigRef; filename: string): string = # try standard configuration file (installation did not distribute files # the UNIX way) let p = getPrefixDir(conf) @@ -241,7 +241,7 @@ proc loadConfigs*(cfg: string; cache: IdentCache; conf: ConfigRef) = if readConfigFile(configPath, cache, conf): add(configFiles, configPath) - if optSkipConfigFile notin conf.globalOptions: + if optSkipSystemConfigFile notin conf.globalOptions: readConfigFile(getSystemConfigPath(conf, cfg)) if optSkipUserConfigFile notin conf.globalOptions: @@ -263,4 +263,5 @@ proc loadConfigs*(cfg: string; cache: IdentCache; conf: ConfigRef) = readConfigFile(projectConfig) for filename in configFiles: + # delayed to here so that `hintConf` is honored rawMessage(conf, hintConf, filename) diff --git a/compiler/options.nim b/compiler/options.nim index 04b14c65f..2a10aa9f8 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -54,10 +54,10 @@ type # please make sure we have under 32 options optGenMapping, # generate a mapping file optRun, # run the compiled project optCheckNep1, # check that the names adhere to NEP-1 - optSkipConfigFile, # skip the general config file - optSkipProjConfigFile, # skip the project's config file - optSkipUserConfigFile, # skip the users's config file - optSkipParentConfigFiles, # skip parent dir's config files + optSkipSystemConfigFile, # skip the system's cfg/nims config file + optSkipProjConfigFile, # skip the project's cfg/nims config file + optSkipUserConfigFile, # skip the users's cfg/nims config file + optSkipParentConfigFiles, # skip parent dir's cfg/nims config files optNoMain, # do not generate a "main" proc optUseColors, # use colors for hints, warnings, and errors optThreads, # support for multi-threading @@ -391,6 +391,7 @@ const TexExt* = "tex" IniExt* = "ini" DefaultConfig* = "nim.cfg" + DefaultConfigNims* = "config.nims" DocConfig* = "nimdoc.cfg" DocTexConfig* = "nimdoc.tex.cfg" diff --git a/compiler/scriptconfig.nim b/compiler/scriptconfig.nim index 659206a40..184b60733 100644 --- a/compiler/scriptconfig.nim +++ b/compiler/scriptconfig.nim @@ -171,7 +171,7 @@ proc runNimScript*(cache: IdentCache; scriptName: string; incl(m.flags, sfMainModule) graph.vm = setupVM(m, cache, scriptName, graph) - graph.compileSystemModule() + graph.compileSystemModule() # TODO: see why this unsets hintConf in conf.notes discard graph.processModule(m, llStreamOpen(scriptName, fmRead)) # ensure we load 'system.nim' again for the real non-config stuff! |