-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
Go version
go 1.23.0
Output of go env in your module/workspace:
set GO111MODULE=on
set GOARCH=amd64
set GOEXE=.exe
set GOEXPERIMENT=loopvar
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\xxxx\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLCHAIN=local
set GOVCS=
set GOVERSION=go1.23.0
set GODEBUG=
set GCCGO=gccgo
set GOAMD64=v1What did you do?
go install gitlab.com/metakeule/cmdlibprob1@v0.0.2go install gitlab.com/metakeule/cmdlibprob2/cmd/cmdlibprob2@v0.0.1go install gitlab.com/metakeule/cmdlibprob3/cmd/cmdlibprob3@v0.0.1What did you see happen?
go install gitlab.com/metakeule/cmdlibprob1@v0.0.2
go: downloading gitlab.com/metakeule/cmdlibprob1 v0.0.2
go: gitlab.com/metakeule/cmdlibprob1@v0.0.2 (in gitlab.com/metakeule/cmdlibprob1@v0.0.2):
The go.mod file for the module providing named packages contains one or
more replace directives. It must not contain directives that would cause
it to be interpreted differently than if it were the main module.go install gitlab.com/metakeule/cmdlibprob2/cmd/cmdlibprob2@v0.0.1
go: downloading gitlab.com/metakeule/cmdlibprob2 v0.0.1
go: gitlab.com/metakeule/cmdlibprob2/cmd/cmdlibprob2@v0.0.1: module gitlab.com/metakeule/cmdlibprob2@v0.0.1 found, but does not contain package gitlab.com/metakeule/cmdlibprob2/cmd/cmdlibprob2go install gitlab.com/metakeule/cmdlibprob3/cmd/cmdlibprob3@v0.0.1
go: downloading gitlab.com/metakeule/cmdlibprob3 v0.0.1
go: gitlab.com/metakeule/cmdlibprob3/cmd/cmdlibprob3@v0.0.1: module gitlab.com/metakeule/cmdlibprob3@v0.0.1 found, but does not contain package gitlab.com/metakeule/cmdlibprob3/cmd/cmdlibprob3What did you expect to see?
nothing, it should just install
Context
We have a repository with a library and a command that uses the library. This is pretty common and was never a problem in the pre go modules era.
This allows in principle for a library and a command to be released in sync with the same version number and the same behaviour.
An additional reasonable requirement is, that the command should be able to have more dependencies than the library. And therefor the library and the command are two different go modules (each has its own go.mod file with its own path).
In our case, there are other libraries depending on the library. These other libraries are used by the command. This is not possible without having two separate go modules in this repository.
I have set up three repositories to reflect the three different strategies for combining a command and a library here:
- https://gitlab.com/metakeule/cmdlibprob1
- https://gitlab.com/metakeule/cmdlibprob2
- https://gitlab.com/metakeule/cmdlibprob3
The problem is, that without a replace directive inside the go.mod file of the command, there is no way to release the command and the library at the same time, because the command depending on the library needs to find it first.
However, having a replace directive, even if it is pointing to the same repository, is not supported by go install yet (see above).
Changing this would help a lot and I can't see a reason, why it should not be supported in this case, because the repository needs to be downloaded anyway to compile.
As it is, we need to make double releases all the time: first for the library and then for the command. But before the release of the command we first need to update the version of the library that the command depends on, although it is in the same repo! This is error prone, unnecessary work and confusing for the users, since the same version of library and command might behave differently.
Maybe this should be changed to be a proposal, since another request was closed as "works as intended". But I would say, that this is a very reasonable and useful request with minimal implementation impact.
So it is not about allowing replace directives in general to be used by go install, but only in the very specific case, when:
- the original path of the module that is to be replaced is within the same repository
- the target path is relative and in such a way that it is reachable within the repository
Example
module gitlab.com/metakeule/cmdlibprob3/cmd/cmdlibprob3
replace gitlab.com/metakeule/cmdlibprob3/lib/cmdlibprob3 => ../../lib/cmdlibprob3
would be valid
module gitlab.com/metakeule/cmdlibprob3/cmd/cmdlibprob3
replace gitlab.com/metakeule/cmdlibprob3/lib/cmdlibprob3 => ../../../lib/cmdlibprob3
would not be valid.
From resolving the paths it is actually very easy to check, that
from gitlab.com/metakeule/cmdlibprob3/cmd/cmdlibprob3
to ../../lib/cmdlibprob3 is resulting in gitlab.com/metakeule/cmdlibprob3/lib/cmdlibprob3 so this, is exacly the same as the original path and should be allowed.
go.sum Problem
Tagging both versions at the same time is possible. But the go.sum file of the dependant package is always one commit behind.