feat(elements): add schematics (#23298)

PR Close #23298
This commit is contained in:
Andrew Seguin 2018-04-03 14:52:33 -07:00 committed by Igor Minar
parent ce40e85cbb
commit 37d2cb4553
12 changed files with 292 additions and 3 deletions

View File

@ -29,6 +29,8 @@ node_modules_filegroup(
"tsutils", "tsutils",
"typescript", "typescript",
"zone.js", "zone.js",
"@angular-devkit/core",
"@angular-devkit/schematics",
"@types", "@types",
"@webcomponents/custom-elements", "@webcomponents/custom-elements",
], ],

View File

@ -68,6 +68,7 @@ module.exports = function(config) {
'dist/all/@angular/compiler/test/aot/**', 'dist/all/@angular/compiler/test/aot/**',
'dist/all/@angular/compiler/test/render3/**', 'dist/all/@angular/compiler/test/render3/**',
'dist/all/@angular/core/test/bundling/**', 'dist/all/@angular/core/test/bundling/**',
'dist/all/@angular/elements/schematics/**',
'dist/all/@angular/examples/**/e2e_test/*', 'dist/all/@angular/examples/**/e2e_test/*',
'dist/all/@angular/language-service/**', 'dist/all/@angular/language-service/**',
'dist/all/@angular/router/test/**', 'dist/all/@angular/router/test/**',

View File

@ -27,6 +27,8 @@
"commitmsg": "node ./scripts/git/commit-msg.js" "commitmsg": "node ./scripts/git/commit-msg.js"
}, },
"dependencies": { "dependencies": {
"@angular-devkit/schematics": "^0.5.5",
"@schematics/angular": "^0.5.4",
"core-js": "^2.4.1", "core-js": "^2.4.1",
"reflect-metadata": "^0.1.3", "reflect-metadata": "^0.1.3",
"rxjs": "^6.0.0-terrific-rc.3", "rxjs": "^6.0.0-terrific-rc.3",

View File

@ -27,5 +27,6 @@
"ng-update": { "ng-update": {
"packageGroup": "NG_UPDATE_PACKAGE_GROUP" "packageGroup": "NG_UPDATE_PACKAGE_GROUP"
}, },
"sideEffects": false "sideEffects": false,
"schematics": "./schematics/collection.json"
} }

View File

@ -0,0 +1,58 @@
package(default_visibility = ["//visibility:public"])
load("//tools:defaults.bzl", "ts_library")
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
exports_files([
"package.json",
"collection.json",
])
ts_library(
name = "schematics",
srcs = glob(
[
"ng-add/index.ts",
"ng-add/schema.d.ts",
],
),
module_name = "@angular/elements/schematics",
deps = [
"//packages/common",
"//packages/core",
"@rxjs",
],
)
ts_library(
name = "test_lib",
testonly = 1,
srcs = glob(
[
"ng-add/index_spec.ts",
],
),
deps = [
":schematics",
"//packages/common",
"//packages/core",
"@rxjs",
"@rxjs//operators",
],
)
jasmine_node_test(
name = "test",
data = [":collection"],
deps = [
":test_lib",
],
)
genrule(
name = "collection",
srcs = ["collection.json"],
outs = ["test-collection.json"],
cmd = "cp $< $@",
output_to_bindir = 1,
)

View File

@ -0,0 +1,9 @@
{
"$schema": "../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"ng-add": {
"description": "Adds the document-register-element polyfill.",
"factory": "./ng-add"
}
}
}

View File

@ -0,0 +1,76 @@
/**
* @license
* Copyright Google Inc. 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 {Rule, SchematicContext, Tree, chain, noop} from '@angular-devkit/schematics';
import {NodePackageInstallTask} from '@angular-devkit/schematics/tasks';
import {Schema} from './schema';
export default function(options: Schema): Rule {
return chain([
options && options.skipPackageJson ? noop() : addPackageJsonDependency(), addScript(options)
]);
}
/** Adds a package.json dependency for document-register-element */
function addPackageJsonDependency() {
return (host: Tree, context: SchematicContext) => {
if (host.exists('package.json')) {
const jsonStr = host.read('package.json') !.toString('utf-8');
const json = JSON.parse(jsonStr);
// If there are no dependencies, create an entry for dependencies.
const type = 'dependencies';
if (!json[type]) {
json[type] = {};
}
// If not already present, add the dependency.
const pkg = 'document-register-element';
const version = '^1.7.2';
if (!json[type][pkg]) {
json[type][pkg] = version;
}
// Write the JSON back to package.json
host.overwrite('package.json', JSON.stringify(json, null, 2));
context.logger.log('info', 'Added `document-register-element` as a dependency.');
// Install the dependency
context.addTask(new NodePackageInstallTask());
}
return host;
};
}
/** Adds the document-register-element.js script to the angular CLI json. */
function addScript(options: Schema) {
return (host: Tree, context: SchematicContext) => {
const script = 'node_modules/document-register-element/build/document-register-element.js';
try {
// Handle the new json - angular.json
const angularJsonFile = host.read('angular.json');
if (angularJsonFile) {
const json = JSON.parse(angularJsonFile.toString('utf-8'));
const project = Object.keys(json['projects'])[0] || options.project;
const scripts = json['projects'][project]['architect']['build']['options']['scripts'];
scripts.push({input: script});
host.overwrite('angular.json', JSON.stringify(json, null, 2));
}
} catch (e) {
context.logger.log(
'warn', 'Failed to add the polyfill document-register-element.js to scripts');
}
context.logger.log('info', 'Added document-register-element.js polyfill to scripts');
return host;
};
}

View File

@ -0,0 +1,58 @@
/**
* @license
* Copyright Google Inc. 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 {SchematicTestRunner, UnitTestTree} from '@angular-devkit/schematics/testing';
import * as path from 'path';
import {Observable} from 'rxjs';
import {concatMap} from 'rxjs/operators';
import {Schema as ElementsOptions} from './schema';
const polyfillPath = 'node_modules/document-register-element/build/document-register-element.js';
// tslint:disable:max-line-length
describe('Elements Schematics', () => {
const schematicRunner = new SchematicTestRunner(
'@angular/elements', path.join(__dirname, '../test-collection.json'), );
const defaultOptions: ElementsOptions = {project: 'bar', skipPackageJson: false};
let appTree: UnitTestTree;
// tslint:disable-next-line:no-any
const workspaceOptions: any = {
name: 'workspace',
newProjectRoot: 'projects',
version: '6.0.0',
};
// tslint:disable-next-line:no-any
const appOptions: any = {
name: 'elements',
inlineStyle: false,
inlineTemplate: false,
routing: false,
style: 'css',
skipTests: false,
};
beforeEach((done) => {
schematicRunner.runExternalSchematicAsync('@schematics/angular', 'workspace', workspaceOptions)
.pipe(concatMap(
(tree) => schematicRunner.runExternalSchematicAsync(
'@schematics/angular', 'application', appOptions, tree)))
.subscribe((tree: UnitTestTree) => appTree = tree, done.fail, done);
});
it('should run the ng-add schematic', () => {
const tree = schematicRunner.runSchematic('ng-add', defaultOptions, appTree);
const configText = tree.readContent('/angular.json');
const config = JSON.parse(configText);
const scripts = config.projects.elements.architect.build.options.scripts;
expect(scripts[0].input).toEqual(polyfillPath);
});
});

View File

@ -0,0 +1,11 @@
export interface Schema {
/**
* Skip package.json install.
*/
skipPackageJson: boolean;
/**
* The project that needs the polyfill scripts
*/
project: name;
}

View File

@ -31,7 +31,8 @@
"bazel", "bazel",
"compiler-cli/integrationtest", "compiler-cli/integrationtest",
"platform-server/integrationtest", "platform-server/integrationtest",
"common/locales" "common/locales",
"elements/schematics"
] ]
} }

View File

@ -29,6 +29,7 @@ const sourceFilePathBlacklist = [
/[/\\]packages[/\\]bazel[/\\]/, /[/\\]packages[/\\]bazel[/\\]/,
/[/\\]packages[/\\]benchpress[/\\]/, /[/\\]packages[/\\]benchpress[/\\]/,
/[/\\]packages[/\\]examples[/\\]/, /[/\\]packages[/\\]examples[/\\]/,
/[/\\]packages[/\\]elements[/\\]schematics[/\\]/,
// language-service bundles everything in its UMD, so we don't need a globals. There are // language-service bundles everything in its UMD, so we don't need a globals. There are
// exceptions but we simply ignore those files from this rule. // exceptions but we simply ignore those files from this rule.

View File

@ -2,10 +2,56 @@
# yarn lockfile v1 # yarn lockfile v1
"@angular-devkit/core@0.5.4":
version "0.5.4"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-0.5.4.tgz#94b7462f5039cf811c7e06db0c87bb2299d61c71"
dependencies:
ajv "~5.5.1"
chokidar "^1.7.0"
rxjs "^6.0.0-beta.3"
source-map "^0.5.6"
"@angular-devkit/core@0.5.5":
version "0.5.5"
resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-0.5.5.tgz#659c9ef3f22c3e99c459e325441b1009412a4af6"
dependencies:
ajv "~5.5.1"
chokidar "^1.7.0"
rxjs "^6.0.0-beta.3"
source-map "^0.5.6"
"@angular-devkit/schematics@0.5.4":
version "0.5.4"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.5.4.tgz#6a4b0abb30091fa1a5d0751737f9ed036ac8704f"
dependencies:
"@angular-devkit/core" "0.5.4"
"@ngtools/json-schema" "^1.1.0"
rxjs "^6.0.0-beta.3"
"@angular-devkit/schematics@^0.5.5":
version "0.5.5"
resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-0.5.5.tgz#c0b20980993237f2eeb4182e253c7c9efa299f3b"
dependencies:
"@angular-devkit/core" "0.5.5"
"@ngtools/json-schema" "^1.1.0"
rxjs "^6.0.0-beta.3"
"@bazel/ibazel@^0.1.1": "@bazel/ibazel@^0.1.1":
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/@bazel/ibazel/-/ibazel-0.1.1.tgz#f970c08b4e4efb0ab17e04ade3cc610554f33bed" resolved "https://registry.yarnpkg.com/@bazel/ibazel/-/ibazel-0.1.1.tgz#f970c08b4e4efb0ab17e04ade3cc610554f33bed"
"@ngtools/json-schema@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@ngtools/json-schema/-/json-schema-1.1.0.tgz#c3a0c544d62392acc2813a42c8a0dc6f58f86922"
"@schematics/angular@^0.5.4":
version "0.5.4"
resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-0.5.4.tgz#1c87706703a985fd291d283a4db1a9fc0aa6238f"
dependencies:
"@angular-devkit/core" "0.5.4"
"@angular-devkit/schematics" "0.5.4"
typescript "~2.6.2"
"@types/angularjs@1.5.14-alpha": "@types/angularjs@1.5.14-alpha":
version "1.5.14-alpha" version "1.5.14-alpha"
resolved "https://registry.yarnpkg.com/@types/angularjs/-/angularjs-1.5.14-alpha.tgz#2add80c88e1d84ade07e042918843093b6ac9808" resolved "https://registry.yarnpkg.com/@types/angularjs/-/angularjs-1.5.14-alpha.tgz#2add80c88e1d84ade07e042918843093b6ac9808"
@ -177,6 +223,15 @@ ajv@^5.1.0:
json-schema-traverse "^0.3.0" json-schema-traverse "^0.3.0"
json-stable-stringify "^1.0.1" json-stable-stringify "^1.0.1"
ajv@~5.5.1:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
align-text@^0.1.1, align-text@^0.1.3: align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
@ -840,7 +895,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.0.0" strip-ansi "^3.0.0"
supports-color "^2.0.0" supports-color "^2.0.0"
chokidar@1.7.0, chokidar@^1.0.0, chokidar@^1.4.1: chokidar@1.7.0, chokidar@^1.0.0, chokidar@^1.4.1, chokidar@^1.7.0:
version "1.7.0" version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies: dependencies:
@ -2030,6 +2085,10 @@ fast-deep-equal@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
faye-websocket@~0.10.0: faye-websocket@~0.10.0:
version "0.10.0" version "0.10.0"
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
@ -5083,6 +5142,12 @@ rollup@0.47.4:
version "0.47.4" version "0.47.4"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.47.4.tgz#e3a55de83a78221d232ce29619a8d68189ae845e" resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.47.4.tgz#e3a55de83a78221d232ce29619a8d68189ae845e"
rxjs@^6.0.0-beta.3:
version "6.0.0-tactical-rc.1"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.0.0-tactical-rc.1.tgz#1fe1f1204132d1c71c72f249a487f8e76a5ec1d5"
dependencies:
tslib "^1.9.0"
rxjs@^6.0.0-terrific-rc.3: rxjs@^6.0.0-terrific-rc.3:
version "6.0.0-terrific-rc.3" version "6.0.0-terrific-rc.3"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.0.0-terrific-rc.3.tgz#3acee937c1789ee4addf3cc3f7cc843d7cc2887c" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.0.0-terrific-rc.3.tgz#3acee937c1789ee4addf3cc3f7cc843d7cc2887c"
@ -5928,6 +5993,10 @@ typescript@2.7.x:
version "2.7.2" version "2.7.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836" resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836"
typescript@~2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.6.2.tgz#3c5b6fd7f6de0914269027f03c0946758f7673a4"
uglify-es@^3.3.9: uglify-es@^3.3.9:
version "3.3.9" version "3.3.9"
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"