Skip to content

Commit b554bd7

Browse files
committed
fix(@angular/build): add temporary directory cleanup for Vitest executor
The Vitest-based unit test builder created temporary output directories within `dist/test-out` for each run but did not remove them upon completion. This led to an accumulation of orphaned directories, consuming unnecessary disk space. This commit introduces robust cleanup logic to the `VitestExecutor` by: - Deleting the temporary output directory during graceful shutdown using the `asyncDispose` method. - Registering a `SIGINT` process handler to ensure the directory is also removed during forceful interruptions, such as when a user presses `Ctrl-C` in watch mode.
1 parent abf0032 commit b554bd7

File tree

1 file changed

+11
-1
lines changed
  • packages/angular/build/src/builders/unit-test/runners/vitest

1 file changed

+11
-1
lines changed

packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
import type { BuilderOutput } from '@angular-devkit/architect';
1010
import assert from 'node:assert';
1111
import { randomUUID } from 'node:crypto';
12-
import { createRequire } from 'node:module';
12+
import { rmSync } from 'node:fs';
13+
import { rm } from 'node:fs/promises';
1314
import path from 'node:path';
1415
import type { InlineConfig, Vitest } from 'vitest/node';
1516
import { assertIsError } from '../../../../utils/error';
@@ -30,10 +31,17 @@ export class VitestExecutor implements TestExecutor {
3031
private readonly outputPath: string;
3132
private latestBuildResult: FullResult | IncrementalResult | undefined;
3233

34+
// Graceful shutdown signal handler
35+
// This is needed to remove the temporary output directory on Ctrl+C
36+
private readonly sigintListener = () => {
37+
rmSync(this.outputPath, { recursive: true, force: true });
38+
};
39+
3340
constructor(projectName: string, options: NormalizedUnitTestBuilderOptions) {
3441
this.projectName = projectName;
3542
this.options = options;
3643
this.outputPath = toPosixPath(path.join(options.workspaceRoot, generateOutputPath()));
44+
process.on('SIGINT', this.sigintListener);
3745
}
3846

3947
async *execute(buildResult: FullResult | IncrementalResult): AsyncIterable<BuilderOutput> {
@@ -78,7 +86,9 @@ export class VitestExecutor implements TestExecutor {
7886
}
7987

8088
async [Symbol.asyncDispose](): Promise<void> {
89+
process.off('SIGINT', this.sigintListener);
8190
await this.vitest?.close();
91+
await rm(this.outputPath, { recursive: true, force: true });
8292
}
8393

8494
private async initializeVitest(): Promise<Vitest> {

0 commit comments

Comments
 (0)