chore(gate): check.sh can list its lanes and run one of them
--list prints the lane names, --only "<lane>" runs that one lane, so a runner can schedule the lanes itself and a red lane can be re-run on its own. An --only run reports that lane, never the gate, and an unknown name exits 2 instead of passing with nothing run; the contract test holds both.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { execFileSync, spawnSync } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import { readdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { relative } from "node:path";
|
||||
import { relative, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { ESLint, type Linter } from "eslint";
|
||||
import prettierConfig from "eslint-config-prettier";
|
||||
@@ -375,6 +376,37 @@ describe("the gate snapshot (gates.snapshot.json)", () => {
|
||||
}, 120_000);
|
||||
});
|
||||
|
||||
// Git for Windows' own bash: on a Windows PATH `bash` is often WSL's, which cannot run the script.
|
||||
function bash(): string {
|
||||
if (process.platform !== "win32") return "bash";
|
||||
const exec = execFileSync("git", ["--exec-path"], { encoding: "utf8" }).trim();
|
||||
return resolve(exec, "../../../bin/bash.exe");
|
||||
}
|
||||
const checkSh = (...args: string[]) =>
|
||||
spawnSync(bash(), ["scripts/check.sh", ...args], { cwd: REPO, encoding: "utf8" });
|
||||
|
||||
// A runner that schedules lanes one by one learns them from `--list` and runs each with `--only`; a
|
||||
// lane missing from the list would be a lane it never runs, and an `--only` that passed with nothing
|
||||
// run would be a green about nothing.
|
||||
describe("the gate script's lane list (check.sh --list / --only)", () => {
|
||||
it("lists every lane the script runs, in order", () => {
|
||||
const declared = [...read("scripts/check.sh").matchAll(/^\s*lane "([^"]+)"/gm)].map(
|
||||
(m) => m[1],
|
||||
);
|
||||
const listed = checkSh("--list");
|
||||
expect(listed.status).toBe(0);
|
||||
expect(listed.stdout.trim().split("\n")).toEqual(declared);
|
||||
const lint = checkSh("lint", "--list").stdout.trim().split("\n");
|
||||
expect(lint.length).toBeGreaterThan(0);
|
||||
expect(declared.slice(0, lint.length)).toEqual(lint);
|
||||
});
|
||||
it("refuses an unknown lane instead of passing with nothing run", () => {
|
||||
const r = checkSh("--only", "no such lane");
|
||||
expect(r.status).toBe(2);
|
||||
expect(r.stdout).not.toContain("green");
|
||||
});
|
||||
});
|
||||
|
||||
describe("the gate register (docs/gates.md)", () => {
|
||||
it("lists every ESLint rule narrowed, by scope", async () => {
|
||||
expect(missingFrom(eslintNarrowings(await linted()))).toEqual([]);
|
||||
|
||||
Reference in New Issue
Block a user