cmdlinehelper.nim 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2018 Nim contributors
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## Helpers for binaries that use compiler passes, eg: nim, nimsuggest, nimfix
  10. import
  11. options, idents, nimconf, scriptconfig, extccomp, commands, msgs,
  12. lineinfos, modulegraphs, condsyms, os, pathutils
  13. from strutils import normalize
  14. type
  15. NimProg* = ref object
  16. suggestMode*: bool
  17. supportsStdinFile*: bool
  18. processCmdLine*: proc(pass: TCmdLinePass, cmd: string; config: ConfigRef)
  19. mainCommand*: proc(graph: ModuleGraph)
  20. proc initDefinesProg*(self: NimProg, conf: ConfigRef, name: string) =
  21. condsyms.initDefines(conf.symbols)
  22. defineSymbol conf.symbols, name
  23. proc processCmdLineAndProjectPath*(self: NimProg, conf: ConfigRef) =
  24. self.processCmdLine(passCmd1, "", conf)
  25. if self.supportsStdinFile and conf.projectName == "-":
  26. handleStdinInput(conf)
  27. elif conf.projectName != "":
  28. try:
  29. conf.projectFull = canonicalizePath(conf, AbsoluteFile conf.projectName)
  30. except OSError:
  31. conf.projectFull = AbsoluteFile conf.projectName
  32. let p = splitFile(conf.projectFull)
  33. let dir = if p.dir.isEmpty: AbsoluteDir getCurrentDir() else: p.dir
  34. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile dir)
  35. conf.projectName = p.name
  36. else:
  37. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile getCurrentDir())
  38. proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: ConfigRef): bool =
  39. loadConfigs(DefaultConfig, cache, conf) # load all config files
  40. if self.suggestMode:
  41. conf.command = "nimsuggest"
  42. template runNimScriptIfExists(path: AbsoluteFile) =
  43. let p = path # eval once
  44. if fileExists(p):
  45. runNimScript(cache, p, freshDefines = false, conf)
  46. # Caution: make sure this stays in sync with `loadConfigs`
  47. if optSkipSystemConfigFile notin conf.globalOptions:
  48. runNimScriptIfExists(getSystemConfigPath(conf, DefaultConfigNims))
  49. if optSkipUserConfigFile notin conf.globalOptions:
  50. runNimScriptIfExists(getUserConfigPath(DefaultConfigNims))
  51. if optSkipParentConfigFiles notin conf.globalOptions:
  52. for dir in parentDirs(conf.projectPath.string, fromRoot = true, inclusive = false):
  53. runNimScriptIfExists(AbsoluteDir(dir) / DefaultConfigNims)
  54. if optSkipProjConfigFile notin conf.globalOptions:
  55. runNimScriptIfExists(conf.projectPath / DefaultConfigNims)
  56. block:
  57. let scriptFile = conf.projectFull.changeFileExt("nims")
  58. if not self.suggestMode:
  59. runNimScriptIfExists(scriptFile)
  60. # 'nim foo.nims' means to just run the NimScript file and do nothing more:
  61. if fileExists(scriptFile) and scriptFile == conf.projectFull:
  62. if conf.command == "":
  63. conf.command = "e"
  64. return false
  65. elif conf.command.normalize == "e":
  66. return false
  67. else:
  68. if scriptFile != conf.projectFull:
  69. runNimScriptIfExists(scriptFile)
  70. else:
  71. # 'nimsuggest foo.nims' means to just auto-complete the NimScript file
  72. discard
  73. # now process command line arguments again, because some options in the
  74. # command line can overwrite the config file's settings
  75. extccomp.initVars(conf)
  76. self.processCmdLine(passCmd2, "", conf)
  77. if conf.command == "":
  78. rawMessage(conf, errGenerated, "command missing")
  79. let graph = newModuleGraph(cache, conf)
  80. graph.suggestMode = self.suggestMode
  81. self.mainCommand(graph)
  82. return true