FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix(@angular/build): preserve nested workspace path for git worktree cache by clydin · Pull Request #34220 · angular/angular-cli · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .ts  (4) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
11 changes: 8 additions & 3 deletions packages/angular/build/src/utils/normalize-cache.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

import { existsSync, readFileSync, statSync } from 'node:fs';
import { dirname, isAbsolute, join, resolve } from 'node:path';
import { dirname, isAbsolute, join, relative, resolve } from 'node:path';

/** Version placeholder is replaced during the build process with actual package version */
const VERSION = '0.0.0-PLACEHOLDER';
Expand Down Expand Up @@ -75,11 +75,16 @@ function getCacheBasePath(workspaceRoot: string, cachePathSetting: string): stri
// It's a git worktree
const commondir = readFileSync(commondirPath, 'utf8').trim();
const commonGitDir = resolve(gitdir, commondir);

return resolve(dirname(commonGitDir), cachePathSetting);
const relativeWorkspacePath = relative(currentDir, workspaceRoot);
const mainWorkspaceRoot = resolve(dirname(commonGitDir), relativeWorkspacePath);
if (existsSync(mainWorkspaceRoot)) {
return resolve(mainWorkspaceRoot, cachePathSetting);
}
}
}
}

break;
}
const parentDir = dirname(currentDir);
if (parentDir === currentDir) {
Expand Down
64 changes: 62 additions & 2 deletions packages/angular/build/src/utils/normalize-cache_spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@
* found in the LICENSE file at https://angular.dev/license
*/

import assert from 'node:assert';
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import { normalizeCacheOptions } from './normalize-cache';

describe('normalizeCacheOptions', () => {
let tempDir: string;

beforeEach(async () => {
tempDir = await mkdtemp(join(tmpdir(), 'angular-cache-spec-'));
const baseTmpDir = process.env['TEST_TMPDIR'];
assert(baseTmpDir, 'TEST_TMPDIR is not set');
tempDir = await mkdtemp(join(baseTmpDir, 'angular-cache-spec-'));
});

afterEach(async () => {
Expand Down Expand Up @@ -58,6 +60,64 @@ describe('normalizeCacheOptions', () => {
expect(options.localPath).toBe(resolve(worktreeRoot, '.angular/cache', '0.0.0-PLACEHOLDER'));
});

it('should resolve cache path relative to corresponding nested workspace in main repository for a git worktree', async () => {
const mainRepoRoot = join(tempDir, 'main-repo');
const mainGitDir = join(mainRepoRoot, '.git');
const mainWorkspaceRoot = join(mainRepoRoot, 'Site1/ClientApp');
const worktreeRoot = join(tempDir, 'worktree');
const worktreeWorkspaceRoot = join(worktreeRoot, 'Site1/ClientApp');

// Create main repo with a nested Angular workspace directory
await mkdir(mainGitDir, { recursive: true });
await mkdir(mainWorkspaceRoot, { recursive: true });

// Create worktree with the same nested Angular workspace structure and a .git file at the worktree root
const worktreeMetadataDir = join(mainGitDir, 'worktrees/wt-1');
await mkdir(worktreeMetadataDir, { recursive: true });
await mkdir(worktreeWorkspaceRoot, { recursive: true });
await writeFile(join(worktreeRoot, '.git'), `gitdir: ${worktreeMetadataDir}`);

// Point the worktree metadata back to the main .git directory
await writeFile(join(worktreeMetadataDir, 'commondir'), '../..');

const options = normalizeCacheOptions({}, worktreeWorkspaceRoot);

expect(options.basePath).toBe(resolve(mainWorkspaceRoot, '.angular/cache'));
expect(options.path).toBe(resolve(mainWorkspaceRoot, '.angular/cache', '0.0.0-PLACEHOLDER'));
expect(options.localBasePath).toBe(resolve(worktreeWorkspaceRoot, '.angular/cache'));
expect(options.localPath).toBe(
resolve(worktreeWorkspaceRoot, '.angular/cache', '0.0.0-PLACEHOLDER'),
);
});

it('should fall back to worktree workspace root when nested workspace does not exist in main repository', async () => {
const mainRepoRoot = join(tempDir, 'main-repo');
const mainGitDir = join(mainRepoRoot, '.git');
const worktreeRoot = join(tempDir, 'worktree');
const worktreeWorkspaceRoot = join(worktreeRoot, 'NewSite/ClientApp');

// Create main repo without the 'NewSite/ClientApp' subdirectory (e.g., added only on the worktree branch)
await mkdir(mainGitDir, { recursive: true });

// Create worktree with the new nested Angular workspace and link it to the main repo's .git directory
const worktreeMetadataDir = join(mainGitDir, 'worktrees/wt-1');
await mkdir(worktreeMetadataDir, { recursive: true });
await mkdir(worktreeWorkspaceRoot, { recursive: true });
await writeFile(join(worktreeRoot, '.git'), `gitdir: ${worktreeMetadataDir}`);
await writeFile(join(worktreeMetadataDir, 'commondir'), '../..');

const options = normalizeCacheOptions({}, worktreeWorkspaceRoot);

expect(options.basePath).toBe(resolve(worktreeWorkspaceRoot, '.angular/cache'));
expect(options.path).toBe(
resolve(worktreeWorkspaceRoot, '.angular/cache', '0.0.0-PLACEHOLDER'),
);
expect(options.localBasePath).toBe(resolve(worktreeWorkspaceRoot, '.angular/cache'));
expect(options.localPath).toBe(
resolve(worktreeWorkspaceRoot, '.angular/cache', '0.0.0-PLACEHOLDER'),
);
});

it('should resolve local cache path relative to worktree root with custom relative path', async () => {
const mainRepoRoot = join(tempDir, 'main-repo');
const mainGitDir = join(mainRepoRoot, '.git');
Expand Down
11 changes: 8 additions & 3 deletions packages/angular/cli/src/commands/cache/utilities.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { isJsonObject } from '@angular-devkit/core';
import { existsSync, readFileSync, statSync } from 'node:fs';
import { dirname, isAbsolute, join, resolve } from 'node:path';
import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
import { Cache, Environment } from '../../../lib/config/workspace-schema';
import { AngularWorkspace } from '../../utilities/config';

Expand Down Expand Up @@ -47,11 +47,16 @@ function getCacheBasePath(workspaceRoot: string, cachePathSetting: string): stri
// It's a git worktree
const commondir = readFileSync(commondirPath, 'utf8').trim();
const commonGitDir = resolve(gitdir, commondir);

return resolve(dirname(commonGitDir), cachePathSetting);
const relativeWorkspacePath = relative(currentDir, workspaceRoot);
const mainWorkspaceRoot = resolve(dirname(commonGitDir), relativeWorkspacePath);
if (existsSync(mainWorkspaceRoot)) {
return resolve(mainWorkspaceRoot, cachePathSetting);
}
}
}
}

break;
}
const parentDir = dirname(currentDir);
if (parentDir === currentDir) {
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
*/

import { workspaces } from '@angular-devkit/core';
import assert from 'node:assert';
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import { AngularWorkspace } from '../../utilities/config';
import { getCacheConfig } from './utilities';
Expand All @@ -17,7 +17,9 @@ describe('CLI cache config utilities', () => {
let tempDir: string;

beforeEach(async () => {
tempDir = await mkdtemp(join(tmpdir(), 'angular-cli-cache-spec-'));
const baseTmpDir = process.env['TEST_TMPDIR'];
assert(baseTmpDir, 'TEST_TMPDIR is not set');
tempDir = await mkdtemp(join(baseTmpDir, 'angular-cli-cache-spec-'));
});

afterEach(async () => {
Expand Down Expand Up @@ -67,6 +69,52 @@ describe('CLI cache config utilities', () => {
expect(config.path).toBe(resolve(mainRepoRoot, '.angular/cache'));
});

it('should resolve default cache path relative to corresponding nested workspace in main repository for a git worktree', async () => {
const mainRepoRoot = join(tempDir, 'main-repo');
const mainGitDir = join(mainRepoRoot, '.git');
const mainWorkspaceRoot = join(mainRepoRoot, 'Site1/ClientApp');
const worktreeRoot = join(tempDir, 'worktree');
const worktreeWorkspaceRoot = join(worktreeRoot, 'Site1/ClientApp');

// Create main repo with a nested Angular workspace directory
await mkdir(mainGitDir, { recursive: true });
await mkdir(mainWorkspaceRoot, { recursive: true });

// Create worktree with the same nested Angular workspace structure and a .git file at the worktree root
const worktreeMetadataDir = join(mainGitDir, 'worktrees/wt-1');
await mkdir(worktreeMetadataDir, { recursive: true });
await mkdir(worktreeWorkspaceRoot, { recursive: true });
await writeFile(join(worktreeRoot, '.git'), `gitdir: ${worktreeMetadataDir}`);

// Point the worktree metadata back to the main .git directory
await writeFile(join(worktreeMetadataDir, 'commondir'), '../..');

const config = getCacheConfig(mockWorkspace(worktreeWorkspaceRoot));

expect(config.path).toBe(resolve(mainWorkspaceRoot, '.angular/cache'));
});

it('should fall back to worktree workspace basePath when nested workspace does not exist in main repository', async () => {
const mainRepoRoot = join(tempDir, 'main-repo');
const mainGitDir = join(mainRepoRoot, '.git');
const worktreeRoot = join(tempDir, 'worktree');
const worktreeWorkspaceRoot = join(worktreeRoot, 'NewSite/ClientApp');

// Create main repo without the 'NewSite/ClientApp' subdirectory (e.g., added only on the worktree branch)
await mkdir(mainGitDir, { recursive: true });

// Create worktree with the new nested Angular workspace and link it to the main repo's .git directory
const worktreeMetadataDir = join(mainGitDir, 'worktrees/wt-1');
await mkdir(worktreeMetadataDir, { recursive: true });
await mkdir(worktreeWorkspaceRoot, { recursive: true });
await writeFile(join(worktreeRoot, '.git'), `gitdir: ${worktreeMetadataDir}`);
await writeFile(join(worktreeMetadataDir, 'commondir'), '../..');

const config = getCacheConfig(mockWorkspace(worktreeWorkspaceRoot));

expect(config.path).toBe(resolve(worktreeWorkspaceRoot, '.angular/cache'));
});

it('should resolve custom relative cache path relative to main repository root in a git worktree', async () => {
const mainRepoRoot = join(tempDir, 'main-repo');
const mainGitDir = join(mainRepoRoot, '.git');
Expand Down
Loading

Back | FazBrowse Home | New Git URL