From 07941c1897935319627fa1a7c3ac8520f9412705 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 27 Nov 2019 11:01:31 +0100 Subject: [PATCH 1/2] fix(@angular/cli): `ng version` should report if ivy is enabled Closes: #14491 --- packages/angular/cli/commands/version-impl.ts | 25 +++++++++++++++++-- tests/legacy-cli/e2e/tests/misc/version.ts | 14 ++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/packages/angular/cli/commands/version-impl.ts b/packages/angular/cli/commands/version-impl.ts index acf6d0d5bdb0..a840cd3955a1 100644 --- a/packages/angular/cli/commands/version-impl.ts +++ b/packages/angular/cli/commands/version-impl.ts @@ -5,6 +5,7 @@ * 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 { JsonParseMode, isJsonObject, parseJson } from '@angular-devkit/core'; import * as child_process from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; @@ -21,7 +22,7 @@ export class VersionCommand extends Command { let projPkg; try { projPkg = require(path.resolve(this.workspace.root, 'package.json')); - } catch (exception) { + } catch { projPkg = undefined; } @@ -137,6 +138,7 @@ export class VersionCommand extends Command { Angular CLI: ${ngCliVersion} Node: ${process.versions.node} OS: ${process.platform} ${process.arch} + Angular: ${angularCoreVersion} ... ${angularSameAsCore .reduce((acc, name) => { @@ -154,6 +156,7 @@ export class VersionCommand extends Command { return acc; }, []) .join('\n... ')} + Ivy Workspace: ${projPkg ? this.getIvyWorkspace() : ''} Package${namePad.slice(7)}Version -------${namePad.replace(/ /g, '-')}------------------ @@ -176,7 +179,7 @@ export class VersionCommand extends Command { return modulePkg.version; } - } catch (_) {} + } catch {} try { if (cliNodeModules) { @@ -188,4 +191,22 @@ export class VersionCommand extends Command { return ''; } + + private getIvyWorkspace(): string { + try { + const content = fs.readFileSync(path.resolve(this.workspace.root, 'tsconfig.json'), 'utf-8'); + const tsConfig = parseJson(content, JsonParseMode.Loose); + if (!isJsonObject(tsConfig)) { + return ''; + } + + const { angularCompilerOptions } = tsConfig; + + return isJsonObject(angularCompilerOptions) && angularCompilerOptions.enableIvy === false + ? 'No' + : 'Yes'; + } catch { + return ''; + } + } } diff --git a/tests/legacy-cli/e2e/tests/misc/version.ts b/tests/legacy-cli/e2e/tests/misc/version.ts index 121d1aa123e1..09eff96fec9c 100644 --- a/tests/legacy-cli/e2e/tests/misc/version.ts +++ b/tests/legacy-cli/e2e/tests/misc/version.ts @@ -1,3 +1,4 @@ +import { getGlobalVariable } from '../../utils/env'; import { deleteFile } from '../../utils/fs'; import { ng } from '../../utils/process'; @@ -8,6 +9,17 @@ export default async function() { if (!optionOutput.includes('Angular CLI:')) { throw new Error('version not displayed'); } + + const argv = getGlobalVariable('argv'); + const veProject = argv['ve']; + + const ivyWorkspaceMatch = veProject + ? 'Ivy Workspace: No' + : 'Ivy Workspace: Yes'; + if (!optionOutput.includes(ivyWorkspaceMatch)) { + throw new Error(`Expected output to contain ${ivyWorkspaceMatch}`); + } + if (commandOutput !== optionOutput) { throw new Error('version variants have differing output'); } @@ -17,6 +29,6 @@ export default async function() { await ng('version'); // Doesn't fail outside a project. - await process.chdir('/'); + process.chdir('/'); await ng('version'); } From 42de4d029cf970492e8791ca73b6955fe0871514 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 27 Nov 2019 11:02:34 +0100 Subject: [PATCH 2/2] refactor(@angular/cli): use `isJsonObject` helper in to read config --- packages/angular/cli/utilities/config.ts | 28 +++++++++++------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/packages/angular/cli/utilities/config.ts b/packages/angular/cli/utilities/config.ts index 261a97ec6653..d165c80a1420 100644 --- a/packages/angular/cli/utilities/config.ts +++ b/packages/angular/cli/utilities/config.ts @@ -11,6 +11,7 @@ import { JsonObject, JsonParseMode, experimental, + isJsonObject, normalize, parseJson, parseJsonAst, @@ -213,7 +214,7 @@ export function migrateLegacyGlobalConfig(): boolean { if (existsSync(legacyGlobalConfigPath)) { const content = readFileSync(legacyGlobalConfigPath, 'utf-8'); const legacy = parseJson(content, JsonParseMode.Loose); - if (!legacy || typeof legacy != 'object' || Array.isArray(legacy)) { + if (!isJsonObject(legacy)) { return false; } @@ -224,16 +225,13 @@ export function migrateLegacyGlobalConfig(): boolean { cli['packageManager'] = legacy.packageManager; } - if (legacy.defaults && typeof legacy.defaults == 'object' && !Array.isArray(legacy.defaults) - && legacy.defaults.schematics && typeof legacy.defaults.schematics == 'object' - && !Array.isArray(legacy.defaults.schematics) - && typeof legacy.defaults.schematics.collection == 'string') { + if (isJsonObject(legacy.defaults) + && isJsonObject(legacy.defaults.schematics) + && typeof legacy.defaults.schematics.collection == 'string') { cli['defaultCollection'] = legacy.defaults.schematics.collection; } - if (legacy.warnings && typeof legacy.warnings == 'object' - && !Array.isArray(legacy.warnings)) { - + if (isJsonObject(legacy.warnings)) { const warnings: JsonObject = {}; if (typeof legacy.warnings.versionMismatch == 'boolean') { warnings['versionMismatch'] = legacy.warnings.versionMismatch; @@ -265,7 +263,7 @@ function getLegacyPackageManager(): string | null { const content = readFileSync(legacyGlobalConfigPath, 'utf-8'); const legacy = parseJson(content, JsonParseMode.Loose); - if (!legacy || typeof legacy != 'object' || Array.isArray(legacy)) { + if (!isJsonObject(legacy)) { return null; } @@ -294,7 +292,7 @@ export async function getSchematicDefaults( result = { ...result, ...(schematicObject as {}) }; } const collectionObject = workspace.getSchematics()[collection]; - if (typeof collectionObject == 'object' && !Array.isArray(collectionObject)) { + if (isJsonObject(collectionObject)) { result = { ...result, ...(collectionObject[schematic] as {}) }; } @@ -309,7 +307,7 @@ export async function getSchematicDefaults( result = { ...result, ...(schematicObject as {}) }; } const collectionObject = workspace.getSchematics()[collection]; - if (typeof collectionObject == 'object' && !Array.isArray(collectionObject)) { + if (isJsonObject(collectionObject)) { result = { ...result, ...(collectionObject[schematic] as {}) }; } } @@ -321,7 +319,7 @@ export async function getSchematicDefaults( result = { ...result, ...(schematicObject as {}) }; } const collectionObject = workspace.getProjectSchematics(project)[collection]; - if (typeof collectionObject == 'object' && !Array.isArray(collectionObject)) { + if (isJsonObject(collectionObject)) { result = { ...result, ...(collectionObject[schematic] as {}) }; } } @@ -337,7 +335,7 @@ export async function isWarningEnabled(warning: string): Promise { const project = getProjectByCwd(workspace); if (project && workspace.getProjectCli(project)) { const warnings = workspace.getProjectCli(project)['warnings']; - if (typeof warnings == 'object' && !Array.isArray(warnings)) { + if (isJsonObject(warnings)) { const value = warnings[warning]; if (typeof value == 'boolean') { return value; @@ -346,7 +344,7 @@ export async function isWarningEnabled(warning: string): Promise { } if (workspace.getCli()) { const warnings = workspace.getCli()['warnings']; - if (typeof warnings == 'object' && !Array.isArray(warnings)) { + if (isJsonObject(warnings)) { const value = warnings[warning]; if (typeof value == 'boolean') { return value; @@ -358,7 +356,7 @@ export async function isWarningEnabled(warning: string): Promise { workspace = await getWorkspace('global'); if (workspace && workspace.getCli()) { const warnings = workspace.getCli()['warnings']; - if (typeof warnings == 'object' && !Array.isArray(warnings)) { + if (isJsonObject(warnings)) { const value = warnings[warning]; if (typeof value == 'boolean') { return value;