Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The ~ operator should not accept pre-releases #21

Closed
technosophos opened this issue Oct 11, 2016 · 9 comments
Closed

The ~ operator should not accept pre-releases #21

technosophos opened this issue Oct 11, 2016 · 9 comments
Assignees
Labels

Comments

@technosophos
Copy link
Member

The filter ~1.4.1 should match 1.4.2 but not 1.4.2-beta.1. Currently it allows the pre-release flags.

@sdboyer
Copy link
Member

sdboyer commented Oct 12, 2016

There's differences on extant implementation with this. npm and cargo, for example, simply exclude prereleases. pub, OTOH, includes them, but not at the edge of the range (so, ~1.4.2 does include 1.4.2-beta.1, but not 1.5.0, AND ALSO not 1.5.0-beta.1), and also sorts them lower.

Implicit in this is that, IMO, we should be talking about general semantics of ranges, rather than one operator or another. That is, rather than describing the issue as "The ~ operator should not accept pre-releases," it should be "Ranges should not accept pre-releases." Otherwise, these would suddenly start meaning different things:

~1.4.1
>=1.4.1, <1.5.0

@mattfarina
Copy link
Member

I would say that ranges should not accept pre-releases. For some reason I thought pre-releases were already excluded so I personally consider this a bug.

Does that work @technosophos @sdboyer?

@sdboyer
Copy link
Member

sdboyer commented Oct 13, 2016

it's definitely an easier solution than the pub approach. and in the general case, i agree.

i wonder if it matters for people who actually WANT prereleases, though. does it make sense that if, say, you specify ~1.0.0, you don't get prereleases, but if you specify ~1.0.0-alpha.1, then you do?

@technosophos
Copy link
Member Author

I think Section 9 of SemVer 2 makes it pretty clear that pre-releases are not considered compatible with anything else.

A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version.

If that's the case, then a pre-release should not be considered to match compatibility requirements of a range, which implies compatibility level with everything in the range.

@sdboyer
Copy link
Member

sdboyer commented Oct 13, 2016

Sure, OK, that makes sense.

But...ranges aren't actually something described by the semver spec. The ~ and ^ operators are something either npm or gems (I think?) came up with. If we interpret those as compatibility operators, then yes, it would follow from that part of the spec that they couldn't possibly include prereleases, because there is no implied compatibility relationship between them. OTOH, if we view them as arithmetic operators, that's less clear.

Of course, if we follow this rule and want to consistently apply the idea of compatibility operators, then we should adhere to Section 4 as well, which dictates that no compatibility relationship is implied by ANY versions with major version 0. So, those operators are just meaningless pre-1.0.

At some point, this goes back to my original comment - is a range the same thing as a compatibility operator? If so, and we apply these rules, then it becomes difficult to include any sort of prerelease with any sort of range (though not impossible: you can specify e.g. ~1.0.1 || 1.0.2-alpha.1 || 1.0.2-alpha.2). That gets arduous, and you can't "update to" new upstream prereleases without explicit statements in the manifest.

Maybe that's bad. It's pretty common for software to sit, endlessly, at pre-1.0.0. logrus is one of the most commonly imported public Go projects, and all of its releases are 0.x. Do we really want to create a situation where there are lots of projects having diamond dep conflicts on logrus simply because the declaration system makes it difficult to declare a wide range?

Or maybe that's good, because it will create pressure for projects like logrus to actually tag a 1.0.0 release. And thereby, push people towards really embracing semver - that it's not the end of the world to have breaking changes, because that just means bumping the major version, and the tooling can work around that.

These questions are difficult to answer from the perspective of their likely effects, so I don't really have an opinion on what's best here (apart from wanting to keep the range operators synonymous, to control complexity of the declarations). If I had to make a decision, I'd probably opt for strict adherence to semver, because that at least provides more consistent rules for the system. But I also know the deep-seated dread that comes from releasing a 1.0.0, and I doubt that shouting "SEMVER!" from the rooftops will change that. And I wouldn't want to create an ecosystem where the easy/default behaviors aren't useful for the bulk of the actual projects out there.

@sdboyer
Copy link
Member

sdboyer commented Oct 20, 2016

Oooh. Actually. I like what Cargo does - it kinda splits the difference:

^1.2.3 := >=1.2.3 <2.0.0
^1.2 := >=1.2.0 <2.0.0
^1 := >=1.0.0 <2.0.0
^0.2.3 := >=0.2.3 <0.3.0
^0.0.3 := >=0.0.3 <0.0.4
^0.0 := >=0.0.0 <0.1.0
^0 := >=0.0.0 <1.0.0

@technosophos
Copy link
Member Author

Yeah, I think what Cargo does is good. The deal with the -alpha/-beta/etc prerelease modifiers is that I feel like they are intended to convey that the product is (a) usable, but (b) subject to change. By versioning them this way, the developers are signaling that it is acceptable for an alpha/beta to be incompatible with both earlier and later releases.

This differs from the 0.y.z case, where it seems increasingly common for projects to stay below 1.0.0 for no apparently reason.

@mattfarina mattfarina added the bug label Oct 25, 2016
@mattfarina
Copy link
Member

What @sdboyer outlined is what I had originally intended. I consider the current state a bug. But, due to the nature of the change I'm debating wether this should be labeled a minor change rather than a patch when released.

@mattfarina
Copy link
Member

@sdboyer @technosophos can you take a look at #23. It's not exactly what we said here but close. Tries to deal with some backwards compatibility situations. If it looks ok I'll update the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants