Skip to content

Commit adc0db2

Browse files
committed
fix(@angular-devkit/build-angular): deleteOutputPath when using esbuild-builder
Prior to this change the `deleteOutputPath` was not being used in the esbuild-builder. Closes #26308
1 parent 49f503b commit adc0db2

File tree

3 files changed

+135
-1
lines changed

3 files changed

+135
-1
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import { buildApplication } from '../../index';
10+
import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setup';
11+
12+
describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
13+
describe('Option: "deleteOutputPath"', () => {
14+
beforeEach(async () => {
15+
// Application code is not needed for asset tests
16+
await harness.writeFile('src/main.ts', 'console.log("TEST");');
17+
18+
// Add file in output
19+
await harness.writeFile('dist/dummy.txt', '');
20+
});
21+
22+
it(`should delete the output files when 'deleteOutputPath' is true`, async () => {
23+
harness.useTarget('build', {
24+
...BASE_OPTIONS,
25+
deleteOutputPath: true,
26+
});
27+
28+
const { result } = await harness.executeOnce();
29+
expect(result?.success).toBeTrue();
30+
harness.expectFile('dist/dummy.txt').toNotExist();
31+
});
32+
33+
it(`should delete the output files when 'deleteOutputPath' is not set`, async () => {
34+
harness.useTarget('build', {
35+
...BASE_OPTIONS,
36+
deleteOutputPath: undefined,
37+
});
38+
39+
const { result } = await harness.executeOnce();
40+
expect(result?.success).toBeTrue();
41+
harness.expectFile('dist/dummy.txt').toNotExist();
42+
});
43+
44+
it(`should delete the output files when 'deleteOutputPath' is false`, async () => {
45+
harness.useTarget('build', {
46+
...BASE_OPTIONS,
47+
deleteOutputPath: false,
48+
});
49+
50+
const { result } = await harness.executeOnce();
51+
expect(result?.success).toBeTrue();
52+
harness.expectFile('dist/dummy.txt').toExist();
53+
});
54+
});
55+
});

packages/angular_devkit/build_angular/src/builders/browser-esbuild/index.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import path from 'node:path';
1414
import { BuildOutputFile } from '../../tools/esbuild/bundler-context';
1515
import { BuildOutputAsset } from '../../tools/esbuild/bundler-execution-result';
1616
import { emitFilesToDisk } from '../../tools/esbuild/utils';
17+
import { assertIsError } from '../../utils/error';
1718
import { buildApplicationInternal } from '../application';
1819
import { Schema as ApplicationBuilderOptions } from '../application/schema';
1920
import { logBuilderStatusWarnings } from './builder-status-warnings';
@@ -42,7 +43,30 @@ export async function* buildEsbuildBrowser(
4243
// Inform user of status of builder and options
4344
logBuilderStatusWarnings(userOptions, context);
4445
const normalizedOptions = normalizeOptions(userOptions);
45-
const fullOutputPath = path.join(context.workspaceRoot, normalizedOptions.outputPath);
46+
const { deleteOutputPath, outputPath } = normalizedOptions;
47+
const fullOutputPath = path.join(context.workspaceRoot, outputPath);
48+
49+
if (infrastructureSettings?.write !== false) {
50+
if (deleteOutputPath) {
51+
if (outputPath === context.workspaceRoot) {
52+
context.logger.error('Output path MUST not be workspace root directory!');
53+
54+
return;
55+
}
56+
57+
await fs.rm(fullOutputPath, { force: true, recursive: true, maxRetries: 3 });
58+
}
59+
60+
// Create output directory if needed
61+
try {
62+
await fs.mkdir(fullOutputPath, { recursive: true });
63+
} catch (e) {
64+
assertIsError(e);
65+
context.logger.error('Unable to create output directory: ' + e.message);
66+
67+
return;
68+
}
69+
}
4670

4771
for await (const result of buildApplicationInternal(
4872
normalizedOptions,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import { buildEsbuildBrowser } from '../../index';
10+
import { BASE_OPTIONS, BROWSER_BUILDER_INFO, describeBuilder } from '../setup';
11+
12+
describeBuilder(buildEsbuildBrowser, BROWSER_BUILDER_INFO, (harness) => {
13+
describe('Option: "deleteOutputPath"', () => {
14+
beforeEach(async () => {
15+
// Application code is not needed for asset tests
16+
await harness.writeFile('src/main.ts', 'console.log("TEST");');
17+
18+
// Add file in output
19+
await harness.writeFile('dist/dummy.txt', '');
20+
});
21+
22+
it(`should delete the output files when 'deleteOutputPath' is true`, async () => {
23+
harness.useTarget('build', {
24+
...BASE_OPTIONS,
25+
deleteOutputPath: true,
26+
});
27+
28+
const { result } = await harness.executeOnce();
29+
expect(result?.success).toBeTrue();
30+
harness.expectFile('dist/dummy.txt').toNotExist();
31+
});
32+
33+
it(`should delete the output files when 'deleteOutputPath' is not set`, async () => {
34+
harness.useTarget('build', {
35+
...BASE_OPTIONS,
36+
deleteOutputPath: undefined,
37+
});
38+
39+
const { result } = await harness.executeOnce();
40+
expect(result?.success).toBeTrue();
41+
harness.expectFile('dist/dummy.txt').toNotExist();
42+
});
43+
44+
it(`should delete the output files when 'deleteOutputPath' is false`, async () => {
45+
harness.useTarget('build', {
46+
...BASE_OPTIONS,
47+
deleteOutputPath: false,
48+
});
49+
50+
const { result } = await harness.executeOnce();
51+
expect(result?.success).toBeTrue();
52+
harness.expectFile('dist/dummy.txt').toExist();
53+
});
54+
});
55+
});

0 commit comments

Comments
 (0)