cmdlinehelper.nim 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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. conf.projectFull = canonicalizePath(conf, AbsoluteFile conf.projectName)
  31. if conf.projectFull.isEmpty:
  32. conf.projectFull = AbsoluteFile conf.projectName
  33. let p = splitFile(conf.projectFull)
  34. let dir = if p.dir.isEmpty: AbsoluteDir getCurrentDir() else: p.dir
  35. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile dir)
  36. conf.projectName = p.name
  37. else:
  38. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile getCurrentDir())
  39. proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: ConfigRef): bool =
  40. loadConfigs(DefaultConfig, cache, conf) # load all config files
  41. if self.suggestMode:
  42. conf.command = "nimsuggest"
  43. proc runNimScriptIfExists(path: AbsoluteFile)=
  44. if fileExists(path):
  45. runNimScript(cache, path, 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. return false
  63. else:
  64. if scriptFile != conf.projectFull:
  65. runNimScriptIfExists(scriptFile)
  66. else:
  67. # 'nimsuggest foo.nims' means to just auto-complete the NimScript file
  68. discard
  69. # now process command line arguments again, because some options in the
  70. # command line can overwite the config file's settings
  71. extccomp.initVars(conf)
  72. self.processCmdLine(passCmd2, "", conf)
  73. if conf.command == "":
  74. rawMessage(conf, errGenerated, "command missing")
  75. let graph = newModuleGraph(cache, conf)
  76. graph.suggestMode = self.suggestMode
  77. self.mainCommand(graph)
  78. return true