Open 246859 opened 1 month ago
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
cc @rsc seems like 1.8.5 was the only patch version to have release candidate tags? ref #22264
The reason go1.8.5rc5 sorts as oldest is because the go/version package doesn't consider it valid; go1 isn't very relevant as you could pick any other valid version to compare with. Compare docs include:
Invalid versions, including the empty string, compare less than valid versions and equal to each other.
And version.IsValid("go1.8.5rc5") reports false.
These case will not happen If I get versions from
https://go.dev/dl/?mode=json&include=all
, becausego1.8.5rc5
andgo1.8.5rc4
is not exist in that list.
Interestingly, go1.9.2rc2
is an old Go version that can be downloaded from https://go.dev/dl/#go1.9.2rc2 and exists in the versions list API output, but doesn't have a corresponding tag.
I asked about the intended behavior these IsValid edge cases in https://github.com/golang/go/issues/62039#issuecomment-1680697372 but I don't see an answer there.
Interestingly, go1.9.2rc2 is an old Go version that can be downloaded from https://go.dev/dl/#go1.9.2rc2 and exists in the versions list API output, but doesn't have a corresponding tag.
I found this point too when I tested it more deeply, and version.IsValid
doesn't seem to be dealing with prereleases (alpha, beta, rc) for patch releases, as the comments says:
// Parse patch if present.
if x[0] == '.' {
v.Patch, x, ok = cutInt(x[1:])
if !ok || x != "" {
// Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != "").
// Allowing them would be a bit confusing because we already have:
// 1.21 < 1.21rc1
// But a prerelease of a patch would have the opposite effect:
// 1.21.3rc1 < 1.21.3
// We've never needed them before, so let's not start now.
return Version{}
}
return v
}
I don't think this is a rational reason to disallowing prereleases for patch releases
We've never needed them before, so let's not start now.
So I'd like to create a pull request to solve this.
Change https://go.dev/cl/602096 mentions this issue: go/version,internal/gover: treat prerelease patch as valid version
At this time it's not clear to me that the scope of this package intends to consider a number of one-off old (pre-go1.21.0) releases that followed the "goA.B.CrcN" pattern as valid. The package comment says:
Package version provides operations on Go versions in Go toolchain name syntax: strings like "go1.20", "go1.21.0", "go1.22rc2", and "go1.23.4-bigcorp".
Only "goA.BrcN" pre-release version strings come up in https://go.dev/doc/toolchain. The current release process includes only those pre-release versions, there aren't pre-releases for minor Go releases, so version.IsValid correctly reports true for all planned future Go release versions.
Maybe @rsc has more thoughts on this, otherwise I don't expect the behavior of version.IsValid
on old versions strings (i.e., before go1.21.0) needs any changes.
At this time it's not clear to me that the scope of this package intends to consider a number of one-off old (pre-go1.21.0) releases that followed the "goA.B.CrcN" pattern as valid. The package comment says:
Package version provides operations on Go versions in Go toolchain name syntax: strings like "go1.20", "go1.21.0", "go1.22rc2", and "go1.23.4-bigcorp".
Only "goA.BrcN" pre-release version strings come up in https://go.dev/doc/toolchain. The current release process includes only those pre-release versions, there aren't pre-releases for minor Go releases, so version.IsValid correctly reports true for all planned future Go release versions.
Maybe @rsc has more thoughts on this, otherwise I don't expect the behavior of
version.IsValid
on old versions strings (i.e., before go1.21.0) needs any changes.
Thanks for your patient replying.
Actually the cause of this issue is that I wrote a tiny cmd tool a week ago which could manage multiple versions for go. At the beginning of the work, the go version rules make me confused. After scanning docs about Go version, I found rules as
below:
I think I should handle all possible situations, so I tried to depend on std pkg go/version
to deal with them. Then the scene I described at the issue beginning happened.
Although I no longer rely on this pkg now, I still have some questions:
verson.IsValid("go1.9.2rc2")
report falseversion.Compare("go1.9.2rc2", "go1")
= -1slices.Sort
and slices.Min
may produce wrong output when input contain prerelease patch versionsI'd be glad if you could answer these questions
Go version
go version go1.22.5 windows/amd64
Output of
go env
in your module/workspace:What did you do?
When I try to sort go version list that got from below command
I got an incredible result that the version
go1.8.5rc5
is the minimum version, even less thango1
. The reason is thatgo/version.IsValid
do not consider prerelease patch as valid version, but some prerelease patch really do exist in history versions, such asgo1.8.5rc5
,go1.8.5rc4
,go1.9.2rc2
.The versiongo1.9.2rc2
even could be discovered from https://go.dev/dl/?mode=json&include=all, and downloaded from https://dl.google.com/go/go1.9.2rc2.linux-amd64.tar.gz, it's very unreasonable to treat it as an invalid version.Here is a snippset to prove this: https://go.dev/play/p/TBz7px5tMd_8
What did you see happen?
output
What did you expect to see?
output