Skip to content

Commit 74f6ef1

Browse files
committed
fixup! fix(@angular/cli): also clean the worktree-local cache in a git worktree
1 parent cb6542b commit 74f6ef1

3 files changed

Lines changed: 46 additions & 13 deletions

File tree

‎packages/angular/cli/src/commands/cache/clean/cli.ts‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ export class CacheCleanModule extends CommandModule implements CommandModuleImpl
2929

3030
// In a Git worktree, `path` is shared with the main checkout and `localPath` holds the
3131
// development server's Vite cache. Both are the same path outside of a worktree.
32-
for (const cachePath of new Set([path, localPath])) {
33-
await rm(cachePath, {
34-
force: true,
35-
recursive: true,
36-
maxRetries: 3,
37-
});
38-
}
32+
await Promise.all(
33+
Array.from(new Set([path, localPath]), (cachePath) =>
34+
rm(cachePath, {
35+
force: true,
36+
recursive: true,
37+
maxRetries: 3,
38+
}),
39+
),
40+
);
3941
}
4042
}

‎packages/angular/cli/src/commands/cache/clean/cli_spec.ts‎

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { workspaces } from '@angular-devkit/core';
9+
import type { workspaces } from '@angular-devkit/core';
1010
import assert from 'node:assert';
1111
import { existsSync } from 'node:fs';
1212
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
1313
import { join } from 'node:path';
14-
import { CommandContext } from '../../../command-builder/command-module';
15-
import { AngularWorkspace } from '../../../utilities/config';
14+
import type { CommandContext } from '../../../command-builder/command-module';
15+
import type { AngularWorkspace } from '../../../utilities/config';
1616
import { CacheCleanModule } from './cli';
1717

1818
describe('CacheCleanModule', () => {
@@ -28,13 +28,13 @@ describe('CacheCleanModule', () => {
2828
await rm(tempDir, { recursive: true, force: true });
2929
});
3030

31-
function runClean(basePath: string): Promise<void> {
31+
function runClean(basePath: string, cliExtension?: unknown): Promise<void> {
3232
const workspace = {
3333
basePath,
34-
extensions: {},
34+
extensions: cliExtension ? { cli: cliExtension } : {},
3535
projects: {} as unknown as workspaces.ProjectDefinitionCollection,
3636
filePath: join(basePath, 'angular.json'),
37-
getCli: () => undefined,
37+
getCli: () => cliExtension,
3838
getProjectCli: () => undefined,
3939
save: () => Promise.resolve(),
4040
} as unknown as AngularWorkspace;
@@ -73,4 +73,32 @@ describe('CacheCleanModule', () => {
7373
expect(existsSync(join(mainRepoRoot, '.angular/cache'))).toBeFalse();
7474
expect(existsSync(join(worktreeRoot, '.angular/cache'))).toBeFalse();
7575
});
76+
77+
it('should succeed when cache directories do not exist', async () => {
78+
const workspaceRoot = join(tempDir, 'project');
79+
await mkdir(join(workspaceRoot, '.git'), { recursive: true });
80+
81+
await expectAsync(runClean(workspaceRoot)).toBeResolved();
82+
});
83+
84+
it('should delete both the shared and the worktree-local cache with a custom relative path', async () => {
85+
const mainRepoRoot = join(tempDir, 'main-repo');
86+
const mainGitDir = join(mainRepoRoot, '.git');
87+
const worktreeRoot = join(tempDir, 'worktree');
88+
const worktreeMetadataDir = join(mainGitDir, 'worktrees/wt-1');
89+
90+
await mkdir(worktreeMetadataDir, { recursive: true });
91+
await mkdir(worktreeRoot, { recursive: true });
92+
await writeFile(join(worktreeRoot, '.git'), `gitdir: ${worktreeMetadataDir}`);
93+
await writeFile(join(worktreeMetadataDir, 'commondir'), '../..');
94+
95+
const customCachePath = 'custom-cache-dir';
96+
await mkdir(join(mainRepoRoot, customCachePath, 'app'), { recursive: true });
97+
await mkdir(join(worktreeRoot, customCachePath, 'app/dev-server/vite'), { recursive: true });
98+
99+
await runClean(worktreeRoot, { cache: { path: customCachePath } });
100+
101+
expect(existsSync(join(mainRepoRoot, customCachePath))).toBeFalse();
102+
expect(existsSync(join(worktreeRoot, customCachePath))).toBeFalse();
103+
});
76104
});

‎packages/angular/cli/src/commands/cache/utilities_spec.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ describe('CLI cache config utilities', () => {
9494
const config = getCacheConfig(mockWorkspace(worktreeWorkspaceRoot));
9595

9696
expect(config.path).toBe(resolve(mainWorkspaceRoot, '.angular/cache'));
97+
expect(config.localPath).toBe(resolve(worktreeWorkspaceRoot, '.angular/cache'));
9798
});
9899

99100
it('should fall back to worktree workspace basePath when nested workspace does not exist in main repository', async () => {
@@ -115,6 +116,7 @@ describe('CLI cache config utilities', () => {
115116
const config = getCacheConfig(mockWorkspace(worktreeWorkspaceRoot));
116117

117118
expect(config.path).toBe(resolve(worktreeWorkspaceRoot, '.angular/cache'));
119+
expect(config.localPath).toBe(config.path);
118120
});
119121

120122
it('should resolve custom relative cache path relative to main repository root in a git worktree', async () => {
@@ -158,5 +160,6 @@ describe('CLI cache config utilities', () => {
158160
const config = getCacheConfig(mockWorkspace(submoduleRoot));
159161

160162
expect(config.path).toBe(resolve(submoduleRoot, '.angular/cache'));
163+
expect(config.localPath).toBe(config.path);
161164
});
162165
});

0 commit comments

Comments
 (0)