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

proposal: cmd/go: build tag for detecting go modules usage #37995

Closed
pjebs opened this issue Mar 22, 2020 · 16 comments
Closed

proposal: cmd/go: build tag for detecting go modules usage #37995

pjebs opened this issue Mar 22, 2020 · 16 comments

Comments

@pjebs
Copy link
Contributor

pjebs commented Mar 22, 2020

It would be nice if there was a build tag for detecting if go modules is being used.

I have created a package: https://github.com/rocketlaunchr/dbq. I went out of my way to put v2 in a separate v2 directory so that it would be compatible with go module users and non-go module users. This is supposedly preferred practice.

For v2, I want to introduce a dependency (https://github.com/cenkalti/backoff) that is at v4 but did not use the separate directory approach.

For my package, in order to support Go Modules and non-modules users, I need to use a build tag so that I can use github.com/cenkalti/backoff/v4 for go modules users and gopkg.in/cenkalti/backoff.v4 for non-go modules users.

@gopherbot gopherbot added this to the Proposal milestone Mar 22, 2020
@pjebs pjebs changed the title proposal: build tag for go modules proposal: build tag for detecting go modules usage Mar 22, 2020
@pjebs
Copy link
Contributor Author

pjebs commented Mar 22, 2020

@propersam

@dmitshur
Copy link
Contributor

For my package, in order to support Go Modules and non-modules users, I need to use a build tag so that I can use github.com/cenkalti/backoff/v4 for go modules users and gopkg.in/cenkalti/backoff.v4 for non-go modules users.

It may not be necessary to use a build tag to achieve compatibility for both modes because of "minimal module-awareness for legacy operation" that was implemented in commit d4e2128 and issue #25069. Are you familiar with that behavior?

/cc @jayconrod @bcmills @matloob

@pjebs
Copy link
Contributor Author

pjebs commented Mar 22, 2020

So how do I achieve my aim? As it stands adding /v4 to imports prevents compilation when go modules is not enabled.

@dmitshur on a separate matter did you get my email from about a week ago?

@jayconrod
Copy link
Contributor

Minimal module compatibility lets code built in GOPATH mode stay compatible in this situation. The Modules wiki has more information about this.

If a package has a go.mod file in some parent directory within GOPATH, it should import github.com/cenkalti/backoff/v4 (as is required in module mode). If a package does not have a go.mod file, it should import github.com/cenkalti/backoff without the /v4 suffix, matching the directory structure.

The path gopkg.in/cenkalti/backoff.v4 should not be used in either case, even though it's possible to use in GOPATH mode. The module declares its name as github.com/cenkalti/backoff/v4. Referring to a package by multiple names can lead to migration problems, duplicate packages, and conflicts. They will not be de-duplicated.

@pjebs
Copy link
Contributor Author

pjebs commented Mar 23, 2020

github.com/cenkalti/backoff default branch is set to v4. When in gopath mode does it use master which is quite old?

@bcmills
Copy link
Contributor

bcmills commented Mar 23, 2020

Yes. If you want to support GOPATH-mode users with this particular dependency, probably the simplest approach is to use go mod vendor to generate (and check in) a vendor directory for your project.

GOPATH-mode users would then build your dependencies from your vendor directory instead of whatever is in their GOPATH/src.

@pjebs
Copy link
Contributor Author

pjebs commented Mar 23, 2020

Is there a way to use this solution just for 1 dependency?

@bcmills
Copy link
Contributor

bcmills commented Mar 23, 2020

I don't think so, no — but users who are sensitive to extra dependencies should generally be building in module mode anyway.

@pjebs
Copy link
Contributor Author

pjebs commented Mar 23, 2020

In the blog post: https://blog.golang.org/v2-go-modules they recommend the separate directory approach. They mention the downsides are maintaining 2 separate codebases (this is a big downside I am already facing). They say the benefits are compatibility with GOPATH mode. They didn't mention the issue I just faced.

Is this still the recommend approach?

For my package, I'd love to abandon the separate directory approach since it looks like supporting GOPATH is not viable (and never was). It's possibly too late now to abandon it because I may have GOPATH users already pointing to the v2 directory.

@pjebs
Copy link
Contributor Author

pjebs commented Mar 23, 2020

Also what's wrong with a build tag for detecting GO MODULES enabled?

@jayconrod
Copy link
Contributor

When in gopath mode does it use master which is quite old?

In GOPATH mode, go get will download the default branch. That's set to v4 for this repo, so GOPATH users will get something pretty recent.

In the blog post: https://blog.golang.org/v2-go-modules they recommend the separate directory approach. They mention the downsides are maintaining 2 separate codebases (this is a big downside I am already facing). They say the benefits are compatibility with GOPATH mode. They didn't mention the issue I just faced.

If you have GOPATH users that need to refer to anything other than the latest version of the default branch, then using separate directories is recommended. For example, if you have the module example.com/mod, and you rewrite your API in example.com/mod/v2, GOPATH users of example.com/mod will be broken unless you have both versions on the default branch with v2 in a subdirectory.

I don't know enough about backoff to judge its compatibility with GOPATH. Since it's at major version v4 on the default branch, not in a subdirectory, it should be imported as github.com/cenkalti/backoff/v4 in projects with a go.mod file and as github.com/cenkalti/backoff in projects without a go.mod file.

As @bcmills mentioned, you may be able to check in a vendor directory to work around compatibility issues with GOPATH users so they get the correct version. As another alternative, you could create a branch named go1 with code for GOPATH users. In GOPATH mode, go get will pick that instead of the default branch if it's present (see go help gopath-get.

Also what's wrong with a build tag for detecting GO MODULES enabled?

We'd rather not add features if there's already a way to solve a problem. There are some options here, and we'd like to be sure none of those can work before pursuing something new.

@pjebs
Copy link
Contributor Author

pjebs commented Mar 26, 2020

@jayconrod

In GOPATH mode, go get will download the default branch. That's set to v4 for this repo, so GOPATH users will get something pretty recent.

That doesn't seem to be the case. go get seems to get master instead of the default branch: v4. NOTE: I'm using Go1.12 so maybe it's changed. (I can't use Go1.14)

As @bcmills mentioned, you may be able to check in a vendor directory to work around compatibility issues with GOPATH users so they get the correct version. As another alternative, you could create a branch named go1 with code for GOPATH users. In GOPATH mode, go get will pick that instead of the default branch if it's present (see go help gopath-get.

This is not viable. It's already a nuisance maintaining a v1 and v2 directory. I can't maintain another branch.

@rsc
Copy link
Contributor

rsc commented Jul 14, 2021

At this point I think you could reasonably just use modules unconditionally in your new versions.

@rsc rsc changed the title proposal: build tag for detecting go modules usage proposal: cmd/go: build tag for detecting go modules usage Jul 14, 2021
@rsc
Copy link
Contributor

rsc commented Jul 21, 2021

This proposal has been added to the active column of the proposals project
and will now be reviewed at the weekly proposal review meetings.
— rsc for the proposal review group

@rsc rsc moved this from Incoming to Active in Proposals (old) Jul 21, 2021
@rsc
Copy link
Contributor

rsc commented Jul 28, 2021

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

@rsc rsc moved this from Active to Likely Decline in Proposals (old) Jul 28, 2021
@rsc rsc moved this from Likely Decline to Declined in Proposals (old) Aug 4, 2021
@rsc
Copy link
Contributor

rsc commented Aug 4, 2021

No change in consensus, so declined.
— rsc for the proposal review group

@rsc rsc closed this as completed Aug 4, 2021
@golang golang locked and limited conversation to collaborators Aug 4, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Development

No branches or pull requests

6 participants