Skip to content

refactor(schematics): detect package version from node modules #12535

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/lib/schematics/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package(default_visibility = ["//visibility:public"])

load("@build_bazel_rules_typescript//:defs.bzl", "ts_library")
load("@build_bazel_rules_nodejs//:defs.bzl", "npm_package", "jasmine_node_test")
load("//:packages.bzl", "VERSION_PLACEHOLDER_REPLACEMENTS")

filegroup(
name = "schematics_assets",
Expand All @@ -20,6 +21,7 @@ npm_package(
name = "npm_package",
srcs = [":schematics_assets"],
deps = [":schematics"],
replacements = VERSION_PLACEHOLDER_REPLACEMENTS,
)

### Testing rules
Expand Down
5 changes: 4 additions & 1 deletion src/lib/schematics/install/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {SchematicTestRunner} from '@angular-devkit/schematics/testing';
import {getProjectFromWorkspace} from '../utils/get-project';
import {getFileContent} from '@schematics/angular/utility/test';
import {collectionPath, createTestApp} from '../utils/testing';
import {getConfig, getAppFromConfig, getWorkspace} from '@schematics/angular/utility/config';
import {getWorkspace} from '@schematics/angular/utility/config';
import {getIndexHtmlPath} from '../utils/ast';
import {normalize} from '@angular-devkit/core';

Expand All @@ -19,9 +19,12 @@ describe('material-install-schematic', () => {
it('should update package.json', () => {
const tree = runner.runSchematic('ng-add', {}, appTree);
const packageJson = JSON.parse(getFileContent(tree, '/package.json'));
const angularCoreVersion = packageJson.dependencies['@angular/core'];

expect(packageJson.dependencies['@angular/material']).toBeDefined();
expect(packageJson.dependencies['@angular/cdk']).toBeDefined();
expect(packageJson.dependencies['@angular/animations']).toBe(angularCoreVersion,
'Expected the @angular/animations package to have the same version as @angular/core.');
});

it('should add default theme', () => {
Expand Down
20 changes: 14 additions & 6 deletions src/lib/schematics/install/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import {
Tree,
} from '@angular-devkit/schematics';
import {NodePackageInstallTask} from '@angular-devkit/schematics/tasks';
import {addModuleImportToRootModule, getStylesPath} from '../utils/ast';
import {InsertChange} from '@schematics/angular/utility/change';
import {getWorkspace} from '@schematics/angular/utility/config';
import {materialVersion, requiredAngularVersion} from './version-names';
import {addModuleImportToRootModule, getStylesPath} from '../utils/ast';
import {getProjectFromWorkspace} from '../utils/get-project';
import {addHeadLink} from '../utils/html';
import {angularVersion, materialVersion} from '../utils/lib-versions';
import {addPackageToPackageJson} from '../utils/package';
import {addPackageToPackageJson, getPackageVersionFromPackageJson} from '../utils/package';
import {Schema} from './schema';
import {addThemeToAppStyles} from './theming';
import * as parse5 from 'parse5';
Expand All @@ -30,7 +30,7 @@ import * as parse5 from 'parse5';
* Scaffolds the basics of a Angular Material application, this includes:
* - Add Packages to package.json
* - Adds pre-built themes to styles.ext
* - Adds Browser Animation to app.momdule
* - Adds Browser Animation to app.module
*/
export default function(options: Schema): Rule {
if (!parse5) {
Expand All @@ -47,13 +47,21 @@ export default function(options: Schema): Rule {
]);
}

/** Add material, cdk, annimations to package.json if not already present. */
/** Add material, cdk, animations to package.json if not already present. */
function addMaterialToPackageJson() {
return (host: Tree, context: SchematicContext) => {
// Version tag of the `@angular/core` dependency that has been loaded from the `package.json`
// of the CLI project. This tag should be preferred because all Angular dependencies should
// have the same version tag if possible.
const ngCoreVersionTag = getPackageVersionFromPackageJson(host, '@angular/core');

addPackageToPackageJson(host, 'dependencies', '@angular/cdk', materialVersion);
addPackageToPackageJson(host, 'dependencies', '@angular/material', materialVersion);
addPackageToPackageJson(host, 'dependencies', '@angular/animations', angularVersion);
addPackageToPackageJson(host, 'dependencies', '@angular/animations',
ngCoreVersionTag || requiredAngularVersion);

context.addTask(new NodePackageInstallTask());

return host;
};
}
Expand Down
24 changes: 24 additions & 0 deletions src/lib/schematics/install/version-names.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @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
*/

/** Name of the Material version that is shipped together with the schematics. */
export const materialVersion =
loadPackageVersionGracefully('@angular/cdk') ||
loadPackageVersionGracefully('@angular/material');

/** Angular version that is needed for the Material version that comes with the schematics. */
export const requiredAngularVersion = '0.0.0-NG';

/** Loads the full version from the given Angular package gracefully. */
function loadPackageVersionGracefully(packageName: string): string | null {
try {
return require(packageName).VERSION.full;
} catch {
return null;
}
}
10 changes: 0 additions & 10 deletions src/lib/schematics/utils/lib-versions.ts

This file was deleted.

24 changes: 19 additions & 5 deletions src/lib/schematics/utils/package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@

import {Tree} from '@angular-devkit/schematics';

/**
* Adds a package to the package.json
*/
export function addPackageToPackageJson(
host: Tree, type: string, pkg: string, version: string): Tree {
/** Adds a package to the package.json in the given host tree. */
export function addPackageToPackageJson(host: Tree, type: string, pkg: string,
version: string): Tree {

if (host.exists('package.json')) {
const sourceText = host.read('package.json')!.toString('utf-8');
const json = JSON.parse(sourceText);
Expand All @@ -29,3 +28,18 @@ export function addPackageToPackageJson(

return host;
}

/** Gets the version of the specified package by looking at the package.json in the given tree. */
export function getPackageVersionFromPackageJson(tree: Tree, name: string): string | null {
if (!tree.exists('package.json')) {
return null;
}

const packageJson = JSON.parse(tree.read('package.json')!.toString('utf8'));

if (packageJson.dependencies && packageJson.dependencies[name]) {
return packageJson.dependencies[name];
}

return null;
}
4 changes: 2 additions & 2 deletions tools/gulp/tasks/material-release.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ task('material:prepare-release', sequenceTask(
));

task('material:copy-schematics', () => {
src(schematicsGlobs).pipe(dest(join(releasePath, 'schematics')));
return src(schematicsGlobs).pipe(dest(join(releasePath, 'schematics')));
});

/** Copies all prebuilt themes into the release package under `prebuilt-themes/` */
task('material:copy-prebuilt-themes', () => {
src(prebuiltThemeGlob)
return src(prebuiltThemeGlob)
.pipe(gulpRename({dirname: ''}))
.pipe(dest(join(releasePath, 'prebuilt-themes')));
});
Expand Down