cmdlinehelper.nim 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. proc runNimScriptIfExists(path: AbsoluteFile)=
  45. if fileExists(path):
  46. runNimScript(cache, path, freshDefines = false, conf)
  47. # Caution: make sure this stays in sync with `loadConfigs`
  48. if optSkipSystemConfigFile notin conf.globalOptions:
  49. runNimScriptIfExists(getSystemConfigPath(conf, DefaultConfigNims))
  50. if optSkipUserConfigFile notin conf.globalOptions:
  51. runNimScriptIfExists(getUserConfigPath(DefaultConfigNims))
  52. if optSkipParentConfigFiles notin conf.globalOptions:
  53. for dir in parentDirs(conf.projectPath.string, fromRoot = true, inclusive = false):
  54. runNimScriptIfExists(AbsoluteDir(dir) / DefaultConfigNims)
  55. if optSkipProjConfigFile notin conf.globalOptions:
  56. runNimScriptIfExists(conf.projectPath / DefaultConfigNims)
  57. block:
  58. let scriptFile = conf.projectFull.changeFileExt("nims")
  59. if not self.suggestMode:
  60. runNimScriptIfExists(scriptFile)
  61. # 'nim foo.nims' means to just run the NimScript file and do nothing more:
  62. if fileExists(scriptFile) and scriptFile == conf.projectFull:
  63. return false
  64. else:
  65. if scriptFile != conf.projectFull:
  66. runNimScriptIfExists(scriptFile)
  67. else:
  68. # 'nimsuggest foo.nims' means to just auto-complete the NimScript file
  69. discard
  70. # now process command line arguments again, because some options in the
  71. # command line can overwite the config file's settings
  72. extccomp.initVars(conf)
  73. self.processCmdLine(passCmd2, "", conf)
  74. if conf.command == "":
  75. rawMessage(conf, errGenerated, "command missing")
  76. let graph = newModuleGraph(cache, conf)
  77. graph.suggestMode = self.suggestMode
  78. self.mainCommand(graph)
  79. return true