diff --git a/packages/angular/build/src/builders/application/tests/options/assets_spec.ts b/packages/angular/build/src/builders/application/tests/options/assets_spec.ts index afa42cc1804e..7ca19daefa53 100644 --- a/packages/angular/build/src/builders/application/tests/options/assets_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/assets_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import fs from 'node:fs/promises'; import { buildApplication } from '../../index'; import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setup'; @@ -408,6 +409,44 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { harness.expectFile('dist/browser/test.svg').toNotExist(); }); + + it('does not follow symlink directories by default', async () => { + await harness.writeFile('target/test.txt', 'symlink-content'); + await fs.symlink( + harness.resolvePath('target'), + harness.resolvePath('src/symlink-dir'), + 'junction', + ); + + harness.useTarget('build', { + ...BASE_OPTIONS, + assets: [{ glob: '**/*', input: 'src' }], + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + harness.expectFile('dist/browser/symlink-dir/test.txt').toNotExist(); + }); + + it('follows symlink directories when followSymlinks is true', async () => { + await harness.writeFile('target/test.txt', 'symlink-content'); + await fs.symlink( + harness.resolvePath('target'), + harness.resolvePath('src/symlink-dir'), + 'junction', + ); + + harness.useTarget('build', { + ...BASE_OPTIONS, + assets: [{ glob: '**/*', input: 'src', followSymlinks: true }], + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + harness.expectFile('dist/browser/symlink-dir/test.txt').content.toBe('symlink-content'); + }); }); }); }); diff --git a/packages/angular/build/src/utils/resolve-assets.ts b/packages/angular/build/src/utils/resolve-assets.ts index 41ae41d66b9b..79ddd8548266 100644 --- a/packages/angular/build/src/utils/resolve-assets.ts +++ b/packages/angular/build/src/utils/resolve-assets.ts @@ -39,7 +39,7 @@ export async function resolveAssets( cwd, dot: true, ignore: entry.ignore ? [...DEFAULT_ASSET_IGNORE, ...entry.ignore] : DEFAULT_ASSET_IGNORE, - followSymbolicLinks: entry.followSymlinks, + followSymbolicLinks: entry.followSymlinks ?? false, }); for (const file of files) { diff --git a/packages/angular_devkit/build_angular/src/utils/copy-assets.ts b/packages/angular_devkit/build_angular/src/utils/copy-assets.ts index ed739970cd09..a525cab99b34 100644 --- a/packages/angular_devkit/build_angular/src/utils/copy-assets.ts +++ b/packages/angular_devkit/build_angular/src/utils/copy-assets.ts @@ -33,7 +33,7 @@ export async function copyAssets( cwd, dot: true, ignore: entry.ignore ? defaultIgnore.concat(entry.ignore) : defaultIgnore, - followSymbolicLinks: entry.followSymlinks, + followSymbolicLinks: entry.followSymlinks ?? false, }); const directoryExists = new Set();