Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions packages/angular/cli/src/commands/update/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,29 +682,30 @@ export default class UpdateCommandModule extends CommandModule<UpdateCommandArgs
case 'version':
manifest = metadata.versions[requestIdentifier.fetchSpec];
break;
case 'range':
for (const potentialManifest of Object.values(metadata.versions)) {
// Ignore deprecated package versions
if (potentialManifest.deprecated) {
continue;
}
// Only consider versions that are within the range
if (
!semver.satisfies(potentialManifest.version, requestIdentifier.fetchSpec, {
loose: true,
})
) {
continue;
}
// Update the used manifest if current potential is newer than existing or there is not one yet
if (
!manifest ||
semver.gt(potentialManifest.version, manifest.version, { loose: true })
) {
manifest = potentialManifest;
case 'range': {
const potentialManifests = Object.values(metadata.versions).filter((potentialManifest) =>
semver.satisfies(potentialManifest.version, requestIdentifier.fetchSpec, {
loose: true,
}),
);

const nonDeprecated = potentialManifests.filter((m) => !m.deprecated);
const deprecated = potentialManifests.filter((m) => !!m.deprecated);

const selectLatest = (manifests: PackageManifest[]) => {
let max: PackageManifest | undefined;
for (const m of manifests) {
if (!max || semver.gt(m.version, max.version, { loose: true })) {
max = m;
}
}
}

return max;
};

manifest = selectLatest(nonDeprecated) ?? selectLatest(deprecated);
break;
}
Comment thread
alan-agius4 marked this conversation as resolved.
}

if (!manifest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ function _addPackageGroup(
if (Array.isArray(packageGroup) && !packageGroup.some((x) => typeof x != 'string')) {
packageGroupNormalized = packageGroup.reduce(
(acc, curr) => {
acc[curr] = maybePackage;
acc[curr] = version;

return acc;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^20.0.0-next.0",
"@angular/common": "^20.0.0-next.0",
"@angular/compiler": "^20.0.0-next.0",
"@angular/core": "^20.0.0-next.0",
Expand Down
13 changes: 7 additions & 6 deletions tests/legacy-cli/e2e/tests/commands/add/version-specifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ export default async function () {
'Installation was not skipped',
);

const output2 = await ng('add', '@angular/localize@latest', '--skip-confirmation');
assert.doesNotMatch(
output2.stdout,
/Skipping installation: Package already installed/,
'Installation should not have been skipped',
);
// Skipped as `@latest` installs a version that does not support the used Node.js version.
// const output2 = await ng('add', '@angular/localize@latest', '--skip-confirmation');
// assert.doesNotMatch(
// output2.stdout,
// /Skipping installation: Package already installed/,
// 'Installation should not have been skipped',
// );

const output3 = await ng('add', '@angular/localize@19.1.0', '--skip-confirmation');
assert.doesNotMatch(
Expand Down
Loading