feat(core): update the migrate command to support @nrwl/devkit generators

This commit is contained in:
victor savkin 2020-11-26 13:50:05 -05:00 committed by Victor Savkin
parent 234ca36385
commit 48bcaf099d
25 changed files with 300 additions and 328 deletions

View File

@ -64,16 +64,6 @@ Type: `string`
The name of the project.
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Test runner to use for unit tests
### version
Alias(es): v

View File

@ -64,16 +64,6 @@ Type: `string`
The name of the project.
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Test runner to use for unit tests
### version
Alias(es): v

View File

@ -64,16 +64,6 @@ Type: `string`
The name of the project.
### unitTestRunner
Default: `jest`
Type: `string`
Possible values: `jest`, `none`
Test runner to use for unit tests
### version
Alias(es): v

View File

@ -134,7 +134,7 @@ describe('migrate', () => {
run20: {
version: '2.0.0',
description: '2.0.0',
factory: './run20',
implementation: './run20',
},
},
})
@ -154,10 +154,8 @@ describe('migrate', () => {
updateFile(
`./node_modules/migrate-parent-package/run20.js`,
`
exports.default = function default_1() {
return function(host) {
host.create('file-20', 'content20')
}
exports.default = function (host) {
host.write('file-20', 'content20')
}
`
);
@ -183,12 +181,13 @@ describe('migrate', () => {
if (packageName === 'migrate-parent-package') {
return Promise.resolve({
version: '2.0.0',
schematics: {
generators: {
'run11': {
version: '1.1.0'
},
'run20': {
version: '2.0.0'
version: '2.0.0',
cli: 'nx'
}
},
packageJsonUpdates: {
@ -228,6 +227,7 @@ describe('migrate', () => {
package: 'migrate-parent-package',
version: '2.0.0',
name: 'run20',
cli: 'nx',
},
],
});

View File

@ -91,17 +91,16 @@ describe('Nx Plugin', () => {
checkFilesExist(
`dist/libs/${plugin}/src/migrations/update-${version}/update-${version}.js`,
`dist/libs/${plugin}/src/migrations/update-${version}/update-${version}.ts`,
`dist/libs/${plugin}/src/migrations/update-${version}/update-${version}.spec.ts`,
`libs/${plugin}/src/migrations/update-${version}/update-${version}.ts`,
`libs/${plugin}/src/migrations/update-${version}/update-${version}.spec.ts`
`libs/${plugin}/src/migrations/update-${version}/update-${version}.ts`
);
const migrationsJson = readJson(`libs/${plugin}/migrations.json`);
expect(migrationsJson).toMatchObject({
schematics: expect.objectContaining({
generators: expect.objectContaining({
[`update-${version}`]: {
version: version,
description: `update-${version}`,
factory: `./src/migrations/update-${version}/update-${version}`,
cli: `nx`,
implementation: `./src/migrations/update-${version}/update-${version}`,
},
}),
});

View File

@ -107,7 +107,6 @@ export function runNgNew(): string {
* for the currently selected CLI.
*/
export function newProject(): void {
projName = uniq('proj');
try {
if (!directoryExists(tmpBackupProjPath())) {
runCreateWorkspace('proj', { preset: 'empty' });
@ -129,8 +128,10 @@ export function newProject(): void {
.forEach((p) => {
runCLI(`g ${p}:init`, { cwd: `./tmp/${currentCli()}/proj` });
});
execSync(`mv ./tmp/${currentCli()}/proj ${tmpBackupProjPath()}`);
}
projName = uniq('proj');
execSync(`cp -a ${tmpBackupProjPath()} ${tmpProjPath()}`);
} catch (e) {
console.log(`Failed to set up project for e2e tests.`);

View File

@ -1,6 +1,6 @@
{
"name": "@nrwl/nx-source",
"version": "11.0.0-beta.4",
"version": "999.9.11",
"description": "Extensible Dev Tools for Monorepos",
"homepage": "https://nx.dev",
"main": "index.js",

View File

@ -10,6 +10,7 @@ export {
} from '@nrwl/tao/src/shared/nx';
export { TargetContext } from '@nrwl/tao/src/commands/run';
export { formatFiles } from './src/schematics/format-files';
export { readJson } from './src/utils/read-json';
export { generateFiles } from './src/schematics/generate-files';
export { installPackagesTask } from './src/tasks/install-packages-task';
export { addProjectConfiguration } from './src/schematics/add-project-configuration';

View File

@ -4,6 +4,11 @@
"version": "10.2.0",
"description": "Remove deprecated jest builder options",
"factory": "./src/migrations/update-10-2-0/update-10-2-0"
},
"update-11.0.0": {
"version": "11.0.0-beta.4",
"description": "Rename ng-update into nx-migrate",
"factory": "./src/migrations/update-11-0-0/rename-ng-update-into-nx-migrate"
}
}
}

View File

@ -0,0 +1,10 @@
import { Tree, readJson } from '@nrwl/devkit';
export default function update(host: Tree) {
const p = readJson(host, 'package.json');
if (p['ng-update']) {
p['ng-migrate'] = p['ng-update'];
delete p['ng-update'];
}
host.write('package.json', JSON.stringify(p, null, 2));
}

View File

@ -1,35 +0,0 @@
import { Tree } from '@angular-devkit/schematics';
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
import { readJsonInTree, serializeJson } from '@nrwl/workspace';
import { createEmptyWorkspace } from '@nrwl/workspace/testing';
import * as path from 'path';
describe('<%= name %>', () => {
let initialTree: Tree;
let schematicRunner: SchematicTestRunner;
beforeEach(async () => {
initialTree = createEmptyWorkspace(Tree.empty());
schematicRunner = new SchematicTestRunner(
'@nrwl/nx-plugin',
path.join(__dirname, '../../../migrations.json')
);
initialTree.overwrite(
'package.json',
serializeJson({
dependencies: {}
})
);
});
it(`should update dependencies`, async () => {
const result = await schematicRunner
.runSchematicAsync('<%= name %>', {}, initialTree)
.toPromise();
const { dependencies } = readJsonInTree(result, '/package.json');
expect(dependencies).toEqual({});
});
});

View File

@ -1,12 +1,6 @@
import { chain, Rule } from '@angular-devkit/schematics';<% if (packageJsonUpdates) { %>
import { updatePackagesInPackageJson } from '@nrwl/workspace';
import * as path from 'path';<% } %>
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Tree } from '@nrwl/devkit';
export default function update(): Rule {
return chain([<% if (packageJsonUpdates) { %>
updatePackagesInPackageJson(
path.join(__dirname, '../../../', 'migrations.json'),
'<%= version %>'
)
<% } %>]);
export default function update(host: Tree) {
// ...
}

View File

@ -17,9 +17,6 @@ export function addFiles(options: NormalizedSchema): Rule {
...options,
tmpl: '',
}),
options.unitTestRunner === 'none'
? filter((file) => !file.endsWith('.spec.ts'))
: noop(),
move(`${options.projectSourceRoot}/migrations`),
])
);

View File

@ -7,13 +7,19 @@ export function updateMigrationsJson(options: NormalizedSchema): Rule {
return updateJsonInTree(
path.join(options.projectRoot, 'migrations.json'),
(json) => {
const schematics = json.schematics ? json.schematics : {};
schematics[options.name] = {
if (json.schematics) {
json.generators = json.schematics;
delete json.schematics;
}
const generators = json.generators ? json.generators : {};
generators[options.name] = {
version: options.version,
description: options.description,
factory: `./src/migrations/${options.name}/${options.name}`,
cli: 'nx',
implementation: `./src/migrations/${options.name}/${options.name}`,
};
json.schematics = schematics;
json.generators = generators;
if (options.packageJsonUpdates) {
const packageJsonUpdatesObj = json.packageJsonUpdates

View File

@ -7,11 +7,11 @@ export function updatePackageJson(options: NormalizedSchema): Rule {
return updateJsonInTree(
path.join(options.projectRoot, 'package.json'),
(json) => {
if (!json['ng-update'] || !json['ng-update'].migrations) {
if (json['ng-update']) {
json['ng-update'].migrations = './migrations.json';
if (!json['nx-migrate'] || !json['nx-migrate'].migrations) {
if (json['nx-migrate']) {
json['nx-migrate'].migrations = './migrations.json';
} else {
json['ng-update'] = {
json['nx-migrate'] = {
migrations: './migrations.json',
};
}

View File

@ -58,22 +58,17 @@ describe('NxPlugin migration', () => {
expect(
tree.exists('libs/my-plugin/src/migrations/my-migration/my-migration.ts')
).toBeTruthy();
expect(
tree.exists(
'libs/my-plugin/src/migrations/my-migration/my-migration.spec.ts'
)
).toBeTruthy();
expect(migrationsJson.schematics['my-migration'].version).toEqual('1.0.0');
expect(migrationsJson.schematics['my-migration'].description).toEqual(
expect(migrationsJson.generators['my-migration'].version).toEqual('1.0.0');
expect(migrationsJson.generators['my-migration'].description).toEqual(
'my-migration description'
);
expect(migrationsJson.schematics['my-migration'].factory).toEqual(
expect(migrationsJson.generators['my-migration'].implementation).toEqual(
'./src/migrations/my-migration/my-migration'
);
expect(migrationsJson.packageJsonUpdates).toBeFalsy();
expect(packageJson['ng-update'].migrations).toEqual('./migrations.json');
expect(packageJson['nx-migrate'].migrations).toEqual('./migrations.json');
});
it('should generate files with default name', async () => {
@ -96,7 +91,7 @@ describe('NxPlugin migration', () => {
tree.exists('libs/my-plugin/src/migrations/update-1.0.0/update-1.0.0.ts')
).toBeTruthy();
expect(migrationsJson.schematics['update-1.0.0'].factory).toEqual(
expect(migrationsJson.generators['update-1.0.0'].implementation).toEqual(
'./src/migrations/update-1.0.0/update-1.0.0'
);
});
@ -117,7 +112,7 @@ describe('NxPlugin migration', () => {
'libs/my-plugin/migrations.json'
);
expect(migrationsJson.schematics['my-migration'].description).toEqual(
expect(migrationsJson.generators['my-migration'].description).toEqual(
'my-migration'
);
});
@ -146,32 +141,4 @@ describe('NxPlugin migration', () => {
},
});
});
describe('--unitTestRunner', () => {
describe('none', () => {
it('should not generate test files', async () => {
const tree = await runSchematic(
'migration',
{
project: projectName,
name: 'my-migration',
version: '1.0.0',
unitTestRunner: 'none',
},
appTree
);
expect(
tree.exists(
'libs/my-plugin/src/migrations/my-migration/my-migration.ts'
)
).toBeTruthy();
expect(
tree.exists(
'libs/my-plugin/src/migrations/my-migration/my-migration.spec.ts'
)
).toBeFalsy();
});
});
});
});

View File

@ -4,7 +4,6 @@ export interface Schema {
description: string;
version: string;
packageJsonUpdates: boolean;
unitTestRunner: 'jest' | 'none';
}
export interface NormalizedSchema extends Schema {

View File

@ -43,12 +43,6 @@
"description": "Whether or not to include package.json updates",
"alias": "p",
"default": false
},
"unitTestRunner": {
"type": "string",
"enum": ["jest", "none"],
"description": "Test runner to use for unit tests",
"default": "jest"
}
},
"required": ["project", "version"]

View File

@ -38,6 +38,7 @@
"semver": "6.3.0",
"tmp": "0.0.33",
"tslib": "^2.0.0",
"yargs-parser": "20.0.0"
"yargs-parser": "20.0.0",
"fs-extra": "7.0.1"
}
}

View File

@ -388,30 +388,30 @@ describe('Migration', () => {
},
},
},
schematics: {
generators: {
version2: {
version: '2.0.0',
factory: 'parent-factory',
description: 'parent-desc',
},
},
});
} else if (p === 'child') {
return Promise.resolve({
version: '2.0.0',
schematics: {
generators: {
version2: {
version: '2.0.0',
factory: 'child-factory',
description: 'child-desc',
},
},
});
} else if (p === 'newChild') {
return Promise.resolve({
version: '3.0.0',
schematics: {
generators: {
version2: {
version: '2.0.0',
factory: 'new-child-factory',
description: 'new-child-desc',
},
},
});
@ -425,16 +425,16 @@ describe('Migration', () => {
expect(await migrator.updatePackageJson('parent', '2.0.0')).toEqual({
migrations: [
{
package: 'parent',
version: '2.0.0',
name: 'version2',
factory: 'parent-factory',
package: 'parent',
description: 'parent-desc',
},
{
package: 'child',
version: '2.0.0',
name: 'version2',
factory: 'child-factory',
description: 'child-desc',
},
],
packageJson: {

View File

@ -1,14 +1,9 @@
import { logging, normalize, virtualFs } from '@angular-devkit/core';
import { NodeJsSyncHost } from '@angular-devkit/core/node';
import { TaskExecutor } from '@angular-devkit/schematics';
import { BaseWorkflow } from '@angular-devkit/schematics/src/workflow';
import { BuiltinTaskExecutor } from '@angular-devkit/schematics/tasks/node';
import { NodePackageName } from '@angular-devkit/schematics/tasks/package-manager/options';
import { NodeModulesEngineHost } from '@angular-devkit/schematics/tools';
import { logging } from '@angular-devkit/core';
import { execSync } from 'child_process';
import * as fs from 'fs';
import { readFileSync, writeFileSync } from 'fs';
import * as minimist from 'minimist';
import { dirname, extname, join, resolve } from 'path';
import { dirname, join } from 'path';
import { gt, lte } from 'semver';
import * as stripJsonComments from 'strip-json-comments';
import { dirSync } from 'tmp';
@ -18,10 +13,15 @@ import {
detectPackageManager,
getPackageManagerInstallCommand,
} from '../shared/detect-package-manager';
import { FsTree } from '@nrwl/tao/src/shared/tree';
import { flushChanges } from '@nrwl/tao/src/commands/generate';
export type MigrationsJson = {
version: string;
schematics?: { [name: string]: { version: string } };
collection?: string;
generators?: {
[name: string]: { version: string; description?: string; cli?: string };
};
packageJsonUpdates?: {
[name: string]: {
version: string;
@ -107,15 +107,16 @@ export class Migrator {
const target = versions[c];
const migrationsJson = await this.fetch(c, target.version);
if (!migrationsJson.schematics) return [];
return Object.keys(migrationsJson.schematics)
const generators = migrationsJson.generators;
if (!generators) return [];
return Object.keys(generators)
.filter(
(r) =>
this.gt(migrationsJson.schematics[r].version, currentVersion) &
this.lte(migrationsJson.schematics[r].version, target.version)
this.gt(generators[r].version, currentVersion) &
this.lte(generators[r].version, target.version)
)
.map((r) => ({
...migrationsJson.schematics[r],
...migrationsJson.generators[r],
package: c,
name: r,
}));
@ -423,46 +424,31 @@ function createFetcher(packageManager: string, logger: logging.Logger) {
stdio: [],
cwd: dir,
});
const migrationsFilePath = packageToMigrationsFilePath(
logger,
packageName,
dir
);
const packageJsonPath = require.resolve(`${packageName}/package.json`, {
paths: [dir],
});
const json = JSON.parse(
stripJsonComments(readFileSync(packageJsonPath).toString())
);
let migrationsFile = json['nx-migrations'] || json['ng-update'];
// migrationsFile is an object
if (migrationsFile && migrationsFile.migrations) {
migrationsFile = migrationsFile.migrations;
}
// packageVersion can be a tag, resolvedVersion works with semver
const resolvedVersion = json.version;
try {
if (migrationsFile && typeof migrationsFile === 'string') {
const migrationsFilePath = require.resolve(
`${packageName}/${migrationsFile}`,
{ paths: [dir] }
);
const json = JSON.parse(
stripJsonComments(readFileSync(migrationsFilePath).toString())
);
cache[`${packageName}-${packageVersion}`] = {
version: resolvedVersion,
schematics: json.schematics,
packageJsonUpdates: json.packageJsonUpdates,
};
} else {
cache[`${packageName}-${packageVersion}`] = {
version: resolvedVersion,
};
}
} catch (e) {
logger.warn(
`Could not find '${migrationsFile}' in '${packageName}'. Skipping it`
if (migrationsFilePath) {
const json = JSON.parse(
stripJsonComments(readFileSync(migrationsFilePath).toString())
);
cache[`${packageName}-${packageVersion}`] = {
version: resolvedVersion,
generators: json.generators || json.schematics,
packageJsonUpdates: json.packageJsonUpdates,
};
} else {
cache[`${packageName}-${packageVersion}`] = {
version: resolvedVersion,
};
@ -471,15 +457,46 @@ function createFetcher(packageManager: string, logger: logging.Logger) {
return cache[`${packageName}-${packageVersion}`];
};
}
// testing-fetch-end
function packageToMigrationsFilePath(
logger: logging.Logger,
packageName: string,
dir: string
) {
const packageJsonPath = require.resolve(`${packageName}/package.json`, {
paths: [dir],
});
const json = JSON.parse(
stripJsonComments(readFileSync(packageJsonPath).toString())
);
let migrationsFile = json['nx-migrations'] || json['ng-update'];
// migrationsFile is an object
if (migrationsFile && migrationsFile.migrations) {
migrationsFile = migrationsFile.migrations;
}
try {
if (migrationsFile && typeof migrationsFile === 'string') {
return require.resolve(`${packageName}/${migrationsFile}`, {
paths: [dir],
});
} else {
return null;
}
} catch (e) {
logger.warn(
`Could not find '${migrationsFile}' in '${packageName}'. Skipping it`
);
return null;
}
}
function createMigrationsFile(
root: string,
migrations: {
package: string;
name: string;
version: string;
}[]
) {
writeFileSync(
@ -581,118 +598,55 @@ async function generateMigrationsJsonAndUpdatePackageJson(
}
}
class MigrationEngineHost extends NodeModulesEngineHost {
private nodeInstallLogPrinted = false;
constructor(logger: logging.Logger) {
super();
// Overwrite the original CLI node package executor with a new one that does basically nothing
// since nx migrate doesn't do npm installs by itself
// (https://github.com/angular/angular-cli/blob/5df776780deadb6be5048b3ab006a5d3383650dc/packages/angular_devkit/schematics/tools/workflow/node-workflow.ts#L41)
this.registerTaskExecutor({
name: NodePackageName,
create: () =>
Promise.resolve<TaskExecutor>(() => {
return new Promise((res) => {
if (!this.nodeInstallLogPrinted) {
logger.warn(
`An installation of node_modules has been required. Make sure to run it after the migration`
);
this.nodeInstallLogPrinted = true;
}
res();
});
}),
});
this.registerTaskExecutor(BuiltinTaskExecutor.RunSchematic);
}
protected _resolveCollectionPath(name: string): string {
let collectionPath: string | undefined = undefined;
if (name.startsWith('.') || name.startsWith('/')) {
name = resolve(name);
}
if (extname(name)) {
collectionPath = require.resolve(name);
} else {
const packageJsonPath = require.resolve(join(name, 'package.json'));
// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageJson = require(packageJsonPath);
let pkgJsonSchematics = packageJson['nx-migrations'];
if (!pkgJsonSchematics) {
pkgJsonSchematics = packageJson['ng-update'];
if (!pkgJsonSchematics) {
throw new Error(`Could not find migrations in package: "${name}"`);
}
}
if (typeof pkgJsonSchematics != 'string') {
pkgJsonSchematics = pkgJsonSchematics.migrations;
}
collectionPath = resolve(dirname(packageJsonPath), pkgJsonSchematics);
}
try {
if (collectionPath) {
JSON.parse(stripJsonComments(readFileSync(collectionPath).toString()));
return collectionPath;
}
} catch (e) {
throw new Error(`Invalid migration file in package: "${name}"`);
}
throw new Error(`Collection cannot be resolved: "${name}"`);
}
}
class MigrationsWorkflow extends BaseWorkflow {
constructor(host: virtualFs.Host, logger: logging.Logger) {
super({
host,
engineHost: new MigrationEngineHost(logger),
force: true,
dryRun: false,
});
}
}
async function runMigrations(
logger: logging.Logger,
root: string,
opts: { runMigrations: string }
) {
const migrationsFile = JSON.parse(
const migrations: {
package: string;
name: string;
version: string;
cli?: 'nx' | 'angular';
}[] = JSON.parse(
stripJsonComments(readFileSync(join(root, opts.runMigrations)).toString())
);
).migrations;
const host = new virtualFs.ScopedHost(new NodeJsSyncHost(), normalize(root));
const workflow = new MigrationsWorkflow(host, logger);
let p = Promise.resolve(null);
migrationsFile.migrations.forEach((m) => {
p = p.then(() => {
logger.info(`Running migration ${m.package}:${m.name}`);
return workflow
.execute({
collection: m.package,
schematic: m.name,
options: {},
debug: false,
logger,
})
.toPromise()
.then(() => {
logger.info(`Successfully finished ${m.package}:${m.name}`);
logger.info(
`---------------------------------------------------------`
);
});
});
for (let m of migrations) {
logger.info(`Running migration ${m.name}`);
if (m.cli === 'nx') {
await runNxMigration(logger, root, m.package, m.name);
} else {
await (await import('./ngcli-adapter')).runMigration(
logger,
root,
m.package,
m.name
);
}
logger.info(`Successfully finished ${m.name}`);
logger.info(`---------------------------------------------------------`);
}
}
async function runNxMigration(
logger: logging.Logger,
root: string,
packageName: string,
name: string
) {
const collectionPath = packageToMigrationsFilePath(logger, packageName, root);
const collection = JSON.parse(fs.readFileSync(collectionPath).toString());
const g = collection.generators || collection.schematics;
const implRelativePath = g[name].implementation || g[name].factory;
const implPath = require.resolve(implRelativePath, {
paths: [dirname(collectionPath)],
});
await p;
const fn = require(implPath).default;
const host = new FsTree(root, false, logger as any);
await fn(host, {});
const changes = host.listChanges();
flushChanges(root, changes);
}
export async function migrate(root: string, args: string[], isVerbose = false) {

View File

@ -24,16 +24,28 @@ import { printRunHelp, RunOptions } from './run';
import {
FileSystemCollectionDescription,
FileSystemSchematicDescription,
NodeModulesEngineHost,
NodeWorkflow,
validateOptionsWithSchema,
} from '@angular-devkit/schematics/tools';
import { DryRunEvent, formats, Schematic } from '@angular-devkit/schematics';
import {
DryRunEvent,
formats,
Schematic,
TaskExecutor,
} from '@angular-devkit/schematics';
import * as fs from 'fs';
import * as inquirer from 'inquirer';
import { detectPackageManager } from '../shared/detect-package-manager';
import { GenerateOptions, printGenHelp } from './generate';
import * as taoTree from '../shared/tree';
import { workspaceConfigName } from '@nrwl/tao/src/shared/workspace';
import { BaseWorkflow } from '@angular-devkit/schematics/src/workflow';
import { NodePackageName } from '@angular-devkit/schematics/tasks/package-manager/options';
import { BuiltinTaskExecutor } from '@angular-devkit/schematics/tasks/node';
import { dirname, extname, join, resolve } from 'path';
import { readFileSync } from 'fs';
import * as stripJsonComments from 'strip-json-comments';
function normalizeOptions(opts: Options, schema: Schema): Options {
return convertAliases(coerceTypesInOptions(opts, schema), schema, false);
@ -324,6 +336,84 @@ function isTTY(): boolean {
return !!process.stdout.isTTY && process.env['CI'] !== 'true';
}
class MigrationEngineHost extends NodeModulesEngineHost {
private nodeInstallLogPrinted = false;
constructor(logger: logging.Logger) {
super();
// Overwrite the original CLI node package executor with a new one that does basically nothing
// since nx migrate doesn't do npm installs by itself
// (https://github.com/angular/angular-cli/blob/5df776780deadb6be5048b3ab006a5d3383650dc/packages/angular_devkit/schematics/tools/workflow/node-workflow.ts#L41)
this.registerTaskExecutor({
name: NodePackageName,
create: () =>
Promise.resolve<TaskExecutor>(() => {
return new Promise((res) => {
if (!this.nodeInstallLogPrinted) {
logger.warn(
`An installation of node_modules has been required. Make sure to run it after the migration`
);
this.nodeInstallLogPrinted = true;
}
res();
});
}),
});
this.registerTaskExecutor(BuiltinTaskExecutor.RunSchematic);
}
protected _resolveCollectionPath(name: string): string {
let collectionPath: string | undefined = undefined;
if (name.startsWith('.') || name.startsWith('/')) {
name = resolve(name);
}
if (extname(name)) {
collectionPath = require.resolve(name);
} else {
const packageJsonPath = require.resolve(join(name, 'package.json'));
// eslint-disable-next-line @typescript-eslint/no-var-requires
const packageJson = require(packageJsonPath);
let pkgJsonSchematics = packageJson['nx-migrations'];
if (!pkgJsonSchematics) {
pkgJsonSchematics = packageJson['ng-update'];
if (!pkgJsonSchematics) {
throw new Error(`Could not find migrations in package: "${name}"`);
}
}
if (typeof pkgJsonSchematics != 'string') {
pkgJsonSchematics = pkgJsonSchematics.migrations;
}
collectionPath = resolve(dirname(packageJsonPath), pkgJsonSchematics);
}
try {
if (collectionPath) {
JSON.parse(stripJsonComments(readFileSync(collectionPath).toString()));
return collectionPath;
}
} catch (e) {
throw new Error(`Invalid migration file in package: "${name}"`);
}
throw new Error(`Collection cannot be resolved: "${name}"`);
}
}
class MigrationsWorkflow extends BaseWorkflow {
constructor(host: virtualFs.Host, logger: logging.Logger) {
super({
host,
engineHost: new MigrationEngineHost(logger),
force: true,
dryRun: false,
});
}
}
export async function generate(
logger: logging.Logger,
root: string,
@ -347,6 +437,25 @@ export async function generate(
).status;
}
export async function runMigration(
logger: logging.Logger,
root: string,
collection: string,
schematic: string
) {
const host = new virtualFs.ScopedHost(new NodeJsSyncHost(), normalize(root));
const workflow = new MigrationsWorkflow(host, logger);
return workflow
.execute({
collection,
schematic,
options: {},
debug: false,
logger,
})
.toPromise();
}
export function wrapAngularDevkitSchematic(
collectionName: string,
generatorName: string

View File

@ -138,7 +138,8 @@
"update-decorate-angular-cli": {
"version": "11.0.0-beta.3",
"description": "Update the decoration script when using Angular CLI",
"factory": "./src/migrations/update-11-0-0/update-decorate-angular-cli"
"implementation": "./src/migrations/update-11-0-0/update-decorate-angular-cli",
"cli": "nx"
},
"update-node-types": {
"version": "11.0.0-beta.3",

View File

@ -1,21 +1,17 @@
import { Rule, Tree } from '@angular-devkit/schematics';
import { join as pathJoin } from 'path';
import { readFileSync } from 'fs';
import { Tree } from '@nrwl/devkit';
export default function update(): Rule {
return (host: Tree) => {
const decorateCli = readFileSync(
pathJoin(
__dirname as any,
'..',
'..',
'schematics',
'utils',
'decorate-angular-cli.js__tmpl__'
)
).toString();
if (host.exists('/decorate-angular-cli.js')) {
host.overwrite('/decorate-angular-cli.js', decorateCli);
}
};
export default function update(host: Tree) {
const decorateCli = readFileSync(
pathJoin(
__dirname as any,
'..',
'..',
'schematics',
'utils',
'decorate-angular-cli.js__tmpl__'
)
).toString();
host.write('/decorate-angular-cli.js', decorateCli);
}

View File

@ -114,9 +114,12 @@ async function runTest() {
execSync(`./scripts/package.sh 9999.0.2 "~10.0.0" "3.9.3" "2.0.4"`, {
stdio: [0, 1, 2],
});
execSync(`rm -rf tmp`);
execSync(`mkdir -p tmp/angular`);
execSync(`mkdir -p tmp/nx`);
if (process.argv[5] != '--rerun') {
execSync(`rm -rf tmp`);
execSync(`mkdir -p tmp/angular`);
execSync(`mkdir -p tmp/nx`);
}
try {
await setup();