golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.01k stars 17.54k forks source link

cmd/go: accept tags of the form X.Y.Z (without leading 'v') as semantic versions #32945

Closed tamalsaha closed 2 years ago

tamalsaha commented 5 years ago

What version of Go are you using (go version)?

$ go1.13beta1 version
go version go1.13beta1 linux/amd64
$ go version
go version go1.12.6 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env

GOARCH="amd64"
GOBIN=""
GOCACHE="/home/tamal/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/tamal/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build803673677=/tmp/go-build -gno-record-gcc-switches"

What did you do?

$ go1.13beta1 get github.com/kubedb/apimachinery@v0.11.0
go: finding github.com/kubedb/apimachinery v0.11.0
go: finding github.com/kubedb/apimachinery v0.11.0
go: finding github.com v0.11.0
go: finding github.com/kubedb v0.11.0
go get github.com/kubedb/apimachinery@v0.11.0: unknown revision v0.11.0

$ go1.13beta1 get github.com/kubedb/apimachinery@0.11.0
go: finding github.com/kubedb/apimachinery 0.11.0

We use the git tag also as the Docker image tag. I like kubedb/operator:1.0.0 (without v) over kubedb/operator:v1.0.0. So, we went with that. Tools like glide, dep will automatically handle the presence or absence of v. But go mod does not do that.

What did you expect to see?

My question is can go mod automatically search for both of these prefixes?

What did you see instead?

bcmills commented 5 years ago

See previously #30146.

bcmills commented 5 years ago

CC @jayconrod

To reiterate from that discussion: the difference is mainly aesthetic and relatively arbitrary. Absent a compelling need otherwise, Go usually resolves aesthetic differences by picking one to use consistently (think of gofmt), not supporting both.

jayconrod commented 5 years ago

+1 to not supporting this. It's unfortunate that different systems have different standards for this, but supporting both formats would lead to ambiguity and confusion. For example, both vX.Y.Z and X.Y.Z might exist and point to different commits.

go release should probably warn against creating such a version accidentally in the future.

bcmills commented 5 years ago

supporting both formats would lead to ambiguity and confusion

Note that there is a similar problem for build metadata, which we resolve (in Go 1.13) by resolving to a unique pseudo-version derived from the tagged version.

mattharr-is commented 4 years ago

i think the ironic part about all of this is this bit in the semver.org FAQ https://semver.org/#is-v123-a-semantic-version In my case, we have an existing build system that handles repo versioning and tagging for us, using standard semver format (no v prefix). When one reads the go module docs about how it all works with a "standard semver format", and then seeing that it's not actually standard semver format, is a bit confusing. It also requires retooling some build processes that actually do follow the standard.

alexellis commented 4 years ago

+1 cc @LucasRoesler @Waterdrips @stefanprodan - we were all hit by this today, we use semver but "the valid way" i.e. without a "v" prefix and dep was fine for us - we could have a proper tag in our dependency file, but now we're stuck with lots of v0.0.0 SHA in all our code. Was hoping that moving to go modules was going to be a pleasant, pain-free upgrade.

We don't want to change the tags if we can avoid it because semver itself recommends against no prefix and also, we rely on the numbering for Docker images.

gudvinr commented 4 years ago

We consistently use unprefixed tags X.Y.Z versions across all of the internal projects. Some of them are shared between projects and not every project is written in Go. This is really annoying requirement because it is not language-related but still ruining existing workflow.

Arguments like "you may have both prefixed and unprefixed tags in repo" is quite silly because if you do have such tags in your repo you probably have a bigger problem with your VCS already.

You may as well have very old commit tagged by higher version number and this also doesn't look right. You may have tags with same version and different metadata which is not used in version comparison too.

gudvinr commented 4 years ago

the difference is mainly aesthetic and relatively arbitrary.

@bcmills This is not aesthetic for projects that existed outside of Google (and companies that use prefixed tags) before introduction of go modules. It is messing up with build process.

Reference to gofmt also seems wrong here. gofmt is tool for Go language only and can't interfere with anything outside Go ecosystem, but requirement on git tags leads to unwanted changes.

taiidani commented 4 years ago

Agreeing with the above. My company is highly polyglot among multiple languages but our release and tagging automation is reused between them. We implemented this logic using the "correct" semver way without the "v" prefix.

It will be an extremely bitter pill to swallow if we have to update our automation and [ideally] re-tag all of our repositories to add the "v" prefix because of one languages' requirement.

MCBrandenburg commented 4 years ago

I'm in the a similar boat to @taiidani, trying to get a company to prefix with their already automated process with a v to satisfy the case for go https://github.com/FusionAuth/go-client/pull/32

mieubrisse commented 3 years ago

Another +1 - we started our project using X.Y.Z the official semver way, but consumers of our library are confused as to why the go.mod file ends up as v0.0.0-YYYYMMDDSSSSS-abcd1234

FiloSottile commented 3 years ago

This does not feel worth introducing conflicts and confusion about which of two tags v1.2.3 and 1.2.3 is the correct one. Moreover, we definitely should not magically promote to versions existing unprefixed tags without any action on the repository's part, which would require yet another complexity axis (like the go.mod version).

About unprefixed tags being the "official" way, I don't think that's what the docs say. The semver FAQ explicitly calls out using v as a prefix for git version tags (not all git tags are versions), and this is the GitHub help sidebar in the release page.

image

gotgenes commented 3 years ago

@FiloSottile Would you mind sharing a link to the direct source of the text in that screenshot?

I don't see the text you screenshotted in the Semantic Versioning FAQ. Moreover, as of the 2.0.0 spec, the FAQ has little to say on using "v"-prefixes in tags, and what it does is far from a mandate:

Is “v1.2.3” a semantic version?

No, “v1.2.3” is not a semantic version. However, prefixing a semantic version with a “v” is a common way (in English) to indicate it is a version number. Abbreviating “version” as “v” is often seen with version control. Example: git tag v1.2.3 -m "Release version 1.2.3", in which case “v1.2.3” is a tag name and the semantic version is “1.2.3”.

( Direct link to the text above: https://semver.org/spec/v2.0.0.html#is-v123-a-semantic-version )

If anything, the text reads favorably to omitting a v-prefix from tags.

Note also that the suggested regular expression to parse a semver string omits handling a v-prefix: https://semver.org/spec/v2.0.0.html#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string

gudvinr commented 3 years ago

About unprefixed tags being the "official" way, I don't think that's what the docs say.

@FiloSottile Except it's exactly what they say?

Is “v1.2.3” a semantic version?

No, “v1.2.3” is not a semantic version. However, prefixing a semantic version with a “v” is a common way (in English) to indicate it is a version number. Abbreviating “version” as “v” is often seen with version control.

They only mention that it is common way of doing so. But common doesn't even mean "most people do that".

this is the GitHub help sidebar in the release page

If you are willing to go this route, here's quote from GitLab help page:

The release tag name should include the release version. GitLab uses Semantic Versioning for our releases, and we recommend you do too. Use (Major).(Minor).(Patch), as detailed in the GitLab Policy for Versioning.

gudvinr commented 3 years ago

This does not feel worth introducing conflicts and confusion about which of two tags v1.2.3 and 1.2.3 is the correct one.

@FiloSottile What's wrong with consistent version scheme which doesn't use prefix? For repositories that use only unprefixed tags it will change nothing at all.

Current scheme forces you either to continue natural version order (e.g. from X.Y.Z to vX+1.0) which also leads to breaking existing packages who depend on yours or to wrap around to v1.0 and start over with breaking CI and maybe something else leading to even more confusion. There's also an option to stick with "handy" pseudo-tags which you can't say won't cause confusions.

Are there real word cases where it will introduce conflicts which can't be resolved in sane way?

davecheney commented 3 years ago

What's wrong with consistent version scheme which doesn't use prefix? For repositories that use only unprefixed tags it will change nothing at all.

@gudvinr way back in #12302 it was discovered that the majority of the large Go projects used the v prefix on their tags. A scheme which would imply that all the tags from those projects would be unusable was a non starter. I don't know why the folks who wrote the semver spec didn't follow the advice in their own product (disclaimer, I work for github) but the boat has well and truely sailed on this one.

gotgenes commented 3 years ago

In the words of a wise young woman, "¿Por qué no los dos?" :-)

This proposal here is, "Accept tags without the leading 'v'." The implication is "in addition to tags with a 'v'-prefix." The implication is not, "to the exclusion of tags with 'v'-prefix."

davecheney commented 3 years ago

The argument I made in #12302 was this is not an opportunity to apply Postel’s law. Iff tags could have an optional v tag, then every tool that interoperates with the Go ecosystem will have to rediscover this compromise position independently.

gudvinr commented 3 years ago

If tags could have an optional v tag, then every tool that interoperates with the Go ecosystem will have to rediscover this compromise position independently.

Based on 1.16 announcement, according to our 2020 Go Developer Survey, 96% of Go developers have made the switch [to go modules]. This means that external package management tools aren't widely present in active part of Go community.

Apart from that, are there tools that do not use modfile to work with go.mod files? Since this package appears recommended to be used by such tools, will it really have impact on every tool?

go/mod repository also says

The specific case of loading packages should still be done by invoking the go command, which remains the single point of truth for package loading algorithms.

@davecheney you also mentioned in #12302 that

The preference for a v prefix comes from observations <...>, it is also widely used by our language contemporaries like Rust, Nodejs and Bower (javascript).

But I see on crates.io that official-ish packages do not use v prefix and npm also has tag-version-prefix which may be set per-package. Although in the latter case they raise the same concern:

Because other tools may rely on the convention that npm version tags look like v1.0.0, only use this property if it is absolutely necessary.

davecheney commented 3 years ago

Based on 1.16 announcement, according to our 2020 Go Developer Survey, 96% of Go developers have made the switch [to go modules]. This means that external package management tools aren't widely present in active part of Go community.

I think that gives weight to the status quo; most of the module tags in the Go ecosystem carry a v prefix. Relaxing that restriction now adds confusion.

Apart from that, are there tools that do not use modfile to work with go.mod files?

If they're not written in Go, i'd say that's quite likely.

But I see on crates.io that official-ish packages do not use v prefix and npm also has tag-version-prefix which may be set per-package

The situation might have changed in the years since I wrote that, but as it stands today there is no confusion about what a version tag looks like in Go, it's v<semver>. Why add confusion to what is an already bumpy rollout of go modules?

gudvinr commented 3 years ago

Relaxing that restriction now adds confusion.

How? What you have in go.mod is version identifier specific to go mod package tool. What you have in VCS is tag which is not specific to Go and not a part of Go ecosystem.

docker uses v-prefixed tags for their versions. But at the same time debian package uses unprefixed version for Go package. As well as their own docker hub entry

If they're not written in Go, i'd say that's quite likely.

Are there popular tools that target go modules specifically and not written in Go?
Tools that supposed to work with broad range of package management systems for different languages likely already v-aware since PYPI doesn't have prefixes, CPAN doesn't have them too, C/C++ package management probably sometimes do but I never saw ones.

gotgenes commented 3 years ago

From my perspective, opponents to this proposal seem to be arguing that proponents lack empathy for the increased support burden this will place on not just the Go core tooling, but on downstream tools.

And from my perspective, I have to agree that I could use more help empathizing. The arguments are abstract and hypothetical. Concrete examples would really help here. When we say, "then every tool that interoperates with the Go ecosystem", what specific tools are we actually talking about that exist today? When we say, "Relaxing that restriction now adds confusion," what, specifically, will be confusing?

Again from my perspective, the proponents for this proposal are calling for empathy for users who are surprised by the current behavior, users who are used to not adding "v" prefixes for projects in other language or technology ecosystems, and users for whom it is easier to convince a FOSS project to be more permissive than it is to change practices within their own organizations (as crazy as that might seem, if you have yet to experience this).

FiloSottile commented 3 years ago

A specific example is any project that currently has only a few unprefixed tags, maybe from early experimentation, and no prefixed tags, for which latest currently resolves to the default branch HEAD as a pseudo-version. If this change was introduced, those projects would suddenly rollback to the highest unprefixed tag.

If we chose to mitigate this by gating unprefixed tags on the go.mod version, now we'd have to fetch the content of the tree to decide what the latest version is, as opposed to just getting a git ref list, to a significant performance loss and complexity increase. In particular, since the go.mod changes between tags, the behavior would be subtle: what do you expect from a repository that does NOT opt-in to unprefixed tags in the go.mod of the highest unprefixed tag, but does opt-in at HEAD of the default branch (currently latest)? What if some other lower unprefixed tags do opt-in?

Next let's think about module proxies. Since they can be used from both old and new versions of Go, they will need to be updated to serve versions with both unprefixed and prefixed tags. However, an old version of Go would not resolve latest to an unprefixed tag with GOPROXY=direct, and the behavior should definitely be kept consistent, so the proxy protocol would have to be updated to present a split view to clients based on whether they support unprefixed tags.

Even if tooling and services were changed to accomodate all that, users would have to learn that unprefixed tags work sometimes, depending on the contents of go.mod and the version of Go used to fetch it and whether proxies are doing the correct post-processing.

As always, complexity is emergent, and can't be limited by enumerating its concrete outcomes.

gudvinr commented 3 years ago

@FiloSottile first of all, these kind of changes should be opt-in, for example as new 1.17 tags (I have an urge to pull confusion card here but let's keep discussion healthy).

If this change was introduced, those projects would suddenly rollback to the highest unprefixed tag.

Even if you won't introduce changes, adding prefixed tag will break go mod in the exact same way.
I think this can be mitigated by checking go version inside go.mod after the fact. If project has go version bigger than "go version where such change was introduced" then handle it as valid version. Otherwise put +incompatible or something of sorts. It kind of works same way with prefixed tags.
I don't know whether it is a good idea or not but it has its drawbacks. It won't silently break dependency cycle for end users (who are willing to opt-in) but package provider must update go version. Last one isn't a bad thing considering official support for N-1 versions and good backward compatibility code-wise.

we'd have to fetch the content of the tree to decide what the latest version is, as opposed to just getting a git ref list

Yes, but no. To put +incompatible tag go mod need to ensure that at least go.mod file is present for given tag. It does that only for latest version. You don't really need to know whether every version has compatible go.mod or not because you don't do that for every prefixed version.

What if some other lower unprefixed tags do opt-in?

What if some other lower prefixed tags have go.mod and other don't? What if prefixed tag with bigger semver placed at lower commit by accident or because it exist from early experimentation?

Couple of project from libs.garden popular list did use unprefixed versions before introduction of go modules (and one of them does today). Notably, prometheus had unprefixed versions up until v1.0.0. You may see that they used old notation and switched to another. Let's not argue about "they did a switch and you must too" and keep in mind that they only have github projects, apparently.
I won't mention other ones, but point is that from, like, hundred of projects there was only five-ish with wild unprefixed tags and even them didn't have such issue. It was either typo and there was no prefixed tag with such version or it was a tag with exact same version on the exact same commit.

Since they can be used from both old and new versions of Go, they will need to be updated to serve versions with both unprefixed and prefixed tags, <...> so the proxy protocol would have to be updated to present a split view to clients based on whether they support unprefixed tags.

Yes, that one is hard to argue with but not unsolvable

Even if tooling and services were changed to accomodate all that, users would have to learn that unprefixed tags work sometimes

Same with other opt-in features introduced by Go team during transition period. For average folk, after couple of Go releases, it won't be noticeable.

As always, complexity is emergent, and can't be limited by enumerating its concrete outcomes.

Indeed, it can't be. Although, you can't prove absence of something (in that case absence of conflicts) but you can prove that projects with these conflicts exist at all.

dominikh commented 3 years ago

Staticcheck, a project that acts as both an application and a Go module, uses a dual versioning scheme: semantic versions to make Go happy, and our own versioning scheme (year.minor.patch) for end-users. As such, both tags like v0.1.2 and 2020.2.2 exist. Go starting to consider 2020.2.2 a semantic version would be a breaking change, and break the established order of releases.

Gating this change behind the Go version denoted in go.mod is not an acceptable option. That would require a change to my versioning scheme just to be allowed to benefit from new language features.

I can't speak to the prevalence of tags that aren't prefixed with v in other languages, but plenty of ecosystems do use the v prefix in their git tags – the major difference to Go is that most of these ecosystems have explicit package repositories, manifest files, and versions stored in those manifests – that is, their versions are completely decoupled from git tags. Ruby and Rust are two popular ecosystems that use semver, without a v prefix in their package versions, whose users nevertheless use v-prefixed tags in git.

gudvinr commented 3 years ago

Go starting to consider 2020.2.2 a semantic version would <...> break the established order of releases

Why though? 2020.2.2 perfectly fine semver-compatible string. go-tools is more collection of, well, tools, which are main packages. They generally have loose restrictions on major version. It shouldn't interfere with release management from your side in any way. You just leave single tag with Y.M.D and that's it.

Y.M.D is not a semantic version but there's some feeling that not a single person will be confused by thinking that there was 2020 backward incompatible changes in software release cycle

Although end-users might want to import libraries from go-tools repo, its readme says:

Unless otherwise noted, none of these libraries have stable APIs. Their main purpose is to aid the implementation of the tools. If you decide to use these libraries, please vendor them and expect regular backwards-incompatible changes.

gotgenes commented 3 years ago

Staticcheck […] uses a dual versioning scheme: semantic versions to make Go happy, and our own versioning scheme (year.minor.patch) for end-users

I would argue Staticcheck is relying on distributing itself as an application under one versioning scheme, and a library under a different verisoning scheme, based on exploiting an implementation detail of Go module tooling.

I would argue that either the two should share a unified versioning scheme, or they should be split. Other decisions that, at the time the maintainers chose to use two tagging schemes, would have been more straightforward:

  1. Continue to use the Y.M.D versioning scheme but start prefixing its tags with "v", like v2020.2.2. Library version equals application version. This is how, for example, curl and libcurl work.
  2. If the maintainers really want to use SemVer for the library, break the library out to a separate repository and make it a dependency for the application. I don't have a good example of this. Maybe libgit2, if the Git CLI were to use it as a dependency.
gudvinr commented 3 years ago

I don't have a good example of this. Maybe libgit2, if the Git CLI were to use it as a dependency.

GTK/GNOME use GLib which implements different version scheme but developed in parallel with GTK/GNOME

If the maintainers really want to use SemVer for the library, break the library out to a separate repository and make it a dependency for the application.

I want to note that it's not even necessary since go mod already can do that:

Modules are sometimes defined in repository subdirectories. This is typically done for large repositories with multiple components that need to be released and versioned independently

You can just put either library or command in subdirectory and consider repository root as "module" and version "library" subdirectory separately or other way around. gopls does that.

dominikh commented 3 years ago

It shouldn't interfere with release management from your side in any way. You just leave single tag with Y.M.D and that's it.

Major versions higher than 1 need to be part of the import paths. I do not intend to change all my import paths every year.

Y.M.D is not a semantic version

Then why would Go start treating it as one?

Although end-users might want to import libraries from go-tools repo, its readme says:

There are several ways in which people use Staticcheck as a module:

  1. people who maintain their tool requirements in go.mod, or an alternate list of module requirements, such as tools.mod
  2. people who use alternate static analysis pipelines and import the individual checks, to use them in their own analysis runners
  3. projects like gopls, which bundle Staticcheck's analyzes

I would argue Staticcheck is relying on distributing itself as an application under one versioning scheme, and a library under a different verisoning scheme, based on exploiting an implementation detail of Go module tooling.

Not an "implementation detail", well-documented and well-understood behavior that one wouldn't expect to suddenly change.

I would argue that either the two should share a unified versioning scheme, or they should be split. Other decisions that, at the time the maintainers chose to use two tagging schemes, would have been more straightforward:

In what world is it more straightforward to maintain multiple repositories than to have two sets of tags? Not that it matters, we want both sets of tags for both the libraries and the commands, see point 1 in my list of reasons for using Staticcheck as a module.

You can just put either library or command in subdirectory and consider repository root as "module" and version "library" subdirectory separately or other way around. gopls does that.

Having multiple Go modules in a single repository has turned out to be error-prone, confusing and in general ill-advised. It's not a decision to be made lightly. This is especially true when the modules depend on each other.

People seem to think that I arrived at my versioning scheme on a whim. That is not so. Please read https://github.com/dominikh/go-tools/issues/777 to understand the decisions that went into this.

People seem to think that it is acceptable to break existing workflows to avoid a minor inconvenience. If it is deemed an acceptable solution to split my project into multiple repositories or modules, to get rid of my existing versioning scheme, or to adopt other unsatisfying workarounds, then why is it not deemed an acceptable solution to prefix your tags with a v? You could even have both tags, with and without v!

gudvinr commented 3 years ago

Not an "implementation detail", well-documented and well-understood behavior that one wouldn't expect to suddenly change.

One of the arguments against making prefixes optional was "it will be confusing" for users to determine which of tags is the correct one. And you are making counterargument by showing module which uses different version sets for different parts of module with only difference that ones bypass golang restriction but other don't.

How on earth is this not confusing but having consistent single set of unprefixed tags is?

dominikh commented 3 years ago

@gudvinr please re-read the arguments for why the change would be confusing (https://github.com/golang/go/issues/32945#issuecomment-782215450) and note that these relate in no way to my tags, which as of now, work with old and new software alike, behaving identically, and will continue to do so as long as this proposal isn't adopted.

by showing module which uses different version sets for different parts of module

Both sets of tags apply to the entire module. The difference is not in which parts of the module are covered by the tags, but the intended consumers of the tags. Referring to https://github.com/golang/go/issues/32945#issuecomment-782215450 once more, you will find that old and new software alike is currently able to handle both sets of tags, and even correctly translates between them. Something that wouldn't be true for the change proposed in this issue.

How on earth is this not confusing but having consistent single set of unprefixed tags is?

That has never been the argument.

gudvinr commented 3 years ago

@dominikh that's fair. My point was that you can make things that will confuse users either way. Only thing that matters is consistency and proper release management. Otherwise other people will have troubles using your software whether it has v prefix or not.

You could even have both tags, with and without v!

Yes, you need to tag every release using both X.Y.Z and vX.Y.Z just to be able to appear in go.mod as vX.Y.Z and not some wild gibberish. It doesn't seem to be not error-prone.
It's your choice how to put versions on your software and your position on having different version set with different meaning sounds sane. However putting exact same tags on exact same commit doesn't look very convenient.

If it is deemed an acceptable solution to split my project into multiple repositories or modules, to get rid of my existing versioning scheme, or to adopt other unsatisfying workarounds, then why is it not deemed an acceptable solution to prefix your tags with a v?

It just one's words against others. No one says this solution is right and this is wrong. It is acceptable solution, yes. For some people. Other solution is acceptable too. Again, for some people.

However, there is a world outside of "Go ecosystem" and projects that do not use Go but should interact with Go projects.
VCS isn't a part of "Go ecosystem" and shouldn't be treated by go team as it is. I doubt that this issue will be ever accepted, although I still open to discuss solutions if it will. But I don't like the decision that led to existence of this discussion. It is poisonous and "there should be one way to do %thing%" must not spread outside to things that aren't part of Go.

gotgenes commented 3 years ago

Imagine that Staticcheck maintainers had tagged its versions as v2020.2.2 before thinking about how to distribute its libraries under go mod. What then?

Alternatively, imagine if the prevailing decision in #12302 was to use tags without v-prefixes, or even both with and without prefixes—as existing tools at the time, like glide, already did. What then?

Anyways, the Go maintainers have been explicit about not accepting this. The real underlying cause is that the Go maintainers chose reliance on Git for package distribution, then said, "There can be only one tagging scheme," even though two were and continue to be popular, as was already pointed out numerous times in #12302. (Hat tip to Glide for doing it better for the end-user.)

Regards.

mieubrisse commented 3 years ago

I've been following these notifications, and it seems like this is something that people on both sides of the issue feel strongly about. Could there be a compromise, e.g. something like a disabled-by-default-but-opt-in setting in go.mod, maybe like versionPrefixToStrip? That way, the average Go user wouldn't need to know anything about the complexity but projects that opt in can have their X.Y.Z versions resolved appropriately?

FiloSottile commented 3 years ago

A setting would have much of the same performance and complexity cost as gating on the go.mod version, as described above.

gudvinr commented 3 years ago

A setting would have much of the same performance and complexity cost as gating on the go.mod version, as described above.

What about performance and complexity cost added by checking for existence of go.mod for prefixed tags in projects existed before go.mod?

FiloSottile commented 3 years ago

The existence and contents of go.mod do not influence the choice of what tags represent a version, as far as I know, while the mechanisms proposed here would.

Anyway, the whole +incompatible migration was definitely complex and confusing. That was necessary to make modules happen at all. I don't think supporting multiple tagging conventions is worth nearly as much disruption.

I understand that there are projects that have strong opinions on the tagging scheme and that are inconvenienced by the scheme we picked, but I also notice that it looks like this is not a particularly common issue: the proposal currently has 23 👍, which puts it in page 8 of is:issue is:open sort:reactions-+1-desc. This is not a primary concern in deciding what to implement—they are not votes—but it's an indicator of how relatively widespread the issue is, which we need to keep in mind when considering changes that might affect all Go developers, directly or indirectly.

mieubrisse commented 3 years ago

Thanks for explaining the underlying machinery that would need to be implemented, @FiloSottile ! Tactically, how should we go about handling repos where the vX.Y.Z requirement conflicts? E.g. I have a repo that has both Go and Rust subprojects, where Go is requiring vX.Y.Z while Rust requires X.Y.Z.

gudvinr commented 3 years ago

The existence and contents of go.mod do not influence the choice of what tags represent a version, as far as I know

Existence of go.mod does though. Correct me if I'm wrong but there's couple of comments there:

// The latest compatible version has a go.mod file, so assume that all
// subsequent versions do as well, and do not include any +incompatible
// versions.
// The latest release of this major version has a go.mod file, so it is
// not allowed as +incompatible. <...> so drop all +incompatible
// versions for this major version.

it looks like this is not a particularly common issue

Opinions based on github user base will be kinda biased. As Dave and you mentioned before, many projects already had prefixed versions but from what I understand this research was based mostly on github projects. And github slightly pushes you towards having prefix in version tag despite it being optional in every spec available.

Time also has a huge impact on this issue. Issue that Dave linked here is from 2015 but this one is quite recent. Go itself somewhat skyrocketed in 2016-ish. If you're just starting project, using any tag scheme is painless even mandatory one. It is relatively easy to change if you only use Go.
It is completely different story if you use different languages and if you have some kind of CI it may be inconvenient. Either at the same time or while switching from another language to Go. Projects impacted by this issue may be internal so pseudo-versions are good enough™ but that still cause inconvenience although it's impossible to know how much.

bcmills commented 3 years ago

@mieubrisse

Tactically, how should we go about handling repos where the vX.Y.Z requirement conflicts? E.g. I have a repo that has both Go and Rust subprojects, where Go is requiring vX.Y.Z while Rust requires X.Y.Z.

Is there something preventing you from adding both forms of tags?

gudvinr commented 3 years ago

Is there something preventing you from adding both forms of tags?

It is kinda confusing, I'd say.
What are you going to do if you put v3.4.5 and 3.5.4 on a single commit by accident?
What are you going to do when you forget to add one of them?
How do you explain team members who do not use go or rust that they must place both tags from now?

Last one may not be applicable for this particular team, but adding responsibilities for people who don't even use go is not really a viable solution.

criscola commented 3 years ago

I think that we should support versions without v prefixes because Semver is an open, industry-wide standard. In this occasions I think we should always strive to support the open standard. Then we can say we support versions with a v prefix because there is a significant amount of people who use this convention.

At the very least I would expect to have one line of docs explicitly stating versions must be prefixed with v in the About page, and maybe avoid linking the semver website to avoid confusion.

joe-mann commented 3 years ago

I think that we should support versions without v prefixes because Semver is an open, industry-wide standard. In this occasions I think we should always strive to support the open standard.

But semantic versioning doesn't say anything about the v prefix. This is a Go convention.

And as I have understood FiloSottile's comments (notably https://github.com/golang/go/issues/32945#issuecomment-782215450), there are significant hurdles to overcome to loosen this convention. I surmise that, if this issue had been opened during the planning and development of modules, Go may well have supported both tagging schemes from the start.

Then we can say we support versions with a v prefix because there is a significant amount of people who use this convention.

Yes, but as explained in https://github.com/golang/go/issues/32945#issuecomment-782869623, there do not appear to be anything like a significant number of people who experience significant issues interoperating with Go.

At the very least I would expect to have one line of docs explicitly stating versions must be prefixed with v in the About page, and maybe avoid linking the semver website to avoid confusion.

By way of reference, the tagging standard is explained here: https://golang.org/doc/modules/release-workflow. Personally, I don't think we're lacking clarity in this regard.

wallyqs commented 2 years ago

On the other hand Docker containers running on K8S won't accept a version that starts with a v, I think main source of confusion would be with those both doing Go dev and deploying to K8S.

seankhliao commented 2 years ago

Nothing about docker or k8s requires no leading v, how the container images are tagged are entirely up to the project (it can be arbitrary strings) and some do choose to use v

wallyqs commented 2 years ago

@seankhliao docker is ok without having a v and either works, but kubernetes does need you to remove the v otherwise your image will get stuck with an ErrImagePull from the kubelet.

e.g.

  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   BackOff    19s (x2 over 20s)  kubelet            Back-off pulling image "wallyqs/nack:v0.6.0"
  Warning  Failed     19s (x2 over 20s)  kubelet            Error: ImagePullBackOff
  Normal   Pulling    4s (x2 over 21s)   kubelet            Pulling image "wallyqs/nack:v0.6.0"
  Warning  Failed     4s (x2 over 21s)   kubelet            Failed to pull image "wallyqs/nack:v0.6.0": rpc error: code = Unknown desc = Error response from daemon: manifest for wallyqs/nack:v0.6.0 not found: manifest unknown: manifest unknown
  Warning  Failed     4s (x2 over 21s)   kubelet            Error: ErrImagePull
seankhliao commented 2 years ago

you didn't tag it with v0.6.0 so of course it can't pull it. in any case this is off topic

wallyqs commented 2 years ago

@seankhliao oh right, seems it is fine in k8s now, apologies for the noise.

rsc commented 2 years ago

As has been discussed, we chose the v specifically to avoid problems with legacy repos that had old tags. Now we wouldn't want to change that, nor would we want the possibility of two different conflicting tags for a given version.

rsc commented 2 years ago

Based on the discussion above, this proposal seems like a likely decline. — rsc for the proposal review group