fix(park): park from a CRLF diff and say that a staged new file is parked

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-26 14:44:33 +01:00
commit afe56899a9
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
4 changed files with 59 additions and 6 deletions

View file

@ -10,6 +10,9 @@
// prefix and lists review_version 1.1 as current, and /trekexecute's
// main-merge gate maps it to "not measured" with the merge locked.
// M11 Handover 6 states that only a full 40- or 64-hex reviewed commit is read.
// E22e The park tool parks every file new in the attempt's diff, untracked or
// staged but not in HEAD: its header and /trekexecute's resume paragraph
// no longer say "still untracked".
// No static import of a new export: the file must load at be0b631.
// Fix the SOURCE a pin guards, not the pin.
@ -101,3 +104,29 @@ test('[M11] Handover 6 states the full 40- or 64-hex reviewed commit', () => {
assert.match(gateParagraph(), /`scope_sha_end`[^.]*full 40- or 64-hex/,
'the verdict-gate paragraph of Handover 6 does not state that only a full 40- or 64-hex scope_sha_end is read');
});
// --- E22e --------------------------------------------------------------------------
/** The sentences of `text` (flattened) that say what the park tool moves or parks. */
function parkSentences(text) {
return flat(text).split(/(?<=\.)\s+(?=[A-Z`"*(])/).filter((s) => /\b(moves|parks)\b/.test(s) && /\bfile\b/.test(s));
}
test('[E22e] the park header says untracked or staged but not in HEAD', () => {
const src = read('lib/util/park-attempt-files.mjs');
const header = src.slice(0, src.indexOf('\nimport '));
assert.ok(header.length > 0, 'lib/util/park-attempt-files.mjs has no header before its imports');
const comment = header.split('\n').map((l) => l.replace(/^\/\/ ?/, '')).join('\n');
assert.doesNotMatch(flat(comment), /still untracked/, 'the park header still says the tool parks only files "still untracked"');
const hits = parkSentences(comment);
assert.ok(hits.some((s) => /new in the attempt's diff/.test(s) && /untracked, or staged but not in HEAD/.test(s)),
`no header sentence says every file new in the attempt's diff is parked, untracked, or staged but not in HEAD: ${hits.join(' | ')}`);
});
test('[E22e] the execute command says the same', () => {
const para = between('commands/trekexecute.md', 'A step at `fix_rounds` 4 on `--resume` was re-planned', 'Then launch a fresh');
assert.doesNotMatch(flat(para), /still untracked/, 'the /trekexecute resume paragraph still says the tool moves only files "still untracked"');
const hits = parkSentences(para);
assert.ok(hits.some((s) => /new in the attempt's diff/.test(s) && /untracked, or staged but not in HEAD/.test(s)),
`no /trekexecute sentence says every file new in the attempt's diff is parked, untracked, or staged but not in HEAD: ${hits.join(' | ')}`);
});

View file

@ -488,3 +488,27 @@ test('[M7] an unborn HEAD parks the attempt\'s files', () => {
rmSync(dir, { recursive: true, force: true });
}
});
// --- fix round 4-5b: E22c --------------------------------------------------------
// [E22c] The diff was split on '\n' only: in a CRLF diff every line kept its '\r',
// so no `new file mode` line matched and nothing was parked, with exit 0.
test('[E22c] a CRLF diff parks its new files', async () => {
const mod = await import('../../lib/util/park-attempt-files.mjs');
assert.equal(typeof mod.newFilesInDiff, 'function', 'newFilesInDiff is not exported');
const crlf = DIFF.split('\n').join('\r\n');
assert.ok(crlf.includes('new file mode 100755\r\n'), 'control: the diff has CRLF line ends');
assert.deepEqual(mod.newFilesInDiff(crlf).paths, ['tests/batch.sh', 'tests/cli-stdin.test.mjs'],
'a CRLF diff did not yield its new files');
const dir = repo();
try {
attemptFiles(dir);
const r = run(dir, crlf);
assert.equal(r.status, 0, r.stdout + r.stderr);
assert.deepEqual(JSON.parse(r.stdout).parked, ['tests/batch.sh', 'tests/cli-stdin.test.mjs'], `a CRLF diff parked nothing: ${r.stdout}`);
assert.equal(existsSync(join(dir, 'tests/batch.sh')), false, 'the file is still in the tree');
assert.equal(readFileSync(parkedPath(dir, 'tests/batch.sh'), 'utf8'), 'stale | cat\n', 'the file is not under the parked directory');
} finally {
rmSync(dir, { recursive: true, force: true });
}
});