* fix(#2994): move verify-reapply-patches.cjs to get-shit-done/bin/ so installer ships it scripts/verify-reapply-patches.cjs (added in #2972 to close the verified-yes-without-checking gap from #2969) shipped in the npm tarball but never reached user installs: bin/install.js copies get-shit-done/ recursively but does not copy the top-level scripts/ directory. Effect: every fresh install hit `Cannot find module …/scripts/verify-reapply-patches.cjs` on Step 5 of /gsd-reapply-patches. The whole point of moving verification out of LLM-driven prose into a deterministic script is undone if the script does not resolve at runtime. Fix: move the script to get-shit-done/bin/verify-reapply-patches.cjs (same pattern as gsd-tools.cjs and other runtime bin scripts that the installer ships) and update reapply-patches.md Step 5 to invoke ${GSD_HOME}/get-shit-done/bin/verify-reapply-patches.cjs. Tests: - bug-2969 SCRIPT path updated to the new location - New bug-2994-verify-reapply-patches-installed-path.test.cjs parses reapply-patches.md into structured invocation records and asserts every node ${GSD_HOME}/... reference lives under get-shit-done/ (the installed tree). Catches future regressions where someone moves a runtime-needed script back to scripts/. Closes #2994 * chore(#2994): add changeset fragment for PR #3000 * chore(#2994): add changeset fragment for PR #3000 * docs(#2994): update verifier-script-location comment to reflect new path (CR) CodeRabbit on PR #3000: the parenthetical at line 278 still said the script ships under scripts/, but this PR moved it to get-shit-done/bin/. Updated the prose to reference the new location and the installer target path. * chore(#3000): drop direct CHANGELOG.md edit; release entry now lives in .changeset/ The changeset-fragment workflow (#2975) renders fragments into CHANGELOG.md at release time. Direct edits to [Unreleased] on each PR caused merge conflicts on every concurrent PR. This commit restores CHANGELOG.md to match origin/main; the release entry for this fix is preserved in the .changeset/*.md fragment(s) on this branch, which the release workflow consolidates.
82 lines
3.6 KiB
JavaScript
82 lines
3.6 KiB
JavaScript
'use strict';
|
|
|
|
process.env.GSD_TEST_MODE = '1';
|
|
|
|
/**
|
|
* Bug #2994: scripts/verify-reapply-patches.cjs ships in tarball but is
|
|
* not installed at ${GSD_HOME}/scripts/.
|
|
*
|
|
* Root cause: bin/install.js copies the get-shit-done/ source tree to
|
|
* ${configDir}/get-shit-done/ but does NOT copy the top-level scripts/
|
|
* directory. The verifier script lived under scripts/ so /gsd-reapply-patches
|
|
* Step 5 hit `Cannot find module …/scripts/verify-reapply-patches.cjs`.
|
|
*
|
|
* Fix: move the script to get-shit-done/bin/verify-reapply-patches.cjs
|
|
* (which IS installed) and update reapply-patches.md to point there.
|
|
*
|
|
* This test enforces the structural invariant that prevents regression.
|
|
*/
|
|
|
|
const { test, describe } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
const ROOT = path.join(__dirname, '..');
|
|
const RUNTIME_SCRIPT_PATH = path.join(ROOT, 'get-shit-done', 'bin', 'verify-reapply-patches.cjs');
|
|
const STALE_SCRIPT_PATH = path.join(ROOT, 'scripts', 'verify-reapply-patches.cjs');
|
|
const REAPPLY_WORKFLOW = path.join(ROOT, 'get-shit-done', 'workflows', 'reapply-patches.md');
|
|
|
|
describe('Bug #2994: verify-reapply-patches.cjs lives at the runtime-installed path', () => {
|
|
test('the script exists under get-shit-done/bin/ (installed by copyWithPathReplacement)', () => {
|
|
assert.equal(fs.existsSync(RUNTIME_SCRIPT_PATH), true,
|
|
`Expected verifier script at ${RUNTIME_SCRIPT_PATH} -- installer copies get-shit-done/ recursively`);
|
|
});
|
|
|
|
test('the script does NOT live at the legacy scripts/ path (not installed)', () => {
|
|
assert.equal(fs.existsSync(STALE_SCRIPT_PATH), false,
|
|
`scripts/ is not copied by installer; verifier must be under get-shit-done/bin/ instead`);
|
|
});
|
|
|
|
test('the script is requireable (loads without throwing)', () => {
|
|
const mod = require(RUNTIME_SCRIPT_PATH);
|
|
assert.equal(typeof mod.REASON, 'object');
|
|
assert.notEqual(mod.REASON, null);
|
|
});
|
|
});
|
|
|
|
// Parse reapply-patches.md to extract every `node "${GSD_HOME}/...cjs"`
|
|
// invocation as structured records. Assertions go against the parsed
|
|
// records, not against the markdown text.
|
|
function extractScriptInvocations(markdown) {
|
|
const invocations = [];
|
|
const re = /node\s+"\$\{GSD_HOME\}\/([^"]+\.cjs)"/g;
|
|
let match;
|
|
while ((match = re.exec(markdown)) !== null) {
|
|
invocations.push({ relPath: match[1] });
|
|
}
|
|
return invocations;
|
|
}
|
|
|
|
describe('Bug #2994: reapply-patches workflow references the runtime-installed path', () => {
|
|
test('every node ${GSD_HOME}/... invocation in reapply-patches.md uses an installed runtime path', () => {
|
|
const md = fs.readFileSync(REAPPLY_WORKFLOW, 'utf-8');
|
|
const invocations = extractScriptInvocations(md);
|
|
assert.ok(invocations.length > 0, 'sanity: expected at least one node ${GSD_HOME}/... invocation in reapply-patches.md');
|
|
|
|
const violations = invocations.filter(inv => !inv.relPath.startsWith('get-shit-done/'));
|
|
assert.deepEqual(violations, [], `invocations under non-installed paths: ${JSON.stringify(violations)}`);
|
|
});
|
|
|
|
test('reapply-patches.md references the verifier at get-shit-done/bin/verify-reapply-patches.cjs', () => {
|
|
const md = fs.readFileSync(REAPPLY_WORKFLOW, 'utf-8');
|
|
const invocations = extractScriptInvocations(md);
|
|
const verifierInvocations = invocations.filter(inv => inv.relPath.endsWith('verify-reapply-patches.cjs'));
|
|
assert.deepEqual(
|
|
verifierInvocations.map(i => i.relPath),
|
|
['get-shit-done/bin/verify-reapply-patches.cjs'],
|
|
'workflow must call the runtime-installed verifier path exactly once',
|
|
);
|
|
});
|
|
});
|