Skip to content
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

feat(elements): add schematics #23298

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions BUILD.bazel
Expand Up @@ -29,6 +29,8 @@ node_modules_filegroup(
"tsutils",
"typescript",
"zone.js",
"@angular-devkit/core",
"@angular-devkit/schematics",
"@types",
"@webcomponents/custom-elements",
],
Expand Down
1 change: 1 addition & 0 deletions karma-js.conf.js
Expand Up @@ -68,6 +68,7 @@ module.exports = function(config) {
'dist/all/@angular/compiler/test/aot/**',
'dist/all/@angular/compiler/test/render3/**',
'dist/all/@angular/core/test/bundling/**',
'dist/all/@angular/elements/schematics/**',
'dist/all/@angular/examples/**/e2e_test/*',
'dist/all/@angular/language-service/**',
'dist/all/@angular/router/test/**',
Expand Down
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -27,6 +27,8 @@
"commitmsg": "node ./scripts/git/commit-msg.js"
},
"dependencies": {
"@angular-devkit/schematics": "^0.5.5",
"@schematics/angular": "^0.5.4",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
"rxjs": "^6.0.0-terrific-rc.3",
Expand Down
3 changes: 2 additions & 1 deletion packages/elements/package.json
Expand Up @@ -27,5 +27,6 @@
"ng-update": {
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
},
"sideEffects": false
"sideEffects": false,
"schematics": "./schematics/collection.json"
}
58 changes: 58 additions & 0 deletions packages/elements/schematics/BUILD.bazel
@@ -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,
)
9 changes: 9 additions & 0 deletions packages/elements/schematics/collection.json
@@ -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"
}
}
}
76 changes: 76 additions & 0 deletions packages/elements/schematics/ng-add/index.ts
@@ -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());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi: I heard from Hans that there is now a shorthand way to add a package to a project by passing the package name into one of the options of NodePackageInstallTask. don't change this now, but you might want to refactor this in a followup PR.

(you will need a recent version of schemantics for this)

}

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;
};
}
58 changes: 58 additions & 0 deletions packages/elements/schematics/ng-add/index_spec.ts
@@ -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);
});
});
11 changes: 11 additions & 0 deletions packages/elements/schematics/ng-add/schema.d.ts
@@ -0,0 +1,11 @@
export interface Schema {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why put this into a "d.ts" file rather than ".ts" file?

/**
* Skip package.json install.
*/
skipPackageJson: boolean;

/**
* The project that needs the polyfill scripts
*/
project: name;
}
3 changes: 2 additions & 1 deletion packages/tsconfig.json
Expand Up @@ -31,7 +31,8 @@
"bazel",
"compiler-cli/integrationtest",
"platform-server/integrationtest",
"common/locales"
"common/locales",
"elements/schematics"
]

}
1 change: 1 addition & 0 deletions tools/tslint/rollupConfigRule.ts
Expand Up @@ -29,6 +29,7 @@ const sourceFilePathBlacklist = [
/[/\\]packages[/\\]bazel[/\\]/,
/[/\\]packages[/\\]benchpress[/\\]/,
/[/\\]packages[/\\]examples[/\\]/,
/[/\\]packages[/\\]elements[/\\]schematics[/\\]/,

// 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.
Expand Down
71 changes: 70 additions & 1 deletion yarn.lock
Expand Up @@ -2,10 +2,56 @@
# 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":
version "0.1.1"
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":
version "1.5.14-alpha"
resolved "https://registry.yarnpkg.com/@types/angularjs/-/angularjs-1.5.14-alpha.tgz#2add80c88e1d84ade07e042918843093b6ac9808"
Expand Down Expand Up @@ -177,6 +223,15 @@ ajv@^5.1.0:
json-schema-traverse "^0.3.0"
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:
version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
Expand Down Expand Up @@ -840,7 +895,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
strip-ansi "^3.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"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
dependencies:
Expand Down Expand Up @@ -2030,6 +2085,10 @@ fast-deep-equal@^1.0.0:
version "1.0.0"
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:
version "0.10.0"
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4"
Expand Down Expand Up @@ -5083,6 +5142,12 @@ rollup@0.47.4:
version "0.47.4"
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:
version "6.0.0-terrific-rc.3"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.0.0-terrific-rc.3.tgz#3acee937c1789ee4addf3cc3f7cc843d7cc2887c"
Expand Down Expand Up @@ -5928,6 +5993,10 @@ typescript@2.7.x:
version "2.7.2"
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:
version "3.3.9"
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"
Expand Down