Skip to content

Commit 13df67e

Browse files
committed
test: reuse shared temp dir roots
1 parent d01ec5c commit 13df67e

1 file changed

Lines changed: 53 additions & 2 deletions

File tree

src/test-helpers/temp-dir.ts

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,51 @@ import fs from "node:fs/promises";
33
import os from "node:os";
44
import path from "node:path";
55

6+
const asyncPrefixRoots = new Map<string, string>();
7+
const pendingAsyncPrefixRoots = new Map<string, Promise<string>>();
8+
const syncPrefixRoots = new Map<string, string>();
9+
let nextAsyncDirIndex = 0;
10+
let nextSyncDirIndex = 0;
11+
12+
function getRootKey(options: { prefix: string; parentDir?: string }): string {
13+
return `${options.parentDir ?? os.tmpdir()}\u0000${options.prefix}`;
14+
}
15+
16+
async function ensureAsyncPrefixRoot(options: {
17+
prefix: string;
18+
parentDir?: string;
19+
}): Promise<string> {
20+
const key = getRootKey(options);
21+
const cached = asyncPrefixRoots.get(key);
22+
if (cached) {
23+
return cached;
24+
}
25+
const pending = pendingAsyncPrefixRoots.get(key);
26+
if (pending) {
27+
return await pending;
28+
}
29+
const create = fs.mkdtemp(path.join(options.parentDir ?? os.tmpdir(), options.prefix));
30+
pendingAsyncPrefixRoots.set(key, create);
31+
try {
32+
const root = await create;
33+
asyncPrefixRoots.set(key, root);
34+
return root;
35+
} finally {
36+
pendingAsyncPrefixRoots.delete(key);
37+
}
38+
}
39+
40+
function ensureSyncPrefixRoot(options: { prefix: string; parentDir?: string }): string {
41+
const key = getRootKey(options);
42+
const cached = syncPrefixRoots.get(key);
43+
if (cached) {
44+
return cached;
45+
}
46+
const root = fsSync.mkdtempSync(path.join(options.parentDir ?? os.tmpdir(), options.prefix));
47+
syncPrefixRoots.set(key, root);
48+
return root;
49+
}
50+
651
export async function withTempDir<T>(
752
options: {
853
prefix: string;
@@ -11,7 +56,10 @@ export async function withTempDir<T>(
1156
},
1257
run: (dir: string) => Promise<T>,
1358
): Promise<T> {
14-
const base = await fs.mkdtemp(path.join(options.parentDir ?? os.tmpdir(), options.prefix));
59+
const root = await ensureAsyncPrefixRoot(options);
60+
const base = path.join(root, `dir-${String(nextAsyncDirIndex)}`);
61+
nextAsyncDirIndex += 1;
62+
await fs.mkdir(base, { recursive: true });
1563
const dir = options.subdir ? path.join(base, options.subdir) : base;
1664
if (options.subdir) {
1765
await fs.mkdir(dir, { recursive: true });
@@ -68,7 +116,10 @@ export function withTempDirSync<T>(
68116
},
69117
run: (dir: string) => T,
70118
): T {
71-
const base = fsSync.mkdtempSync(path.join(options.parentDir ?? os.tmpdir(), options.prefix));
119+
const root = ensureSyncPrefixRoot(options);
120+
const base = path.join(root, `dir-${String(nextSyncDirIndex)}`);
121+
nextSyncDirIndex += 1;
122+
fsSync.mkdirSync(base, { recursive: true });
72123
const dir = options.subdir ? path.join(base, options.subdir) : base;
73124
if (options.subdir) {
74125
fsSync.mkdirSync(dir, { recursive: true });

0 commit comments

Comments
 (0)