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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ export type BrowserBuilderOutput = json.JsonObject &
outputPath: string;
};

/**
* Maximum time in milliseconds for single build/rebuild
* This accounts for CI variability.
*/
export const BUILD_TIMEOUT = 30_000;

async function initialize(
options: BrowserBuilderSchema,
context: BuilderContext,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import { concatMap, count, take, timeout } from 'rxjs/operators';
import { BUILD_TIMEOUT, buildWebpackBrowser } from '../../index';
import { BASE_OPTIONS, BROWSER_BUILDER_INFO, describeBuilder } from '../setup';

describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
describe('Behavior: "localize works in watch mode"', () => {
beforeEach(() => {
harness.useProject('test', {
root: '.',
sourceRoot: 'src',
cli: {
cache: {
enabled: false,
},
},
i18n: {
locales: {
'fr': 'src/locales/messages.fr.xlf',
},
},
});
});

it('localize works in watch mode', async () => {
harness.useTarget('build', {
...BASE_OPTIONS,
watch: true,
localize: true,
});

await harness.writeFile(
'src/app/app.component.html',
`
<p id="hello" i18n="An introduction header for this sample">Hello {{ title }}! </p>
`,
);

await harness.writeFile('src/locales/messages.fr.xlf', TRANSLATION_FILE_CONTENT);

const buildCount = await harness
.execute()
.pipe(
timeout(BUILD_TIMEOUT),
concatMap(async ({ result }, index) => {
expect(result?.success).toBe(true);

switch (index) {
case 0: {
harness.expectFile('dist/fr/main.js').content.toContain('Bonjour');

// Trigger rebuild
await harness.appendToFile('src/app/app.component.html', '\n\n');
break;
}
case 1: {
harness.expectFile('dist/fr/main.js').content.toContain('Bonjour');
break;
}
}
}),
take(2),
count(),
)
.toPromise();

expect(buildCount).toBe(2);
});
});
});

const TRANSLATION_FILE_CONTENT = `
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file target-language="en-US" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="4286451273117902052" datatype="html">
<target>Bonjour <x id="INTERPOLATION" equiv-text="{{ title }}"/>! </target>
<context-group purpose="location">
<context context-type="targetfile">src/app/app.component.html</context>
<context context-type="linenumber">2,3</context>
</context-group>
<note priority="1" from="description">An introduction header for this sample</note>
</trans-unit>
</body>
</file>
</xliff>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { logging } from '@angular-devkit/core';
import { concatMap, count, take, timeout } from 'rxjs/operators';
import { buildWebpackBrowser } from '../../index';
import { BUILD_TIMEOUT, buildWebpackBrowser } from '../../index';
import { BASE_OPTIONS, BROWSER_BUILDER_INFO, describeBuilder } from '../setup';

describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
Expand Down Expand Up @@ -70,7 +70,7 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const buildCount = await harness
.execute({ outputLogsOnFailure: false })
.pipe(
timeout(60000),
timeout(BUILD_TIMEOUT),
concatMap(async ({ result, logs }, index) => {
switch (index) {
case 0:
Expand Down Expand Up @@ -219,7 +219,7 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const buildCount = await harness
.execute({ outputLogsOnFailure: false })
.pipe(
timeout(60000),
timeout(BUILD_TIMEOUT),
concatMap(async ({ result, logs }, index) => {
switch (index) {
case 0:
Expand Down Expand Up @@ -307,7 +307,7 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const buildCount = await harness
.execute({ outputLogsOnFailure: false })
.pipe(
timeout(30000),
timeout(BUILD_TIMEOUT),
concatMap(async ({ result, logs }, index) => {
switch (index) {
case 0:
Expand Down
18 changes: 0 additions & 18 deletions packages/angular_devkit/build_angular/src/utils/i18n-inlining.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,10 @@ function emittedFilesToInlineOptions(
};
originalFiles.push(originalPath);

// Remove temporary original file as the content has now been read
try {
fs.unlinkSync(originalPath);
} catch (e) {
context.logger.debug(
`Unable to delete i18n temporary file [${originalPath}]: ${e.toString()}`,
);
}

try {
const originalMapPath = originalPath + '.map';
action.map = fs.readFileSync(originalMapPath, 'utf8');
originalFiles.push(originalMapPath);

// Remove temporary original map file as the content has now been read
try {
fs.unlinkSync(originalMapPath);
} catch (e) {
context.logger.debug(
`Unable to delete i18n temporary file [${originalMapPath}]: ${e.toString()}`,
);
}
} catch (err) {
if (err.code !== 'ENOENT') {
throw err;
Expand Down
35 changes: 30 additions & 5 deletions packages/angular_devkit/build_angular/src/utils/i18n-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,12 @@ export async function configureI18nBuild<T extends BrowserBuilderSchema | Server
const tempPath = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), 'angular-cli-i18n-'));
buildOptions.outputPath = tempPath;

// Remove temporary directory used for i18n processing
process.on('exit', () => {
try {
fs.rmdirSync(tempPath, { recursive: true, maxRetries: 3 });
} catch {}
process.on('exit', () => deleteTempDirectory(tempPath));
process.once('SIGINT', () => {
deleteTempDirectory(tempPath);

// Needed due to `ora` as otherwise process will not terminate.
process.kill(process.pid, 'SIGINT');
});
}

Expand All @@ -275,6 +276,30 @@ function findLocaleDataPath(locale: string, resolver: (locale: string) => string
}
}

/** Remove temporary directory used for i18n processing. */
function deleteTempDirectory(tempPath: string): void {
// The below should be removed and replaced with just `rmSync` when support for Node.Js 12 is removed.
const { rmSync, rmdirSync } = fs as typeof fs & {
rmSync?: (
path: fs.PathLike,
options?: {
force?: boolean;
maxRetries?: number;
recursive?: boolean;
retryDelay?: number;
},
) => void;
};

try {
if (rmSync) {
rmSync(tempPath, { force: true, recursive: true, maxRetries: 3 });
} else {
rmdirSync(tempPath, { recursive: true, maxRetries: 3 });
}
} catch {}
}

export function loadTranslations(
locale: string,
desc: LocaleDescription,
Expand Down