Skip to content

Commit 92e72bd

Browse files
fix(schematics): fix schematics after npm testing (#6211)
1 parent 19b6c37 commit 92e72bd

File tree

8 files changed

+55
-91
lines changed

8 files changed

+55
-91
lines changed

libs/common-docs/src/lib/common/schematics/schematics.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ <h2 id="getting-started">
2828
<p>When you install ngx-bootstrap with Angular Cli Schematics you will get such updates:</p>
2929
<ul id="installation">
3030
<li><p><code>package.json</code></p>
31-
<p>List of dependencies will be updated with 2 new packages <code>"bootstrap": "^4.5.0"</code>, <code>"ngx-bootstrap": "7.0.0-rc.1"</code>. After packages will be installed and node_modules folder will be updated also.</p>
31+
<p>List of dependencies will be updated with 2 new packages <code>"bootstrap": "^4.5.3"</code>, <code>"ngx-bootstrap": "7.0.0"</code>. After packages will be installed and node_modules folder will be updated also.</p>
3232
</li>
3333
<li id="style_updates"><p>Depending on which style extension is used in the project, schematics will add necessary imports or styles links. It, as expected, allows the use SCSS or CSS extensions.</p>
3434
<p>In case CSS extension - <code>angular.json</code> file will be updated.</p>

src/schematics/src/ng-add/index.spec.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,24 @@ import { getFileContent } from '@schematics/angular/utility/test';
99
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
1010
import { Tree } from '@angular-devkit/schematics';
1111

12-
import {
13-
createTestApp,
14-
getProjectFromWorkSpace, getProjectTargetOptions,
15-
removePackageJsonDependency,
16-
getWorkspace
17-
} from '../utils';
12+
import { createTestApp, getProjectTargetOptions, removePackageJsonDependency } from '../utils';
1813

1914
import * as path from 'path';
20-
import { WorkspaceProject } from '@schematics/angular/utility/workspace-models';
2115
import { getProjectMainFile } from '../utils/project-main-file';
2216
import { getAppModulePath } from '@schematics/angular/utility/ng-ast-utils';
2317
import { checkComponentName } from './index';
18+
import { getWorkspace } from '@schematics/angular/utility/workspace';
19+
import { workspaces } from '@angular-devkit/core';
2420

2521
const defaultOptions = {
2622
component: 'carousel'
2723
};
2824

29-
export function expectProjectStyleFile(project: WorkspaceProject, filePath: string) {
25+
export function expectProjectStyleFile(project: workspaces.ProjectDefinition, filePath: string) {
3026
expect(getProjectTargetOptions(project, 'build').styles).toContain(filePath);
3127
}
3228

29+
3330
describe('ng-add schematic', () => {
3431
let runner: SchematicTestRunner;
3532
let appTree: Tree;
@@ -63,7 +60,8 @@ describe('ng-add schematic', () => {
6360
.toPromise();
6461

6562
const workspace = await getWorkspace(tree);
66-
const project = getProjectFromWorkSpace(workspace);
63+
const projectName = workspace.extensions.defaultProject !.toString();
64+
const project = workspace.projects.get(projectName);
6765

6866
expectProjectStyleFile(project, './node_modules/bootstrap/dist/css/bootstrap.min.css');
6967
});
@@ -74,7 +72,8 @@ describe('ng-add schematic', () => {
7472
.runSchematicAsync('ng-add', options, appTree)
7573
.toPromise();
7674
const workspace = await getWorkspace(tree);
77-
const project = getProjectFromWorkSpace(workspace);
75+
const projectName = workspace.extensions.defaultProject !.toString();
76+
const project = workspace.projects.get(projectName);
7877
const content = tree.readContent(getAppModulePath(tree, getProjectMainFile(project)));
7978
expect(checkComponentName(options.component)).toBeTruthy();
8079
expect(content).toBeTruthy();

src/schematics/src/ng-add/index.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
8+
import { workspaces } from '@angular-devkit/core';
99
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
1010
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
1111
import { getAppModulePath } from '@schematics/angular/utility/ng-ast-utils';
12-
import { addModuleImportToRootModule, addPackageToPackageJson, getProjectFromWorkSpace, getWorkspace } from '../utils';
12+
import { addModuleImportToRootModule, addPackageToPackageJson } from '../utils';
1313
import { hasNgModuleImport } from '../utils/ng-module-imports';
1414
import { getProjectMainFile } from '../utils/project-main-file';
1515
import { Schema } from './schema';
16-
import { WorkspaceProject } from '@schematics/angular/utility/workspace-models';
1716
import { addStyles } from '../utils/addStyles';
1817
import { getDependencies } from '../utils/getVersions';
18+
import { getWorkspace } from '@schematics/angular/utility/workspace';
1919

2020
const datepickerComponentName = 'datepicker';
2121
const bsName = 'ngx-bootstrap';
@@ -59,28 +59,28 @@ export default function addBsToPackage(options: Schema): Rule {
5959
? options.component
6060
: options['--'] && options['--'][1];
6161

62-
return (tree: Tree, context: SchematicContext) => {
63-
const workspace = getWorkspace(tree) as any;
64-
const projectName = options.project ? options.project : Object.keys(workspace.projects)[0];
65-
const projectWorkspace = getProjectFromWorkSpace(workspace, projectName);
62+
return async (tree: Tree, context: SchematicContext) => {
63+
const workspace = await getWorkspace(tree);
64+
const projectName = options.project || workspace.extensions.defaultProject !.toString();
65+
const project = workspace.projects.get(projectName);
6666

6767
addPackageJsonDependencies(tree, context);
68-
if (!componentName || componentName === datepickerComponentName) {
69-
insertCommonStyles(projectWorkspace, tree, projectName, options.stylesExtension);
68+
if (!componentName || componentName === datepickerComponentName || !components[componentName]) {
69+
insertCommonStyles(project, tree, projectName, options.stylesExtension);
7070
} else {
71-
insertBootstrapStyles(projectWorkspace, tree, projectName, options.stylesExtension);
71+
insertBootstrapStyles(project, tree, projectName, options.stylesExtension);
7272
}
7373

7474
context.addTask(new NodePackageInstallTask());
7575
if (componentName) {
76-
addModuleOfComponent(projectWorkspace, tree, context, componentName);
76+
addModuleOfComponent(project, tree, context, componentName);
7777
}
7878

79-
addAnimationModule(projectWorkspace, tree, context, componentName);
79+
addAnimationModule(project, tree, context, componentName);
8080
};
8181
}
8282

83-
function addModuleOfComponent(project: WorkspaceProject, host: Tree, context: SchematicContext, componentName: string): Rule {
83+
function addModuleOfComponent(project: workspaces.ProjectDefinition, host: Tree, context: SchematicContext, componentName: string): Rule {
8484
if (!project) {
8585
return;
8686
}
@@ -106,15 +106,15 @@ function addPackageJsonDependencies(host: Tree, context: SchematicContext): Tree
106106
return host;
107107
}
108108

109-
function insertBootstrapStyles(project: WorkspaceProject, host: Tree, projectName: string, extension?: string ): Tree {
109+
function insertBootstrapStyles(project: workspaces.ProjectDefinition, host: Tree, projectName: string, extension?: string ): Tree {
110110
if (!project) {
111111
return;
112112
}
113113

114114
return addStyles(project, 'build', host, BOOTSTRAP_AVAILABLE_STYLES, projectName, extension);
115115
}
116116

117-
function insertCommonStyles(project: WorkspaceProject, host: Tree, projectName: string, extension?: string): Tree {
117+
function insertCommonStyles(project: workspaces.ProjectDefinition, host: Tree, projectName: string, extension?: string): Tree {
118118
if (!project) {
119119
return;
120120
}
@@ -123,7 +123,7 @@ function insertCommonStyles(project: WorkspaceProject, host: Tree, projectName:
123123
return addStyles(project, 'build', host, DATEPICKER_AVAILABLESTYLES, projectName, extension);
124124
}
125125

126-
function addAnimationModule(project: WorkspaceProject, host: Tree, context: SchematicContext, componentName: string): Rule {
126+
function addAnimationModule(project: workspaces.ProjectDefinition, host: Tree, context: SchematicContext, componentName: string): Rule {
127127
if (!project || !(!componentName || components[componentName]?.animated)) {
128128
return;
129129
}

src/schematics/src/utils/addStyles.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
import {
2-
BrowserBuilderOptions,
3-
TestBuilderOptions,
4-
WorkspaceProject
5-
} from '@schematics/angular/utility/workspace-models';
61
import { Tree } from '@angular-devkit/schematics';
7-
import { JsonArray } from '@angular-devkit/core';
2+
import { JsonArray, JsonObject, workspaces } from '@angular-devkit/core';
83
import { getProjectStyleFile } from './getVersions';
9-
import { getProjectTargetName, getProjectTargetOptions } from './index';
4+
import { getProjectTargetOptions } from './index';
105
import path = require('path');
116

127
const DEFAULT_STYLE_EXTENSION = 'css';
@@ -15,7 +10,7 @@ interface availablePaths {
1510
'css': string[];
1611
'scss': string[];
1712
}
18-
export function addStyles(project: WorkspaceProject, targetName: string, host: Tree, availableAssetPaths: availablePaths, projectName: string, extension?: string): Tree {
13+
export function addStyles(project: workspaces.ProjectDefinition, targetName: string, host: Tree, availableAssetPaths: availablePaths, projectName: string, extension?: string): Tree {
1914
let targetOptions = getProjectTargetOptions(project, targetName);
2015
const styles = (targetOptions.styles as JsonArray | undefined);
2116
if (!styles || (styles instanceof Array && !styles.length)) {
@@ -43,14 +38,14 @@ export function addStyles(project: WorkspaceProject, targetName: string, host: T
4338
return host;
4439
}
4540

46-
function addStylesPathsToTargetOptions(targetOptions: BrowserBuilderOptions | TestBuilderOptions, existingStyles: string[], stylePatch: string): BrowserBuilderOptions | TestBuilderOptions {
41+
function addStylesPathsToTargetOptions(targetOptions: any, existingStyles: string[], stylePatch: string): Record<string, string | number | boolean | JsonArray | JsonObject> {
4742
if (!existingStyles.some(path => path === stylePatch)) {
48-
targetOptions.styles.unshift(stylePatch);
43+
targetOptions.styles?.unshift?.(stylePatch);
4944
}
5045
return targetOptions;
5146
}
5247

53-
function addEmptyStyles(targetOptions: BrowserBuilderOptions | TestBuilderOptions, extension: string, availableAssetPaths: availablePaths) {
48+
function addEmptyStyles(targetOptions: Record<string, string | number | boolean | JsonArray | JsonObject>, extension: string, availableAssetPaths: availablePaths) {
5449
targetOptions.styles = availableAssetPaths[DEFAULT_STYLE_EXTENSION];
5550
return targetOptions;
5651
}
@@ -66,10 +61,16 @@ function addImportToStylesFile(host: Tree, styleFilePath: string, styleFilePatch
6661
return host;
6762
}
6863

69-
function setUpdatedTargetOptions(host: Tree, project: WorkspaceProject, targetOptions: BrowserBuilderOptions | TestBuilderOptions, targetName: string, projectName: string): Tree {
64+
function setUpdatedTargetOptions(host: Tree, project: workspaces.ProjectDefinition, targetOptions: Record<string, string | number | boolean | JsonArray | JsonObject>, targetName: string, projectName: string): Tree {
7065
if (host.exists('angular.json')) {
7166
const currentAngular = JSON.parse(host.read('angular.json')!.toString('utf-8'));
72-
currentAngular['projects'][projectName][getProjectTargetName(project)][targetName]['options'] = targetOptions;
67+
if (currentAngular['projects'][projectName].targets) {
68+
currentAngular['projects'][projectName].targets[targetName]['options'] = targetOptions;
69+
}
70+
71+
if (currentAngular['projects'][projectName].architect) {
72+
currentAngular['projects'][projectName].architect[targetName]['options'] = targetOptions;
73+
}
7374
host.overwrite('angular.json', JSON.stringify(currentAngular, null, 2));
7475
}
7576
return host;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"NGX_BOOTSTRAP_VERSION": "7.0.0-rc.4",
3-
"BOOTSTRAP_VERSION": "^4.5.0"
3+
"BOOTSTRAP_VERSION": "^4.5.3"
44
}

src/schematics/src/utils/index.ts

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,43 +13,17 @@ import { getAppModulePath } from '@schematics/angular/utility/ng-ast-utils';
1313
import { getFileContent } from '@schematics/angular/utility/test';
1414
import * as ts from 'typescript';
1515
import { getProjectMainFile } from './project-main-file';
16-
import {
17-
BrowserBuilderOptions,
18-
TestBuilderOptions,
19-
WorkspaceProject,
20-
WorkspaceSchema
21-
} from '@schematics/angular/utility/workspace-models';
22-
import { getWorkspacePath } from '@nrwl/workspace';
23-
import { parse } from 'jsonc-parser';
24-
25-
const enum availableTargetNames {
26-
targets = 'targets',
27-
architect ='architect'
28-
}
16+
import { WorkspaceProject, WorkspaceSchema } from '@schematics/angular/utility/workspace-models';
17+
import { JsonArray, JsonObject, workspaces } from '@angular-devkit/core';
18+
2919

30-
export function getProjectTargetOptions(project: WorkspaceProject, buildTarget: string): BrowserBuilderOptions | TestBuilderOptions{
20+
export function getProjectTargetOptions(project: workspaces.ProjectDefinition, buildTarget: string): Record<string, string | number | boolean | JsonArray | JsonObject> {
3121
if (project?.targets?.get(buildTarget)?.options) {
3222
return project.targets.get(buildTarget).options;
3323
}
34-
35-
if (project?.architect?.[buildTarget]?.options) {
36-
return project.architect[buildTarget].options;
37-
}
38-
3924
throw new Error(`Cannot determine project target configuration for: ${buildTarget}.`);
4025
}
4126

42-
export function getProjectTargetName(project: WorkspaceProject): string {
43-
if (project?.targets) {
44-
return availableTargetNames.targets;
45-
}
46-
47-
if(project?.architect) {
48-
return availableTargetNames.architect;
49-
}
50-
throw new Error(`Cannot determine target name`);
51-
}
52-
5327
function sortObjectByKeys(obj: { [key: string]: string }) {
5428
return Object
5529
.keys(obj)
@@ -103,7 +77,7 @@ export function removePackageJsonDependency(tree: Tree, dependencyName: string)
10377
tree.overwrite('/package.json', JSON.stringify(packageContent, null, 2));
10478
}
10579

106-
export function addModuleImportToRootModule(host: Tree, moduleName: string, src: string, project: WorkspaceProject) {
80+
export function addModuleImportToRootModule(host: Tree, moduleName: string, src: string, project: workspaces.ProjectDefinition) {
10781
const modulePath = getAppModulePath(host, getProjectMainFile(project));
10882
const moduleSource = getSourceFile(host, modulePath);
10983
if (!moduleSource) {
@@ -146,14 +120,3 @@ export function getProjectFromWorkSpace(workspace: WorkspaceSchema, projectName?
146120
return project;
147121
}
148122

149-
export function getWorkspace (host: Tree) {
150-
const path = getWorkspacePath(host);
151-
const configBuffer = host.read(path);
152-
if (configBuffer === null) {
153-
throw new SchematicsException(`Could not find (${path})`);
154-
}
155-
156-
const content = configBuffer.toString();
157-
return parse(content);
158-
}
159-

src/schematics/src/utils/project-main-file.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99
import { SchematicsException } from '@angular-devkit/schematics';
1010
import { getProjectTargetOptions } from './project-targets';
11-
import { WorkspaceProject } from '@schematics/angular/utility/workspace-models';
11+
import { workspaces } from '@angular-devkit/core';
1212

1313
/** Looks for the main TypeScript file in the given project and returns its path. */
14-
export function getProjectMainFile(project: WorkspaceProject): string {
14+
export function getProjectMainFile(project: workspaces.ProjectDefinition): string {
1515
const buildOptions = getProjectTargetOptions(project, 'build');
1616
if (!buildOptions.main) {
1717
throw new SchematicsException(`Could not find the project main file inside of the ` +
1818
`workspace config (${project.sourceRoot})`);
1919
}
2020

21-
return buildOptions.main;
21+
return buildOptions.main.toString();
2222
}

src/schematics/src/utils/project-targets.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { WorkspaceProject } from '@schematics/angular/utility/workspace-models';
9+
import { workspaces } from '@angular-devkit/core';
1010

1111
/** Resolves the architect options for the build target of the given project. */
12-
export function getProjectTargetOptions(project: WorkspaceProject, buildTarget: string) {
13-
if (!project?.architect?.[buildTarget]?.options?.main) {
14-
throw new Error(`Cannot determine project target configuration for: ${buildTarget}.`);
12+
export function getProjectTargetOptions(project: workspaces.ProjectDefinition, buildTarget: string) {
13+
if (project?.targets?.get(buildTarget)?.options) {
14+
return project.targets.get(buildTarget).options;
1515
}
16-
return project.architect[buildTarget].options;
16+
17+
throw new Error(`Cannot determine project target configuration for: ${buildTarget}.`);
1718
}

0 commit comments

Comments
 (0)