Skip to content

Commit

Permalink
fix: Use package.json location as project root
Browse files Browse the repository at this point in the history
  • Loading branch information
dividedmind committed Jan 6, 2024
1 parent 1429711 commit 0bcfe0b
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 13 deletions.
50 changes: 50 additions & 0 deletions src/__tests__/config.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { chdir, cwd } from "node:process";

import tmp from "tmp";

import { Config } from "../config";
import { basename, join } from "node:path";
import { mkdirSync, writeFileSync } from "node:fs";
import { PackageJson } from "type-fest";

tmp.setGracefulCleanup();

describe(Config, () => {
it("respects environment variables", () => {
process.env.APPMAP_ROOT = "/test/app";
expect(new Config()).toMatchObject({
root: "/test/app",
appmapDir: "/test/app/tmp/appmap",
appName: "app",
});
});

it("uses the current directory for root", () => {
expect(new Config()).toMatchObject({
root: dir,
appmapDir: join(dir, "tmp", "appmap"),
appName: basename(dir),
});
});

it("searches for package.json and uses package name from it", () => {
writeFileSync("package.json", JSON.stringify({ name: "test-package" } as PackageJson));

mkdirSync("subdirectory");
chdir("subdirectory");
expect(new Config()).toMatchObject({
root: dir,
appmapDir: join(dir, "tmp", "appmap"),
appName: "test-package",
});
});
});

let dir: string;
beforeEach(() => {
chdir((dir = tmp.dirSync().name));
jest.replaceProperty(process, "env", {});
});

const origCwd = cwd();
afterEach(() => chdir(origCwd));
17 changes: 12 additions & 5 deletions src/config.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import { dirname, join } from "node:path";
import { basename, join } from "node:path";
import { cwd } from "node:process";

import { readPkgUp } from "./util/readPkgUp";
import locateFileUp from "./util/findFileUp";
import { readFileSync } from "node:fs";
import { PackageJson } from "type-fest";

export class Config {
public readonly appmapDir: string;
public readonly appName: string;
public readonly root: string;

constructor(public readonly root = process.env.APPMAP_ROOT ?? cwd()) {
constructor() {
const packageDir = locateFileUp("package.json", process.env.APPMAP_ROOT ?? cwd());
const root = (this.root = process.env.APPMAP_ROOT ?? packageDir ?? cwd());
this.appmapDir = join(root, "tmp", "appmap");
const targetPackage = readPkgUp(root);
this.appName = targetPackage?.name ?? dirname(root);
const targetPackage = packageDir
? (JSON.parse(readFileSync(join(packageDir, "package.json"), "utf8")) as PackageJson)
: undefined;
this.appName = targetPackage?.name ?? basename(root);
}

export() {
Expand Down
10 changes: 10 additions & 0 deletions src/util/findFileUp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { existsSync } from "node:fs";
import { dirname, join } from "node:path";
import { cwd } from "node:process";

export default function locateFileUp(filename: string, dir = cwd()): string | undefined {
if (existsSync(join(dir, filename))) return dir;
const parent = dirname(dir);
if (parent === dir) return;
return locateFileUp(filename, parent);
}
13 changes: 5 additions & 8 deletions src/util/readPkgUp.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { join } from "node:path";

import type { PackageJson } from "type-fest";
import findFileUp from "./findFileUp";

export function readPkgUp(dir: string): PackageJson | undefined {
try {
return JSON.parse(readFileSync(join(dir, "package.json"), "utf-8")) as PackageJson;
} catch {
const parent = dirname(dir);
if (parent === dir) return;
else return readPkgUp(parent);
}
const path = findFileUp("package.json", dir);
if (path) return JSON.parse(readFileSync(join(path, "package.json"), "utf-8")) as PackageJson;
}

0 comments on commit 0bcfe0b

Please sign in to comment.