Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(@angular/cli): support running a single migration from a package
Browse files Browse the repository at this point in the history
(cherry picked from commit 0ee5f2f)
alan-agius4 authored and dgp1130 committed Nov 15, 2019
1 parent 76307a4 commit 62fb2f2
Showing 2 changed files with 76 additions and 23 deletions.
89 changes: 67 additions & 22 deletions packages/angular/cli/commands/update-impl.ts
Original file line number Diff line number Diff line change
@@ -139,18 +139,44 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
}
}

/**
* @return Whether or not the migration was performed successfully.
*/
private async executeMigration(
packageName: string,
collectionPath: string,
migrationName: string,
commit?: boolean,
): Promise<boolean> {
const collection = this.workflow.engine.createCollection(collectionPath);
const name = collection.listSchematicNames().find(name => name === migrationName);
if (!name) {
this.logger.error(`Cannot find migration '${migrationName}' in '${packageName}'.`);

return false;
}

const schematic = this.workflow.engine.createSchematic(name, collection);

this.logger.info(
colors.cyan(`** Executing '${migrationName}' of package '${packageName}' **\n`),
);

return this.executePackageMigrations([schematic.description], packageName, commit);
}

/**
* @return Whether or not the migrations were performed successfully.
*/
private async executeMigrations(
packageName: string,
collectionPath: string,
range: semver.Range,
commit = false,
commit?: boolean,
): Promise<boolean> {
const collection = this.workflow.engine.createCollection(collectionPath);

const migrations = [];

for (const name of collection.listSchematicNames()) {
const schematic = this.workflow.engine.createSchematic(name, collection);
const description = schematic.description as typeof schematic.description & {
@@ -166,16 +192,21 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
}
}

migrations.sort((a, b) => semver.compare(a.version, b.version) || a.name.localeCompare(b.name));

if (migrations.length === 0) {
return true;
}

migrations.sort((a, b) => semver.compare(a.version, b.version) || a.name.localeCompare(b.name));

this.logger.info(
colors.cyan(`** Executing migrations of package '${packageName}' **\n`),
);

return this.executePackageMigrations(migrations, packageName, commit);
}

// tslint:disable-next-line: no-any
private async executePackageMigrations(migrations: any[], packageName: string, commit = false): Promise<boolean> {
for (const migration of migrations) {
this.logger.info(`${colors.symbols.pointer} ${migration.description.replace(/\. /g, '.\n ')}`);

@@ -242,6 +273,10 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
return 1;
}

if (options.migrateOnly && packageIdentifier.rawSpec) {
this.logger.warn('Package specifier has no effect when using "migrate-only" option.');
}

// If next option is used and no specifier supplied, use next tag
if (options.next && !packageIdentifier.rawSpec) {
packageIdentifier.fetchSpec = 'next';
@@ -334,8 +369,8 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
}

if (options.migrateOnly) {
if (!options.from) {
this.logger.error('"from" option is required when using the "migrate-only" option.');
if (!options.from && typeof options.migrateOnly !== 'string') {
this.logger.error('"from" option is required when using the "migrate-only" option without a migration name.');

return 1;
} else if (packages.length !== 1) {
@@ -346,13 +381,6 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
return 1;
}

const from = coerceVersionNumber(options.from);
if (!from) {
this.logger.error(`"from" value [${options.from}] is not a valid version.`);

return 1;
}

if (options.next) {
this.logger.warn('"next" option has no effect when using "migrate-only" option.');
}
@@ -430,16 +458,33 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
}
}

const migrationRange = new semver.Range(
'>' + from + ' <=' + (options.to || packageNode.package.version),
);
let success = false;
if (typeof options.migrateOnly == 'string') {
success = await this.executeMigration(
packageName,
migrations,
options.migrateOnly,
options.createCommits,
);
} else {
const from = coerceVersionNumber(options.from);
if (!from) {
this.logger.error(`"from" value [${options.from}] is not a valid version.`);

const success = await this.executeMigrations(
packageName,
migrations,
migrationRange,
options.createCommits,
);
return 1;
}

const migrationRange = new semver.Range(
'>' + from + ' <=' + (options.to || packageNode.package.version),
);

success = await this.executeMigrations(
packageName,
migrations,
migrationRange,
options.createCommits,
);
}

if (success) {
if (
10 changes: 9 additions & 1 deletion packages/angular/cli/commands/update.json
Original file line number Diff line number Diff line change
@@ -44,7 +44,15 @@
},
"migrateOnly": {
"description": "Only perform a migration, does not update the installed version.",
"type": "boolean"
"oneOf": [
{
"type": "boolean"
},
{
"type": "string",
"description": "The name of the migration to run."
}
]
},
"from": {
"description": "Version from which to migrate from. Only available with a single package being updated, and only on migration only.",

0 comments on commit 62fb2f2

Please sign in to comment.