Commit 9f5336d8 authored by Russ Cox's avatar Russ Cox

cmd/go: fix install target name for versioned binaries

For a package in the module root, using the containing directory name
might mean the directory in the module cache, in which case the
executable has a final @v1.2.3 in it, which is no good. Fix that.

While we're here, change go install example.com/cmd/foo/v2 to
install foo instead of the less useful "v2".

Fixes #24667.
Fixes #26869.

Change-Id: Ie40ca1bc9e27955441f1cdb7abd3a1f69034c9f5
Reviewed-on: https://go-review.googlesource.com/128900Reviewed-by: 's avatarBryan C. Mills <bcmills@google.com>
parent cb7d0efc
......@@ -1241,6 +1241,37 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
return
}
_, elem := filepath.Split(p.Dir)
if cfg.ModulesEnabled {
// NOTE(rsc): Using p.ImportPath instead of p.Dir
// makes sure we install a package in the root of a
// cached module directory as that package name
// not name@v1.2.3.
// Using p.ImportPath instead of p.Dir
// is probably correct all the time,
// even for non-module-enabled code,
// but I'm not brave enough to change the
// non-module behavior this late in the
// release cycle. Maybe for Go 1.12.
// See golang.org/issue/26869.
_, elem = pathpkg.Split(p.ImportPath)
// If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2.
// See golang.org/issue/24667.
isVersion := func(v string) bool {
if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] {
return false
}
for i := 2; i < len(v); i++ {
if c := v[i]; c < '0' || '9' < c {
return false
}
}
return true
}
if isVersion(elem) {
_, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath))
}
}
full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH {
// Install cross-compiled binaries to subdirectories of bin.
......
rsc.io/fortune v1.0.0
written by hand
-- .mod --
module rsc.io/fortune
-- .info --
{"Version":"v1.0.0"}
-- fortune.go --
package main
import "rsc.io/quote"
func main() {
println(quote.Hello())
}
rsc.io/fortune v2.0.0
written by hand
-- .mod --
module rsc.io/fortune/v2
-- .info --
{"Version":"v2.0.0"}
-- fortune.go --
package main
import "rsc.io/quote"
func main() {
println(quote.Hello())
}
env GO111MODULE=on
go mod init example.com/m
# get of a binary should install it to $GOPATH/bin
# BUG: vgo-tour should be installed as vgo-tour, not vgo-tour@v1.0.0.
go get research.swtch.com/vgo-tour
exec $GOPATH/bin/vgo-tour@v1.0.0
stdout 'Hello, world.'
rm $GOPATH/bin/vgo-tour@v1.0.0
# install of a binary should install it to $GOPATH/bin
# BUG: vgo-tour should be installed as vgo-tour, not vgo-tour@v1.0.0.
go install research.swtch.com/vgo-tour
exec $GOPATH/bin/vgo-tour@v1.0.0
stdout 'Hello, world.'
env GO111MODULE=on
go list -f '{{.Target}}' rsc.io/fortune
! stdout fortune@v1
stdout 'fortune(\.exe)?$'
go list -f '{{.Target}}' rsc.io/fortune/v2
! stdout v2
stdout 'fortune(\.exe)?$'
-- go.mod --
module m
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment