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

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

Open
tamalsaha opened this issue Jul 4, 2019 · 41 comments
Open

Comments

@tamalsaha
Copy link

@tamalsaha tamalsaha commented Jul 4, 2019

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?

@dmitshur dmitshur added this to the Go1.14 milestone Jul 4, 2019
@dmitshur dmitshur changed the title Automatically handle vX.Y.Z and X.Y.Z cmd/go: automatically handle vX.Y.Z and X.Y.Z Jul 4, 2019
@bcmills bcmills changed the title cmd/go: automatically handle vX.Y.Z and X.Y.Z cmd/go: accept tags of the form X.Y.Z (without leading 'v') as semantic versions Jul 18, 2019
@bcmills
Copy link
Member

@bcmills bcmills commented Jul 18, 2019

See previously #30146.

@bcmills
Copy link
Member

@bcmills bcmills commented Jul 18, 2019

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
Copy link
Contributor

@jayconrod jayconrod commented Jul 18, 2019

+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
Copy link
Member

@bcmills bcmills commented Jul 18, 2019

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
Copy link

@mattharr-is mattharr-is commented Oct 16, 2019

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
Copy link

@alexellis alexellis commented Feb 5, 2020

+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.

wadells added a commit to wadells/robotest that referenced this issue May 13, 2020
As discussed at:

  golang/go#32945
  https://semver.org/#is-v123-a-semantic-version

Go and semver disagree about handling of a leading 'v' on version
strings.  This patch allows robotest to play nicely with both.
wadells added a commit to wadells/robotest that referenced this issue May 13, 2020
As discussed at:

  golang/go#32945
  https://semver.org/#is-v123-a-semantic-version

Go and semver disagree about handling of a leading 'v' on version
strings.  This patch allows robotest to play nicely with both.
wadells added a commit to wadells/robotest that referenced this issue May 13, 2020
As discussed at:

  golang/go#32945
  https://semver.org/#is-v123-a-semantic-version

Go and semver disagree about handling of a leading 'v' on version
strings.  This patch allows robotest to play nicely with both.

Contributes to gravitational#200.
wadells added a commit to gravitational/robotest that referenced this issue May 14, 2020
As discussed at:

  golang/go#32945
  https://semver.org/#is-v123-a-semantic-version

Go and semver disagree about handling of a leading 'v' on version
strings.  This patch allows robotest to play nicely with both.

Contributes to #200.
@wadells wadells mentioned this issue Jun 4, 2020
8 of 8 tasks complete
@gudvinr
Copy link

@gudvinr gudvinr commented Jul 9, 2020

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
Copy link

@gudvinr gudvinr commented Jul 9, 2020

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
Copy link

@taiidani taiidani commented Jul 22, 2020

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
Copy link
Contributor

@MCBrandenburg MCBrandenburg commented Aug 12, 2020

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 FusionAuth/go-client#32

gotgenes added a commit to gotgenes/getignore that referenced this issue Aug 28, 2020
This is to support using go mod, and is necessary until
golang/go#32945 is resolved.
@mieubrisse
Copy link

@mieubrisse mieubrisse commented Nov 26, 2020

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
Copy link
Contributor

@FiloSottile FiloSottile commented Feb 18, 2021

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

@gudvinr
Copy link

@gudvinr gudvinr commented Feb 18, 2021

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
Copy link
Contributor

@davecheney davecheney commented Feb 19, 2021

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
Copy link

@gotgenes gotgenes commented Feb 19, 2021

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
Copy link
Contributor

@davecheney davecheney commented Feb 19, 2021

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
Copy link

@gudvinr gudvinr commented Feb 19, 2021

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
Copy link
Contributor

@davecheney davecheney commented Feb 19, 2021

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
Copy link

@gudvinr gudvinr commented Feb 19, 2021

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
Copy link

@gotgenes gotgenes commented Feb 19, 2021

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).

@bcmills bcmills modified the milestones: Backlog, Proposal Feb 19, 2021
@FiloSottile
Copy link
Contributor

@FiloSottile FiloSottile commented Feb 19, 2021

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
Copy link

@gudvinr gudvinr commented Feb 19, 2021

@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
Copy link
Member

@dominikh dominikh commented Feb 19, 2021

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
Copy link

@gudvinr gudvinr commented Feb 19, 2021

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
Copy link

@gotgenes gotgenes commented Feb 19, 2021

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
Copy link

@gudvinr gudvinr commented Feb 19, 2021

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
Copy link
Member

@dominikh dominikh commented Feb 20, 2021

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 dominikh/go-tools#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
Copy link

@gudvinr gudvinr commented Feb 20, 2021

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
Copy link
Member

@dominikh dominikh commented Feb 20, 2021

@gudvinr please re-read the arguments for why the change would be confusing (#32945 (comment)) 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 #32945 (comment) 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
Copy link

@gudvinr gudvinr commented Feb 20, 2021

@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
Copy link

@gotgenes gotgenes commented Feb 21, 2021

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
Copy link

@mieubrisse mieubrisse commented Feb 21, 2021

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
Copy link
Contributor

@FiloSottile FiloSottile commented Feb 21, 2021

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

@gudvinr
Copy link

@gudvinr gudvinr commented Feb 21, 2021

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
Copy link
Contributor

@FiloSottile FiloSottile commented Feb 21, 2021

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
Copy link

@mieubrisse mieubrisse commented Feb 21, 2021

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
Copy link

@gudvinr gudvinr commented Feb 21, 2021

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
Copy link
Member

@bcmills bcmills commented Feb 22, 2021

@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
Copy link

@gudvinr gudvinr commented Feb 22, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Proposals
Awaiting triage
Linked pull requests

Successfully merging a pull request may close this issue.

None yet