mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-11 03:00:26 +01:00
* Load the Capy crew skills only on Capy machines (GST-1833) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Add changelog entry for Capy-only crew skills (GST-1833) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Move the Capy-only crew tooling into crew/ and run its tests only when needed (GST-1833) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Test that the Capy launch file puts crew/bin on PATH Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Count any ~/.capy as a Capy machine, so a Mac running Capy keeps /captain Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Fix the tests and fixtures that broke when crew tooling moved into crew/ Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Plan every crew test when a pull request's merge-base can't be read Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Add a test that checks each crew-only module left the root tree for crew/ Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Run crew tests on pull requests that change bin/ commands or workflows they drive Review-Finding: p1/specialist-batched#1 reader=testing Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Keep running every crew test on every pull request; the skip comes in a later change Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Keep copied installs and older release bisects working after the crew/ move Setup now copies crew/lib into every host's runtime root beside bin and lib, so Windows installs (which copy instead of linking) can still start gstack-ship-receipt, gstack-pregate and the other commands that import it. The release bisect runs the train-gate script from wherever the checked-out commit has it, so a bisect over commits from before the move still gets a verdict. Review-Finding: p1/outside-voice#1 reader=outside-voice Review-Finding: p1/outside-voice#2 reader=outside-voice Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Say in the changelog that Windows installs keep working after the crew/ move Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Point the harness guide's merge-queue rows at crew/lib/ where those modules moved Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * Point the plain-title test at the wave module's new home in crew/ (GST-1833) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
42 lines
1.9 KiB
TypeScript
42 lines
1.9 KiB
TypeScript
/**
|
|
* Tripwire and fix messages point readers at docs/TESTING_INTERNALS.md#<anchor>.
|
|
* Every such anchor in code must match a heading there, or the fix text sends
|
|
* the reader to the top of a 900-line page.
|
|
*/
|
|
import { expect, test } from 'bun:test';
|
|
import * as fs from 'node:fs';
|
|
import * as path from 'node:path';
|
|
|
|
const ROOT = path.resolve(import.meta.dir, '..');
|
|
const DOC = 'docs/TESTING_INTERNALS.md';
|
|
const SCAN = ['scripts', 'test', 'lib', 'bin', 'crew', '.github'];
|
|
|
|
function githubSlug(heading: string): string {
|
|
return heading.trim().toLowerCase().replace(/[^\p{L}\p{N}\s-]/gu, '').replace(/\s/g, '-');
|
|
}
|
|
|
|
function walk(dir: string): string[] {
|
|
const out: string[] = [];
|
|
for (const entry of fs.readdirSync(path.join(ROOT, dir), { withFileTypes: true })) {
|
|
const rel = `${dir}/${entry.name}`;
|
|
if (entry.isDirectory()) {
|
|
if (entry.name === 'node_modules' || entry.name === 'fixtures' || entry.name === 'dist') continue;
|
|
out.push(...walk(rel));
|
|
} else if (/\.(ts|sh|ya?ml|mjs)$/.test(entry.name) || !entry.name.includes('.')) out.push(rel);
|
|
}
|
|
return out;
|
|
}
|
|
|
|
test('every TESTING_INTERNALS.md anchor named in code matches a heading', () => {
|
|
const anchors = new Set(
|
|
[...fs.readFileSync(path.join(ROOT, DOC), 'utf8').matchAll(/^#{1,6} (.+)$/gm)].map(match => githubSlug(match[1]!)),
|
|
);
|
|
const references = SCAN.flatMap(walk).flatMap(file =>
|
|
[...fs.readFileSync(path.join(ROOT, file), 'utf8').matchAll(/TESTING_INTERNALS\.md#([a-z0-9-]+)/g)]
|
|
.map(match => ({ file, anchor: match[1]! })));
|
|
expect(references.length, 'scan found no TESTING_INTERNALS.md anchors; the regex or scan roots rotted').toBeGreaterThan(0);
|
|
const missing = references.filter(ref => !anchors.has(ref.anchor) && ref.file !== 'test/testing-internals-anchors.test.ts');
|
|
expect(missing.map(ref => `${ref.file} points at ${DOC}#${ref.anchor}, which has no heading; fix: add a "### " heading with that slug to ${DOC} or correct the link`))
|
|
.toEqual([]);
|
|
});
|