]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.12] cmd/go: fix the default build output name for versioned binaries
authorHana Kim <hyangah@gmail.com>
Mon, 14 Jan 2019 16:13:34 +0000 (11:13 -0500)
committerAndrew Bonventre <andybons@golang.org>
Wed, 13 Mar 2019 21:18:41 +0000 (21:18 +0000)
`go build` has chosen the last element of the package import path
as the default output name when -o option is given. That caused
the output of a package build when the module root is the major
version component such as 'v2'.

A similar issue involving `go install` was fixed in
https://golang.org/cl/128900. This CL refactors the logic added
with the change and makes it available as
internal/load.DefaultExecName.

This CL makes 'go test' to choose the right default test binary
name when the tested package is in the module root. (E.g.,
instead of v2.test, choose pkg.test for the test of 'path/pkg/v2')

Fixes #27283
Fixes #30266

Change-Id: I6905754f0906db46e3ce069552715f45356913ae
Reviewed-on: https://go-review.googlesource.com/c/go/+/140863
Reviewed-by: Bryan C. Mills <bcmills@google.com>
(cherry picked from commit bf94fc3ae387fc09929443393741919fac6727af)
Reviewed-on: https://go-review.googlesource.com/c/go/+/167384
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/go/internal/load/pkg.go
src/cmd/go/internal/test/test.go
src/cmd/go/internal/work/build.go
src/cmd/go/testdata/mod/rsc.io_fortune_v2_v2.0.0.txt
src/cmd/go/testdata/script/mod_build_versioned.txt [new file with mode: 0644]

index 228be07f2492a46237d6d8e6a42418598b485745..187295b3459ae88f510ae3a5449525f5e00d45d6 100644 (file)
@@ -1178,6 +1178,44 @@ var cgoSyscallExclude = map[string]bool{
 
 var foldPath = make(map[string]string)
 
+// DefaultExecName returns the default executable name of the given
+// package.
+func DefaultExecName(p *Package) string {
+       _, elem := filepath.Split(p.ImportPath)
+       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))
+               }
+       }
+       return elem
+}
+
 // load populates p using information from bp, err, which should
 // be the result of calling build.Context.Import.
 func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
@@ -1218,38 +1256,7 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
                        p.Error = &PackageError{Err: e}
                        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))
-                       }
-               }
+               elem := DefaultExecName(p)
                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.
index 8dfb3df22d3b9ed4ba93d0b22d16b1550dbdac1a..2eca627c9ae50722d2e925554ee704d28f790711 100644 (file)
@@ -805,7 +805,7 @@ func builderTest(b *work.Builder, p *load.Package) (buildAction, runAction, prin
        if p.ImportPath == "command-line-arguments" {
                elem = p.Name
        } else {
-               _, elem = path.Split(p.ImportPath)
+               elem = load.DefaultExecName(p)
        }
        testBinary := elem + ".test"
 
index 145b87513a9166aecb9d9c7b7efd690425f3b1b3..d89ee899f095b5abf6afcbd8d91f6aa1d24a48df 100644 (file)
@@ -10,7 +10,6 @@ import (
        "go/build"
        "os"
        "os/exec"
-       "path"
        "path/filepath"
        "runtime"
        "strings"
@@ -285,7 +284,7 @@ func runBuild(cmd *base.Command, args []string) {
        pkgs := load.PackagesForBuild(args)
 
        if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" {
-               _, cfg.BuildO = path.Split(pkgs[0].ImportPath)
+               cfg.BuildO = load.DefaultExecName(pkgs[0])
                cfg.BuildO += cfg.ExeSuffix
        }
 
index cfa91f08a5d84ba07ffd96eef8580a43c455899b..3acd6379311f643194e45a712464b4af4aed5fa6 100644 (file)
@@ -13,3 +13,9 @@ import "rsc.io/quote"
 func main() {
        println(quote.Hello())
 }
+-- fortune_test.go --
+package main
+
+import "testing"
+
+func TestFortuneV2(t *testing.T) {}
diff --git a/src/cmd/go/testdata/script/mod_build_versioned.txt b/src/cmd/go/testdata/script/mod_build_versioned.txt
new file mode 100644 (file)
index 0000000..eb081c9
--- /dev/null
@@ -0,0 +1,16 @@
+env GO111MODULE=on
+
+go get -m rsc.io/fortune/v2
+
+# The default executable name shouldn't be v2$exe
+go build rsc.io/fortune/v2
+! exists v2$exe
+exists fortune$exe
+
+# The default test binary name shouldn't be v2.test$exe
+go test -c rsc.io/fortune/v2
+! exists v2.test$exe
+exists fortune.test$exe
+
+-- go.mod --
+module scratch