[x] I have searched for similiar issues before filing this issue.
node version: v12.10.0
I'm after an option that will bump existing ranges in package.json, so they point to the latest version (within a reflected range).
Currently ncu does that well, only if we use ^ and rely on latest major of given dependency.
However if there's a package where we rely on non-latest major, it automatically updates to latest major (which I find unwanted, as any major version upgrade should rather be done manually ensuring breaking changes are handled).
There's a package where:
3.2.52.8.52.4.8Range in is package.json is ^2.4.5.
I'd love ncu to upgrade the range to ^2.8.5 (and not ^3.2.5 as it does now).
Range in is package.json is ~2.4.5.
I'd love ncu to upgrade the range to ~2.4.8 (and not ^3.2.5 as it does now).
In #159 it was suggested that npm update does that. That's not true
npm update updates package.json only if:
node_modules__So in above scenario if in node_modules package is already installed at 2.8.5 (or is not installed at all), there's no way to forcenpm update to update the range in package.json.
Thank you for the detailed explanation! And thank you for looking through existing issues.
I marked this as an enhancement and am open to PR's ~or +1's to signal interest if others are wanting this option~.
As a side note, I'm somewhat unclear what benefit there is to having the number changed in the package.json when the version range gives you the control you are looking for. This likely does not change the status of this ticket, but I thought I would mention that this came up for me.
what benefit there is to having the number changed in the package.json when the version range gives you the control you are looking for.
Bumping the ranges ensures that when user updates our package, its dependencies will be upgraded to latest versions (otherwise if ranges are not updated, npm won't do deep update).
Repeatedly I deal with a situation when some dependency of my project introduces accidentally a bug, and then quickly follows with a fix (note that buggy version cannot be removed from npm), then it's always recommended to bump the range so it gives no chance for buggy version to be installed.
(otherwise if ranges are not updated npm won't do deep update)
Does this help?
As of [email protected], the npm update will only inspect top-level packages. Prior versions of npm would also recursively inspect all dependencies. To get the old behavior, use npm --depth 9999 update.
Does this help?
Not really, as it's not about how packages are being installed for maintainer of a package, but for projects that rely on it.
It's impossible to enforce users of my package (and packages that depend on it), to runnpm update --depth 9999 instead of npm install (or npm update)
Also just for maintainers npm update is not very useful.. as it requires two separate runs for _prod_ and _dev_ dependencies (there's no way to update both with one command run)
Good point! I will keep this open for the feature as requested.
Big +1 on my part!
It's actually what I was hoping to achieve with ncu --semverLevel major -u but have ncu ignore any hard-coded versions.
This is my goal and I believe it should be a flag called --packageRanges or something very clear.
I have a use case:
v1.2.0 introduced breaking changes on v1.3.0)."1.2.0" in package.jsonncu does not touch this ever.ncu auto-update "^0.8.0" to "^0.9.0" in our package.jsonSo in conclusion I think a command ncu --packageRanges would be awesome!!
Sounds reasonable! Just need someone willing to work on this. I'm working on other things at the moment.
@raineorshine i can cry and make a PR for you!! 🙃 Can I request a little guidance on where you suggest me adding new code ?
I have a few questions for clarification.
It's actually what I was hoping to achieve with
ncu --semverLevel major -ubut havencuignore any hard-coded versions.
So you're looking for a flag that:
maxSatisfying version (i.e. respects semver)@medikoo Is this the same as what you are looking for? Is --semverLevel major also inadequate for your use case?
I have a use case:
- Some package introduced changed behaviour on a major update (eg.
v1.2.0introduced breaking changes onv1.3.0).
I'm a little confused by this: v1.2.0 → v1.3.0 is a minor version update, not a major version update. Are you saying the package author accidentally published breaking changes on a minor version?
- So we want to hard code the version to a specific version. Eg. set to
"1.2.0"in package.json- this should make it so
ncudoes not touch this ever.
This can be accomplished with an .ncurc file set to not touch that dependency:
{
"reject": ["mypackage"]
}
All other package we want to keep the latest versions in package.json explicitly (because of the reason above)
- So that means, have
ncuauto-update"^0.8.0"to"^0.9.0"in our package.json
Upgrading "^0.8.0" to "^0.9.0" is the current behavior, right?
Sorry, I was confused and thought the name of the "middle" number was "major".
ncu --semverLevel major -uThis updates everything to latest "_minor_" (the middle one) version and it's currently my most used command.
This means, with these flags in package.json, the behaviour of this command is:
This is the reason I was a bit confused on the naming, since we need to write _major_ but it only upgrades _minor_ versions, or is this a bug?
Upgrading "^0.8.0" to "^0.9.0" is the current behavior, right?
I'm not 100% sure what you mean by this. But, I believe ncu -u upgrades _everything_ even to _major_ versions, completely ignoring package ranges.
ncu --packageRanges -u
I want it to upgrade everything as indicated in package.json. (also see npm ranges docs).
This means, with these flags in package.json, the behaviour of this command is:
I think saving an extra special file just for when hard coding a package version is too confusing when working with teams. If authors can just have a single script like so:
"update-all-dependancies": "ncu --packageRanges -u && npm i"This way the source of all truth _is_ just the package version range, and no extra files are needed that add clutter and can lead to discrepancies more easily.
I feel that ncu --packageRanges -u is so beautiful.
It's the command of commands. The command that will end all other commands.
NCU would basically offer:
ncu for checking new major versions and then go in an manually upgrade them on a case-by-case basis after checking breaking changesncu --packageRanges -u as the main command to upgrade everything in package.json. This can be done routinely every week.NCU is so nice, especially in monorepos.
"~1.2.3" should be upgraded to latest patch version like: "~1.2.4"
"^1.2.3" should be upgraded to latest minor version like: "^1.3.3"
"1.2.3" should never be touched
@raineorshine ☝️ this is exactly the behavior I had in mind with this proposal.
This is the reason I was a bit confused on the naming, since we need to write _major_ but it only upgrades _minor_ versions, or is this a bug?
It was intended to convey that it locks upgrades to the current "major" version. I can see how it could be interpreted the other way though.
But, I believe
ncu -uupgrades _everything_ even to _major_ versions, completely ignoring package ranges.
Yes, aside from semverLevel, that's correct.
I want it to upgrade everything as indicated in
package.json. (also see npm ranges docs).This means, with these flags in
package.json, the behaviour of this command is:
- "~1.2.3" should be upgraded to latest patch version like: "~1.2.4"
- "^1.2.3" should be upgraded to latest minor version like: "^1.3.3"
- "1.2.3" should never be touched
I think saving an extra special file just for when hard coding a package version is too confusing when working with teams. If authors can just have a single script like so:
"update-all-dependancies": "ncu --packageRanges -u && npm i"This way the source of all truth _is_ just the package version range, and no extra files are needed that add clutter and can lead to discrepancies more easily.
This makes total sense. It's an interesting use case, as it wasn't the original intent of the library, but it is entirely coherent.
I feel that
ncu --packageRanges -uis so beautiful.
It's the command of commands. The command that will end all other commands.
Ha. I am enjoying your hyperbolism.
I think --packageRanges can be combined with --semverLevel since they are mutually exclusive and do the same type of thing: setting the allowable range of upgrades. In fact, this also includes --greatest and --newest. Let's do --semverLevel semver for now and we can combine them all in a separate PR. I hope the name change does not curb your zeal in the slightest.
Can I request a little guidance on where you suggest me adding new code ?
Sure!
semverLevel gets converted to versionTarget in queryVersions. Start by adding semver as a valid versionTarget.
Then export a semver function from npm.js. This is where the different filtering logic will go. I would recommend copying greatestMajor and adapting it to use semver.maxSatisfying.
Unit tests can be added with the other --semverLevel tests.
@raineorshine I'll try to see if I can get a PR working.
I'm fine with keeping the --semverLevel flag, but
--semverLevel semver--semverLevel packageRangesJust for clarity's sake.
Because the message I read in my head when comparing these two:
--semverLevel semver--semverLevel packageRangesI hope it's not just in my head, but I think we'll avoid a loot of confusion with the latter as opposed to the former.
I hope you can agree with my opinion, let me know if I can get the green light on that naming scheme!
You have a point. --semverLevel semver is redundant and confusing. I still find that packageRanges to be less than clear. The option is there to constrain upgrades to latest, greatest, newest, or semver (the new option). All of them reference the package ranges, but each of them constrains the upgrades in a different way.
I would suggest one of the following two options:
--semverLevel maxsatisfying - Explicitly references the node-semver comparison--target semver - Use a more generic option name, similar to versionTarget that is already used internally--to semver - Another generic name that reads well literally.Open to feedback.
@raineorshine
Thanks for your insights!
Personally I find --semverLevel maxsatisfying to be clearest in this case. : )
However, I re-read your previous comment and you mention:
In fact, this also includes --greatest and --newest. Let's do --semverLevel semver for now and we can combine them all in a separate PR.
and I think I kind of overlooked this: you want to also come up with alternatives for those --greatest and --newest flags, correct? In this case I will just go ahead with a PR, call it --semverLevel maxsatisfying for now, and you can revisit the naming scheme for everything at a later date.
@medikoo do you have any opinion on naming?
and I think I kind of overlooked this: you want to also come up with alternatives for those
--greatestand--newestflags, correct?
Yes, I believe they should go under the same flag.
In this case I will just go ahead with a PR, call it
--semverLevel maxsatisfyingfor now, and you can revisit the naming scheme for everything at a later date.
Yes! Agree
@mesqueeb Any update? Thanks!
FYI I am currently planning for the next major release consolidating --semverLevel, --greatest, and --newest into a single flag --target with possible values: latest, greatest, newest, patch, minor, major, semver.
Sounds exciting @raineorshine! I just tried v8.0.5 and could not find --target semver. What’s the option to upgrade to the latest available version within the given semver range? (e.g. ^1.2.3 → ^1.99.0, ~1.2.3 → ~1.2.99).
@kachkaev It hasn't been implemented yet. @mesqueeb had originally volunteered, but it's currently open for submissions.
I'll try to get to it eventually, but am a bit swamped in a couple of pending releases for some projects. 😰
if it's not yet implemented in a few weeks I'll probably eventually try my hand at it. seems like a fun journey!
Most helpful comment
Good point! I will keep this open for the feature as requested.