55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
|
|
import { mkdtempSync, rmSync } from "node:fs";
|
||
|
|
import { tmpdir } from "node:os";
|
||
|
|
import { join } from "node:path";
|
||
|
|
import { RUN_ROOT_ENV } from "./global-setup.js";
|
||
|
|
|
||
|
|
// Every temp dir this process has handed out, in creation order.
|
||
|
|
const created: string[] = [];
|
||
|
|
|
||
|
|
// Where to allocate. Under `vitest run` this is the per-run root that
|
||
|
|
// global-setup.ts created and will remove wholesale when the run ends; the
|
||
|
|
// fallback keeps `tmp()` usable if a file is ever executed outside that config.
|
||
|
|
function base(): string {
|
||
|
|
return process.env[RUN_ROOT_ENV] ?? tmpdir();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Belt-and-braces reaper for the fallback case only.
|
||
|
|
//
|
||
|
|
// It is deliberately NOT the primary mechanism. Vitest recycles its pool workers
|
||
|
|
// by killing them, so an `exit` handler registered from a test file does not run
|
||
|
|
// — verified with a probe test, and by a full suite run that still leaked 750
|
||
|
|
// directories with this hook in place. The real cleanup is global-setup.ts's
|
||
|
|
// teardown, which runs in the main process where an exit IS orderly. This hook
|
||
|
|
// only earns its keep when `tmp()` is called with no run root set, where nothing
|
||
|
|
// else would ever remove the directory.
|
||
|
|
let armed = false;
|
||
|
|
|
||
|
|
function arm(): void {
|
||
|
|
if (armed) return;
|
||
|
|
armed = true;
|
||
|
|
process.once("exit", () => {
|
||
|
|
for (const dir of created) {
|
||
|
|
try {
|
||
|
|
rmSync(dir, { recursive: true, force: true });
|
||
|
|
} catch {
|
||
|
|
// ignore
|
||
|
|
}
|
||
|
|
}
|
||
|
|
created.length = 0;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a temp dir and register it for cleanup. Drop-in replacement for
|
||
|
|
* `mkdtempSync(join(tmpdir(), prefix))` — the prefix survives as the directory's
|
||
|
|
* basename, so paths stay as greppable as they were.
|
||
|
|
*
|
||
|
|
* @param prefix e.g. `"cast-home-"` — mkdtemp appends six random characters.
|
||
|
|
*/
|
||
|
|
export function tmp(prefix: string): string {
|
||
|
|
arm();
|
||
|
|
const dir = mkdtempSync(join(base(), prefix));
|
||
|
|
created.push(dir);
|
||
|
|
return dir;
|
||
|
|
}
|