Skip to content

fix(@schematics/angular): warn when target references a missing tsconfig #16063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 6, 2019
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
13 changes: 10 additions & 3 deletions packages/schematics/angular/migrations/update-9/ivy-libraries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import { getTargets, getWorkspace, readJsonFileAsAstObject } from './utils';
* - Create a prod tsconfig for which disables Ivy and enables VE compilations.
*/
export function updateLibraries(): Rule {
return (tree: Tree) => {
return (tree, context) => {
const logger = context.logger;
const workspacePath = getWorkspacePath(tree);
const workspace = getWorkspace(tree);

Expand Down Expand Up @@ -61,8 +62,14 @@ export function updateLibraries(): Rule {
}

// tsConfig for production already exists.
const tsConfigAst = readJsonFileAsAstObject(tree, tsConfigOption.value);
const tsConfigRecorder = tree.beginUpdate(tsConfigOption.value);
const tsConfigPath = tsConfigOption.value;
const tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath);
if (!tsConfigAst) {
logger.warn(`Cannot find file: ${tsConfigPath}`);
continue;
}

const tsConfigRecorder = tree.beginUpdate(tsConfigPath);
const ngCompilerOptions = findPropertyInAstObject(tsConfigAst, 'angularCompilerOptions');
if (!ngCompilerOptions) {
// Add angularCompilerOptions to the production tsConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +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 { Rule, Tree } from '@angular-devkit/schematics';
import { Rule } from '@angular-devkit/schematics';
import { appendValueInAstArray, findPropertyInAstObject } from '../../utility/json-utils';
import { Builders } from '../../utility/workspace-models';
import { getAllOptions, getTargets, getWorkspace, readJsonFileAsAstObject } from './utils';
Expand All @@ -15,13 +15,15 @@ import { getAllOptions, getTargets, getWorkspace, readJsonFileAsAstObject } from
* Update ngsw-config.json to fix issue https://github.com/angular/angular-cli/pull/15277
*/
export function updateNGSWConfig(): Rule {
return (tree: Tree) => {
return (tree, context) => {
const workspace = getWorkspace(tree);
const logger = context.logger;

for (const { target } of getTargets(workspace, 'build', Builders.Browser)) {
for (const options of getAllOptions(target)) {
const ngswConfigPath = findPropertyInAstObject(options, 'ngswConfigPath');
if (!ngswConfigPath || ngswConfigPath.kind !== 'string') {
logger.warn(`Cannot find file: ${ngswConfigPath}`);
continue;
}

Expand Down
21 changes: 9 additions & 12 deletions packages/schematics/angular/migrations/update-9/remove-tsickle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,19 @@
* 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, parseJsonAst } from '@angular-devkit/core';
import { Rule, Tree } from '@angular-devkit/schematics';
import { Rule } from '@angular-devkit/schematics';
import { removePackageJsonDependency } from '../../utility/dependencies';
import { findPropertyInAstObject, removePropertyInAstObject } from '../../utility/json-utils';
import { Builders } from '../../utility/workspace-models';
import { getAllOptions, getTargets, getWorkspace } from './utils';
import { getAllOptions, getTargets, getWorkspace, readJsonFileAsAstObject } from './utils';

/**
* Remove tsickle from libraries
*/
export function removeTsickle(): Rule {
return (tree: Tree) => {
return (tree, context) => {
removePackageJsonDependency(tree, 'tsickle');

const logger = context.logger;
const workspace = getWorkspace(tree);

for (const { target } of getTargets(workspace, 'build', Builders.NgPackagr)) {
Expand All @@ -28,20 +27,18 @@ export function removeTsickle(): Rule {
continue;
}

const tsConfigContent = tree.read(tsConfigOption.value);
if (!tsConfigContent) {
continue;
}
const tsConfigPath = tsConfigOption.value;
const tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath);
if (!tsConfigAst) {
logger.warn(`Cannot find file: ${tsConfigPath}`);

const tsConfigAst = parseJsonAst(tsConfigContent.toString(), JsonParseMode.Loose);
if (!tsConfigAst || tsConfigAst.kind !== 'object') {
continue;
}

const ngCompilerOptions = findPropertyInAstObject(tsConfigAst, 'angularCompilerOptions');
if (ngCompilerOptions && ngCompilerOptions.kind === 'object') {
// remove annotateForClosureCompiler option
const recorder = tree.beginUpdate(tsConfigOption.value);
const recorder = tree.beginUpdate(tsConfigPath);
removePropertyInAstObject(recorder, ngCompilerOptions, 'annotateForClosureCompiler');
tree.commitUpdate(recorder);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +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 { JsonAstObject } from '@angular-devkit/core';
import { JsonAstObject, logging } from '@angular-devkit/core';
import { Rule, Tree, UpdateRecorder } from '@angular-devkit/schematics';
import { posix } from 'path';
import {
Expand All @@ -16,33 +16,32 @@ import {
import { Builders } from '../../utility/workspace-models';
import { getAllOptions, getTargets, getWorkspace, readJsonFileAsAstObject } from './utils';


/**
* Update the tsconfig files for applications
* - Removes enableIvy: true
* - Sets stricter file inclusions
*/
export function updateApplicationTsConfigs(): Rule {
return (tree: Tree) => {
return (tree, context) => {
const workspace = getWorkspace(tree);

for (const { target } of getTargets(workspace, 'build', Builders.Browser)) {
updateTsConfig(tree, target, Builders.Browser);
updateTsConfig(tree, target, Builders.Browser, context.logger);
}

for (const { target } of getTargets(workspace, 'server', Builders.Server)) {
updateTsConfig(tree, target, Builders.Server);
updateTsConfig(tree, target, Builders.Server, context.logger);
}

for (const { target } of getTargets(workspace, 'test', Builders.Karma)) {
updateTsConfig(tree, target, Builders.Karma);
updateTsConfig(tree, target, Builders.Karma, context.logger);
}

return tree;
};
}

function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: Builders) {
function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: Builders, logger: logging.LoggerApi) {
const options = getAllOptions(builderConfig);
for (const option of options) {
let recorder: UpdateRecorder;
Expand All @@ -55,6 +54,7 @@ function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: B
const tsConfigPath = tsConfigOption.value;
let tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath);
if (!tsConfigAst) {
logger.warn(`Cannot find file: ${tsConfigPath}`);
continue;
}

Expand All @@ -78,7 +78,10 @@ function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: B
if (builderName !== Builders.Karma) {
// Note: we need to re-read the tsconfig after very commit because
// otherwise the updates will be out of sync since we are ammending the same node.
tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath);

// we are already checking that tsconfig exists above!
// tslint:disable-next-line: no-non-null-assertion
tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath) !;
const include = findPropertyInAstObject(tsConfigAst, 'include');

if (include && include.kind === 'array') {
Expand Down Expand Up @@ -109,13 +112,15 @@ function updateTsConfig(tree: Tree, builderConfig: JsonAstObject, builderName: B

if (newFiles.length) {
recorder = tree.beginUpdate(tsConfigPath);
tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath);
// tslint:disable-next-line: no-non-null-assertion
tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath) !;
insertPropertyInAstObjectInOrder(recorder, tsConfigAst, 'files', newFiles, 2);
tree.commitUpdate(recorder);
}

recorder = tree.beginUpdate(tsConfigPath);
tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath);
// tslint:disable-next-line: no-non-null-assertion
tsConfigAst = readJsonFileAsAstObject(tree, tsConfigPath) !;
removePropertyInAstObject(recorder, tsConfigAst, 'exclude');
tree.commitUpdate(recorder);
}
Expand Down
8 changes: 6 additions & 2 deletions packages/schematics/angular/migrations/update-9/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,15 @@ export function getAllOptions(builderConfig: JsonAstObject, configurationsOnly =

export function getWorkspace(host: Tree): JsonAstObject {
const path = getWorkspacePath(host);
const content = readJsonFileAsAstObject(host, path);
if (!content) {
throw new SchematicsException(`Could not find (${path})`);
}

return readJsonFileAsAstObject(host, path);
return content;
}

export function readJsonFileAsAstObject(host: Tree, path: string): JsonAstObject {
export function readJsonFileAsAstObject(host: Tree, path: string): JsonAstObject | undefined {
const configBuffer = host.read(path);
if (!configBuffer) {
throw new SchematicsException(`Could not find (${path})`);
Expand Down