cmd/go: list command fails when directory is the target of a module replace directive
subash-a opened this issue · 4 comments
What version of Go are you using (go version
)?
$ go version go version go1.12beta1 darwin/amd64
Does this issue reproduce with the latest release?
Yes the issue is reproducible with the latest version of go (go1.12beta1
)
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GOARCH="amd64" GOBIN="" GOCACHE="/Users/subhash_sharma/Library/Caches/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOOS="darwin" GOPATH="/Users/subhash_sharma/go" GOPROXY="" GORACE="" GOROOT="/Users/subhash_sharma/.goversions/go1.12beta1" GOTMPDIR="" GOTOOLDIR="/Users/subhash_sharma/.goversions/go1.12beta1/pkg/tool/darwin_amd64" GCCGO="gccgo" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="/Users/subhash_sharma/subash/go.mod" 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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/w0/d6l19r7j3dbg7fq56_nn4l340000gp/T/go-build083506298=/tmp/go-build -gno-record- gcc-switches -fno-common"
What did you do?
The following testscript
reproduces the issue:
# listbug.txt # prime the mod cache with a replaced module go mod download example.com/fruit@v1.0.0 go mod download go list ./gopath/pkg/mod/example.com/replacedfruit@v1.0.0 ! go list ./gopath/pkg/mod/example.com/fruit@v1.0.0 -- go.mod -- module mod require example.com/fruit v1.0.0 replace example.com/fruit => example.com/replacedfruit v1.0.0 -- main.go -- package main import ( "fmt" ) func main() { fmt.Println(fruit.Apple) }
# mod/example.com_fruit_v1.0.0.txt -- .mod -- module example.com/fruit -- .info -- {"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} -- go.mod -- module example.com/fruit -- fruit.go -- package fruit const Apple = "apple"
# mod/example.com_replacedfruit_v1.0.0.txt -- .mod -- module example.com/fruit -- .info -- {"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"} -- go.mod -- module example.com/fruit -- fruit.go -- package fruit const Apple = "apple"
What did you see?
go list ./gopath/pkg/mod/example.com/fruit@v1.0.0
passes with output
example.com/fruit
go list ./gopath/pkg/mod/example.com/replacedfruit@v1.0.0
fails with output
go: directory gopath/pkg/mod/example.com/replacedfruit@v1.0.0 outside available modules
What did you expect to see?
go list ./gopath/pkg/mod/example.com/replacedfruit@v1.0.0
should pass because that is the directory in which the replaced example.com/fruit
is now located
go list ./gopath/pkg/mod/example.com/fruit@v1.0.0
should fail because that module is now located elsewhere due to the aforementioned replace
in go.mod
.
I couldn't get the original test script to work, but I believe this one reproduces the same problem:
go mod download
! go list ./gopath/pkg/mod/example.com/fruit@v1.0.0
go list ./gopath/pkg/mod/example.com/replacedfruit@v1.0.0
-- go.mod --
module mod
require example.com/fruit v1.0.0
replace example.com/fruit => example.com/replacedfruit v1.0.0
-- main.go --
package main
import (
"fmt"
"example.com/fruit"
)
func main() {
fmt.Println(fruit.Apple)
}
-- .gomodproxy/example.com_fruit_v1.0.0/.mod --
module example.com/fruit
-- .gomodproxy/example.com_fruit_v1.0.0/.info --
{"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"}
-- .gomodproxy/example.com_fruit_v1.0.0/fruit.go --
package fruit
const Apple = "Apple"
-- .gomodproxy/example.com_replacedfruit_v1.0.0/.mod --
module example.com/replacedfruit
-- .gomodproxy/example.com_replacedfruit_v1.0.0/.info --
{"Version":"v1.0.0","Time":"2018-10-22T18:45:39Z"}
-- .gomodproxy/example.com_replacedfruit_v1.0.0/fruit.go --
package fruit
const Apple = "Apple"
pathInModuleCache
in internal/modload/load.go
is the culprit. It needs to be made aware of replacements.
Change https://golang.org/cl/165381 mentions this issue: cmd/go: list directories in module cache replacements