Skip to content

Commit 62fb2f2

Browse files
alan-agius4dgp1130
authored andcommitted
fix(@angular/cli): support running a single migration from a package
(cherry picked from commit 0ee5f2f)
1 parent 76307a4 commit 62fb2f2

File tree

2 files changed

+76
-23
lines changed

2 files changed

+76
-23
lines changed

packages/angular/cli/commands/update-impl.ts

Lines changed: 67 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -139,18 +139,44 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
139139
}
140140
}
141141

142+
/**
143+
* @return Whether or not the migration was performed successfully.
144+
*/
145+
private async executeMigration(
146+
packageName: string,
147+
collectionPath: string,
148+
migrationName: string,
149+
commit?: boolean,
150+
): Promise<boolean> {
151+
const collection = this.workflow.engine.createCollection(collectionPath);
152+
const name = collection.listSchematicNames().find(name => name === migrationName);
153+
if (!name) {
154+
this.logger.error(`Cannot find migration '${migrationName}' in '${packageName}'.`);
155+
156+
return false;
157+
}
158+
159+
const schematic = this.workflow.engine.createSchematic(name, collection);
160+
161+
this.logger.info(
162+
colors.cyan(`** Executing '${migrationName}' of package '${packageName}' **\n`),
163+
);
164+
165+
return this.executePackageMigrations([schematic.description], packageName, commit);
166+
}
167+
142168
/**
143169
* @return Whether or not the migrations were performed successfully.
144170
*/
145171
private async executeMigrations(
146172
packageName: string,
147173
collectionPath: string,
148174
range: semver.Range,
149-
commit = false,
175+
commit?: boolean,
150176
): Promise<boolean> {
151177
const collection = this.workflow.engine.createCollection(collectionPath);
152-
153178
const migrations = [];
179+
154180
for (const name of collection.listSchematicNames()) {
155181
const schematic = this.workflow.engine.createSchematic(name, collection);
156182
const description = schematic.description as typeof schematic.description & {
@@ -166,16 +192,21 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
166192
}
167193
}
168194

195+
migrations.sort((a, b) => semver.compare(a.version, b.version) || a.name.localeCompare(b.name));
196+
169197
if (migrations.length === 0) {
170198
return true;
171199
}
172200

173-
migrations.sort((a, b) => semver.compare(a.version, b.version) || a.name.localeCompare(b.name));
174-
175201
this.logger.info(
176202
colors.cyan(`** Executing migrations of package '${packageName}' **\n`),
177203
);
178204

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

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

276+
if (options.migrateOnly && packageIdentifier.rawSpec) {
277+
this.logger.warn('Package specifier has no effect when using "migrate-only" option.');
278+
}
279+
245280
// If next option is used and no specifier supplied, use next tag
246281
if (options.next && !packageIdentifier.rawSpec) {
247282
packageIdentifier.fetchSpec = 'next';
@@ -334,8 +369,8 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
334369
}
335370

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

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

349-
const from = coerceVersionNumber(options.from);
350-
if (!from) {
351-
this.logger.error(`"from" value [${options.from}] is not a valid version.`);
352-
353-
return 1;
354-
}
355-
356384
if (options.next) {
357385
this.logger.warn('"next" option has no effect when using "migrate-only" option.');
358386
}
@@ -430,16 +458,33 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
430458
}
431459
}
432460

433-
const migrationRange = new semver.Range(
434-
'>' + from + ' <=' + (options.to || packageNode.package.version),
435-
);
461+
let success = false;
462+
if (typeof options.migrateOnly == 'string') {
463+
success = await this.executeMigration(
464+
packageName,
465+
migrations,
466+
options.migrateOnly,
467+
options.createCommits,
468+
);
469+
} else {
470+
const from = coerceVersionNumber(options.from);
471+
if (!from) {
472+
this.logger.error(`"from" value [${options.from}] is not a valid version.`);
436473

437-
const success = await this.executeMigrations(
438-
packageName,
439-
migrations,
440-
migrationRange,
441-
options.createCommits,
442-
);
474+
return 1;
475+
}
476+
477+
const migrationRange = new semver.Range(
478+
'>' + from + ' <=' + (options.to || packageNode.package.version),
479+
);
480+
481+
success = await this.executeMigrations(
482+
packageName,
483+
migrations,
484+
migrationRange,
485+
options.createCommits,
486+
);
487+
}
443488

444489
if (success) {
445490
if (

packages/angular/cli/commands/update.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,15 @@
4444
},
4545
"migrateOnly": {
4646
"description": "Only perform a migration, does not update the installed version.",
47-
"type": "boolean"
47+
"oneOf": [
48+
{
49+
"type": "boolean"
50+
},
51+
{
52+
"type": "string",
53+
"description": "The name of the migration to run."
54+
}
55+
]
4856
},
4957
"from": {
5058
"description": "Version from which to migrate from. Only available with a single package being updated, and only on migration only.",

0 commit comments

Comments
 (0)