* fix(#856): remove gsd-cmd-rewrites temp dirs after install applyRuntimeContentRewritesForCommandsInPlace() returns a fresh mkdtemp dir under os.tmpdir() (gsd-cmd-rewrites-*) with rewritten command markdown. installRuntimeArtifacts() copied from it but never removed it, leaking one temp dir per commands kind per install — on tmpfs /tmp hosts these accumulate and consume RAM-backed storage. Wrap the per-kind copy in try/finally and rmSync the temp dir (only when it differs from the staged source, i.e. the commands kind) once the copy completes or fails. dest creation moved inside the try so a mkdir failure still triggers cleanup. Regression test isolates os.tmpdir() to a private TMPDIR root and asserts no gsd-cmd-rewrites-* dir survives the install. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(#856): add changeset for installer temp-dir cleanup Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -135,6 +135,41 @@ describe('enh-790 — installRuntimeArtifacts augment emits both commands and sk
|
||||
});
|
||||
});
|
||||
|
||||
describe('enh-790 — installRuntimeArtifacts does not leak temp dirs', () => {
|
||||
test('install cleans up gsd-cmd-rewrites-* temp dirs (no leak) — #856', (t) => {
|
||||
const { resolveProfile } = require('../gsd-core/bin/lib/install-profiles.cjs');
|
||||
const RESOLVED_FULL = resolveProfile({ modes: ['full'], manifest: MANIFEST });
|
||||
|
||||
// Isolate os.tmpdir() to a private root so parallel test processes can't race
|
||||
// on the shared system temp dir. os.tmpdir() resolves $TMPDIR/$TEMP/$TMP per call.
|
||||
const isolatedTmp = createTempDir('gsd-enh790-tmproot-');
|
||||
const prev = { TMPDIR: process.env.TMPDIR, TEMP: process.env.TEMP, TMP: process.env.TMP };
|
||||
process.env.TMPDIR = isolatedTmp;
|
||||
process.env.TEMP = isolatedTmp;
|
||||
process.env.TMP = isolatedTmp;
|
||||
|
||||
const configDir = createTempDir('gsd-enh790-leak-');
|
||||
t.after(() => {
|
||||
for (const k of ['TMPDIR', 'TEMP', 'TMP']) {
|
||||
if (prev[k] === undefined) delete process.env[k];
|
||||
else process.env[k] = prev[k];
|
||||
}
|
||||
cleanup(configDir);
|
||||
cleanup(isolatedTmp);
|
||||
});
|
||||
|
||||
installRuntimeArtifacts('augment', configDir, 'global', RESOLVED_FULL);
|
||||
|
||||
// The install creates its gsd-cmd-rewrites-* temp dirs under the isolated root;
|
||||
// after the fix none must remain.
|
||||
const leaked = fs.readdirSync(isolatedTmp).filter(n => n.startsWith('gsd-cmd-rewrites-'));
|
||||
assert.ok(
|
||||
leaked.length === 0,
|
||||
`installer must not leak gsd-cmd-rewrites-* temp dirs; leaked: ${leaked.join(', ')}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Uninstall contract ──────────────────────────────────────────────────────
|
||||
|
||||
describe('enh-790 — uninstallRuntimeArtifacts removes augment commands', () => {
|
||||
|
||||
Reference in New Issue
Block a user