// Where a umtool CLI finds the corpus: from its OWN checkout (the entry // script's path), whatever directory it is run from. // // Run with: pnpm test:scripts import assert from "node:assert/strict"; import { execFileSync } from "node:child_process"; import { mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import path from "node:path"; import test from "node:test"; import { cliRepoRoot } from "./paths.mjs"; const PATHS = new URL("./paths.mjs", import.meta.url); function checkout() { const root = mkdtempSync(path.join(tmpdir(), "umtool-paths-")); writeFileSync(path.join(root, "pnpm-workspace.yaml"), "packages: []\n"); mkdirSync(path.join(root, "umtool", "bin"), { recursive: true }); return root; } test("cliRepoRoot: a umtool/bin entry names its checkout; anything else is null", (t) => { const root = checkout(); t.after(() => rmSync(root, { recursive: true, force: true })); const cli = path.join(root, "umtool", "bin", "umtool.mjs"); writeFileSync(cli, ""); assert.equal(cliRepoRoot(cli), root); // The server, a test file, report-to-video's CLIs: the cwd walk decides. assert.equal(cliRepoRoot(path.join(root, "node_modules", "next", "dist", "bin", "next")), null); assert.equal(cliRepoRoot(path.join(root, "umtool", "report-to-video", "build-video.mjs")), null); assert.equal(cliRepoRoot(undefined), null); // A bin/ whose grandparent is not a checkout, and one that does not exist. const loose = mkdtempSync(path.join(tmpdir(), "umtool-loose-")); t.after(() => rmSync(loose, { recursive: true, force: true })); mkdirSync(path.join(loose, "umtool", "bin"), { recursive: true }); writeFileSync(path.join(loose, "umtool", "bin", "x.mjs"), ""); assert.equal(cliRepoRoot(path.join(loose, "umtool", "bin", "x.mjs")), null); assert.equal(cliRepoRoot(path.join(root, "umtool", "bin", "missing.mjs")), null); // Reached through a link: the TARGET's checkout, not the link's. const link = path.join(loose, "umtool", "bin", "linked.mjs"); symlinkSync(cli, link); assert.equal(cliRepoRoot(link), root); }); test("a CLI run from outside its checkout reads that checkout's sites and channels", (t) => { const root = checkout(); t.after(() => rmSync(root, { recursive: true, force: true })); const probe = path.join(root, "umtool", "bin", "probe.mjs"); writeFileSync( probe, `const p = await import(${JSON.stringify(PATHS.href)});\n` + "console.log(JSON.stringify({ repo: p.REPO_ROOT, sites: p.SITES_DIR, channels: p.CHANNELS_DIR }));\n", ); const away = mkdtempSync(path.join(tmpdir(), "umtool-away-")); t.after(() => rmSync(away, { recursive: true, force: true })); const env = { ...process.env }; for (const k of ["SITES_DIR", "CHANNELS_DIR", "TRANSCRIPTS_DIR"]) delete env[k]; const got = JSON.parse(execFileSync(process.execPath, [probe], { cwd: away, env, encoding: "utf8" })); assert.deepEqual(got, { repo: root, sites: path.join(root, "transcripts", "sites"), channels: path.join(root, "transcripts", "channels"), }); // SITES_DIR still wins when it is set. const set = JSON.parse( execFileSync(process.execPath, [probe], { cwd: away, env: { ...env, SITES_DIR: away }, encoding: "utf8" }), ); assert.equal(set.sites, away); });