Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: factory-maintain lab next progress prove-homework doctor dev check check-affected prove levels claude smoke hooks eval factory exercise
.PHONY: fast factory-maintain lab next progress prove-homework doctor dev check check-affected prove levels claude smoke hooks eval factory exercise

doctor:
@node -v | grep -qE '^v2[2-9]' && echo "ok node $$(node -v)" || (echo "need Node 22+" && exit 1)
Expand All @@ -22,6 +22,12 @@ check:
check-affected:
npx tsx scripts/check-affected.ts $(if $(BASE),--base $(BASE))

# Quickest local read on the first red CI step: lint, types, then only the affected checks. make check stays the gate.
fast:
npm run lint
npm run typecheck
npx tsx scripts/check-affected.ts --base origin/main

prove:
npm run prove -- $(LEVEL)

Expand Down
1 change: 1 addition & 0 deletions levels.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
"scripts/impact.ts",
"scripts/impact.test.ts",
"scripts/check-affected.ts",
"scripts/fast.test.ts",
"tests/structure/impact.test.ts",
"scripts/dependencies.ts",
"tests/structure/dependency-drift.test.ts",
Expand Down
38 changes: 38 additions & 0 deletions scripts/fast.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";

const makefile = readFileSync("Makefile", "utf8");

// The tab-indented lines of one target's recipe.
function recipe(target: string): string[] {
const lines = makefile.split("\n");
const start = lines.indexOf(`${target}:`);
if (start < 0) return [];
const body: string[] = [];
for (const line of lines.slice(start + 1)) {
if (!line.startsWith("\t")) break;
body.push(line.trim());
}
return body;
}

describe("make fast", () => {
it("is declared phony", () => {
const phony = makefile.split("\n").find((l) => l.startsWith(".PHONY:")) ?? "";
expect(phony.split(/\s+/)).toContain("fast");
});

it("runs lint, typecheck, then the affected checks against origin/main", () => {
expect(recipe("fast")).toEqual([
"npm run lint",
"npm run typecheck",
"npx tsx scripts/check-affected.ts --base origin/main",
]);
});

it("is not called from check, which stays the gate", () => {
const check = recipe("check");
expect(check.length).toBeGreaterThan(0);
expect(check.join("\n")).not.toMatch(/\bfast\b/);
});
});
Loading