Skip to content

Commit fb38454

Browse files
committed
fix(@angular/cli): fallback to deprecated versions when resolving ranges if no non-deprecated version is found
When using ng update to resolve package version ranges on the command line, we previously skipped deprecated package versions entirely during pre-validation. In cases where all versions satisfying the range are deprecated, this resulted in update failure. Now, we attempt to find a satisfying version from non-deprecated versions first, and fallback to deprecated versions if none are found. This aligns the CLI pre-validation with the update schematic resolution logic.
1 parent da23ee7 commit fb38454

1 file changed

Lines changed: 22 additions & 21 deletions

File tree

  • packages/angular/cli/src/commands/update

packages/angular/cli/src/commands/update/cli.ts

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -682,29 +682,30 @@ export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs
682682
case 'version':
683683
manifest = metadata.versions[requestIdentifier.fetchSpec];
684684
break;
685-
case 'range':
686-
for (const potentialManifest of Object.values(metadata.versions)) {
687-
// Ignore deprecated package versions
688-
if (potentialManifest.deprecated) {
689-
continue;
690-
}
691-
// Only consider versions that are within the range
692-
if (
693-
!semver.satisfies(potentialManifest.version, requestIdentifier.fetchSpec, {
694-
loose: true,
695-
})
696-
) {
697-
continue;
698-
}
699-
// Update the used manifest if current potential is newer than existing or there is not one yet
700-
if (
701-
!manifest ||
702-
semver.gt(potentialManifest.version, manifest.version, { loose: true })
703-
) {
704-
manifest = potentialManifest;
685+
case 'range': {
686+
const potentialManifests = Object.values(metadata.versions).filter((potentialManifest) =>
687+
semver.satisfies(potentialManifest.version, requestIdentifier.fetchSpec, {
688+
loose: true,
689+
}),
690+
);
691+
692+
const nonDeprecated = potentialManifests.filter((m) => !m.deprecated);
693+
const deprecated = potentialManifests.filter((m) => !!m.deprecated);
694+
695+
const selectLatest = (manifests: PackageManifest[]) => {
696+
let max: PackageManifest | undefined;
697+
for (const m of manifests) {
698+
if (!max || semver.gt(m.version, max.version, { loose: true })) {
699+
max = m;
700+
}
705701
}
706-
}
702+
703+
return max;
704+
};
705+
706+
manifest = selectLatest(nonDeprecated) ?? selectLatest(deprecated);
707707
break;
708+
}
708709
}
709710

710711
if (!manifest) {

0 commit comments

Comments
 (0)