diff --git a/.monorepo.json b/.monorepo.json index 81367b00b7..28126dcd52 100644 --- a/.monorepo.json +++ b/.monorepo.json @@ -161,11 +161,6 @@ "name": "Schematics Schematics", "section": "Schematics", "snapshotRepo": "angular/schematics-schematics-builds" - }, - "@schematics/update": { - "name": "Package Update Schematics", - "section": "Schematics", - "snapshotRepo": "angular/schematics-update-builds" } } } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 817aa82f54..c0f00ec99f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -225,7 +225,6 @@ The following is the list of supported scopes: * **@ngtools/webpack** * **@schematics/angular** * **@schematics/schematics** -* **@schematics/update** ### Subject diff --git a/README.md b/README.md index af0d07aa24..2ce41a4254 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,6 @@ This is a monorepo which contains many tools and packages: **Angular PWA Schematics** | [`@angular/pwa`](https://npmjs.com/package/@angular/pwa) | [![latest](https://img.shields.io/npm/v/%40angular%2Fpwa/latest.svg)](https://npmjs.com/package/@angular/pwa) | [![snapshot](https://img.shields.io/badge/snapshot--blue.svg)](https://github.com/angular/angular-pwa-builds) **Angular Schematics** | [`@schematics/angular`](https://npmjs.com/package/@schematics/angular) | [![latest](https://img.shields.io/npm/v/%40schematics%2Fangular/latest.svg)](https://npmjs.com/package/@schematics/angular) | [![snapshot](https://img.shields.io/badge/snapshot--blue.svg)](https://github.com/angular/schematics-angular-builds) **Schematics Schematics** | [`@schematics/schematics`](https://npmjs.com/package/@schematics/schematics) | [![latest](https://img.shields.io/npm/v/%40schematics%2Fschematics/latest.svg)](https://npmjs.com/package/@schematics/schematics) | [![snapshot](https://img.shields.io/badge/snapshot--blue.svg)](https://github.com/angular/schematics-schematics-builds) -**Package Update Schematics** | [`@schematics/update`](https://npmjs.com/package/@schematics/update) | [![latest](https://img.shields.io/npm/v/%40schematics%2Fupdate/latest.svg)](https://npmjs.com/package/@schematics/update) | [![snapshot](https://img.shields.io/badge/snapshot--blue.svg)](https://github.com/angular/schematics-update-builds) #### Misc diff --git a/packages/schematics/update/BUILD.bazel b/packages/schematics/update/BUILD.bazel deleted file mode 100644 index 5a5f3ba4b3..0000000000 --- a/packages/schematics/update/BUILD.bazel +++ /dev/null @@ -1,116 +0,0 @@ -# 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 - -load("@npm//@bazel/jasmine:index.bzl", "jasmine_node_test") -load("//tools:defaults.bzl", "ts_library") -load("//tools:ts_json_schema.bzl", "ts_json_schema") - -# @external_begin -load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar") -load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm") -# @external_end - -licenses(["notice"]) # MIT - -package(default_visibility = ["//visibility:public"]) - -ts_library( - name = "update", - srcs = glob( - include = ["**/*.ts"], - exclude = [ - "**/*_spec.ts", - "**/*_benchmark.ts", - # NB: we need to exclude the nested node_modules that is laid out by yarn workspaces - "node_modules/**", - ], - ) + [ - "//packages/schematics/update:update/schema.ts", - "//packages/schematics/update:migrate/schema.ts", - ], - deps = [ - "//packages/angular_devkit/core", - "//packages/angular_devkit/schematics", - "//packages/angular_devkit/schematics/tasks", - "@npm//@types/node", - "@npm//@types/npm-package-arg", - "@npm//@types/semver", - "@npm//npm-package-arg", - "@npm//semver", - ], -) - -ts_json_schema( - name = "update_schema", - src = "update/schema.json", -) - -ts_json_schema( - name = "migrate_schema", - src = "migrate/schema.json", -) - -ts_library( - name = "update_test_lib", - testonly = True, - srcs = glob( - include = ["**/*_spec.ts"], - exclude = [ - # NB: we need to exclude the nested node_modules that is laid out by yarn workspaces - "node_modules/**", - ], - ), - data = glob( - include = [ - "**/*.json", - ], - exclude = [ - # NB: we need to exclude the nested node_modules that is laid out by yarn workspaces - "node_modules/**", - ], - ), - # @external_begin - deps = [ - ":update", - "//packages/angular_devkit/core", - "//packages/angular_devkit/schematics", - "//packages/angular_devkit/schematics/testing", - "@npm//@types/semver", - "@npm//@yarnpkg/lockfile", - "@npm//ini", - "@npm//pacote", - "@npm//rxjs", - ], - # @external_end -) - -jasmine_node_test( - name = "update_test", - srcs = [":update_test_lib"], - # TODO: Audit tests to determine if tests can be run in RBE environments - local = True, - deps = [ - "@npm//jasmine", - "@npm//npm-registry-client", - "@npm//source-map", - ], -) - -# @external_begin -pkg_npm( - name = "npm_package", - deps = [ - ":update", - ], -) - -pkg_tar( - name = "npm_package_archive", - srcs = [":npm_package"], - extension = "tar.gz", - strip_prefix = "./npm_package", - tags = ["manual"], -) -# @external_end diff --git a/packages/schematics/update/migrate/index.ts b/packages/schematics/update/migrate/index.ts deleted file mode 100644 index 3f3529575d..0000000000 --- a/packages/schematics/update/migrate/index.ts +++ /dev/null @@ -1,109 +0,0 @@ -/** - * @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 { JsonObject } from '@angular-devkit/core'; -import { - Rule, - SchematicContext, - SchematicsException, - Tree, - chain, - externalSchematic, -} from '@angular-devkit/schematics'; -import * as semver from 'semver'; -import { Schema as PostUpdateSchema } from './schema'; - - -/** - * Cleans up "short" version numbers so they become valid semver. For example; - * 1 => 1.0.0 - * 1.2 => 1.2.0 - * 1-beta => 1.0.0-beta - * - * Exported for testing only. - */ -export function _coerceVersionNumber(version: string): string | null { - if (!version.match(/^\d{1,30}\.\d{1,30}\.\d{1,30}/)) { - const match = version.match(/^\d{1,30}(\.\d{1,30})*/); - - if (!match) { - return null; - } - - if (!match[1]) { - version = version.substr(0, match[0].length) + '.0.0' + version.substr(match[0].length); - } else if (!match[2]) { - version = version.substr(0, match[0].length) + '.0' + version.substr(match[0].length); - } else { - return null; - } - } - - return semver.valid(version); -} - - -export default function(options: PostUpdateSchema): Rule { - return (tree: Tree, context: SchematicContext) => { - const schematicsToRun: { name: string; version: string; }[] = []; - - const from = _coerceVersionNumber(options.from); - if (!from) { - throw new SchematicsException( - `Invalid from option: ${JSON.stringify(options.from)}`, - ); - } - - const to = semver.validRange('<=' + options.to); - if (!to) { - throw new SchematicsException( - `Invalid to option: ${JSON.stringify(options.to)}`, - ); - } - - // Create the collection for the package. - const collection = context.engine.createCollection(options.collection); - for (const name of collection.listSchematicNames()) { - const schematic = collection.createSchematic(name, true); - - const description: JsonObject = schematic.description as JsonObject; - let version = description['version']; - - if (typeof version == 'string') { - version = _coerceVersionNumber(version); - - if (!version) { - throw new SchematicsException( - `Invalid migration version: ${JSON.stringify(description['version'])}`, - ); - } - - if (semver.gt(version, from) && - semver.satisfies(version, to, { includePrerelease: true })) { - schematicsToRun.push({ name, version }); - } - } - } - - schematicsToRun.sort((a, b) => { - const cmp = semver.compare(a.version, b.version); - - // Revert to comparing the names of the collection if the versions are equal. - return cmp == 0 ? a.name.localeCompare(b.name) : cmp; - }); - - if (schematicsToRun.length > 0) { - context.logger.info(`** Executing migrations for package '${options.package}' **`); - - const rules = schematicsToRun.map(x => externalSchematic(options.collection, x.name, {})); - - return chain(rules); - } - - return tree; - }; -} diff --git a/packages/schematics/update/migrate/index_spec.ts b/packages/schematics/update/migrate/index_spec.ts deleted file mode 100644 index 8e2b197ca7..0000000000 --- a/packages/schematics/update/migrate/index_spec.ts +++ /dev/null @@ -1,155 +0,0 @@ -/** - * @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 { virtualFs } from '@angular-devkit/core'; -import { HostTree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { map } from 'rxjs/operators'; // tslint:disable-line: no-implicit-dependencies -import { _coerceVersionNumber } from './index'; - - -describe('@schematics/update:migrate', () => { - const schematicRunner = new SchematicTestRunner( - '@schematics/update', - require.resolve('../collection.json'), - ); - let host: virtualFs.test.TestHost; - let appTree: UnitTestTree = new UnitTestTree(new HostTree()); - - beforeEach(() => { - host = new virtualFs.test.TestHost({}); - appTree = new UnitTestTree(new HostTree(host)); - }); - - it('sorts and understand RC', done => { - // Since we cannot run tasks in unit tests, we need to validate that the default - // update schematic updates the package.json appropriately, AND validate that the - // migrate schematic actually do work appropriately, in a separate test. - schematicRunner.runSchematicAsync('migrate', { - package: 'test', - collection: require.resolve('./test/migration.json'), - from: '1.0.0', - to: '2.0.0', - }, appTree).pipe( - map(tree => { - const resultJson = JSON.parse(tree.readContent('/migrations')); - - expect(resultJson).toEqual([ - 'migration-03', // "1.0.5" - 'migration-05', // "1.1.0-beta.0" - 'migration-04', // "1.1.0-beta.1" - 'migration-02', // "1.1.0" - 'migration-13', // "1.1.0" - 'migration-19', // "1.1" - 'migration-06', // "1.4.0" - 'migration-17', // "2.0.0-alpha" - 'migration-16', // "2.0.0-alpha.5" - 'migration-08', // "2.0.0-beta.0" - 'migration-07', // "2.0.0-rc.0" - 'migration-12', // "2.0.0-rc.4" - 'migration-14', // "2.0.0" - 'migration-20', // "2" - ]); - }), - ).toPromise().then(done, done.fail); - }); - - it('supports partial version ranges with only major', done => { - // Since we cannot run tasks in unit tests, we need to validate that the default - // update schematic updates the package.json appropriately, AND validate that the - // migrate schematic actually do work appropriately, in a separate test. - schematicRunner.runSchematicAsync('migrate', { - package: 'test', - collection: require.resolve('./test/migration.json'), - from: '1', - to: '2', - }, appTree).pipe( - map(tree => { - const resultJson = JSON.parse(tree.readContent('/migrations')); - - expect(resultJson).toEqual([ - 'migration-03', // "1.0.5" - 'migration-05', // "1.1.0-beta.0" - 'migration-04', // "1.1.0-beta.1" - 'migration-02', // "1.1.0" - 'migration-13', // "1.1.0" - 'migration-19', // "1.1" - 'migration-06', // "1.4.0" - 'migration-17', // "2.0.0-alpha" - 'migration-16', // "2.0.0-alpha.5" - 'migration-08', // "2.0.0-beta.0" - 'migration-07', // "2.0.0-rc.0" - 'migration-12', // "2.0.0-rc.4" - 'migration-14', // "2.0.0" - 'migration-20', // "2" - 'migration-15', // "2.0.1" - 'migration-11', // "2.1.0" - ]); - }), - ).toPromise().then(done, done.fail); - }); - - it('supports partial version ranges with major and minor', done => { - // Since we cannot run tasks in unit tests, we need to validate that the default - // update schematic updates the package.json appropriately, AND validate that the - // migrate schematic actually do work appropriately, in a separate test. - schematicRunner.runSchematicAsync('migrate', { - package: 'test', - collection: require.resolve('./test/migration.json'), - from: '1.0', - to: '2.0', - }, appTree).pipe( - map(tree => { - const resultJson = JSON.parse(tree.readContent('/migrations')); - - expect(resultJson).toEqual([ - 'migration-03', // "1.0.5" - 'migration-05', // "1.1.0-beta.0" - 'migration-04', // "1.1.0-beta.1" - 'migration-02', // "1.1.0" - 'migration-13', // "1.1.0" - 'migration-19', // "1.1" - 'migration-06', // "1.4.0" - 'migration-17', // "2.0.0-alpha" - 'migration-16', // "2.0.0-alpha.5" - 'migration-08', // "2.0.0-beta.0" - 'migration-07', // "2.0.0-rc.0" - 'migration-12', // "2.0.0-rc.4" - 'migration-14', // "2.0.0" - 'migration-20', // "2" - 'migration-15', // "2.0.1" - ]); - }), - ).toPromise().then(done, done.fail); - }); -}); - - -describe('_coerceVersionNumber', () => { - const testCases: { [expected: string]: string | null } = { - '1': '1.0.0', - '1.2': '1.2.0', - '1.2.3': '1.2.3', - '1-beta.0': '1.0.0-beta.0', - '1.2-beta.0': '1.2.0-beta.0', - '1.2.3-beta.0': '1.2.3-beta.0', - 'a': null, - '1.a': null, - '1a': null, - '1.': null, - '1.-beta.0': null, - }; - - Object.keys(testCases).forEach(input => { - const expected = testCases[input]; - it(`${JSON.stringify(input)} => ${JSON.stringify(expected)}`, () => { - const actual = _coerceVersionNumber(input); - - expect(actual).toBe(expected); - }); - }); -}); diff --git a/packages/schematics/update/migrate/schema.json b/packages/schematics/update/migrate/schema.json deleted file mode 100644 index 58fca362d0..0000000000 --- a/packages/schematics/update/migrate/schema.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "id": "PostUpdateSchema", - "type": "object", - "properties": { - "package": { - "description": "The package to migrate.", - "type": "string" - }, - "collection": { - "description": "The collection to load the migrations from.", - "type": "string" - }, - "from": { - "description": "The version installed previously.", - "type": "string" - }, - "to": { - "description": "The version to migrate to.", - "type": "string" - } - }, - "required": ["package", "collection", "from", "to"] -} diff --git a/packages/schematics/update/migrate/test/migration.json b/packages/schematics/update/migrate/test/migration.json deleted file mode 100644 index 22e886c078..0000000000 --- a/packages/schematics/update/migrate/test/migration.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "schematics": { - "migration-00": { "version": "0.1.0", "factory": "./t1", "description": "." }, - "migration-01": { "version": "1.0.0", "factory": "./t1", "description": "." }, - "migration-02": { "version": "1.1.0", "factory": "./t1", "description": "." }, - "migration-03": { "version": "1.0.5", "factory": "./t1", "description": "." }, - "migration-04": { "version": "1.1.0-beta.1", "factory": "./t1", "description": "." }, - "migration-05": { "version": "1.1.0-beta.0", "factory": "./t1", "description": "." }, - "migration-06": { "version": "1.4.0", "factory": "./t1", "description": "." }, - "migration-07": { "version": "2.0.0-rc.0", "factory": "./t1", "description": "." }, - "migration-08": { "version": "2.0.0-beta.0", "factory": "./t1", "description": "." }, - "migration-09": { "version": "4.0.0", "factory": "./t1", "description": "." }, - "migration-10": { "version": "0.1.0", "factory": "./t1", "description": "." }, - "migration-11": { "version": "2.1.0", "factory": "./t1", "description": "." }, - "migration-12": { "version": "2.0.0-rc.4", "factory": "./t1", "description": "." }, - "migration-13": { "version": "1.1.0", "factory": "./t1", "description": "." }, - "migration-14": { "version": "2.0.0", "factory": "./t1", "description": "." }, - "migration-15": { "version": "2.0.1", "factory": "./t1", "description": "." }, - "migration-16": { "version": "2.0.0-alpha.5", "factory": "./t1", "description": "." }, - "migration-17": { "version": "2.0.0-alpha", "factory": "./t1", "description": "." }, - "migration-18": { "version": "1", "factory": "./t1", "description": "." }, - "migration-19": { "version": "1.1", "factory": "./t1", "description": "." }, - "migration-20": { "version": "2", "factory": "./t1", "description": "." } - } -} \ No newline at end of file diff --git a/packages/schematics/update/migrate/test/t1.ts b/packages/schematics/update/migrate/test/t1.ts deleted file mode 100644 index 9122c812c2..0000000000 --- a/packages/schematics/update/migrate/test/t1.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * @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, SchematicsException } from '@angular-devkit/schematics'; - -export default function(): Rule { - return (tree, context) => { - let content = tree.read('/migrations'); - - // Append the information to migration file. We then verify the order of execution. - if (!content) { - tree.create('/migrations', '[]'); - content = tree.read('/migrations'); - - if (!content) { - throw new SchematicsException(); - } - } - - const json = JSON.parse(content.toString('utf-8')); - json.push(context.schematic.description.name); - - tree.overwrite('/migrations', JSON.stringify(json)); - - return tree; - }; -} diff --git a/packages/schematics/update/package.json b/packages/schematics/update/package.json deleted file mode 100644 index 7c02a5910f..0000000000 --- a/packages/schematics/update/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@schematics/update", - "version": "0.0.0", - "description": "Schematics specific to updating packages", - "experimental": true, - "keywords": [ - "blueprints", - "code generation", - "schematics", - "schematic" - ], - "schematics": "./collection.json", - "dependencies": { - "@angular-devkit/core": "0.0.0", - "@angular-devkit/schematics": "0.0.0", - "@yarnpkg/lockfile": "1.1.0", - "ini": "2.0.0", - "npm-package-arg": "^8.0.0", - "pacote": "11.3.1", - "semver": "7.3.5", - "semver-intersect": "1.4.0" - } -}