76 lines
1.7 KiB
JavaScript
76 lines
1.7 KiB
JavaScript
/**
|
|
* @author Toru Nagashima
|
|
* See LICENSE file in root directory for full license.
|
|
*/
|
|
"use strict"
|
|
|
|
const fs = require("fs")
|
|
const path = require("path")
|
|
const Cache = require("./cache")
|
|
|
|
const cache = new Cache()
|
|
|
|
/**
|
|
* Reads the `package.json` data in a given path.
|
|
*
|
|
* Don't cache the data.
|
|
*
|
|
* @param {string} dir - The path to a directory to read.
|
|
* @returns {object|null} The read `package.json` data, or null.
|
|
*/
|
|
function readPackageJson(dir) {
|
|
const filePath = path.join(dir, "package.json")
|
|
try {
|
|
const text = fs.readFileSync(filePath, "utf8")
|
|
const data = JSON.parse(text)
|
|
|
|
if (typeof data === "object" && data !== null) {
|
|
data.filePath = filePath
|
|
return data
|
|
}
|
|
} catch (_err) {
|
|
// do nothing.
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
/**
|
|
* Gets a `package.json` data.
|
|
* The data is cached if found, then it's used after.
|
|
*
|
|
* @param {string} startPath - A file path to lookup.
|
|
* @returns {object|null} A found `package.json` data or `null`.
|
|
* This object have additional property `filePath`.
|
|
*/
|
|
module.exports = function getPackageJson(startPath) {
|
|
const startDir = path.dirname(path.resolve(startPath))
|
|
let dir = startDir
|
|
let prevDir = ""
|
|
let data = null
|
|
|
|
do {
|
|
data = cache.get(dir)
|
|
if (data) {
|
|
if (dir !== startDir) {
|
|
cache.set(startDir, data)
|
|
}
|
|
return data
|
|
}
|
|
|
|
data = readPackageJson(dir)
|
|
if (data) {
|
|
cache.set(dir, data)
|
|
cache.set(startDir, data)
|
|
return data
|
|
}
|
|
|
|
// Go to next.
|
|
prevDir = dir
|
|
dir = path.resolve(dir, "..")
|
|
} while (dir !== prevDir)
|
|
|
|
cache.set(startDir, null)
|
|
return null
|
|
}
|