mirror of
https://github.com/morluto/rea.git
synced 2026-11-07 07:16:13 +00:00
* fix(cli): share boolean timing argument handling * fix(cli): preserve executable launcher mode
144 lines
5.8 KiB
TypeScript
144 lines
5.8 KiB
TypeScript
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
import { delimiter, join } from "node:path";
|
|
import { expect } from "vitest";
|
|
|
|
import { PRODUCT_IDENTITY } from "../../../src/identity.js";
|
|
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
|
import { cliTest } from "../../support/cli/cliFixture.js";
|
|
|
|
cliTest(
|
|
"root update flag uses the verified workflow and preserves executable output policies",
|
|
async ({ cli }) => {
|
|
const home = await createTestTempDirectory("rea-update-alias-");
|
|
const bin = join(home, "bin");
|
|
const script = join(home, "npm-fixture.mjs");
|
|
const log = join(home, "commands.jsonl");
|
|
await mkdir(bin);
|
|
await writeFile(log, "");
|
|
await writeFile(
|
|
script,
|
|
`
|
|
import {appendFileSync} from 'node:fs';
|
|
import {join} from 'node:path';
|
|
const args=process.argv.slice(2);
|
|
appendFileSync(process.env.REA_TEST_NPM_LOG, JSON.stringify(args)+'\\n');
|
|
if(args[0]==='root') console.log(join(process.env.USERPROFILE,'unowned','node_modules'));
|
|
else if(args[0]==='prefix') console.log(join(process.env.USERPROFILE,'unowned'));
|
|
else if(args[0]==='view') {
|
|
if(process.env.REA_TEST_NPM_FAILURE==='1') {process.stderr.write('owned fake registry denied');process.exitCode=2;}
|
|
else if(process.env.REA_TEST_NPM_OVERSIZED==='1') process.stdout.write(JSON.stringify(${JSON.stringify(PRODUCT_IDENTITY.packageVersion)})+' '.repeat(4 * 1024 * 1024));
|
|
else console.log(JSON.stringify(${JSON.stringify(PRODUCT_IDENTITY.packageVersion)}));
|
|
} else {process.stderr.write('No installation or unexpected package-manager commands are allowed');process.exitCode=97;}
|
|
`,
|
|
);
|
|
await writeFile(
|
|
join(bin, process.platform === "win32" ? "npm.cmd" : "npm"),
|
|
process.platform === "win32"
|
|
? '@echo off\r\n"%REA_TEST_NODE%" "%REA_TEST_NPM_SCRIPT%" %*\r\n'
|
|
: '#!/bin/sh\nexec "$REA_TEST_NODE" "$REA_TEST_NPM_SCRIPT" "$@"\n',
|
|
{ mode: 0o700 },
|
|
);
|
|
const run = (
|
|
arguments_: readonly string[],
|
|
failure = false,
|
|
oversized = false,
|
|
) =>
|
|
cli.run({
|
|
arguments: arguments_,
|
|
cwd: home,
|
|
timeoutMs: 20_000,
|
|
environment: {
|
|
USERPROFILE: home,
|
|
PATH: [
|
|
bin,
|
|
...(process.platform === "win32"
|
|
? [join(process.env.SystemRoot ?? "C:\\Windows", "System32")]
|
|
: ["/usr/bin", "/bin"]),
|
|
].join(delimiter),
|
|
npm_config_prefix: join(home, "prefix"),
|
|
npm_config_cache: join(home, "cache"),
|
|
npm_config_user_agent: "npm/test",
|
|
REA_TEST_NODE: process.execPath,
|
|
REA_TEST_NPM_SCRIPT: script,
|
|
REA_TEST_NPM_LOG: log,
|
|
REA_TEST_NPM_FAILURE: failure ? "1" : "0",
|
|
REA_TEST_NPM_OVERSIZED: oversized ? "1" : "0",
|
|
CI: "1",
|
|
NO_UPDATE_NOTIFIER: "1",
|
|
},
|
|
});
|
|
const canonical = await run(["update", "--json"]);
|
|
expect(canonical.exitCode, canonical.stderr).toBe(0);
|
|
expect(canonical.json).toMatchObject({
|
|
status: "current",
|
|
currentVersion: PRODUCT_IDENTITY.packageVersion,
|
|
latestVersion: PRODUCT_IDENTITY.packageVersion,
|
|
});
|
|
const alias = await run(["--json", "--update"]);
|
|
expect(alias.exitCode, alias.stderr).toBe(0);
|
|
expect(alias.json).toEqual(canonical.json);
|
|
for (const flag of ["--no-timings", "--timings=false", "--timings=true"]) {
|
|
const canonicalTimed = await run(["update", "--json", flag]);
|
|
const aliasTimed = await run([flag, "--update", "--json"]);
|
|
expect(canonicalTimed.exitCode, canonicalTimed.stdout).toBe(0);
|
|
expect(aliasTimed.exitCode, aliasTimed.stdout).toBe(0);
|
|
expect(aliasTimed.json).toEqual(canonicalTimed.json);
|
|
expect(aliasTimed.json).toEqual(canonical.json);
|
|
for (const result of [canonicalTimed, aliasTimed]) {
|
|
if (flag === "--timings=true")
|
|
expect(JSON.parse(result.stderr)).toMatchObject({
|
|
rea_timings: { version: 1, command_ms: expect.any(Number) },
|
|
});
|
|
else expect(result.stderr).toBe("");
|
|
}
|
|
}
|
|
const filtered = await run([
|
|
"--update",
|
|
"--format=json",
|
|
"--full-output",
|
|
"--filter-output=status",
|
|
]);
|
|
expect(filtered.exitCode, filtered.stderr).toBe(0);
|
|
expect(filtered.json).toMatchObject({
|
|
ok: true,
|
|
data: "current",
|
|
meta: { command: expect.stringContaining("update") },
|
|
});
|
|
const failed = await run(["--update", "--json"], true);
|
|
expect(failed.exitCode).toBe(1);
|
|
expect(failed.json).toMatchObject({
|
|
status: "failed",
|
|
reason: "version-check",
|
|
remediation: expect.stringContaining("owned fake registry denied"),
|
|
});
|
|
const oversized = await run(["update", "--json"], false, true);
|
|
expect(oversized.exitCode).toBe(1);
|
|
expect(oversized.json).toMatchObject({
|
|
status: "failed",
|
|
reason: "version-check",
|
|
remediation: expect.stringContaining("complete-output retention budget"),
|
|
});
|
|
const before = await readFile(log, "utf8");
|
|
const ambiguous = await run(["providers", "--update", "--json"]);
|
|
expect(ambiguous.exitCode).toBe(1);
|
|
expect(ambiguous.json).toMatchObject({
|
|
code: "UPDATE_FAILED",
|
|
message: expect.stringContaining("rea update"),
|
|
});
|
|
expect(await readFile(log, "utf8")).toBe(before);
|
|
const help = await run(["--update", "--help"]);
|
|
expect(help.exitCode, help.stderr).toBe(0);
|
|
expect(help.stdout).toContain("update");
|
|
expect(await readFile(log, "utf8")).toBe(before);
|
|
const commands: unknown[] = before
|
|
.trim()
|
|
.split("\n")
|
|
.map((line) => JSON.parse(line));
|
|
expect(commands.length).toBeGreaterThan(0);
|
|
expect(commands).toEqual(
|
|
expect.arrayContaining([expect.arrayContaining(["view"])]),
|
|
);
|
|
for (const command of commands) expect(command).not.toContain("install");
|
|
},
|
|
);
|