diff --git a/BUILD.bazel b/BUILD.bazel index 9e35d75c04d..9cbc68cdf02 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -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/**", ]), ) diff --git a/package-lock.json b/package-lock.json index b906f59abb6..3fd65bbc197 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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": { diff --git a/package.json b/package.json index 4bb03b92d38..1c42e6199bf 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/lib/schematics/install/fonts/project-index-html.ts b/src/lib/schematics/install/fonts/project-index-html.ts index a4b60fddad7..b79aea32d5d 100644 --- a/src/lib/schematics/install/fonts/project-index-html.ts +++ b/src/lib/schematics/install/fonts/project-index-html.ts @@ -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.'); diff --git a/src/lib/schematics/install/index.spec.ts b/src/lib/schematics/install/index.spec.ts index 2e0b1ea398c..bb82c1883c6 100644 --- a/src/lib/schematics/install/index.spec.ts +++ b/src/lib/schematics/install/index.spec.ts @@ -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.`); } diff --git a/src/lib/schematics/install/theming/theming.ts b/src/lib/schematics/install/theming/theming.ts index d11a5f18497..aefa689c915 100644 --- a/src/lib/schematics/install/theming/theming.ts +++ b/src/lib/schematics/install/theming/theming.ts @@ -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.'); } } diff --git a/src/lib/schematics/update/project-tsconfig-paths.ts b/src/lib/schematics/update/project-tsconfig-paths.ts new file mode 100644 index 00000000000..46b085eeebb --- /dev/null +++ b/src/lib/schematics/update/project-tsconfig-paths.ts @@ -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([ + './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)); +} diff --git a/src/lib/schematics/update/update.ts b/src/lib/schematics/update/update.ts index a67d5c45cf5..6f80cf7a55c 100644 --- a/src/lib/schematics/update/update.ts +++ b/src/lib/schematics/update/update.ts @@ -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); -} diff --git a/src/lib/schematics/utils/architect-options.ts b/src/lib/schematics/utils/architect-options.ts deleted file mode 100644 index 82e9c31a4f1..00000000000 --- a/src/lib/schematics/utils/architect-options.ts +++ /dev/null @@ -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}.`); -} diff --git a/src/lib/schematics/utils/ast.ts b/src/lib/schematics/utils/ast.ts index 06cb9b14cf2..ccb7f3b44f7 100644 --- a/src/lib/schematics/utils/ast.ts +++ b/src/lib/schematics/utils/ast.ts @@ -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) => { diff --git a/src/lib/schematics/utils/build-component.ts b/src/lib/schematics/utils/build-component.ts index 0c2b0927ea6..2e8124bf0eb 100644 --- a/src/lib/schematics/utils/build-component.ts +++ b/src/lib/schematics/utils/build-component.ts @@ -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 = { diff --git a/src/lib/schematics/utils/project-main-file.ts b/src/lib/schematics/utils/project-main-file.ts index 71c87c6c264..ce652c35005 100644 --- a/src/lib/schematics/utils/project-main-file.ts +++ b/src/lib/schematics/utils/project-main-file.ts @@ -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 ` + diff --git a/src/lib/schematics/utils/project-style-file.ts b/src/lib/schematics/utils/project-style-file.ts index bb5340d2d65..7737b95a5ca 100644 --- a/src/lib/schematics/utils/project-style-file.ts +++ b/src/lib/schematics/utils/project-style-file.ts @@ -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); diff --git a/src/lib/schematics/utils/project-targets.ts b/src/lib/schematics/utils/project-targets.ts new file mode 100644 index 00000000000..2b2e4b9ea78 --- /dev/null +++ b/src/lib/schematics/utils/project-targets.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 {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}.`); +} diff --git a/src/lib/schematics/utils/version-agnostic-typescript.ts b/src/lib/schematics/utils/version-agnostic-typescript.ts index d52e90f3599..79c9ed95d59 100644 --- a/src/lib/schematics/utils/version-agnostic-typescript.ts +++ b/src/lib/schematics/utils/version-agnostic-typescript.ts @@ -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