Skip to content

Commit

Permalink
fix(core): prevent duplicated migration prompts (#15202)
Browse files Browse the repository at this point in the history
  • Loading branch information
leosvelperez authored Feb 23, 2023
1 parent ba6cc33 commit e54ee0a
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 29 deletions.
2 changes: 1 addition & 1 deletion packages/nx/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"nx-migrations": {
"migrations": "./migrations.json",
"packageGroup": [
"@nrwl/js",
"@nrwl/jest",
"@nrwl/linter",
"@nrwl/workspace",
Expand All @@ -104,7 +105,6 @@
"@nrwl/eslint-plugin-nx",
"@nrwl/expo",
"@nrwl/express",
"@nrwl/js",
"@nrwl/nest",
"@nrwl/next",
"@nrwl/node",
Expand Down
68 changes: 41 additions & 27 deletions packages/nx/src/command-line/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export class Migrator {
private readonly excludeAppliedMigrations: MigratorOptions['excludeAppliedMigrations'];
private readonly packageUpdates: Record<string, PackageUpdate> = {};
private readonly collectedVersions: Record<string, string> = {};
private readonly promptAnswers: Record<string, boolean> = {};

constructor(opts: MigratorOptions) {
this.packageJson = opts.packageJson;
Expand Down Expand Up @@ -188,14 +189,13 @@ export class Migrator {
const filteredUpdates: Record<string, PackageUpdate> = {};
for (const packageUpdate of packageToCheck.updates) {
if (
this.areRequirementsMet(packageUpdate.requires, filteredUpdates) &&
this.areRequirementsMet(packageUpdate.requires) &&
(!this.interactive ||
(await this.runPackageJsonUpdatesConfirmationPrompt(
packageUpdate['x-prompt']
)))
(await this.runPackageJsonUpdatesConfirmationPrompt(packageUpdate)))
) {
Object.entries(packageUpdate.packages).forEach(([name, update]) => {
filteredUpdates[name] = update;
this.packageUpdates[name] = update;
});
}
}
Expand Down Expand Up @@ -443,30 +443,28 @@ export class Migrator {
}

private areRequirementsMet(
requirements: PackageJsonUpdates[string]['requires'],
extraPackageUpdatesToCheck?: Record<string, PackageUpdate>
requirements: PackageJsonUpdates[string]['requires']
): boolean {
if (!requirements || !Object.keys(requirements).length) {
return true;
}

return Object.entries(requirements).every(
([pkgName, versionRange]) =>
(this.getPkgVersion(pkgName) &&
satisfies(this.getPkgVersion(pkgName), versionRange, {
includePrerelease: true,
})) ||
(this.packageUpdates[pkgName]?.version &&
satisfies(this.packageUpdates[pkgName].version, versionRange, {
includePrerelease: true,
})) ||
(extraPackageUpdatesToCheck?.[pkgName]?.version &&
satisfies(
cleanSemver(extraPackageUpdatesToCheck[pkgName].version),
versionRange,
{ includePrerelease: true }
))
);
return Object.entries(requirements).every(([pkgName, versionRange]) => {
if (this.packageUpdates[pkgName]) {
return satisfies(
cleanSemver(this.packageUpdates[pkgName].version),
versionRange,
{ includePrerelease: true }
);
}

return (
this.getPkgVersion(pkgName) &&
satisfies(this.getPkgVersion(pkgName), versionRange, {
includePrerelease: true,
})
);
});
}

private areMigrationRequirementsMet(
Expand Down Expand Up @@ -519,20 +517,36 @@ export class Migrator {
}

private async runPackageJsonUpdatesConfirmationPrompt(
confirmationPrompt: string
packageUpdate: PackageJsonUpdates[string]
): Promise<boolean> {
if (!confirmationPrompt) {
if (!packageUpdate['x-prompt']) {
return Promise.resolve(true);
}
const promptKey = this.getPackageUpdatePromptKey(packageUpdate);
if (this.promptAnswers[promptKey] !== undefined) {
// a same prompt was already answered, skip
return Promise.resolve(false);
}

return await prompt([
{
name: 'shouldApply',
type: 'confirm',
message: confirmationPrompt,
message: packageUpdate['x-prompt'],
initial: true,
},
]).then((a: { shouldApply: boolean }) => a.shouldApply);
]).then(({ shouldApply }: { shouldApply: boolean }) => {
this.promptAnswers[promptKey] = shouldApply;
return shouldApply;
});
}

private getPackageUpdatePromptKey(
packageUpdate: PackageJsonUpdates[string]
): string {
return Object.entries(packageUpdate.packages)
.map(([name, update]) => `${name}:${JSON.stringify(update)}`)
.join('|');
}

private getPkgVersion(pkg: string): string {
Expand Down
2 changes: 1 addition & 1 deletion packages/workspace/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"requirements": {},
"migrations": "./migrations.json",
"packageGroup": {
"@nrwl/js": "*",
"@nrwl/jest": "*",
"@nrwl/linter": "*",
"@nrwl/angular": "*",
Expand All @@ -44,7 +45,6 @@
"@nrwl/eslint-plugin-nx": "*",
"@nrwl/expo": "*",
"@nrwl/express": "*",
"@nrwl/js": "*",
"@nrwl/nest": "*",
"@nrwl/next": "*",
"@nrwl/node": "*",
Expand Down

1 comment on commit e54ee0a

@vercel
Copy link

@vercel vercel bot commented on e54ee0a Feb 23, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-git-master-nrwl.vercel.app
nx-five.vercel.app
nx-dev-nrwl.vercel.app
nx.dev

Please sign in to comment.