Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Make version="v1.2.3" and version="=v1.2.3" equivalent or throw an error #929
What version of Go (
hi! i know this is something that can be confusing and frustrating, and we need to improve docs around it.
as a practical matter, we're locked into it now - changing the meaning of the symbols (so that
but, we have to give it an honest shot. people expressing unnecessarily narrow constraints to serve immediate-term needs is a path that could land us all, as a community, in painful dependency hell. this mechanism is one of a set that helps nudge us in a different direction. this is a nuanced and carefully-weighed design choice that, unfortunately, really only makes sense in the big picture; i need to write a blog post laying it out.
the basic reason we believe this tradeoff is acceptable is because your
if, OTOH, you actually ran
couple more thoughts...
just to be clear, we fundamentally agree on this. the issue is the expectations for when that happens, and the corresponding approach taken to achieving goals.
there certainly are cases where it make sense to aggressively restrict to only a single version of a dependency. but, most of the time, the goal folks are looking to achieve is stability for now. that is, in your case, is it true that your application only works with
the former case is less common, so we give it the more awkward constraint syntax. the latter case is the overwhelming majority, so we prioritize it with an implicit
when constraints are narrowed to a single version,
there are some additional flags and behaviors we could introduce to make this an even safer process, even with the open constraints, and i'm entirely open to doing that.
How come the second line is constrained on the minor range (
- 0.2.3 becomes the range >=0.2.3, <0.3.0 + 0.2.3 becomes the range >=0.2.3, <1.0.0
technically, we can't assume anything about the relationship between versions in the zero range. if we were to follow that strictly, then the caret - which it is helpful to think of as a "compatibility" operator, rather than a numerical one - should be meaningless below 1.0.0.
such is the algorithmic and dependency-hell-avoiding importance of having open constraints that we're willing to dance into this territory. but nuances like these are exactly why all this needs a blog post, as well as probably its own dedicated help section.
If there was no magic implying caret for stable releases then there would be no need for a yet another, different magical behaviour for the 0.x.x versions.
It's still just carets below 1.0.0 - no new magic.
this would still invalidate old, already-committed
now, we could probably apply the extra validation you describe only for the current project's constraint declarations, but use the implicit caret for
however, every counterargument to this, both here and on the reddit thread, has focused on peoples' dislike for the narrow, immediately-obvious problem that implicit carets are surprising and non-obvious.
i don't dispute that it can be counterintuitive and frustrating when you first encounter it. i never have. but we didn't just do this to annoy people - there are larger tradeoffs to weigh here, which i've at least summarized above. the arguments i need to see to move on this must take this bigger picture into account.
referenced this issue
Aug 18, 2017
@sdboyer Another suggestion, a bit silly, that could elevate some of the issues around this:
If we implicitly add a caret (e.g.
That way we keep the current behavior while preserving the stability of manifests. In the same time, we nudged people towards explicitly using carets.