mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(schematics): compatibility with Angular CLI 6.2.0 (#13078)
* Upgrades the devkit dependencies to the latest versions. * Adds support for the newly introduced and published `project.targets` instead of `project.architect` (see: https://github.com/angular/angular-cli/commit/307160806cb48c95ecb8982854f452303801ac9f) * Compatibility behavior for a published but non-announced breaking change within the schematic context (see: https://github.com/angular/angular-cli/commit/9720077a4b5ae628ddfaf5f1a26bac3b04bdf637#diff-e73df838d6700d187eff76a50c7e1c53R233`) * Supports the new `project.targets` schema within the update schematics (in order to properly determine `tsconfig` files) * Due to the fact that the @angular-devkit/schematics now handles Bazel better, the template files will be resolved through NodeJS. This means that the template files need to be referenced in the @//:node_modules label. Fixes #11438
This commit is contained in:
committed by
Jeremy Elbourn
parent
6b2f00897f
commit
714c205312
@@ -38,6 +38,9 @@ filegroup(
|
||||
"*.d.ts",
|
||||
]] + [
|
||||
"node_modules/http-server/**",
|
||||
# Reference all files of the "@schematics/angular" package because the schematic
|
||||
# tests depend on the template files of the angular schematics.
|
||||
"node_modules/@schematics/angular/**",
|
||||
]),
|
||||
)
|
||||
|
||||
|
||||
Generated
+16
-23
@@ -5,14 +5,15 @@
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@angular-devkit/core": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.7.4.tgz",
|
||||
"integrity": "sha512-Blh44vzZVzE8B9xIwjRoo7hXPGSDdlrrax0rntvt3DDGVTjsSGm43qT95aDmXiwJruOCJNC5DsaP3+tTAkAyQQ==",
|
||||
"version": "0.9.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.9.0-beta.2.tgz",
|
||||
"integrity": "sha512-zs6kCtFSg1GBqC0Jq0nxndX43Tp1IphwCF8PCy2airLLs15OTzZ0lRqDy5hSzKWy6WsY3X6yUXXmSe+5fO6SiQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "~6.4.0",
|
||||
"chokidar": "^2.0.3",
|
||||
"rxjs": "^6.0.0",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"rxjs": "~6.2.0",
|
||||
"source-map": "^0.5.6"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -25,13 +26,13 @@
|
||||
}
|
||||
},
|
||||
"@angular-devkit/schematics": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.7.4.tgz",
|
||||
"integrity": "sha512-Gkm2mBMm6a0mNKqZsAcS42VaO7zNSIXhIKbMyZQIcQ1ZMwbsx+Rs0dliQwFVfEVCNGc1pjh0Idc5O5V/g/N5Fw==",
|
||||
"version": "0.9.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.9.0-beta.2.tgz",
|
||||
"integrity": "sha512-+4wJ7tTmzzTKxu8EUdIzytmDddeUNeUFfakqz7lG6Go5rGJCOO+GMY4oLPl8OAbE4kGv8Psz8DDP1xf/emlX1Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@angular-devkit/core": "0.7.4",
|
||||
"rxjs": "^6.0.0"
|
||||
"@angular-devkit/core": "0.9.0-beta.2",
|
||||
"rxjs": "~6.2.0"
|
||||
}
|
||||
},
|
||||
"@angular/animations": {
|
||||
@@ -1027,22 +1028,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"@schematics/angular": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.7.4.tgz",
|
||||
"integrity": "sha512-/KJH5fPv+40VdadWmVnXR2GlvFZKYH01eYw7XOi77gXM896gk2tGlWmm+6RjUaVyec49ivusmmhRJEjiTyA7NA==",
|
||||
"version": "0.9.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.9.0-beta.2.tgz",
|
||||
"integrity": "sha512-+IR5m3tVFSpyjSj0avWr9oKEBbHgstZZ7lfsmaNwrpNRxiQVlERGS0qLWJYLiOiMBQmJlss71lQAXtug8i1a/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@angular-devkit/core": "0.7.4",
|
||||
"@angular-devkit/schematics": "0.7.4",
|
||||
"typescript": ">=2.6.2 <2.10"
|
||||
},
|
||||
"dependencies": {
|
||||
"typescript": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz",
|
||||
"integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==",
|
||||
"dev": true
|
||||
}
|
||||
"@angular-devkit/core": "0.9.0-beta.2",
|
||||
"@angular-devkit/schematics": "0.9.0-beta.2",
|
||||
"typescript": ">=2.6.2 <3.1"
|
||||
}
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
|
||||
+3
-3
@@ -44,8 +44,8 @@
|
||||
"zone.js": "^0.8.26"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/core": "0.7.4",
|
||||
"@angular-devkit/schematics": "0.7.4",
|
||||
"@angular-devkit/core": "^0.9.0-beta.2",
|
||||
"@angular-devkit/schematics": "^0.9.0-beta.2",
|
||||
"@angular/bazel": "7.0.0-beta.4",
|
||||
"@angular/compiler-cli": "7.0.0-beta.4",
|
||||
"@angular/http": "7.0.0-beta.4",
|
||||
@@ -56,7 +56,7 @@
|
||||
"@bazel/ibazel": "0.3.1",
|
||||
"@google-cloud/storage": "^1.1.1",
|
||||
"@octokit/rest": "^15.9.4",
|
||||
"@schematics/angular": "0.7.4",
|
||||
"@schematics/angular": "^0.9.0-beta.2",
|
||||
"@types/chalk": "^0.4.31",
|
||||
"@types/fs-extra": "^4.0.3",
|
||||
"@types/glob": "^5.0.33",
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
import {SchematicsException} from '@angular-devkit/schematics';
|
||||
import {WorkspaceProject} from '@schematics/angular/utility/config';
|
||||
import {getArchitectOptions} from '../../utils/architect-options';
|
||||
import {getProjectTargetOptions} from '../../utils/project-targets';
|
||||
|
||||
/** Looks for the index HTML file in the given project and returns its path. */
|
||||
export function getIndexHtmlPath(project: WorkspaceProject): string {
|
||||
const buildOptions = getArchitectOptions(project, 'build');
|
||||
const buildOptions = getProjectTargetOptions(project, 'build');
|
||||
|
||||
if (!buildOptions.index) {
|
||||
throw new SchematicsException('No project "index.html" file could be found.');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {Tree} from '@angular-devkit/schematics';
|
||||
import {SchematicTestRunner} from '@angular-devkit/schematics/testing';
|
||||
import {getProjectTargetOptions} from '@angular/material/schematics/utils/project-targets';
|
||||
import {getProjectStyleFile} from '../utils/project-style-file';
|
||||
import {getIndexHtmlPath} from './fonts/project-index-html';
|
||||
import {getProjectFromWorkspace} from '../utils/get-project';
|
||||
@@ -19,11 +20,7 @@ describe('material-install-schematic', () => {
|
||||
|
||||
/** Expects the given file to be in the styles of the specified workspace project. */
|
||||
function expectProjectStyleFile(project: WorkspaceProject, filePath: string) {
|
||||
const architect = project.architect!;
|
||||
|
||||
expect(architect!['build']).toBeTruthy();
|
||||
expect(architect!['build']['options']).toBeTruthy();
|
||||
expect(architect!['build']['options']['styles']).toContain(filePath,
|
||||
expect(getProjectTargetOptions(project, 'build').styles).toContain(filePath,
|
||||
`Expected "${filePath}" to be added to the project styles in the workspace.`);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import {getWorkspace, WorkspaceProject, WorkspaceSchema} from '@schematics/angul
|
||||
import {join} from 'path';
|
||||
import {getProjectFromWorkspace} from '../../utils/get-project';
|
||||
import {getProjectStyleFile} from '../../utils/project-style-file';
|
||||
import {getProjectTargetOptions} from '../../utils/project-targets';
|
||||
import {Schema} from '../schema';
|
||||
import {createCustomTheme} from './custom-theme';
|
||||
|
||||
@@ -60,9 +61,7 @@ function insertCustomTheme(project: WorkspaceProject, projectName: string, host:
|
||||
|
||||
host.create(customThemePath, themeContent);
|
||||
|
||||
// Architect is always defined because we initially asserted if the default builder
|
||||
// configuration is set up or not.
|
||||
return addStyleToTarget(project.architect!['build'], host, customThemePath, workspace);
|
||||
return addStyleToTarget(project, 'build', host, customThemePath, workspace);
|
||||
}
|
||||
|
||||
const insertion = new InsertChange(stylesPath, 0, themeContent);
|
||||
@@ -79,27 +78,24 @@ function insertPrebuiltTheme(project: WorkspaceProject, host: Tree, theme: strin
|
||||
// Path needs to be always relative to the `package.json` or workspace root.
|
||||
const themePath = `./node_modules/@angular/material/prebuilt-themes/${theme}.css`;
|
||||
|
||||
// Architect is always defined because we initially asserted if the default builder
|
||||
// configuration is set up or not.
|
||||
addStyleToTarget(project.architect!['build'], host, themePath, workspace);
|
||||
addStyleToTarget(project.architect!['test'], host, themePath, workspace);
|
||||
addStyleToTarget(project, 'build', host, themePath, workspace);
|
||||
addStyleToTarget(project, 'test', host, themePath, workspace);
|
||||
}
|
||||
|
||||
/** Adds a style entry to the given target. */
|
||||
function addStyleToTarget(target: any, host: Tree, asset: string, workspace: WorkspaceSchema) {
|
||||
// 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: [asset]};
|
||||
} else if (!target.options.styles) {
|
||||
target.options.styles = [asset];
|
||||
/** Adds a style entry to the given project target. */
|
||||
function addStyleToTarget(project: WorkspaceProject, targetName: string, host: Tree,
|
||||
assetPath: string, workspace: WorkspaceSchema) {
|
||||
const targetOptions = getProjectTargetOptions(project, targetName);
|
||||
|
||||
if (!targetOptions.styles) {
|
||||
targetOptions.styles = [assetPath];
|
||||
} else {
|
||||
const existingStyles = target.options.styles.map(s => typeof s === 'string' ? s : s.input);
|
||||
const hasGivenTheme = existingStyles.find(s => s.includes(asset));
|
||||
const existingStyles = targetOptions.styles.map(s => typeof s === 'string' ? s : s.input);
|
||||
const hasGivenTheme = existingStyles.find(s => s.includes(assetPath));
|
||||
const hasOtherTheme = existingStyles.find(s => s.includes('material/prebuilt'));
|
||||
|
||||
if (!hasGivenTheme && !hasOtherTheme) {
|
||||
target.options.styles.unshift(asset);
|
||||
targetOptions.styles.unshift(assetPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,18 +104,23 @@ function addStyleToTarget(target: any, host: Tree, asset: string, workspace: Wor
|
||||
|
||||
/** Throws if the project is not using the default Angular devkit builders. */
|
||||
function assertDefaultBuildersConfigured(project: WorkspaceProject) {
|
||||
const defaultBuilder = '@angular-devkit/build-angular:browser';
|
||||
const defaultTestBuilder = '@angular-devkit/build-angular:karma';
|
||||
checkProjectTargetBuilder(project, 'build', '@angular-devkit/build-angular:browser');
|
||||
checkProjectTargetBuilder(project, 'test', '@angular-devkit/build-angular:karma');
|
||||
}
|
||||
|
||||
const hasDefaultBuilders = project.architect &&
|
||||
project.architect['build'] &&
|
||||
project.architect['build']['builder'] === defaultBuilder &&
|
||||
project.architect['test'] &&
|
||||
project.architect['test']['builder'] === defaultTestBuilder;
|
||||
/**
|
||||
* Checks if the specified project target is configured with the default builders which are
|
||||
* provided by the Angular CLI.
|
||||
*/
|
||||
function checkProjectTargetBuilder(project: WorkspaceProject, targetName: string,
|
||||
defaultBuilder: string) {
|
||||
|
||||
if (!hasDefaultBuilders) {
|
||||
const targetConfig = project.architect && project.architect[targetName] ||
|
||||
project.targets && project.targets[targetName];
|
||||
|
||||
if (!targetConfig || targetConfig['builder'] !== defaultBuilder) {
|
||||
throw new SchematicsException(
|
||||
'Your project is not using the default builders for build and test. The Angular Material ' +
|
||||
`Your project is not using the default builders for "${targetName}". The Angular Material ` +
|
||||
'schematics can only be used if the original builders from the Angular CLI are configured.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @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 {Tree} from '@angular-devkit/schematics';
|
||||
import {getWorkspace} from '@schematics/angular/utility/config';
|
||||
|
||||
/**
|
||||
* Gets all tsconfig paths from a CLI project by reading the workspace configuration
|
||||
* and looking for common tsconfig locations.
|
||||
*/
|
||||
export function getProjectTsConfigPaths(tree: Tree): string[] {
|
||||
// Start with some tsconfig paths that are generally used within CLI projects.
|
||||
const tsconfigPaths = new Set<string>([
|
||||
'./tsconfig.json',
|
||||
'./src/tsconfig.json',
|
||||
'./src/tsconfig.app.json',
|
||||
]);
|
||||
|
||||
// Add any tsconfig directly referenced in a build or test task of the angular.json workspace.
|
||||
const workspace = getWorkspace(tree);
|
||||
|
||||
for (const project of Object.values(workspace.projects)) {
|
||||
['build', 'test'].forEach(targetName => {
|
||||
if (project.targets &&
|
||||
project.targets[targetName] &&
|
||||
project.targets[targetName].options &&
|
||||
project.targets[targetName].options.tsConfig) {
|
||||
tsconfigPaths.add(project.targets[targetName].options.tsConfig);
|
||||
}
|
||||
|
||||
if (project.architect &&
|
||||
project.architect[targetName] &&
|
||||
project.architect[targetName].options &&
|
||||
project.architect[targetName].options.tsConfig) {
|
||||
tsconfigPaths.add(project.architect[targetName].options.tsConfig);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Filter out tsconfig files that don't exist in the CLI project.
|
||||
return Array.from(tsconfigPaths).filter(p => tree.exists(p));
|
||||
}
|
||||
@@ -8,25 +8,25 @@
|
||||
|
||||
import {Rule, SchematicContext, TaskId, Tree} from '@angular-devkit/schematics';
|
||||
import {RunSchematicTask, TslintFixTask} from '@angular-devkit/schematics/tasks';
|
||||
import {getWorkspace} from '@schematics/angular/utility/config';
|
||||
import {TargetVersion} from './index';
|
||||
import {getProjectTsConfigPaths} from './project-tsconfig-paths';
|
||||
import {createTslintConfig} from './tslint-update';
|
||||
|
||||
/** Entry point for `ng update` from Angular CLI. */
|
||||
export function createUpdateRule(targetVersion: TargetVersion): Rule {
|
||||
return (tree: Tree, context: SchematicContext) => {
|
||||
|
||||
const allTsConfigPaths = getTsConfigPaths(tree);
|
||||
const projectTsConfigPaths = getProjectTsConfigPaths(tree);
|
||||
const tslintFixTasks: TaskId[] = [];
|
||||
|
||||
if (!allTsConfigPaths.length) {
|
||||
if (!projectTsConfigPaths.length) {
|
||||
throw new Error('Could not find any tsconfig file. Please submit an issue on the Angular ' +
|
||||
'Material repository that includes the name of your TypeScript configuration.');
|
||||
}
|
||||
|
||||
const tslintConfig = createTslintConfig(targetVersion);
|
||||
|
||||
for (const tsconfig of allTsConfigPaths) {
|
||||
for (const tsconfig of projectTsConfigPaths) {
|
||||
// Run the update tslint rules.
|
||||
tslintFixTasks.push(context.addTask(new TslintFixTask(tslintConfig, {
|
||||
silent: false,
|
||||
@@ -39,40 +39,3 @@ export function createUpdateRule(targetVersion: TargetVersion): Rule {
|
||||
context.addTask(new RunSchematicTask('ng-post-update', {}), tslintFixTasks);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all tsconfig paths from a CLI project by reading the workspace configuration
|
||||
* and looking for common tsconfig locations.
|
||||
*/
|
||||
function getTsConfigPaths(tree: Tree): string[] {
|
||||
// Start with some tsconfig paths that are generally used.
|
||||
const tsconfigPaths = [
|
||||
'./tsconfig.json',
|
||||
'./src/tsconfig.json',
|
||||
'./src/tsconfig.app.json',
|
||||
];
|
||||
|
||||
// Add any tsconfig directly referenced in a build or test task of the angular.json workspace.
|
||||
const workspace = getWorkspace(tree);
|
||||
|
||||
for (const project of Object.values(workspace.projects)) {
|
||||
if (project && project.architect) {
|
||||
for (const taskName of ['build', 'test']) {
|
||||
const task = project.architect[taskName];
|
||||
if (task && task.options && task.options.tsConfig) {
|
||||
const tsConfigOption = task.options.tsConfig;
|
||||
if (typeof tsConfigOption === 'string') {
|
||||
tsconfigPaths.push(tsConfigOption);
|
||||
} else if (Array.isArray(tsConfigOption)) {
|
||||
tsconfigPaths.push(...tsConfigOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out tsconfig files that don't exist and remove any duplicates.
|
||||
return tsconfigPaths
|
||||
.filter(p => tree.exists(p))
|
||||
.filter((value, index, self) => self.indexOf(value) === index);
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* @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 {WorkspaceProject} from '@schematics/angular/utility/config';
|
||||
|
||||
/** Resolves the architect options for the build target of the given project. */
|
||||
export function getArchitectOptions(project: WorkspaceProject, buildTarget: string) {
|
||||
if (project.architect &&
|
||||
project.architect[buildTarget] &&
|
||||
project.architect[buildTarget].options) {
|
||||
|
||||
return project.architect[buildTarget].options;
|
||||
}
|
||||
|
||||
throw new Error(`Cannot determine architect configuration for target: ${buildTarget}.`);
|
||||
}
|
||||
@@ -49,10 +49,7 @@ export function addModuleImportToModule(host: Tree, modulePath: string, moduleNa
|
||||
throw new SchematicsException(`Module not found: ${modulePath}`);
|
||||
}
|
||||
|
||||
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
|
||||
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
|
||||
// that is a type signature mismatch at compilation which is not valid.
|
||||
const changes = addImportToModule(moduleSource as any, modulePath, moduleName, src);
|
||||
const changes = addImportToModule(moduleSource, modulePath, moduleName, src);
|
||||
const recorder = host.beginUpdate(modulePath);
|
||||
|
||||
changes.forEach((change) => {
|
||||
|
||||
@@ -36,7 +36,7 @@ import {buildRelativePath, findModuleFromOptions} from '@schematics/angular/util
|
||||
import {parseName} from '@schematics/angular/utility/parse-name';
|
||||
import {buildDefaultPath} from '@schematics/angular/utility/project';
|
||||
import {validateHtmlSelector, validateName} from '@schematics/angular/utility/validation';
|
||||
import {readFileSync} from 'fs';
|
||||
import {readFileSync, statSync} from 'fs';
|
||||
import {dirname, join, resolve} from 'path';
|
||||
import {getProjectFromWorkspace} from './get-project';
|
||||
import {getDefaultComponentOptions} from './schematic-options';
|
||||
@@ -67,11 +67,8 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
|
||||
const relativePath = buildRelativePath(modulePath, componentPath);
|
||||
const classifiedName = strings.classify(`${options.name}Component`);
|
||||
|
||||
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
|
||||
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
|
||||
// that is a type signature mismatch at compilation which is not valid.
|
||||
const declarationChanges = addDeclarationToModule(
|
||||
source as any,
|
||||
source,
|
||||
modulePath,
|
||||
classifiedName,
|
||||
relativePath);
|
||||
@@ -89,11 +86,8 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
|
||||
const source = readIntoSourceFile(host, modulePath);
|
||||
const exportRecorder = host.beginUpdate(modulePath);
|
||||
|
||||
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
|
||||
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
|
||||
// that is a type signature mismatch at compilation which is not valid.
|
||||
const exportChanges = addExportToModule(
|
||||
source as any,
|
||||
source,
|
||||
modulePath,
|
||||
strings.classify(`${options.name}Component`),
|
||||
relativePath);
|
||||
@@ -111,11 +105,8 @@ function addDeclarationToNgModule(options: ComponentOptions): Rule {
|
||||
const source = readIntoSourceFile(host, modulePath);
|
||||
const entryComponentRecorder = host.beginUpdate(modulePath);
|
||||
|
||||
// TODO(devversion): Cast to any because the Bazel typescript rules seem to incorrectly resolve
|
||||
// the the required TypeScript version for the @schematics/angular utility functions. Meaning
|
||||
// that is a type signature mismatch at compilation which is not valid.
|
||||
const entryComponentChanges = addEntryComponentToModule(
|
||||
source as any,
|
||||
source,
|
||||
modulePath,
|
||||
strings.classify(`${options.name}Component`),
|
||||
relativePath);
|
||||
@@ -172,9 +163,16 @@ export function buildComponent(options: ComponentOptions,
|
||||
const project = getProjectFromWorkspace(workspace, options.project);
|
||||
const defaultComponentOptions = getDefaultComponentOptions(project);
|
||||
|
||||
// TODO(devversion): Remove if we drop support for older CLI versions.
|
||||
// This handles an unreported breaking change from the @angular-devkit/schematics. Previously
|
||||
// the description path resolved to the factory file, but starting from 6.2.0, it resolves
|
||||
// to the factory directory.
|
||||
const schematicPath = statSync(context.schematic.description.path).isDirectory() ?
|
||||
context.schematic.description.path :
|
||||
dirname(context.schematic.description.path);
|
||||
|
||||
const schematicFilesUrl = './files';
|
||||
const schematicFilesPath = resolve(dirname(context.schematic.description.path),
|
||||
schematicFilesUrl);
|
||||
const schematicFilesPath = resolve(schematicPath, schematicFilesUrl);
|
||||
|
||||
// Add the default component option values to the options if an option is not explicitly
|
||||
// specified but a default component option is available.
|
||||
@@ -188,14 +186,14 @@ export function buildComponent(options: ComponentOptions,
|
||||
|
||||
options.module = findModuleFromOptions(host, options);
|
||||
|
||||
const parsedPath = parseName(options.path, options.name);
|
||||
const parsedPath = parseName(options.path!, options.name);
|
||||
|
||||
options.name = parsedPath.name;
|
||||
options.path = parsedPath.path;
|
||||
options.selector = options.selector || buildSelector(options, project.prefix);
|
||||
|
||||
validateName(options.name);
|
||||
validateHtmlSelector(options.selector);
|
||||
validateHtmlSelector(options.selector!);
|
||||
|
||||
// Object that will be used as context for the EJS templates.
|
||||
const baseTemplateContext = {
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
|
||||
import {SchematicsException} from '@angular-devkit/schematics';
|
||||
import {WorkspaceProject} from '@schematics/angular/utility/config';
|
||||
import {getArchitectOptions} from './architect-options';
|
||||
import {getProjectTargetOptions} from './project-targets';
|
||||
|
||||
/** Looks for the main TypeScript file in the given project and returns its path. */
|
||||
export function getProjectMainFile(project: WorkspaceProject): string {
|
||||
const buildOptions = getArchitectOptions(project, 'build');
|
||||
const buildOptions = getProjectTargetOptions(project, 'build');
|
||||
|
||||
if (!buildOptions.main) {
|
||||
throw new SchematicsException(`Could not find the project main file inside of the ` +
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import {normalize} from '@angular-devkit/core';
|
||||
import {WorkspaceProject} from '@schematics/angular/utility/config';
|
||||
import {getArchitectOptions} from './architect-options';
|
||||
import {getProjectTargetOptions} from './project-targets';
|
||||
|
||||
/** Regular expression that matches all possible Angular CLI default style files. */
|
||||
const defaultStyleFileRegex = /styles\.(c|le|sc)ss/;
|
||||
@@ -21,7 +21,7 @@ const validStyleFileRegex = /\.(c|le|sc)ss/;
|
||||
* extension is specified, any style file with a valid extension will be returned.
|
||||
*/
|
||||
export function getProjectStyleFile(project: WorkspaceProject, extension?: string): string | null {
|
||||
const buildOptions = getArchitectOptions(project, 'build');
|
||||
const buildOptions = getProjectTargetOptions(project, 'build');
|
||||
|
||||
if (buildOptions.styles && buildOptions.styles.length) {
|
||||
const styles = buildOptions.styles.map(s => typeof s === 'string' ? s : s.input);
|
||||
|
||||
@@ -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 {WorkspaceProject} from '@schematics/angular/utility/config';
|
||||
|
||||
/** Resolves the architect options for the build target of the given project. */
|
||||
export function getProjectTargetOptions(project: WorkspaceProject, 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}.`);
|
||||
}
|
||||
@@ -6,8 +6,13 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/** This is just a type import and won't be generated in the release output. */
|
||||
import typescript = require('@schematics/angular/node_modules/typescript');
|
||||
/**
|
||||
* This is just a type import and won't be generated in the release output.
|
||||
*
|
||||
* Note that we always need to adjust this type import based on the location of the Typescript
|
||||
* dependency that will be shipped with `@schematics/angular`.
|
||||
*/
|
||||
import typescript = require('typescript');
|
||||
|
||||
/**
|
||||
* This is an agnostic re-export of TypeScript. Depending on the context, this module file will
|
||||
|
||||
Reference in New Issue
Block a user