cmdlinehelper.nim 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. type
  14. NimProg* = ref object
  15. suggestMode*: bool
  16. supportsStdinFile*: bool
  17. processCmdLine*: proc(pass: TCmdLinePass, cmd: string; config: ConfigRef)
  18. mainCommand*: proc(graph: ModuleGraph)
  19. proc initDefinesProg*(self: NimProg, conf: ConfigRef, name: string) =
  20. condsyms.initDefines(conf.symbols)
  21. defineSymbol conf.symbols, name
  22. proc processCmdLineAndProjectPath*(self: NimProg, conf: ConfigRef) =
  23. self.processCmdLine(passCmd1, "", conf)
  24. if self.supportsStdinFile and conf.projectName == "-":
  25. conf.projectName = "stdinfile"
  26. conf.projectFull = AbsoluteFile "stdinfile"
  27. conf.projectPath = AbsoluteDir getCurrentDir()
  28. conf.projectIsStdin = true
  29. elif conf.projectName != "":
  30. try:
  31. conf.projectFull = canonicalizePath(conf, AbsoluteFile conf.projectName)
  32. except OSError:
  33. conf.projectFull = AbsoluteFile conf.projectName
  34. let p = splitFile(conf.projectFull)
  35. let dir = if p.dir.isEmpty: AbsoluteDir getCurrentDir() else: p.dir
  36. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile dir)
  37. conf.projectName = p.name
  38. else:
  39. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile getCurrentDir())
  40. proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: ConfigRef): bool =
  41. loadConfigs(DefaultConfig, cache, conf) # load all config files
  42. if self.suggestMode:
  43. conf.command = "nimsuggest"
  44. template runNimScriptIfExists(path: AbsoluteFile) =
  45. let p = path # eval once
  46. if fileExists(p):
  47. runNimScript(cache, p, freshDefines = false, conf)
  48. # Caution: make sure this stays in sync with `loadConfigs`
  49. if optSkipSystemConfigFile notin conf.globalOptions:
  50. runNimScriptIfExists(getSystemConfigPath(conf, DefaultConfigNims))
  51. if optSkipUserConfigFile notin conf.globalOptions:
  52. runNimScriptIfExists(getUserConfigPath(DefaultConfigNims))
  53. if optSkipParentConfigFiles notin conf.globalOptions:
  54. for dir in parentDirs(conf.projectPath.string, fromRoot = true, inclusive = false):
  55. runNimScriptIfExists(AbsoluteDir(dir) / DefaultConfigNims)
  56. if optSkipProjConfigFile notin conf.globalOptions:
  57. runNimScriptIfExists(conf.projectPath / DefaultConfigNims)
  58. block:
  59. let scriptFile = conf.projectFull.changeFileExt("nims")
  60. if not self.suggestMode:
  61. runNimScriptIfExists(scriptFile)
  62. # 'nim foo.nims' means to just run the NimScript file and do nothing more:
  63. if fileExists(scriptFile) and scriptFile == conf.projectFull:
  64. return false
  65. else:
  66. if scriptFile != conf.projectFull:
  67. runNimScriptIfExists(scriptFile)
  68. else:
  69. # 'nimsuggest foo.nims' means to just auto-complete the NimScript file
  70. discard
  71. # now process command line arguments again, because some options in the
  72. # command line can overwite the config file's settings
  73. extccomp.initVars(conf)
  74. self.processCmdLine(passCmd2, "", conf)
  75. if conf.command == "":
  76. rawMessage(conf, errGenerated, "command missing")
  77. let graph = newModuleGraph(cache, conf)
  78. graph.suggestMode = self.suggestMode
  79. self.mainCommand(graph)
  80. return true