|
8 | 8 |
|
9 | 9 | import {normalize} from '@angular-devkit/core';
|
10 | 10 | import {WorkspaceProject, WorkspaceSchema} from '@angular-devkit/core/src/workspace';
|
11 |
| -import {SchematicsException, Tree} from '@angular-devkit/schematics'; |
| 11 | +import {Tree} from '@angular-devkit/schematics'; |
12 | 12 | import {
|
13 | 13 | getProjectFromWorkspace,
|
14 | 14 | getProjectStyleFile,
|
15 | 15 | getProjectTargetOptions,
|
16 | 16 | } from '@angular/cdk/schematics';
|
17 | 17 | import {InsertChange} from '@schematics/angular/utility/change';
|
18 | 18 | import {getWorkspace} from '@schematics/angular/utility/config';
|
| 19 | +import {bold, red, yellow} from 'chalk'; |
19 | 20 | import {join} from 'path';
|
20 | 21 | import {Schema} from '../schema';
|
21 |
| -import {createCustomTheme} from './custom-theme'; |
22 |
| -import {red, bold, yellow} from 'chalk'; |
| 22 | +import {createCustomTheme} from './create-custom-theme'; |
23 | 23 |
|
24 | 24 | /** Path segment that can be found in paths that refer to a prebuilt theme. */
|
25 | 25 | const prebuiltThemePathSegment = '@angular/material/prebuilt-themes';
|
26 | 26 |
|
27 | 27 | /** Default file name of the custom theme that can be generated. */
|
28 | 28 | const defaultCustomThemeFilename = 'custom-theme.scss';
|
29 | 29 |
|
| 30 | +/** Object that maps a CLI target to its default builder name. */ |
| 31 | +const defaultTargetBuilders = { |
| 32 | + build: '@angular-devkit/build-angular:browser', |
| 33 | + test: '@angular-devkit/build-angular:karma', |
| 34 | +}; |
| 35 | + |
30 | 36 | /** Add pre-built styles to the main project style file. */
|
31 | 37 | export function addThemeToAppStyles(options: Schema): (host: Tree) => Tree {
|
32 | 38 | return function(host: Tree): Tree {
|
33 | 39 | const workspace = getWorkspace(host);
|
34 | 40 | const project = getProjectFromWorkspace(workspace, options.project);
|
35 | 41 | const themeName = options.theme || 'indigo-pink';
|
36 | 42 |
|
37 |
| - // Because the build setup for the Angular CLI can be changed so dramatically, we can't know |
38 |
| - // where to generate anything if the project is not using the default config for build and test. |
39 |
| - assertDefaultBuildersConfigured(project); |
40 |
| - |
41 | 43 | if (themeName === 'custom') {
|
42 | 44 | insertCustomTheme(project, options.project, host, workspace);
|
43 | 45 | } else {
|
@@ -98,8 +100,12 @@ function insertPrebuiltTheme(project: WorkspaceProject, host: Tree, theme: strin
|
98 | 100 | }
|
99 | 101 |
|
100 | 102 | /** Adds a theming style entry to the given project target options. */
|
101 |
| -function addThemeStyleToTarget(project: WorkspaceProject, targetName: string, host: Tree, |
102 |
| - assetPath: string, workspace: WorkspaceSchema) { |
| 103 | +function addThemeStyleToTarget(project: WorkspaceProject, targetName: 'test' | 'build', host: Tree, |
| 104 | + assetPath: string, workspace: WorkspaceSchema) { |
| 105 | + // Do not update the builder options in case the target does not use the default CLI builder. |
| 106 | + if (!validateDefaultTargetBuilder(project, targetName)) { |
| 107 | + return; |
| 108 | + } |
103 | 109 |
|
104 | 110 | const targetOptions = getProjectTargetOptions(project, targetName);
|
105 | 111 |
|
@@ -135,25 +141,31 @@ function addThemeStyleToTarget(project: WorkspaceProject, targetName: string, ho
|
135 | 141 | host.overwrite('angular.json', JSON.stringify(workspace, null, 2));
|
136 | 142 | }
|
137 | 143 |
|
138 |
| -/** Throws if the project is not using the default Angular devkit builders. */ |
139 |
| -function assertDefaultBuildersConfigured(project: WorkspaceProject) { |
140 |
| - checkProjectTargetBuilder(project, 'build', '@angular-devkit/build-angular:browser'); |
141 |
| - checkProjectTargetBuilder(project, 'test', '@angular-devkit/build-angular:karma'); |
142 |
| -} |
143 |
| - |
144 | 144 | /**
|
145 |
| - * Checks if the specified project target is configured with the default builders which are |
146 |
| - * provided by the Angular CLI. |
| 145 | + * Validates that the specified project target is configured with the default builders which are |
| 146 | + * provided by the Angular CLI. If the configured builder does not match the default builder, |
| 147 | + * this function can either throw or just show a warning. |
147 | 148 | */
|
148 |
| -function checkProjectTargetBuilder(project: WorkspaceProject, targetName: string, |
149 |
| - defaultBuilder: string) { |
150 |
| - |
| 149 | +function validateDefaultTargetBuilder(project: WorkspaceProject, targetName: 'build' | 'test') { |
| 150 | + const defaultBuilder = defaultTargetBuilders[targetName]; |
151 | 151 | const targetConfig = project.architect && project.architect[targetName] ||
|
152 | 152 | project.targets && project.targets[targetName];
|
153 |
| - |
154 |
| - if (!targetConfig || targetConfig['builder'] !== defaultBuilder) { |
155 |
| - throw new SchematicsException( |
156 |
| - `Your project is not using the default builders for "${targetName}". The Angular Material ` + |
157 |
| - 'schematics can only be used if the original builders from the Angular CLI are configured.'); |
| 153 | + const isDefaultBuilder = targetConfig && targetConfig['builder'] === defaultBuilder; |
| 154 | + |
| 155 | + // Because the build setup for the Angular CLI can be customized by developers, we can't know |
| 156 | + // where to put the theme file in the workspace configuration if custom builders are being |
| 157 | + // used. In case the builder has been changed for the "build" target, we throw an error and |
| 158 | + // exit because setting up a theme is a primary goal of `ng-add`. Otherwise if just the "test" |
| 159 | + // builder has been changed, we warn because a theme is not mandatory for running tests |
| 160 | + // with Material. See: https://github.com/angular/material2/issues/14176 |
| 161 | + if (!isDefaultBuilder && targetName === 'build') { |
| 162 | + throw new Error(`Your project is not using the default builders for "${targetName}". The ` + |
| 163 | + `Angular Material schematics cannot add a theme to the workspace configuration if the ` + |
| 164 | + `builder has been changed. Exiting..`); |
| 165 | + } else if (!isDefaultBuilder) { |
| 166 | + console.warn(`Your project is not using the default builders for "${targetName}". This ` + |
| 167 | + `means that we cannot add the configured theme to the "${targetName}" target.`); |
158 | 168 | }
|
| 169 | + |
| 170 | + return isDefaultBuilder; |
159 | 171 | }
|
0 commit comments