packagehandling.nim 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2017 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. iterator myParentDirs(p: string): string =
  10. # XXX os's parentDirs is stupid (multiple yields) and triggers an old bug...
  11. var current = p
  12. while true:
  13. current = current.parentDir
  14. if current.len == 0: break
  15. yield current
  16. proc getNimbleFile*(conf: ConfigRef; path: string): string =
  17. ## returns absolute path to nimble file, eg: /pathto/cligen.nimble
  18. var parents = 0
  19. block packageSearch:
  20. for d in myParentDirs(path):
  21. if conf.packageCache.hasKey(d):
  22. #echo "from cache ", d, " |", packageCache[d], "|", path.splitFile.name
  23. return conf.packageCache[d]
  24. inc parents
  25. for file in walkFiles(d / "*.nimble"):
  26. result = file
  27. break packageSearch
  28. # we also store if we didn't find anything:
  29. when not defined(nimNoNilSeqs):
  30. if result.isNil: result = ""
  31. for d in myParentDirs(path):
  32. #echo "set cache ", d, " |", result, "|", parents
  33. conf.packageCache[d] = result
  34. dec parents
  35. if parents <= 0: break
  36. proc getPackageName*(conf: ConfigRef; path: string): string =
  37. ## returns nimble package name, eg: `cligen`
  38. let path = getNimbleFile(conf, path)
  39. result = path.splitFile.name
  40. proc fakePackageName*(conf: ConfigRef; path: AbsoluteFile): string =
  41. # Convert `path` so that 2 modules with same name
  42. # in different directory get different name and they can be
  43. # placed in a directory.
  44. # foo-#head/../bar becomes @foo-@hhead@s..@sbar
  45. result = "@m" & relativeTo(path, conf.projectPath).string.multiReplace({$os.DirSep: "@s", $os.AltSep: "@s", "#": "@h", "@": "@@", ":": "@c"})
  46. proc demanglePackageName*(path: string): string =
  47. result = path.multiReplace({"@@": "@", "@h": "#", "@s": "/", "@m": "", "@c": ":"})
  48. proc withPackageName*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile =
  49. let x = getPackageName(conf, path.string)
  50. let (p, file, ext) = path.splitFile
  51. if x == "stdlib":
  52. # Hot code reloading now relies on 'stdlib_system' names etc.
  53. result = p / RelativeFile((x & '_' & file) & ext)
  54. else:
  55. result = p / RelativeFile(fakePackageName(conf, path))