npm-check-updates icon indicating copy to clipboard operation
npm-check-updates copied to clipboard

Add `--target semver` option to adhere to package.json ranges

Open raineorshine opened this issue 2 years ago • 15 comments

Following https://github.com/raineorshine/npm-check-updates/pull/1052#issuecomment-1054125274:

One last thing - should we somehow add the two filter + target as a new param/cli option? As in semver = true sets both - so that people don't need to come up with the two functions I posted in the top?

target: (name, [{ operator }]) => operator === '^' ? 'minor' : operator === '~' ? 'patch' : 'latest',
filter: (_, [{ major, operator }]) => !(major === '0' || major === undefined || operator === undefined)

@Primajin Yes, I think that's a great idea.

target: (name, [{ operator }]) => operator === '^' ? 'minor' : operator === '~' ? 'patch' : 'latest',

There are more cases that need to be handled: Basically we need to support Ranges, Advanced Ranges, and Prerelease Tags (which should set the target to greatest).

We may want to use semver.satisfies so that we don't have to implement all of those conditions ourselves.

filter: (_, [{ major, operator }]) => !(major === '0' || major === undefined || operator === undefined)

We still want to upgrade dependencies like ^0.1.1 according to semver, and handle that in target. So wouldn't we just want filter: (_, [{ operator }]) => operator?

raineorshine avatar Feb 28 '22 15:02 raineorshine

Yeah, with 0 I'm always unsure since it often has breaking changes in minor versions

Primajin avatar Feb 28 '22 16:02 Primajin

Users can of course specify their own target function, but if we add a --semver option it should follow semver exactly. ~Thus, ^0.1.1 would be upgraded to greater minor versions, even if they are breaking. The user can remove the ^ if they prefer a fixed dependency.~

^0.1.1 would be upgraded to ^0.1.2 but not ^0.2.0 according to semver.

raineorshine avatar Feb 28 '22 17:02 raineorshine

Sure, fine with me 👍🏻

Primajin avatar Feb 28 '22 19:02 Primajin

I found another edge case - we might not always directly be able to access [{ operator }] - I just ran it on a repo that is using internal npm packages and there the Array is empty - resulting in a TypeError: Cannot read property 'major' of undefined so we probably can't always shorthand destructure this

"@mypackage/lint": "file:lint",

Primajin avatar Mar 02 '22 14:03 Primajin

Users can of course specify their own target function, but if we add a --semver option it should follow semver exactly. Thus, ^0.1.1 would be upgraded to greater minor versions, even if they are breaking. The user can remove the ^ if they prefer a fixed dependency.

Wait, what? In semver, ^0.1.1 would upgrade to 0.1.2, but not to 0.2.0, so I don't understand what you mean?

benface avatar Jul 22 '22 19:07 benface

You are correct! My bad.

raineorshine avatar Jul 22 '22 19:07 raineorshine

Initial support for --target semver added and published in v16.11.0. It will upgrade a dependency if there are newer versions without breaking the specified semver version range. Uses maxSatisfying from https://github.com/npm/node-semver/#ranges-1.

Please create a new issue if you have a case that does not work as expected. I'm sure there are some issues with its handling of prerelease versions, so I could use some feedback to get a better sense of the expected behavior.

raineorshine avatar Aug 12 '23 17:08 raineorshine

It's lovely ❤️ thanks!

Primajin avatar Aug 15 '23 13:08 Primajin

I have "axios": "^1.5.0" as dependencies in package.json. When i try to upgrade it using these command ncu -u --install always --filter axios --target semver, it correctly updates the package.json to "axios": "^1.5.1".

image

But when i see the actual installed modules in node_modules, it showed as "version": "1.6.2"

image

this is what changes in pnpm.lock.yaml

image

Is this the correct behavior?

rifandani avatar Dec 13 '23 08:12 rifandani

Yes, 1.6.2 satisfies ^1.5.1.

ljharb avatar Dec 13 '23 14:12 ljharb

It's just a little odd that it didn't update your package directly to the latest available version still falling under semver

Primajin avatar Dec 13 '23 15:12 Primajin

yeah, if the actual installed module is ^1.6.2, then why in package.json does not also updates to ^1.6.2 instead of ^1.5.1 ?

rifandani avatar Dec 13 '23 16:12 rifandani

@rifandani This appears to be a regression with the pnpm integration. Please open a new issue and I will investigate.

$ ncu --packageManager pnpm --target semver
Checking /Users/raine/projects/ncu-issues/1054/package.json
[====================] 1/1 100%

 axios  ^1.5.0  →  ^1.5.1

Run ncu --packageManager pnpm --target semver -u to upgrade package.json

$ ncu --packageManager npm --target semver
Checking /Users/raine/projects/ncu-issues/1054/package.json
[====================] 1/1 100%

 axios  ^1.5.0  →  ^1.6.2

Run ncu --packageManager npm --target semver -u to upgrade package.json

raineorshine avatar Dec 13 '23 17:12 raineorshine

It was a very dumb mistake. I published a patch to v16.14.12. Let me know if that fixes it.

it correctly updates the package.json to "axios": "^1.5.1".

Actually, semver should upgrade to ^1.6.2 because the ^ range operator includes minor versions (exception for major-version zero).

raineorshine avatar Dec 13 '23 17:12 raineorshine

It was a very dumb mistake. I published a patch to v16.14.12. Let me know if that fixes it.

thanks a lot, now package.json also updates correctly to ^1.6.2

Actually, semver should upgrade to ^1.6.2 because the ^ range operator includes minor versions (exception for major-version zero).

yeah i was wrong, it should upgrade to ^1.6.2 instead of ^1.5.1

rifandani avatar Dec 14 '23 06:12 rifandani