diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c87cf53e028..b66c6355c922 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,40 @@ + + +# 13.0.4 (2021-12-01) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------------------- | +| [ded7b5c06](https://github.com/angular/angular-cli/commit/ded7b5c069a145d1b3e264538d7c4302919ad030) | fix | exit with a non-zero error code when migration fails during `ng update` | +| [250a58b48](https://github.com/angular/angular-cli/commit/250a58b4820a738aba7609627fa7fce0a24f10db) | fix | logic which determines which temp version of the CLI is to be download during `ng update` | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------- | +| [372e2e633](https://github.com/angular/angular-cli/commit/372e2e633f4bd9bf29c35d02890e1c6a70da3169) | fix | address eslint linting failures in `test.ts` | + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------------------------------------------------------- | +| [b835389c8](https://github.com/angular/angular-cli/commit/b835389c8a60749151039ed0baf0be025ce0932b) | fix | correctly extract messages when using cached build ([#22266](https://github.com/angular/angular-cli/pull/22266)) | +| [647a5f0b1](https://github.com/angular/angular-cli/commit/647a5f0b18e49b2ece3f43c0a06bfb75d7caef49) | fix | don't watch nested `node_modules` when polling is enabled | +| [4d01d4f72](https://github.com/angular/angular-cli/commit/4d01d4f72344c42f650f5495b21e6bd94069969a) | fix | transform remapped sourcemap into a plain object | + +### @ngtools/webpack + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------- | +| [4d918ef99](https://github.com/angular/angular-cli/commit/4d918ef9912d53a09d73fb19fa41b121dceed37c) | fix | JIT mode CommonJS accessing inexistent `default` property | + +## Special Thanks + +Alan Agius, Billy Lando, David-Emmanuel DIVERNOIS and Derek Cormier + + + # 13.0.3 (2021-11-17) diff --git a/package.json b/package.json index 4f9e5f0b313f..7733f12a5f6c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "13.0.3", + "version": "13.0.4", "private": true, "description": "Software Development Kit for Angular", "bin": { diff --git a/packages/angular/cli/commands/new.md b/packages/angular/cli/commands/new.md index ca3f14b8d696..135e1b2c108a 100644 --- a/packages/angular/cli/commands/new.md +++ b/packages/angular/cli/commands/new.md @@ -5,7 +5,7 @@ All prompts can safely be allowed to default. - The new workspace folder is given the specified project name, and contains configuration files at the top level. -- By default, the files for a new initial application (with the same name as the workspace) are placed in the `src/` subfolder. Corresponding end-to-end tests are placed in the `e2e/` subfolder. +- By default, the files for a new initial application (with the same name as the workspace) are placed in the `src/` subfolder. - The new application's configuration appears in the `projects` section of the `angular.json` workspace configuration file, under its project name. diff --git a/packages/angular/cli/commands/update-impl.ts b/packages/angular/cli/commands/update-impl.ts index c0c461452bd0..23aca0a5861e 100644 --- a/packages/angular/cli/commands/update-impl.ts +++ b/packages/angular/cli/commands/update-impl.ts @@ -37,11 +37,6 @@ import { } from '../utilities/package-tree'; import { Schema as UpdateCommandSchema } from './update'; -const NG_VERSION_9_POST_MSG = colors.cyan( - '\nYour project has been updated to Angular version 9!\n' + - 'For more info, please see: https://v9.angular.io/guide/updating-to-version-9', -); - const UPDATE_SCHEMATIC_COLLECTION = path.join( __dirname, '../src/commands/update/schematic/collection.json', @@ -57,6 +52,8 @@ const disableVersionCheck = disableVersionCheckEnv !== '0' && disableVersionCheckEnv.toLowerCase() !== 'false'; +const ANGULAR_PACKAGES_REGEXP = /^@(?:angular|nguniversal)\//; + export class UpdateCommand extends Command { public override readonly allowMissingWorkspace = true; private workflow!: NodeWorkflow; @@ -272,19 +269,26 @@ export class UpdateCommand extends Command { async run(options: UpdateCommandSchema & Arguments) { await ensureCompatibleNpm(this.context.root); - // Check if the current installed CLI version is older than the latest version. - if (!disableVersionCheck && (await this.checkCLILatestVersion(options.verbose, options.next))) { - this.logger.warn( - `The installed local Angular CLI version is older than the latest ${ - options.next ? 'pre-release' : 'stable' - } version.\n` + 'Installing a temporary version to perform the update.', + // Check if the current installed CLI version is older than the latest compatible version. + if (!disableVersionCheck) { + const cliVersionToInstall = await this.checkCLIVersion( + options['--'], + options.verbose, + options.next, ); - return runTempPackageBin( - `@angular/cli@${options.next ? 'next' : 'latest'}`, - this.packageManager, - process.argv.slice(2), - ); + if (cliVersionToInstall) { + this.logger.warn( + 'The installed Angular CLI version is outdated.\n' + + `Installing a temporary Angular CLI versioned ${cliVersionToInstall} to perform the update.`, + ); + + return runTempPackageBin( + `@angular/cli@${cliVersionToInstall}`, + this.packageManager, + process.argv.slice(2), + ); + } } const logVerbose = (message: string) => { @@ -452,8 +456,7 @@ export class UpdateCommand extends Command { if (migrations.startsWith('../')) { this.logger.error( - 'Package contains an invalid migrations field. ' + - 'Paths outside the package root are not permitted.', + 'Package contains an invalid migrations field. Paths outside the package root are not permitted.', ); return 1; @@ -479,9 +482,9 @@ export class UpdateCommand extends Command { } } - let success = false; + let result: boolean; if (typeof options.migrateOnly == 'string') { - success = await this.executeMigration( + result = await this.executeMigration( packageName, migrations, options.migrateOnly, @@ -495,7 +498,7 @@ export class UpdateCommand extends Command { return 1; } - success = await this.executeMigrations( + result = await this.executeMigrations( packageName, migrations, from, @@ -504,20 +507,7 @@ export class UpdateCommand extends Command { ); } - if (success) { - if ( - packageName === '@angular/core' && - options.from && - +options.from.split('.')[0] < 9 && - (options.to || packageNode.version).split('.')[0] === '9' - ) { - this.logger.info(NG_VERSION_9_POST_MSG); - } - - return 0; - } - - return 1; + return result ? 0 : 1; } const requests: { @@ -612,7 +602,7 @@ export class UpdateCommand extends Command { continue; } - if (node.package && /^@(?:angular|nguniversal)\//.test(node.package.name)) { + if (node.package && ANGULAR_PACKAGES_REGEXP.test(node.package.name)) { const { name, version } = node.package; const toBeInstalledMajorVersion = +manifest.version.split('.')[0]; const currentMajorVersion = +version.split('.')[0]; @@ -791,17 +781,6 @@ export class UpdateCommand extends Command { return 0; } } - - if ( - migrations.some( - (m) => - m.package === '@angular/core' && - m.to.split('.')[0] === '9' && - +m.from.split('.')[0] < 9, - ) - ) { - this.logger.info(NG_VERSION_9_POST_MSG); - } } return success ? 0 : 1; @@ -879,14 +858,16 @@ export class UpdateCommand extends Command { } /** - * Checks if the current installed CLI version is older than the latest version. - * @returns `true` when the installed version is older. + * Checks if the current installed CLI version is older or newer than a compatible version. + * @returns the version to install or null when there is no update to install. */ - private async checkCLILatestVersion(verbose = false, next = false): Promise { - const installedCLIVersion = VERSION.full; - - const LatestCLIManifest = await fetchPackageManifest( - `@angular/cli@${next ? 'next' : 'latest'}`, + private async checkCLIVersion( + packagesToUpdate: string[] | undefined, + verbose = false, + next = false, + ): Promise { + const { version } = await fetchPackageManifest( + `@angular/cli@${this.getCLIUpdateRunnerVersion(packagesToUpdate, next)}`, this.logger, { verbose, @@ -894,7 +875,38 @@ export class UpdateCommand extends Command { }, ); - return semver.lt(installedCLIVersion, LatestCLIManifest.version); + return VERSION.full === version ? null : version; + } + + private getCLIUpdateRunnerVersion( + packagesToUpdate: string[] | undefined, + next: boolean, + ): string | number { + if (next) { + return 'next'; + } + + const updatingAngularPackage = packagesToUpdate?.find((r) => ANGULAR_PACKAGES_REGEXP.test(r)); + if (updatingAngularPackage) { + // If we are updating any Angular package we can update the CLI to the target version because + // migrations for @angular/core@13 can be executed using Angular/cli@13. + // This is same behaviour as `npx @angular/cli@13 update @angular/core@13`. + + // `@angular/cli@13` -> ['', 'angular/cli', '13'] + // `@angular/cli` -> ['', 'angular/cli'] + const tempVersion = coerceVersionNumber(updatingAngularPackage.split('@')[2]); + + return semver.parse(tempVersion)?.major ?? 'latest'; + } + + // When not updating an Angular package we cannot determine which schematic runtime the migration should to be executed in. + // Typically, we can assume that the `@angular/cli` was updated previously. + // Example: Angular official packages are typically updated prior to NGRX etc... + // Therefore, we only update to the latest patch version of the installed major version of the Angular CLI. + + // This is important because we might end up in a scenario where locally Angular v12 is installed, updating NGRX from 11 to 12. + // We end up using Angular ClI v13 to run the migrations if we run the migrations using the CLI installed major version + 1 logic. + return VERSION.major; } } diff --git a/packages/angular/cli/lib/init.ts b/packages/angular/cli/lib/init.ts index a48f388ba3fe..cf18b8bcd77b 100644 --- a/packages/angular/cli/lib/init.ts +++ b/packages/angular/cli/lib/init.ts @@ -73,7 +73,11 @@ import { isWarningEnabled } from '../utilities/config'; if (isGlobalGreater) { // If using the update command and the global version is greater, use the newer update command // This allows improvements in update to be used in older versions that do not have bootstrapping - if (process.argv[2] === 'update') { + if ( + process.argv[2] === 'update' && + cli.VERSION && + cli.VERSION.major - globalVersion.major <= 1 + ) { cli = await import('./cli'); } else if (await isWarningEnabled('versionMismatch')) { // Otherwise, use local version and warn if global is newer than local diff --git a/packages/angular/pwa/BUILD.bazel b/packages/angular/pwa/BUILD.bazel index 5b7a218b5c96..af8b44ce7f58 100644 --- a/packages/angular/pwa/BUILD.bazel +++ b/packages/angular/pwa/BUILD.bazel @@ -6,6 +6,8 @@ load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") load("//tools:defaults.bzl", "ts_library") load("//tools:ts_json_schema.bzl", "ts_json_schema") +load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar") +load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm") licenses(["notice"]) # MIT @@ -67,3 +69,18 @@ jasmine_node_test( name = "pwa_test", srcs = [":pwa_test_lib"], ) + +pkg_npm( + name = "npm_package", + deps = [ + ":pwa", + ], +) + +pkg_tar( + name = "npm_package_archive", + srcs = [":npm_package"], + extension = "tar.gz", + strip_prefix = "./npm_package", + tags = ["manual"], +) diff --git a/packages/angular_devkit/architect_cli/BUILD.bazel b/packages/angular_devkit/architect_cli/BUILD.bazel index 2381827d2753..3f846ec99627 100644 --- a/packages/angular_devkit/architect_cli/BUILD.bazel +++ b/packages/angular_devkit/architect_cli/BUILD.bazel @@ -1,4 +1,6 @@ load("//tools:defaults.bzl", "ts_library") +load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar") +load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm") # Copyright Google Inc. All Rights Reserved. # @@ -27,3 +29,18 @@ ts_library( "@npm//rxjs", ], ) + +pkg_npm( + name = "npm_package", + deps = [ + ":architect_cli", + ], +) + +pkg_tar( + name = "npm_package_archive", + srcs = [":npm_package"], + extension = "tar.gz", + strip_prefix = "./npm_package", + tags = ["manual"], +) diff --git a/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts b/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts index eae472b33ccd..d74a9e753643 100644 --- a/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts +++ b/packages/angular_devkit/build_angular/src/babel/webpack-loader.ts @@ -239,10 +239,16 @@ export default custom(() => { // `@ampproject/remapping` source map objects but both are compatible with Webpack. // This method for merging is used because it provides more accurate output // and is faster while using less memory. - result.map = remapping( - [result.map as SourceMapInput, inputSourceMap as SourceMapInput], - () => null, - ) as typeof result.map; + result.map = { + // Convert the SourceMap back to simple plain object. + // This is needed because otherwise code-coverage will fail with `don't know how to turn this value into a node` + // Which is thrown by Babel if it is invoked again from `istanbul-lib-instrument`. + // https://github.com/babel/babel/blob/780aa48d2a34dc55f556843074b6aed45e7eabeb/packages/babel-types/src/converters/valueToNode.ts#L115-L130 + ...(remapping( + [result.map as SourceMapInput, inputSourceMap as SourceMapInput], + () => null, + ) as typeof result.map), + }; } return result; diff --git a/packages/angular_devkit/build_angular/src/builders/extract-i18n/ivy-extract-loader.ts b/packages/angular_devkit/build_angular/src/builders/extract-i18n/ivy-extract-loader.ts index 50da54cfe7b4..4a6353662761 100644 --- a/packages/angular_devkit/build_angular/src/builders/extract-i18n/ivy-extract-loader.ts +++ b/packages/angular_devkit/build_angular/src/builders/extract-i18n/ivy-extract-loader.ts @@ -21,6 +21,11 @@ export default function localizeExtractLoader( content: string, map: LoaderSourceMap, ) { + // This loader is not cacheable due to how message extraction works. + // Extracted messages are not part of webpack pipeline and hence they cannot be retrieved from cache. + // TODO: We should investigate in the future on making this deterministic and more cacheable. + this.cacheable(false); + const options = this.getOptions(); const callback = this.async(); diff --git a/packages/angular_devkit/build_angular/src/builders/karma/tests/behavior/module-cjs_spec.ts b/packages/angular_devkit/build_angular/src/builders/karma/tests/behavior/module-cjs_spec.ts new file mode 100644 index 000000000000..fdd972cb169c --- /dev/null +++ b/packages/angular_devkit/build_angular/src/builders/karma/tests/behavior/module-cjs_spec.ts @@ -0,0 +1,31 @@ +/** + * @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 { execute } from '../../index'; +import { BASE_OPTIONS, KARMA_BUILDER_INFO, describeBuilder } from '../setup'; + +describeBuilder(execute, KARMA_BUILDER_INFO, (harness) => { + describe('Behavior: "module commonjs"', () => { + it('should work when module is commonjs', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + }); + + await harness.modifyFile('src/tsconfig.spec.json', (content) => { + const tsConfig = JSON.parse(content); + tsConfig.compilerOptions.module = 'commonjs'; + + return JSON.stringify(tsConfig); + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBeTrue(); + }); + }); +}); diff --git a/packages/angular_devkit/build_angular/src/webpack/utils/helpers.ts b/packages/angular_devkit/build_angular/src/webpack/utils/helpers.ts index fdd2b66de90f..83d202cb4317 100644 --- a/packages/angular_devkit/build_angular/src/webpack/utils/helpers.ts +++ b/packages/angular_devkit/build_angular/src/webpack/utils/helpers.ts @@ -102,7 +102,7 @@ export function getWatchOptions( ): NonNullable { return { poll, - ignored: poll === undefined ? '**/$_lazy_route_resources' : 'node_modules/**', + ignored: poll === undefined ? '**/$_lazy_route_resources' : '**/node_modules/**', }; } diff --git a/packages/angular_devkit/schematics_cli/BUILD.bazel b/packages/angular_devkit/schematics_cli/BUILD.bazel index 1d2ccc908b91..43cc1cba03bc 100644 --- a/packages/angular_devkit/schematics_cli/BUILD.bazel +++ b/packages/angular_devkit/schematics_cli/BUILD.bazel @@ -1,6 +1,8 @@ load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") load("//tools:defaults.bzl", "ts_library") load("//tools:ts_json_schema.bzl", "ts_json_schema") +load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar") +load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm") # Copyright Google Inc. All Rights Reserved. # @@ -88,3 +90,18 @@ ts_json_schema( name = "schematic_schema", src = "schematic/schema.json", ) + +pkg_npm( + name = "npm_package", + deps = [ + ":schematics_cli", + ], +) + +pkg_tar( + name = "npm_package_archive", + srcs = [":npm_package"], + extension = "tar.gz", + strip_prefix = "./npm_package", + tags = ["manual"], +) diff --git a/packages/ngtools/webpack/src/loaders/direct-resource.ts b/packages/ngtools/webpack/src/loaders/direct-resource.ts index b6f2a2cae111..5c5efda6c7c9 100644 --- a/packages/ngtools/webpack/src/loaders/direct-resource.ts +++ b/packages/ngtools/webpack/src/loaders/direct-resource.ts @@ -6,8 +6,14 @@ * found in the LICENSE file at https://angular.io/license */ +import { LoaderContext } from 'webpack'; + export const DirectAngularResourceLoaderPath = __filename; -export default function (content: string) { - return `export default ${JSON.stringify(content)};`; +export default function (this: LoaderContext<{ esModule?: 'true' | 'false' }>, content: string) { + const { esModule } = this.getOptions(); + + return `${esModule === 'false' ? 'module.exports =' : 'export default'} ${JSON.stringify( + content, + )};`; } diff --git a/packages/ngtools/webpack/src/transformers/replace_resources.ts b/packages/ngtools/webpack/src/transformers/replace_resources.ts index 9eba2512148b..a4f47c78c805 100644 --- a/packages/ngtools/webpack/src/transformers/replace_resources.ts +++ b/packages/ngtools/webpack/src/transformers/replace_resources.ts @@ -146,7 +146,7 @@ function visitComponentMetadata( styleReplacements: ts.Expression[], directTemplateLoading: boolean, resourceImportDeclarations: ts.ImportDeclaration[], - moduleKind?: ts.ModuleKind, + moduleKind: ts.ModuleKind = ts.ModuleKind.ES2015, inlineStyleFileExtension?: string, ): ts.ObjectLiteralElementLike | undefined { if (!ts.isPropertyAssignment(node) || ts.isComputedPropertyName(node.name)) { @@ -159,9 +159,10 @@ function visitComponentMetadata( return undefined; case 'templateUrl': + const loaderOptions = moduleKind < ts.ModuleKind.ES2015 ? '?esModule=false' : ''; const url = getResourceUrl( node.initializer, - directTemplateLoading ? `!${DirectAngularResourceLoaderPath}!` : '', + directTemplateLoading ? `!${DirectAngularResourceLoaderPath}${loaderOptions}!` : '', ); if (!url) { return node; @@ -255,14 +256,15 @@ function createResourceImport( nodeFactory: ts.NodeFactory, url: string, resourceImportDeclarations: ts.ImportDeclaration[], - moduleKind = ts.ModuleKind.ES2015, + moduleKind: ts.ModuleKind, ): ts.Identifier | ts.Expression { const urlLiteral = nodeFactory.createStringLiteral(url); if (moduleKind < ts.ModuleKind.ES2015) { - return nodeFactory.createPropertyAccessExpression( - nodeFactory.createCallExpression(nodeFactory.createIdentifier('require'), [], [urlLiteral]), - 'default', + return nodeFactory.createCallExpression( + nodeFactory.createIdentifier('require'), + [], + [urlLiteral], ); } else { const importName = nodeFactory.createIdentifier( diff --git a/packages/ngtools/webpack/src/transformers/replace_resources_spec.ts b/packages/ngtools/webpack/src/transformers/replace_resources_spec.ts index 59d554c6748b..0f09e6f7283a 100644 --- a/packages/ngtools/webpack/src/transformers/replace_resources_spec.ts +++ b/packages/ngtools/webpack/src/transformers/replace_resources_spec.ts @@ -102,8 +102,8 @@ describe('@ngtools/webpack transformers', () => { AppComponent = (0, tslib_1.__decorate)([ (0, core_1.Component)({ selector: 'app-root', - template: require("!${DirectAngularResourceLoaderPath}!./app.component.html").default, - styles: [require("./app.component.css").default, require("./app.component.2.css").default] }) ], AppComponent); + template: require("!${DirectAngularResourceLoaderPath}?esModule=false!./app.component.html"), + styles: [require("./app.component.css"), require("./app.component.2.css")] }) ], AppComponent); exports.AppComponent = AppComponent; `; diff --git a/packages/schematics/angular/application/files/src/test.ts.template b/packages/schematics/angular/application/files/src/test.ts.template index 598d11e862e6..00025daf1720 100644 --- a/packages/schematics/angular/application/files/src/test.ts.template +++ b/packages/schematics/angular/application/files/src/test.ts.template @@ -9,8 +9,8 @@ import { declare const require: { context(path: string, deep?: boolean, filter?: RegExp): { - keys(): string[]; (id: string): T; + keys(): string[]; }; }; diff --git a/packages/schematics/angular/library/files/src/test.ts.template b/packages/schematics/angular/library/files/src/test.ts.template index 9782baeeef23..bcca659d3122 100644 --- a/packages/schematics/angular/library/files/src/test.ts.template +++ b/packages/schematics/angular/library/files/src/test.ts.template @@ -10,8 +10,8 @@ import { declare const require: { context(path: string, deep?: boolean, filter?: RegExp): { - keys(): string[]; (id: string): T; + keys(): string[]; }; }; diff --git a/tests/legacy-cli/e2e/tests/i18n/extract-ivy-disk-cache.ts b/tests/legacy-cli/e2e/tests/i18n/extract-ivy-disk-cache.ts new file mode 100644 index 000000000000..61a2f48e62f5 --- /dev/null +++ b/tests/legacy-cli/e2e/tests/i18n/extract-ivy-disk-cache.ts @@ -0,0 +1,36 @@ +import { join } from 'path'; +import { getGlobalVariable } from '../../utils/env'; +import { expectFileToMatch, rimraf, writeFile } from '../../utils/fs'; +import { installPackage, uninstallPackage } from '../../utils/packages'; +import { ng } from '../../utils/process'; +import { updateJsonFile } from '../../utils/project'; +import { readNgVersion } from '../../utils/version'; + +export default async function () { + // Enable disk cache + updateJsonFile('angular.json', (config) => { + config.cli ??= {}; + config.cli.cache = { environment: 'all' }; + }); + + // Setup an i18n enabled component + await ng('generate', 'component', 'i18n-test'); + await writeFile(join('src/app/i18n-test', 'i18n-test.component.html'), '

Hello world

'); + + // Install correct version + let localizeVersion = '@angular/localize@' + readNgVersion(); + if (getGlobalVariable('argv')['ng-snapshots']) { + localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize']; + } + + await installPackage(localizeVersion); + + for (let i = 0; i < 2; i++) { + // Run the extraction twice and make sure the second time round works with cache. + await rimraf('messages.xlf'); + await ng('extract-i18n'); + await expectFileToMatch('messages.xlf', 'Hello world'); + } + + await uninstallPackage('@angular/localize'); +} diff --git a/tests/legacy-cli/e2e/tests/i18n/extract-ivy.ts b/tests/legacy-cli/e2e/tests/i18n/extract-ivy.ts index 3693481d5ede..9c796f896c01 100644 --- a/tests/legacy-cli/e2e/tests/i18n/extract-ivy.ts +++ b/tests/legacy-cli/e2e/tests/i18n/extract-ivy.ts @@ -1,6 +1,6 @@ import { join } from 'path'; import { getGlobalVariable } from '../../utils/env'; -import { writeFile } from '../../utils/fs'; +import { expectFileToMatch, writeFile } from '../../utils/fs'; import { installPackage, uninstallPackage } from '../../utils/packages'; import { ng } from '../../utils/process'; import { updateJsonFile } from '../../utils/project'; @@ -31,5 +31,7 @@ export default async function () { throw new Error('Expected no warnings to be shown'); } + expectFileToMatch('messages.xlf', 'Hello world'); + await uninstallPackage('@angular/localize'); } diff --git a/tests/legacy-cli/e2e/tests/misc/npm-7.ts b/tests/legacy-cli/e2e/tests/misc/npm-7.ts index c2bff8ad9d34..1789210a534a 100644 --- a/tests/legacy-cli/e2e/tests/misc/npm-7.ts +++ b/tests/legacy-cli/e2e/tests/misc/npm-7.ts @@ -1,11 +1,12 @@ -import { rimraf, writeFile } from '../../utils/fs'; +import { rimraf } from '../../utils/fs'; import { getActivePackageManager } from '../../utils/packages'; import { ng, npm } from '../../utils/process'; +import { isPrereleaseCli } from '../../utils/project'; import { expectToFail } from '../../utils/utils'; const warningText = 'npm version 7.5.6 or higher is recommended'; -export default async function() { +export default async function () { // Only relevant with npm as a package manager if (getActivePackageManager() !== 'npm') { return; @@ -17,12 +18,18 @@ export default async function() { } const currentDirectory = process.cwd(); + + const extraArgs = []; + if (isPrereleaseCli()) { + extraArgs.push('--next'); + } + try { // Install version >=7.5.6 await npm('install', '--global', 'npm@>=7.5.6'); // Ensure `ng update` does not show npm warning - const { stderr: stderrUpdate1 } = await ng('update'); + const { stderr: stderrUpdate1 } = await ng('update', ...extraArgs); if (stderrUpdate1.includes(warningText)) { throw new Error('ng update expected to not show npm version warning.'); } @@ -37,7 +44,7 @@ export default async function() { } // Ensure `ng update` shows npm warning - const { stderr: stderrUpdate2 } = await ng('update'); + const { stderr: stderrUpdate2 } = await ng('update', ...extraArgs); if (!stderrUpdate2.includes(warningText)) { throw new Error('ng update expected to show npm version warning.'); } @@ -85,5 +92,4 @@ export default async function() { // Reset version back to 6.x await npm('install', '--global', 'npm@6'); } - } diff --git a/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts b/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts index 263892d1d01b..f6f7621ffc9a 100644 --- a/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts +++ b/tests/legacy-cli/e2e/tests/update/update-secure-registry.ts @@ -1,29 +1,35 @@ import { ng } from '../../utils/process'; import { createNpmConfigForAuthentication } from '../../utils/registry'; import { expectToFail } from '../../utils/utils'; +import { isPrereleaseCli } from '../../utils/project'; export default async function () { // The environment variable has priority over the .npmrc delete process.env['NPM_CONFIG_REGISTRY']; const worksMessage = 'We analyzed your package.json'; + const extraArgs = []; + if (isPrereleaseCli()) { + extraArgs.push('--next'); + } + // Valid authentication token await createNpmConfigForAuthentication(false); - const { stdout: stdout1 } = await ng('update'); + const { stdout: stdout1 } = await ng('update', ...extraArgs); if (!stdout1.includes(worksMessage)) { throw new Error(`Expected stdout to contain "${worksMessage}"`); } await createNpmConfigForAuthentication(true); - const { stdout: stdout2 } = await ng('update'); + const { stdout: stdout2 } = await ng('update', ...extraArgs); if (!stdout2.includes(worksMessage)) { throw new Error(`Expected stdout to contain "${worksMessage}"`); } // Invalid authentication token await createNpmConfigForAuthentication(false, true); - await expectToFail(() => ng('update')); + await expectToFail(() => ng('update', ...extraArgs)); await createNpmConfigForAuthentication(true, true); - await expectToFail(() => ng('update')); + await expectToFail(() => ng('update', ...extraArgs)); }