packagehandling.nim 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  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 resetPackageCache*(conf: ConfigRef) =
  17. conf.packageCache = newPackageCache()
  18. proc getPackageName*(conf: ConfigRef; path: string): string =
  19. var parents = 0
  20. block packageSearch:
  21. for d in myParentDirs(path):
  22. if conf.packageCache.hasKey(d):
  23. #echo "from cache ", d, " |", packageCache[d], "|", path.splitFile.name
  24. return conf.packageCache[d]
  25. inc parents
  26. for file in walkFiles(d / "*.nimble"):
  27. result = file.splitFile.name
  28. break packageSearch
  29. # we also store if we didn't find anything:
  30. when not defined(nimNoNilSeqs):
  31. if result.isNil: result = ""
  32. for d in myParentDirs(path):
  33. #echo "set cache ", d, " |", result, "|", parents
  34. conf.packageCache[d] = result
  35. dec parents
  36. if parents <= 0: break
  37. proc fakePackageName*(conf: ConfigRef; path: AbsoluteFile): string =
  38. # foo/../bar becomes foo7_7bar
  39. result = relativeTo(path, conf.projectPath, '/').string.multiReplace(
  40. {"/": "7", "..": "_", "7": "77", "_": "__", ":": "8", "8": "88"})
  41. proc demanglePackageName*(path: string): string =
  42. result = path.multiReplace(
  43. {"88": "8", "8": ":", "77": "7", "__": "_", "_7": "../", "7": "/"})
  44. proc withPackageName*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile =
  45. let x = getPackageName(conf, path.string)
  46. if x.len == 0:
  47. result = path
  48. else:
  49. let (p, file, ext) = path.splitFile
  50. if x == "stdlib":
  51. # Hot code reloading now relies on 'stdlib_system' names etc.
  52. result = p / RelativeFile((x & '_' & file) & ext)
  53. else:
  54. result = p / RelativeFile(fakePackageName(conf, path))