amsd-pipeline-shared 0.5.8 → 0.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -58,6 +58,9 @@ function validate(input) {
|
|
|
58
58
|
if (need('test', t, 'envUnset')) out.test.envUnset = strs('test.envUnset', t.envUnset, { nonEmpty: false });
|
|
59
59
|
if (need('test', t, 'greenPatterns')) { if (Array.isArray(t.greenPatterns) && !t.greenPatterns.length) bad('test.greenPatterns', 'at least one pattern is required'); out.test.greenPatterns = rxs('test.greenPatterns', t.greenPatterns); }
|
|
60
60
|
if (need('test', t, 'failedPattern')) out.test.failedPattern = rx('test.failedPattern', t.failedPattern);
|
|
61
|
+
// OPTIONAL: repository paths that git ignores and the tests read (a codeline copy, generated data) — linked into every throwaway worktree the verification runs its tests in
|
|
62
|
+
out.test.fixtures = has(t, 'fixtures') ? (strs('test.fixtures', t.fixtures, { nonEmpty: false }) || []) : [];
|
|
63
|
+
out.test.fixtures.forEach((d, i) => rel(`test.fixtures[${i}]`, d));
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
const i = p.install;
|
|
@@ -34,12 +34,23 @@ function runTests(wt, files, profile) {
|
|
|
34
34
|
return { status: r.status, out: `${r.stdout || ''}${r.stderr || ''}` };
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
/**
|
|
38
|
-
|
|
37
|
+
/**
|
|
38
|
+
* A throwaway work tree of <rev>; removed by the caller's finally. `fixtures` (the profile's test.fixtures): repository paths git ignores and the tests read — each is linked in from the repository, so a
|
|
39
|
+
* correct repair is judged on the data its tests need (run 11: the doctor's own GREEN check failed on a missing git-ignored codeline copy). A fixture the repository does not have is a stated error.
|
|
40
|
+
*/
|
|
41
|
+
function worktree(repo, rev, fixtures = []) {
|
|
39
42
|
const wt = fs.mkdtempSync(path.join(os.tmpdir(), 'doctor-wt-'));
|
|
40
43
|
fs.rmSync(wt, { recursive: true, force: true });
|
|
41
44
|
const r = git(repo, 'worktree', 'add', '--detach', '-q', wt, rev);
|
|
42
45
|
if (r.status !== 0) throw new Error(`worktree of ${rev}: ${r.stderr}`);
|
|
46
|
+
try {
|
|
47
|
+
for (const f of fixtures) {
|
|
48
|
+
const from = path.join(repo, f); const to = path.join(wt, f);
|
|
49
|
+
if (!fs.existsSync(from)) throw new Error(`test.fixtures names ${f}, which is not in ${repo} — nothing to link into the worktree`);
|
|
50
|
+
if (fs.existsSync(to)) continue;
|
|
51
|
+
fs.mkdirSync(path.dirname(to), { recursive: true }); fs.symlinkSync(from, to);
|
|
52
|
+
}
|
|
53
|
+
} catch (e) { drop(repo, wt); throw e; }
|
|
43
54
|
return wt;
|
|
44
55
|
}
|
|
45
56
|
const drop = (repo, wt) => { git(repo, 'worktree', 'remove', '--force', wt); git(repo, 'worktree', 'prune'); fs.rmSync(wt, { recursive: true, force: true }); };
|
|
@@ -72,13 +83,13 @@ function verifyRepair({ repo, base, branch, profile, layer, abortKind }) {
|
|
|
72
83
|
let wtBase = null; let wtTip = null;
|
|
73
84
|
try {
|
|
74
85
|
// RED: the base, with ONLY the repair's tests added — they must fail there (a test that cannot even load is caught by the GREEN run)
|
|
75
|
-
wtBase = worktree(repo, base);
|
|
86
|
+
wtBase = worktree(repo, base, profile.test.fixtures);
|
|
76
87
|
const co = git(wtBase, 'checkout', branch, '--', ...tests);
|
|
77
88
|
if (co.status !== 0) return bad(`cannot place the tests on the base: ${co.stderr.trim()}`, { files });
|
|
78
89
|
const red = runTests(wtBase, tests, profile);
|
|
79
90
|
if (red.status === 0) return bad('the test passes without the fix: it is not RED, so it proves nothing', { files, red: red.out });
|
|
80
91
|
// GREEN: the branch's tip
|
|
81
|
-
wtTip = worktree(repo, branch);
|
|
92
|
+
wtTip = worktree(repo, branch, profile.test.fixtures);
|
|
82
93
|
const green = runTests(wtTip, tests, profile);
|
|
83
94
|
if (green.status !== 0 || !profile.test.greenPatterns.every((r) => r.test(green.out))) return bad('the test fails with the fix: not GREEN', { files, red: red.out, green: green.out });
|
|
84
95
|
return { ok: true, why: 'RED on the base, GREEN with the fix', files, tests, red: red.out, green: green.out };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amsd-pipeline-shared",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.9",
|
|
4
4
|
"description": "The AMSD pipeline's shared components, one source for the bash pipeline and its Claude workflows: the model-call gateway (llm-handler.sh — retry, ladder, self-heal, cost) and the libraries it runs.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"bin": {
|