mirror of
https://github.com/semver/semver.git
synced 2026-07-10 19:50:47 -05:00
[GH-ISSUE #89] The concepts of equality, precedence and dependency satisfaction #4309
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @tbull on GitHub (Apr 18, 2013).
Original GitHub issue: https://github.com/semver/semver/issues/89
This appears to be a Java specific question that hit me in the course of implementation. But maybe it's not. Maybe it's a question for underlying concepts.
How should build information be compared? The spec says, it should not be accounted for in a precedence decision. But should it also not be considered when testing for equality? For example, are X.Y.Z+build.1 and X.Y.Z+build.2 equal?
This question might be a little Java specific. Java has the concept, that "the natural ordering for a class C" may or may not "be consistent with equals". This concept is described in the
Comparableinterface, which a class must implement to define a natural ordering on itself. In Java, all objects also have anequals()method, which determines, if two objects are "equal". The question here is if theequals()method's notion of equality and thecompareTo()method's notion are the same.I'm inclined to think that two SemVer objects representing the SemVer strings X.Y.Z+build.1 and X.Y.Z+build.2 are not equal, so
equals()should returnfalse. However, if the build metadata does not influence the ordering,compareTo()would return 0 in this case, which means for matters of the natural order the two objects are equal. This means, the natural ordering for this SemVer class is not consistent with equals.While this is probably not the end of the world, this has some unfortunate consequences in certain usage scenarios. SemVer objects might be used as keys in a
SortedMap, for example in some kind of dependency server. Such a map would violate Java's generalMapcontract, if the ordering in use is not consistent with equals. To remedy this situation, a separateComparatorhas to be provided, which takes build information into account to be consistent with equals.Maybe the actual problem here is a confusion of concepts. With the concepts being
Any thoughts?
@jeffhandley commented on GitHub (Apr 30, 2013):
It will be up to the implementer to decide how to sort builds. I expect many will go with alphanumeric, but it's important for the spec to indicate that precedence cannot be discerned from the build metadata.
Consider 2 build servers running in parallel; build servers A and B. A may start before B even though B finishes before A. If they each stamp the version with build metadata, which should get precedence? It's non deterministic.
I don't think your question is Java specific though, as any implementation will have to make the choice of how to handle Equals and CompareTo.
I propose:
Do you think the spec itself needs to be augmented to reflect this discussion, or can we keep the spec as-is and perhaps create an "Implementation Addendum" as a separate document?
@Tieske commented on GitHub (Apr 30, 2013):
equalshas two implementations;@TimLovellSmith commented on GitHub (May 3, 2013):
Hm. I felt confused about why Equals returns false even if the build metadata is identical?
I think a possible source of confusion here is that there can be many different application specific notions of 'equivalence'. Substitutability for satisfying a dependency is one notion. Being the same exact version identifier for purposes of e.g. cache lookup is another, different notion. And Equals(), CompareTo(), and GetHashCode() are all intended to satisfy the second purpose, not the first.
So Equals(), CompareTo(), and GetHashCode() should all treat build number as significant, and we should impose an arbitrary but consistant order for purposes of CompareTo(). I propose the logical arbitrary order should be same as using string comparison (non-culture-specific, ignore case?), since the 'type' of build identifier is effectively specified as string.
@Tieske commented on GitHub (May 3, 2013):
I don't think so. Build metadata is excluded from any precedence calculations. So it should not be used in the comparison. Imo
equals()returns version compatibility and does not take buildmetadata into account. You could addequalbuilds()to specifically check for that.@Tieske commented on GitHub (May 3, 2013):
additionally
equals()should probably take an optional boolean argument indicating whether pre-release version are allowed, where the default value isfalse.@haacked commented on GitHub (May 6, 2013):
Coming in late here to reiterate what others have already said. Whether the build metadata should come into account when comparing two versions for equality depends on the context.
In any case, I don't think there's anything actionable here for SemVer itself.