Permalink
Browse files

fix(schematics): compatibility with Angular CLI 6.2.0 (#2131)

  • Loading branch information...
HsuanXyz authored and vthinkxie committed Sep 13, 2018
1 parent 3c6215f commit ac428db410631094775acada45b3d8a2a2944c42
Showing with 84 additions and 28 deletions.
  1. +18 −19 schematics/ng-add/index.ts
  2. +12 −9 schematics/utils/ast.ts
  3. +23 −0 schematics/utils/project-main-file.ts
  4. +31 −0 schematics/utils/project-targets.ts
@@ -15,6 +15,7 @@ import { getAppModulePath } from '../utils/devkit-utils/ng-ast-utils';
import { insertImport } from '../utils/devkit-utils/route-utils';
import { zorroVersion } from '../utils/lib-versions';
import { addPackageToPackageJson } from '../utils/package';
import { getProjectTargetOptions } from '../utils/project-targets';
import { Schema } from './schema';
const ADD_CONFIG = {
@@ -45,7 +46,7 @@ function addI18n(options: Schema): (host: Tree) => Tree {
return function (host: Tree): Tree {
const workspace = getWorkspace(host);
const project = getProjectFromWorkspace(workspace, options.project);
const modulePath = getAppModulePath(host, project.architect.build.options.main);
const modulePath = getAppModulePath(host, getProjectTargetOptions(project, 'build').main);
const moduleSource = getSourceFile(host, modulePath);
const locale = options.i18n;
const localePrefix = locale.split('_')[0];
@@ -206,11 +207,11 @@ function insertCustomTheme(project: Project, host: Tree, workspace: Workspace):
host.create(themePath, createCustomTheme());
}
if (project.architect) {
addStyleToTarget(project.architect.build, host, workspace, themePath, ADD_CONFIG.COMPILED_THEME_PATH);
addStyleToTarget(project.architect.test, host, workspace, themePath, ADD_CONFIG.COMPILED_THEME_PATH);
if ((project as any).targets || project.architect) {
addStyleToTarget('build', host, workspace, project, themePath, ADD_CONFIG.COMPILED_THEME_PATH);
addStyleToTarget('test', host, workspace, project, themePath, ADD_CONFIG.COMPILED_THEME_PATH);
} else {
throw new SchematicsException(`${project.name} does not have an architect configuration`);
throw new SchematicsException(`${project.name} does not have an architect or targets configuration`);
}
}
@@ -234,37 +235,35 @@ function installNodeDeps(): (host: Tree, context: SchematicContext) => void {
function insertCompiledTheme(project: Project, host: Tree, workspace: Workspace): void {
const themePath = ADD_CONFIG.COMPILED_THEME_PATH;
if (project.architect) {
addStyleToTarget(project.architect.build, host, workspace, themePath);
addStyleToTarget(project.architect.test, host, workspace, themePath);
if ((project as any).targets || project.architect) {
addStyleToTarget('build', host, workspace, project, themePath);
addStyleToTarget('test', host, workspace, project, themePath);
} else {
throw new SchematicsException(`${project.name} does not have an architect configuration`);
throw new SchematicsException(`${project.name} does not have an architect or targets configuration`);
}
}
/** Adds a style entry to the given target. */
function addStyleToTarget(target: any, host: Tree, workspace: Workspace, asset: string, exclude: string = ''): void {
function addStyleToTarget(targetName: string, host: Tree, workspace: Workspace, project: Project, asset: string, exclude: string = ''): void {
const styleEntry = asset;
const targetOptions = getProjectTargetOptions(project, targetName);
// We can't assume that any of these properties are defined, so safely add them as we go
// if necessary.
if (!target.options) {
target.options = { styles: [ styleEntry ] };
} else if (!target.options.styles) {
target.options.styles = [ styleEntry ];
if (!targetOptions.styles) {
targetOptions.styles = [ styleEntry ];
} else {
const existingStyles = target.options.styles.map(s => typeof s === 'string' ? s : s.input);
const existingStyles = targetOptions.styles.map(s => typeof s === 'string' ? s : s.input);
const hasGivenTheme = existingStyles.find(s => s.includes(asset));
if (exclude) {
const removeIndex = target.options.styles.indexOf(exclude);
const removeIndex = targetOptions.styles.indexOf(exclude);
if (removeIndex >= 0) {
target.options.styles.splice(removeIndex, 1);
targetOptions.styles.splice(removeIndex, 1);
}
}
if (!hasGivenTheme) {
target.options.styles.splice(0, 0, styleEntry);
targetOptions.styles.splice(0, 0, styleEntry);
}
}
@@ -3,9 +3,11 @@ import {SchematicsException, Tree} from '@angular-devkit/schematics';
import * as ts from 'typescript';
import {addImportToModule} from './devkit-utils/ast-utils';
import {InsertChange} from './devkit-utils/change';
import {Project, getWorkspace} from './devkit-utils/config';
import { Project, getWorkspace, Workspace } from './devkit-utils/config';
import {findBootstrapModulePath, getAppModulePath} from './devkit-utils/ng-ast-utils';
import {ModuleOptions, findModuleFromOptions as internalFindModule} from './devkit-utils/find-module';
import { getProjectMainFile } from './project-main-file'
import { getProjectTargetOptions } from './project-targets'
/** Reads file given path and returns TypeScript source file. */
@@ -19,8 +21,9 @@ export function getSourceFile(host: Tree, path: string): ts.SourceFile {
}
/** Import and add module to root app module. */
export function addModuleImportToRootModule(host: Tree, moduleName: string, src: string, project: Project) {
const modulePath = getAppModulePath(host, project.architect.build.options.main);
export function addModuleImportToRootModule(host: Tree, moduleName: string, src: string,
project: Workspace | any) {
const modulePath = getAppModulePath(host, getProjectMainFile(project));
addModuleImportToModule(host, modulePath, moduleName, src);
}
@@ -53,21 +56,21 @@ export function addModuleImportToModule(
/** Gets the app index.html file */
export function getIndexHtmlPath(host: Tree, project: Project): string {
const buildTarget = project.architect.build.options;
const buildOptions = getProjectTargetOptions(project, 'build');
if (buildTarget.index && buildTarget.index.endsWith('index.html')) {
return buildTarget.index;
if (buildOptions.index && buildOptions.index.endsWith('index.html')) {
return buildOptions.index;
}
throw new SchematicsException('No index.html file was found.');
}
/** Get the root stylesheet file. */
export function getStylesPath(host: Tree, project: Project): string {
const buildTarget = project.architect['build'];
const buildOptions = getProjectTargetOptions(project, 'build');
if (buildTarget.options && buildTarget.options.styles && buildTarget.options.styles.length) {
const styles = buildTarget.options.styles.map(s => typeof s === 'string' ? s : s.input);
if (buildOptions && buildOptions.styles && buildOptions.styles.length) {
const styles = buildOptions.styles.map(s => typeof s === 'string' ? s : s.input);
// First, see if any of the assets is called "styles.(le|sc|c)ss", which is the default
// "main" style sheet.
@@ -0,0 +1,23 @@
/**
* @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 { SchematicsException } from '@angular-devkit/schematics';
import { Workspace } from './devkit-utils/config';
import { getProjectTargetOptions } from './project-targets';
/** Looks for the main TypeScript file in the given project and returns its path. */
export function getProjectMainFile(project: Workspace): string {
const buildOptions = getProjectTargetOptions(project, 'build');
if (!buildOptions.main) {
throw new SchematicsException(`Could not find the project main file inside of the ` +
`workspace config (${(project as any).sourceRoot})`);
}
return buildOptions.main;
}
@@ -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 { Project } from './devkit-utils/config';
/** Resolves the architect options for the build target of the given project. */
export function getProjectTargetOptions(project: Project | any, buildTarget: string) {
if (project.targets &&
project.targets[buildTarget] &&
project.targets[buildTarget].options) {
return project.targets[buildTarget].options;
}
// TODO(devversion): consider removing this architect check if the CLI completely switched
// over to `targets`, and the `architect` support has been removed.
// See: https://github.com/angular/angular-cli/commit/307160806cb48c95ecb8982854f452303801ac9f
if (project.architect &&
project.architect[buildTarget] &&
project.architect[buildTarget].options) {
return project.architect[buildTarget].options;
}
throw new Error(`Cannot determine project target configuration for: ${buildTarget}.`);
}

0 comments on commit ac428db

Please sign in to comment.