get-package-json.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /**
  2. * @author Toru Nagashima
  3. * @copyright 2015 Toru Nagashima. All rights reserved.
  4. * See LICENSE file in root directory for full license.
  5. */
  6. "use strict"
  7. //------------------------------------------------------------------------------
  8. // Requirements
  9. //------------------------------------------------------------------------------
  10. const fs = require("fs")
  11. const path = require("path")
  12. const Cache = require("./cache")
  13. //------------------------------------------------------------------------------
  14. // Helpers
  15. //------------------------------------------------------------------------------
  16. const cache = new Cache()
  17. /**
  18. * Reads the `package.json` data in a given path.
  19. *
  20. * Don't cache the data.
  21. *
  22. * @param {string} dir - The path to a directory to read.
  23. * @returns {object|null} The read `package.json` data, or null.
  24. */
  25. function readPackageJson(dir) {
  26. const filePath = path.join(dir, "package.json")
  27. try {
  28. const text = fs.readFileSync(filePath, "utf8")
  29. const data = JSON.parse(text)
  30. if (typeof data === "object" && data !== null) {
  31. data.filePath = filePath
  32. return data
  33. }
  34. }
  35. catch (_err) {
  36. // do nothing.
  37. }
  38. return null
  39. }
  40. //------------------------------------------------------------------------------
  41. // Public Interface
  42. //------------------------------------------------------------------------------
  43. /**
  44. * Gets a `package.json` data.
  45. * The data is cached if found, then it's used after.
  46. *
  47. * @param {string} startPath - A file path to lookup.
  48. * @returns {object|null} A found `package.json` data or `null`.
  49. * This object have additional property `filePath`.
  50. */
  51. module.exports = function getPackageJson(startPath) {
  52. const startDir = path.dirname(path.resolve(startPath))
  53. let dir = startDir
  54. let prevDir = ""
  55. let data = null
  56. do {
  57. data = cache.get(dir)
  58. if (data) {
  59. if (dir !== startDir) {
  60. cache.set(startDir, data)
  61. }
  62. return data
  63. }
  64. data = readPackageJson(dir)
  65. if (data) {
  66. cache.set(dir, data)
  67. cache.set(startDir, data)
  68. return data
  69. }
  70. // Go to next.
  71. prevDir = dir
  72. dir = path.resolve(dir, "..")
  73. }
  74. while (dir !== prevDir)
  75. cache.set(startDir, null)
  76. return null
  77. }