Skip to content
This repository has been archived by the owner on Aug 11, 2022. It is now read-only.

Version comparators exclude rc releases #8854

Closed
brentvatne opened this issue Jul 7, 2015 · 16 comments
Closed

Version comparators exclude rc releases #8854

brentvatne opened this issue Jul 7, 2015 · 16 comments
Labels

Comments

@brentvatne
Copy link

I believe if we specify >=0.4, then 0.5, 0.5-rc, 0.5-rc.2 etc should all be considered valid.

This might be intentional, curious to hear why that is if so. With React Native, there is a release candidate published every two weeks, so every library author needs to update their package's peerDependencies on that same interval. This is really messy and it would be best if updates were only required when breaking changes occur.

Related conversation on Twitter

screen shot 2015-07-07 at 4 49 43 pm

cc @linclark

@iarna
Copy link
Contributor

iarna commented Jul 8, 2015

This is intentional:

https://github.com/npm/node-semver#prerelease-tags

If a version has a prerelease tag (for example, 1.2.3-alpha.3) then it will only be allowed to satisfy comparator sets if at least one comparator with the same [major, minor, patch] tuple also has a prerelease tag.

For example, the range >1.2.3-alpha.3 would be allowed to match the version 1.2.3-alpha.7, but it would not be satisfied by 3.4.5-alpha.9, even though 3.4.5-alpha.9 is technically "greater than" 1.2.3-alpha.3 according to the SemVer sort rules. The version range only accepts prerelease tags on the 1.2.3 version. The version 3.4.5 would satisfy the range, because it does not have a prerelease flag, and 3.4.5 is greater than 1.2.3-alpha.7.

The link has some of the further justification for the behavior.

@iarna
Copy link
Contributor

iarna commented Jul 8, 2015

So looking at the related ticket, it looks to me that you want to have a fairly lenient limit on what peer deps you can depend on?

That sounds pretty reasonable! When this semver behavior was being reasoned through it was regarding what behavior made sense for regular dependencies. I think we got those right, but peer deps are a different ball of wax, particularly now (now meaning w/ npm@3) that we aren't installing them. I would absolutely want to allow otherwise matching prerelease versions w/ my peer dependencies.

@iarna
Copy link
Contributor

iarna commented Jul 8, 2015

On the plus side, w/ npm@3, having a non-matching peer dep is now just a warning.

@iarna iarna changed the title Bug: Version comparators exclude rc releases Version comparators exclude rc releases Jul 8, 2015
@brentvatne
Copy link
Author

So looking at the related ticket, it looks to me that you want to have a fairly lenient limit on what peer deps you can depend on?

Exactly!

That sounds pretty reasonable! When this semver behavior was being reasoned through it was regarding what behavior made sense for regular dependencies. I think we got those right, but peer deps are a different ball of wax, particularly now (now meaning w/ npm@3) that we aren't installing them. I would absolutely want to allow otherwise matching prerelease versions w/ my peer dependencies.

I believe even with npm 2 latest, peerDependencies are not being installed. It makes perfect sense to ignore the rc's in the context of actual direct dependencies, thanks for that explanation!

If you don't have time to take this on for a bit, I could try to put together a pull request. I'm guessing a good starting point would be npm/deps.js on the 2.x branch?

Thanks for the quick reply @iarna and for all of your work on npm!

@iarna
Copy link
Contributor

iarna commented Jul 8, 2015

@brentvatne No, npm@2 warns that the current use of peer deps is deprecated, but it does still install them (although not always where you want).

npm/install/deps.js exists only in master (w/ npm@3).

Before you jump in with changes, I'd like to get a bit more consensus on the nature of the changes from the rest of our team: @othiym23, @zkat, how do you feel about the behavior described in #8854 (comment) ?

@brentvatne
Copy link
Author

This is what happens any time a new version is released :(

╰─$ npm i
npm WARN peerDependencies The peer dependency react-native@>= 0.4 || 0.5.0-rc1 || 0.6.0-rc included from react-native-blur will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
npm WARN peerDependencies The peer dependency react-native@>=0.4.2 || 0.5.0-rc1 || 0.6.0-rc || 0.7.0-rc || 0.7.0-rc.2 included from react-native-overlay will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
npm WARN peerDependencies The peer dependency react-native@>=0.4.3 included from react-native-modal will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
npm WARN peerDependencies The peer dependency react-native@>=0.5.0 <1.0.0 included from react-native-icons will no
npm WARN peerDependencies longer be automatically installed to fulfill the peerDependency
npm WARN peerDependencies in npm 3+. Your application will need to depend on it explicitly.
npm ERR! Darwin 14.4.0
npm ERR! argv "/Users/user/.nvm/versions/io.js/v2.3.4/bin/iojs" "/Users/user/.nvm/versions/io.js/v2.3.4/bin/npm" "i"
npm ERR! node v2.3.4
npm ERR! npm  v2.12.1
npm ERR! code EPEERINVALID

npm ERR! peerinvalid The package react-native does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer react-native-blur@0.5.3 wants react-native@>= 0.4 || 0.5.0-rc1 || 0.6.0-rc
npm ERR! peerinvalid Peer react-native-icons@0.1.0 wants react-native@>=0.5.0 <1.0.0
npm ERR! peerinvalid Peer react-native-modal@0.3.8 wants react-native@>=0.4.3
npm ERR! peerinvalid Peer react-native-overlay@0.2.7 wants react-native@>=0.4.2 || 0.5.0-rc1 || 0.6.0-rc || 0.7.0-rc || 0.7.0-rc.2
npm ERR! peerinvalid Peer tcomb-form-native@0.2.2 wants react-native@>=0.5.0

@SpainTrain
Copy link

This issue is especially frustrating when the package author has used a range of * for a peer dependency that then causes an error if a prerelease version is installed. In this case the author's intentions are very clear that

@brentvatne
Copy link
Author

@isaacs - any comment on this? thanks :)

@sophiebits
Copy link

I hope that npm can support this use case. It seems like React Native's use of this is the exact case that peer dependencies were designed for. The changes in npm 3 to peer dependencies are appreciated and align well with RN's expectations, but the fact that prerelease versions are excluded from ranges (especially >= and *) seems to have made them peer dependencies but useless for the React Native community.

You can see above on this issue that a large handful of projects are removing their peer dependencies to work around this issue, even though (to my understanding) this is exactly what peer dependencies are for.

Thanks for considering.

@zkat
Copy link
Contributor

zkat commented Jan 7, 2016

Our understanding here, based on experience and long discussions surrounding semver@3, is that semver prereleases are not intended for this sort of use-case -- that is, peerDependencies and such ecosystem packages. In the end, npm has placed its bets on semver, and this particular treatment of semver when it comes to ranges was simply understood to be the right thing.

prereleases do probably have some usefulness left when it comes to individual packages, though.

The practical response for the sake of solving the specific problem at hand here is to point you to the release process we developed during npm@2: we have next and latest tags, and the actual biggest semver release doesn't become latest (and thus the default installed by npm i), until a week afterwards -- this, combined with the deprecation mechanism for releases found to be broken during that "prerelease period", should be good enough for your needs, I think?

I hope this helps clarify it at all -- I'll close this issue now, since we consider this the best resolution we can provide. There is also some discussion about things such as release channels out in the issue tracker for semver that could be of interest!

@zkat zkat closed this as completed Jan 7, 2016
@sophiebits
Copy link

If I am reading the linked issue right, it sounds like 1.2.3-rc would match >= 1.0.0 in the semver spec but node-semver chooses to diverge? I may be reading that wrong.

The tag idea is a good one. I'll see if we can do that – thanks.

drtangible added a commit to bjornco/react-native that referenced this issue Mar 18, 2016
… dependency.

* Workaround since npm doesn't match -rc versions. See RN team's input here: npm/npm#8854.
drtangible added a commit to bjornco/react-native that referenced this issue Mar 18, 2016
… dependency.

* Workaround since npm doesn't match -rc versions. See RN team's input here: npm/npm#8854.
drtangible added a commit to bjornco/react-native that referenced this issue Mar 18, 2016
… dependency.

* Workaround since npm doesn't match -rc versions. See RN team's input here: npm/npm#8854.
@ide
Copy link

ide commented May 7, 2016

Can we revisit this behavior? In practice people use prerelease versions (ex: react@15.0.3-alpha.1 is the version in question) and the fact that they don't match peerDependency versions like "react": "^15.0.0" makes prerelease versions not very useful. The specific case I'm running into is:

  • react@15.0.3-alpha.1 has been published to npm
  • react-native has a peerDependency requirement of 15.0.3-alpha.1 exactly
  • react-redux has a peerDependency requirement of ^15.0.0-0

These three packages work together fine in theory but npm considers react@15.0.3-alpha.1 not to satisfy react-redux's peerDependency version of ^15.0.0-0. Rhetorically speaking, what's the point of prerelease versions if early adopters get errors because of the way npm checks peerDependency versions?

Thinking about a practical solution, I believe peerDependencies should follow the semver convention that dependencies & devDependencies use. It's consistent and matches what people want to do in practice as far as I can tell from issues like hapijs/hapi#2208 and the other ones linked here.

Edit: I learned that 15.0.3-alpha.1 doesn't satisfy "^15.0.0" even for dependencies and devDependencies, so I'd like to propose a small change to how semver works when validating dependencies, devDependencies, and peerDependencies between package.json and node_modules:

Version strings of the form MAJOR.MINOR.PATCH-PRERELEASE should satisfy patterns of the form "^MAJOR.${MINOR that's less than or equal to the actual package's minor version}.${PATCH that's less than the actual package's patch version of the minor versions are equal}". These are some examples of matching patterns with 1.2.3-alpha.1:

pattern result
^1.0.0 matches
^1.2.2 matches
^1.1.9 matches
^1.2.3 does not match

@gaearon
Copy link

gaearon commented May 7, 2016

As the publisher of react-redux I want to say “I’m fine with whatever prerelease of React 15.x as a peer because the burden and conscious decision to install it was on the application developer”.

When an app developer specifies 15.x in their dependencies, they need to be careful to avoid prerelease because they might accidentally break their app. I understand this.

However I as a plugin author don’t have the capacity to vet every single prerelease of the library I peer depend on, and promptly release updates that just bump the number. I want to specify that I trust the application developer to install prerelease versions of the package I peer depend on at their own risk, and the only restriction I care about is the major range.

I'm considering removing peer dependencies from my projects because of this. Generally I find them very useful but I don't want to block people who just want to test early versions of my peer deps.

jeanregisser added a commit to jeanregisser/react-native-popover that referenced this issue May 27, 2016
ethul added a commit to ethul/purs-loader that referenced this issue Jun 4, 2016
Adds support for PureScript 0.9.1 and newer (purescript/purescript#2151)

The `next` tag on NPM points to this pre-release. Also note that
`peerDependencies` has been removed (npm/npm#8854).

Resolves #54
@pwfisher
Copy link

The * range should absolutely match any version, prerelease or not. I consider it a bug that it does not.

@othiym23
Copy link
Contributor

othiym23 commented Aug 8, 2016

@pwfisher If you want to make that argument, node-semver is the place to plead your case, as that's where that behavior is defined. You might want to review the rationale for this behavior in semver@4. While that rationale has proven to be counterintuitive for many users, it was deliberately chosen, and changing it again would require a similarly considered justification.

@ide
Copy link

ide commented Aug 8, 2016

@othiym23 One reason the npm repo could be the right place to open this issue is that I believe there's a good argument that semver semantics for peerDeps should be different than that for deps.

My thinking comes from the fact that deps are implicitly installed while peerDeps are explicitly installed. It is understandable that npm does not install version 15.1.0-rc of a package when its dependent's package.json asks for ^15.0.0. However I believe that if version ^15.0.0 of this package is listed as a peerDep (instead of a dep) then 15.1.0-rc should satisfy the peerDep requirement.

Strate added a commit to megaplan/mobx-react-devtools that referenced this issue Oct 17, 2016
It is hard to use pre-release versions of mobx & mobx-react with this requirements.
See also npm/npm#8854 (comment)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

9 participants