@forwardimpact/libutil 0.1.63 → 0.1.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/finder.js +19 -0
- package/package.json +1 -1
- package/test/finder.test.js +73 -0
package/finder.js
CHANGED
|
@@ -47,6 +47,25 @@ export class Finder {
|
|
|
47
47
|
return null;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Resolve a data directory by upward traversal, with HOME fallback.
|
|
52
|
+
* @param {string} baseName - Directory name to find (e.g. "data")
|
|
53
|
+
* @param {string} homeDir - User home directory path
|
|
54
|
+
* @returns {string} Absolute path to found directory
|
|
55
|
+
*/
|
|
56
|
+
findData(baseName, homeDir) {
|
|
57
|
+
const cwd = this.#process.cwd();
|
|
58
|
+
const found = this.findUpward(cwd, baseName);
|
|
59
|
+
if (found) return found;
|
|
60
|
+
|
|
61
|
+
const homePath = path.join(homeDir, ".fit", baseName);
|
|
62
|
+
if (fs.existsSync(homePath)) return homePath;
|
|
63
|
+
|
|
64
|
+
throw new Error(
|
|
65
|
+
`No ${baseName} directory found from ${cwd} or ${homePath}.`,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
50
69
|
/**
|
|
51
70
|
* Find the project root directory
|
|
52
71
|
* @param {string} startPath - Starting directory path
|
package/package.json
CHANGED
package/test/finder.test.js
CHANGED
|
@@ -257,6 +257,79 @@ describe("Finder", () => {
|
|
|
257
257
|
});
|
|
258
258
|
});
|
|
259
259
|
|
|
260
|
+
describe("findData", () => {
|
|
261
|
+
test("finds data/ in CWD via findUpward", () => {
|
|
262
|
+
const dataDir = path.join(tempDir, "data");
|
|
263
|
+
fs.mkdirSync(dataDir);
|
|
264
|
+
|
|
265
|
+
const cwdFinder = new Finder(fsPromises, mockLogger, {
|
|
266
|
+
cwd: () => tempDir,
|
|
267
|
+
});
|
|
268
|
+
const result = cwdFinder.findData("data", "/nonexistent-home");
|
|
269
|
+
|
|
270
|
+
assert.strictEqual(result, dataDir);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test("finds data/ in a parent directory via findUpward", () => {
|
|
274
|
+
const dataDir = path.join(tempDir, "data");
|
|
275
|
+
fs.mkdirSync(dataDir);
|
|
276
|
+
const subDir = path.join(tempDir, "products", "pathway");
|
|
277
|
+
fs.mkdirSync(subDir, { recursive: true });
|
|
278
|
+
|
|
279
|
+
const cwdFinder = new Finder(fsPromises, mockLogger, {
|
|
280
|
+
cwd: () => subDir,
|
|
281
|
+
});
|
|
282
|
+
const result = cwdFinder.findData("data", "/nonexistent-home");
|
|
283
|
+
|
|
284
|
+
assert.strictEqual(result, dataDir);
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test("falls back to ~/.fit/data/ when CWD traversal fails", () => {
|
|
288
|
+
const fakeHome = path.join(tempDir, "fakehome");
|
|
289
|
+
const homeFitData = path.join(fakeHome, ".fit", "data");
|
|
290
|
+
fs.mkdirSync(homeFitData, { recursive: true });
|
|
291
|
+
|
|
292
|
+
const isolatedDir = path.join(tempDir, "isolated");
|
|
293
|
+
fs.mkdirSync(isolatedDir);
|
|
294
|
+
|
|
295
|
+
const cwdFinder = new Finder(fsPromises, mockLogger, {
|
|
296
|
+
cwd: () => isolatedDir,
|
|
297
|
+
});
|
|
298
|
+
const result = cwdFinder.findData("data", fakeHome);
|
|
299
|
+
|
|
300
|
+
assert.strictEqual(result, homeFitData);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
test("throws when neither CWD traversal nor HOME fallback finds directory", () => {
|
|
304
|
+
const isolatedDir = path.join(tempDir, "isolated");
|
|
305
|
+
fs.mkdirSync(isolatedDir);
|
|
306
|
+
|
|
307
|
+
const cwdFinder = new Finder(fsPromises, mockLogger, {
|
|
308
|
+
cwd: () => isolatedDir,
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
assert.throws(() => cwdFinder.findData("data", "/nonexistent-home"), {
|
|
312
|
+
message: /No data directory found/,
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
test("CWD takes priority over HOME when both exist", () => {
|
|
317
|
+
const cwdData = path.join(tempDir, "data");
|
|
318
|
+
fs.mkdirSync(cwdData);
|
|
319
|
+
|
|
320
|
+
const fakeHome = path.join(tempDir, "fakehome");
|
|
321
|
+
const homeFitData = path.join(fakeHome, ".fit", "data");
|
|
322
|
+
fs.mkdirSync(homeFitData, { recursive: true });
|
|
323
|
+
|
|
324
|
+
const cwdFinder = new Finder(fsPromises, mockLogger, {
|
|
325
|
+
cwd: () => tempDir,
|
|
326
|
+
});
|
|
327
|
+
const result = cwdFinder.findData("data", fakeHome);
|
|
328
|
+
|
|
329
|
+
assert.strictEqual(result, cwdData);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
|
|
260
333
|
describe("findPackagePath", () => {
|
|
261
334
|
test("finds package in local monorepo structure", () => {
|
|
262
335
|
// Create mock monorepo structure
|