[go] go/build: invoke go command to find modules during Import, Context.Import

91 views
Skip to first unread message

Russ Cox (Gerrit)

unread,
Jul 20, 2018, 11:05:31 AM7/20/18
to Michael Matloob, Bryan C. Mills, Ian Cottrell, Ian Lance Taylor, goph...@pubsubhelper.golang.org, Russ Cox, golang-co...@googlegroups.com

Russ Cox would like Michael Matloob, Bryan C. Mills and Ian Cottrell to review this change.

View Change

go/build: invoke go command to find modules during Import, Context.Import

The introduction of modules has broken (intentionally) the rule
that the source code for a package x/y/z is in GOPATH/src/x/y/z
(or GOROOT/src/x/y/z). This breaks the code in go/build.Import,
which uses that rule to find the directory for a package.

In the long term, the fix is to move programs that load packages
off of go/build and onto golang.org/x/tools/go/packages, which
we hope will eventually become go/packages. That code invokes
the go command to learn what it needs to know about where
packages are.

In the short term, though, there are lots of programs that use go/build
and will not be able to find code in module dependencies.
To help those programs, go/build now runs the go command to
ask where a package's source code can be found, if it sees that
modules are in use. (If modules are not in use, it falls back to the
usual lookup code and does not invoke the go command, so that
existing uses are unaffected and not slowed down.)

Helps #24661.
Fixes #26504.

Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
---
M src/cmd/go/go_test.go
M src/cmd/go/internal/cfg/cfg.go
M src/cmd/go/script_test.go
A src/cmd/go/testdata/script/mod_gobuild_import.txt
M src/go/build/build.go
5 files changed, 205 insertions(+), 5 deletions(-)

diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
index 983698c..7fadd0b 100644
--- a/src/cmd/go/go_test.go
+++ b/src/cmd/go/go_test.go
@@ -105,6 +105,7 @@

var testGo string
var testTmpDir string
+var testBin string

// The TestMain function creates a go command for testing purposes and
// deletes it after the tests have been run.
@@ -133,7 +134,11 @@
}

if canRun {
- testGo = filepath.Join(testTmpDir, "testgo"+exeSuffix)
+ testBin = filepath.Join(testTmpDir, "testbin")
+ if err := os.Mkdir(testBin, 0777); err != nil {
+ log.Fatal(err)
+ }
+ testGo = filepath.Join(testBin, "go"+exeSuffix)
args := []string{"build", "-tags", "testgo", "-o", testGo}
if race.Enabled {
args = append(args, "-race")
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index 9dd90ee..c7746b6 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -20,7 +20,7 @@
var (
BuildA bool // -a flag
BuildBuildmode string // -buildmode flag
- BuildContext = build.Default
+ BuildContext = defaultContext()
BuildGetmode string // -getmode flag
BuildI bool // -i flag
BuildLinkshared bool // -linkshared flag
@@ -43,6 +43,12 @@
DebugActiongraph string // -debug-actiongraph flag (undocumented, unstable)
)

+func defaultContext() build.Context {
+ ctxt := build.Default
+ ctxt.JoinPath = filepath.Join // back door to say "do not use go command"
+ return ctxt
+}
+
func init() {
BuildToolchainCompiler = func() string { return "missing-compiler" }
BuildToolchainLinker = func() string { return "missing-linker" }
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
index d8bcd07..263e26f 100644
--- a/src/cmd/go/script_test.go
+++ b/src/cmd/go/script_test.go
@@ -85,7 +85,7 @@
ts.cd = filepath.Join(ts.workdir, "gopath/src")
ts.env = []string{
"WORK=" + ts.workdir, // must be first for ts.abbrev
- "PATH=" + os.Getenv("PATH"),
+ "PATH=" + testBin + string(filepath.ListSeparator) + os.Getenv("PATH"),
homeEnvName() + "=/no-home",
"GOARCH=" + runtime.GOARCH,
"GOCACHE=" + testGOCACHE,
@@ -702,7 +702,7 @@
// exec runs the given command line (an actual subprocess, not simulated)
// in ts.cd with environment ts.env and then returns collected standard output and standard error.
func (ts *testScript) exec(command string, args ...string) (stdout, stderr string, err error) {
- cmd := exec.Command(testGo, args...)
+ cmd := exec.Command(command, args...)
cmd.Dir = ts.cd
cmd.Env = append(ts.env, "PWD="+ts.cd)
var stdoutBuf, stderrBuf strings.Builder
diff --git a/src/cmd/go/testdata/script/mod_gobuild_import.txt b/src/cmd/go/testdata/script/mod_gobuild_import.txt
new file mode 100644
index 0000000..9d7fd2a
--- /dev/null
+++ b/src/cmd/go/testdata/script/mod_gobuild_import.txt
@@ -0,0 +1,67 @@
+# go/build's Import should find modules by invoking the go command
+
+go build -o $WORK/testimport.exe ./testimport
+
+# GO111MODULE=off
+env GO111MODULE=off
+! exec $WORK/testimport.exe x/y/z/w
+
+# GO111MODULE=auto in GOPATH/src
+env GO111MODULE=
+! exec $WORK/testimport.exe x/y/z/w
+env GO111MODULE=auto
+! exec $WORK/testimport.exe x/y/z/w
+
+# GO111MODULE=auto outside GOPATH/src
+cd $GOPATH/other
+env GO111MODULE=
+exec $WORK/testimport.exe other/x/y/z/w
+stdout w2.go
+
+env GO111MODULE=auto
+exec $WORK/testimport.exe other/x/y/z/w
+stdout w2.go
+
+# GO111MODULE=on outside GOPATH/src
+env GO111MODULE=on
+exec $WORK/testimport.exe other/x/y/z/w
+stdout w2.go
+
+# GO111MODULE=on in GOPATH/src
+cd $GOPATH/src
+exec $WORK/testimport.exe x/y/z/w
+stdout w1.go
+
+-- go.mod --
+module x/y/z
+
+-- z.go --
+package z
+
+-- w/w1.go --
+package w
+
+-- testimport/x.go --
+package main
+
+import (
+ "fmt"
+ "go/build"
+ "log"
+ "os"
+ "strings"
+)
+
+func main() {
+ p, err := build.Import(os.Args[1], ".", 0)
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Printf("%s\n%s\n", p.Dir, strings.Join(p.GoFiles, " "))
+}
+
+-- $GOPATH/other/go.mod --
+module other/x/y
+
+-- $GOPATH/other/z/w/w2.go --
+package w
diff --git a/src/go/build/build.go b/src/go/build/build.go
index b19df28..da57f01 100644
--- a/src/go/build/build.go
+++ b/src/go/build/build.go
@@ -16,6 +16,7 @@
"io/ioutil"
"log"
"os"
+ "os/exec"
pathpkg "path"
"path/filepath"
"runtime"
@@ -277,6 +278,8 @@
return ""
}

+var defaultReleaseTags []string
+
func defaultContext() Context {
var c Context

@@ -297,6 +300,8 @@
c.ReleaseTags = append(c.ReleaseTags, "go1."+strconv.Itoa(i))
}

+ defaultReleaseTags = append([]string{}, c.ReleaseTags...) // own own private copy
+
env := os.Getenv("CGO_ENABLED")
if env == "" {
env = defaultCGO_ENABLED
@@ -583,13 +588,17 @@
return p, fmt.Errorf("import %q: cannot import absolute path", path)
}

+ gopath := ctxt.gopath()
+ if ctxt.importGo(p, path, srcDir, mode, gopath) {
+ goto Found
+ }
+
// tried records the location of unsuccessful package lookups
var tried struct {
vendor []string
goroot string
gopath []string
}
- gopath := ctxt.gopath()

// Vendor directories get first chance to satisfy import.
if mode&IgnoreVendor == 0 && srcDir != "" {
@@ -930,6 +939,119 @@
return p, pkgerr
}

+// importGo checks whether it can use the go command to find the directory for path.
+// If using the go command is appopriate, importGo tries it, and if that succeeds,
+// then importGo returns true. Otherwise it returns false.
+// Using the go command lets build.Import and build.Context.Import find code
+// in Go modules. In the long term we want tools to use go/packages (currently golang.org/x/tools/go/packages),
+// which will also use the go command.
+// Invoking the go command here is not very efficient in that it computes information
+// about the requested package and all dependencies and then only reports about the requested package.
+// Then we reinvoke it for every dependency. But this is still better than not working at all.
+// See golang.org/issue/26504.
+func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode, gopath []string) bool {
+ const debugImportGo = false
+
+ // To invoke the go command, we must know the source directory,
+ // we must not being doing special things like AllowBinary or IgnoreVendor,
+ // and all the file system callbacks must be nil (we're meant to use the local file system).
+ if srcDir == "" || mode&AllowBinary != 0 || mode&IgnoreVendor != 0 ||
+ ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ReleaseTags, defaultReleaseTags) {
+ return false
+ }
+
+ // If modules are not enabled, then the in-process code works fine and we should keep using it.
+ switch os.Getenv("GO111MODULE") {
+ case "off":
+ return false
+ case "on":
+ // ok
+ default: // "", "auto", anything else
+ // Automatic mode: no module use in $GOPATH/src.
+ for _, root := range gopath {
+ sub, ok := ctxt.hasSubdir(root, srcDir)
+ if ok && strings.HasPrefix(sub, "src/") {
+ return false
+ }
+ }
+ }
+
+ // For efficiency, if path is a standard library package, let the usual lookup code handle it.
+ if ctxt.GOROOT != "" {
+ dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
+ if ctxt.isDir(dir) {
+ return false
+ }
+ }
+
+ // Look to see if there is a go.mod.
+ abs, err := filepath.Abs(srcDir)
+ if err != nil {
+ return false
+ }
+ for {
+ info, err := os.Stat(filepath.Join(abs, "go.mod"))
+ if err == nil && !info.IsDir() {
+ break
+ }
+ d := filepath.Dir(abs)
+ if len(d) >= len(abs) {
+ return false // reached top of file system, no go.mod
+ }
+ }
+
+ cmd := exec.Command("go", "list", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n", path)
+ cmd.Dir = srcDir
+ var stdout, stderr strings.Builder
+ cmd.Stdout = &stdout
+ cmd.Stderr = &stderr
+
+ cgo := "0"
+ if ctxt.CgoEnabled {
+ cgo = "1"
+ }
+ cmd.Env = append(os.Environ(),
+ "GOOS="+ctxt.GOOS,
+ "GOARCH="+ctxt.GOARCH,
+ "GOROOT="+ctxt.GOROOT,
+ "GOPATH="+ctxt.GOPATH,
+ "CGO_ENABLED="+cgo,
+ )
+
+ if err := cmd.Run(); err != nil {
+ if debugImportGo {
+ fmt.Fprintf(os.Stderr, "go/build: importGo %s: %v\n%s\n", path, err, stderr.String())
+ }
+ return false
+ }
+
+ f := strings.Split(stdout.String(), "\n")
+ if len(f) != 5 || f[4] != "" {
+ if debugImportGo {
+ fmt.Fprintf(os.Stderr, "go/build: importGo %s: unexpected output:\n%s\n", path, stdout.String())
+ }
+ return false
+ }
+
+ p.Dir = f[0]
+ p.ImportPath = f[1]
+ p.Root = f[2]
+ p.Goroot = f[3] == "true"
+ return true
+}
+
+func equal(x, y []string) bool {
+ if len(x) != len(y) {
+ return false
+ }
+ for i, xi := range x {
+ if xi != y[i] {
+ return false
+ }
+ }
+ return true
+}
+
// hasGoFiles reports whether dir contains any files with names ending in .go.
// For a vendor check we must exclude directories that contain no .go files.
// Otherwise it is not possible to vendor just a/b/c and still import the

To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
Gerrit-Change-Number: 125296
Gerrit-PatchSet: 1
Gerrit-Owner: Russ Cox <r...@golang.org>
Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
Gerrit-Reviewer: Russ Cox <r...@golang.org>
Gerrit-MessageType: newchange

Gobot Gobot (Gerrit)

unread,
Jul 20, 2018, 11:05:41 AM7/20/18
to Russ Cox, goph...@pubsubhelper.golang.org, Michael Matloob, Bryan C. Mills, Ian Cottrell, golang-co...@googlegroups.com

TryBots beginning. Status page: https://farmer.golang.org/try?commit=d5bf8386

View Change

    To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
    Gerrit-Change-Number: 125296
    Gerrit-PatchSet: 1
    Gerrit-Owner: Russ Cox <r...@golang.org>
    Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
    Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
    Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
    Gerrit-Reviewer: Russ Cox <r...@golang.org>
    Gerrit-CC: Gobot Gobot <go...@golang.org>
    Gerrit-Comment-Date: Fri, 20 Jul 2018 15:05:38 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: No
    Gerrit-MessageType: comment

    Gobot Gobot (Gerrit)

    unread,
    Jul 20, 2018, 11:12:17 AM7/20/18
    to Russ Cox, goph...@pubsubhelper.golang.org, Michael Matloob, Bryan C. Mills, Ian Cottrell, golang-co...@googlegroups.com

    Build is still in progress...
    This change failed on linux-amd64:
    See https://storage.googleapis.com/go-build-log/d5bf8386/linux-amd64_59f82805.log

    Consult https://build.golang.org/ to see whether it's a new failure. Other builds still in progress; subsequent failure notices suppressed until final report.

    View Change

      To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
      Gerrit-Change-Number: 125296
      Gerrit-PatchSet: 1
      Gerrit-Owner: Russ Cox <r...@golang.org>
      Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
      Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
      Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
      Gerrit-Reviewer: Russ Cox <r...@golang.org>
      Gerrit-CC: Gobot Gobot <go...@golang.org>
      Gerrit-Comment-Date: Fri, 20 Jul 2018 15:12:15 +0000

      Gobot Gobot (Gerrit)

      unread,
      Jul 20, 2018, 11:28:49 AM7/20/18
      to Russ Cox, goph...@pubsubhelper.golang.org, Michael Matloob, Bryan C. Mills, Ian Cottrell, golang-co...@googlegroups.com

      8 of 19 TryBots failed:
      Failed on linux-amd64: https://storage.googleapis.com/go-build-log/d5bf8386/linux-amd64_59f82805.log
      Failed on linux-386: https://storage.googleapis.com/go-build-log/d5bf8386/linux-386_e5cfdba0.log
      Failed on freebsd-amd64-11_1: https://storage.googleapis.com/go-build-log/d5bf8386/freebsd-amd64-11_1_f785a71c.log
      Failed on windows-386-2008: https://storage.googleapis.com/go-build-log/d5bf8386/windows-386-2008_fc4d9e21.log
      Failed on linux-amd64-race: https://storage.googleapis.com/go-build-log/d5bf8386/linux-amd64-race_80fca1c1.log
      Failed on openbsd-amd64-62: https://storage.googleapis.com/go-build-log/d5bf8386/openbsd-amd64-62_ba49b4c6.log
      Failed on windows-amd64-2016: https://storage.googleapis.com/go-build-log/d5bf8386/windows-amd64-2016_0de16291.log
      Failed on misc-vet-vetall: https://storage.googleapis.com/go-build-log/d5bf8386/misc-vet-vetall_aaa9bf08.log

      Consult https://build.golang.org/ to see whether they are new failures.

      Patch set 1:TryBot-Result -1

      View Change

        To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
        Gerrit-Change-Number: 125296
        Gerrit-PatchSet: 1
        Gerrit-Owner: Russ Cox <r...@golang.org>
        Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
        Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
        Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
        Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
        Gerrit-Reviewer: Russ Cox <r...@golang.org>
        Gerrit-Comment-Date: Fri, 20 Jul 2018 15:28:47 +0000
        Gerrit-HasComments: No
        Gerrit-Has-Labels: Yes
        Gerrit-MessageType: comment

        Russ Cox (Gerrit)

        unread,
        Jul 20, 2018, 11:31:07 AM7/20/18
        to Russ Cox, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Gobot Gobot, Michael Matloob, Bryan C. Mills, Ian Cottrell, golang-co...@googlegroups.com

        Uploaded patch set 2: Patch Set 1 was rebased.

        View Change

          To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
          Gerrit-Change-Number: 125296
          Gerrit-PatchSet: 2
          Gerrit-Owner: Russ Cox <r...@golang.org>
          Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
          Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
          Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
          Gerrit-Reviewer: Russ Cox <r...@golang.org>
          Gerrit-Comment-Date: Fri, 20 Jul 2018 15:31:03 +0000

          Gobot Gobot (Gerrit)

          unread,
          Jul 20, 2018, 11:31:19 AM7/20/18
          to Russ Cox, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Michael Matloob, Bryan C. Mills, Ian Cottrell, golang-co...@googlegroups.com

          TryBots beginning. Status page: https://farmer.golang.org/try?commit=949c4211

          View Change

            To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
            Gerrit-Change-Number: 125296
            Gerrit-PatchSet: 2
            Gerrit-Owner: Russ Cox <r...@golang.org>
            Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
            Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
            Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
            Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
            Gerrit-Reviewer: Russ Cox <r...@golang.org>
            Gerrit-Comment-Date: Fri, 20 Jul 2018 15:31:17 +0000

            Gobot Gobot (Gerrit)

            unread,
            Jul 20, 2018, 11:37:58 AM7/20/18
            to Russ Cox, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Michael Matloob, Bryan C. Mills, Ian Cottrell, golang-co...@googlegroups.com

            Build is still in progress...
            This change failed on linux-amd64:

            See https://storage.googleapis.com/go-build-log/949c4211/linux-amd64_60dfd211.log

            Consult https://build.golang.org/ to see whether it's a new failure. Other builds still in progress; subsequent failure notices suppressed until final report.

            View Change

              To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: go
              Gerrit-Branch: master
              Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
              Gerrit-Change-Number: 125296
              Gerrit-PatchSet: 2
              Gerrit-Owner: Russ Cox <r...@golang.org>
              Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
              Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
              Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
              Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
              Gerrit-Reviewer: Russ Cox <r...@golang.org>
              Gerrit-Comment-Date: Fri, 20 Jul 2018 15:37:56 +0000

              Russ Cox (Gerrit)

              unread,
              Jul 20, 2018, 11:40:25 AM7/20/18
              to Russ Cox, Michael Matloob, Ian Lance Taylor, Gobot Gobot, Bryan C. Mills, Ian Cottrell, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

              Russ Cox uploaded patch set #3 to this change.

              View Change

              5 files changed, 207 insertions(+), 5 deletions(-)

              To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: go
              Gerrit-Branch: master
              Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
              Gerrit-Change-Number: 125296
              Gerrit-PatchSet: 3
              Gerrit-Owner: Russ Cox <r...@golang.org>
              Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
              Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
              Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
              Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
              Gerrit-Reviewer: Russ Cox <r...@golang.org>
              Gerrit-MessageType: newpatchset

              Russ Cox (Gerrit)

              unread,
              Jul 20, 2018, 11:40:25 AM7/20/18
              to Russ Cox, goph...@pubsubhelper.golang.org, Gobot Gobot, Ian Lance Taylor, Michael Matloob, Bryan C. Mills, Ian Cottrell, golang-co...@googlegroups.com

              Uploaded patch set 3.

              View Change

                To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-Project: go
                Gerrit-Branch: master
                Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                Gerrit-Change-Number: 125296
                Gerrit-PatchSet: 3
                Gerrit-Owner: Russ Cox <r...@golang.org>
                Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                Gerrit-Reviewer: Russ Cox <r...@golang.org>
                Gerrit-Comment-Date: Fri, 20 Jul 2018 15:40:22 +0000

                Gobot Gobot (Gerrit)

                unread,
                Jul 20, 2018, 11:40:36 AM7/20/18
                to Russ Cox, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Michael Matloob, Bryan C. Mills, Ian Cottrell, golang-co...@googlegroups.com

                TryBots beginning. Status page: https://farmer.golang.org/try?commit=a32acd1b

                View Change

                  To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-Project: go
                  Gerrit-Branch: master
                  Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                  Gerrit-Change-Number: 125296
                  Gerrit-PatchSet: 3
                  Gerrit-Owner: Russ Cox <r...@golang.org>
                  Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                  Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                  Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                  Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                  Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                  Gerrit-Reviewer: Russ Cox <r...@golang.org>
                  Gerrit-Comment-Date: Fri, 20 Jul 2018 15:40:33 +0000

                  Gobot Gobot (Gerrit)

                  unread,
                  Jul 20, 2018, 11:52:29 AM7/20/18
                  to Russ Cox, goph...@pubsubhelper.golang.org, Ian Lance Taylor, Michael Matloob, Bryan C. Mills, Ian Cottrell, golang-co...@googlegroups.com

                  TryBots are happy.

                  Patch set 3:TryBot-Result +1

                  View Change

                    To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                    Gerrit-Project: go
                    Gerrit-Branch: master
                    Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                    Gerrit-Change-Number: 125296
                    Gerrit-PatchSet: 3
                    Gerrit-Owner: Russ Cox <r...@golang.org>
                    Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                    Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                    Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                    Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                    Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                    Gerrit-Reviewer: Russ Cox <r...@golang.org>
                    Gerrit-Comment-Date: Fri, 20 Jul 2018 15:52:27 +0000

                    Bryan C. Mills (Gerrit)

                    unread,
                    Jul 20, 2018, 12:26:15 PM7/20/18
                    to Russ Cox, goph...@pubsubhelper.golang.org, Bryan C. Mills, Gobot Gobot, Ian Lance Taylor, Michael Matloob, Ian Cottrell, golang-co...@googlegroups.com

                    Patch set 3:Code-Review +2

                    View Change

                    4 comments:

                    To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                    Gerrit-Project: go
                    Gerrit-Branch: master
                    Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                    Gerrit-Change-Number: 125296
                    Gerrit-PatchSet: 3
                    Gerrit-Owner: Russ Cox <r...@golang.org>
                    Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                    Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                    Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                    Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                    Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                    Gerrit-Reviewer: Russ Cox <r...@golang.org>
                    Gerrit-Comment-Date: Fri, 20 Jul 2018 16:26:12 +0000
                    Gerrit-HasComments: Yes
                    Gerrit-Has-Labels: Yes
                    Gerrit-MessageType: comment

                    Russ Cox (Gerrit)

                    unread,
                    Jul 24, 2018, 3:12:17 PM7/24/18
                    to Russ Cox, goph...@pubsubhelper.golang.org, Bryan C. Mills, Gobot Gobot, Ian Lance Taylor, Michael Matloob, Ian Cottrell, golang-co...@googlegroups.com

                    Uploaded patch set 4: Patch Set 3 was rebased.

                    View Change

                      To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                      Gerrit-Project: go
                      Gerrit-Branch: master
                      Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                      Gerrit-Change-Number: 125296
                      Gerrit-PatchSet: 4
                      Gerrit-Owner: Russ Cox <r...@golang.org>
                      Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                      Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                      Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                      Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                      Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                      Gerrit-Reviewer: Russ Cox <r...@golang.org>
                      Gerrit-Comment-Date: Tue, 24 Jul 2018 19:12:12 +0000

                      Gobot Gobot (Gerrit)

                      unread,
                      Jul 24, 2018, 3:12:29 PM7/24/18
                      to Russ Cox, goph...@pubsubhelper.golang.org, Bryan C. Mills, Ian Lance Taylor, Michael Matloob, Ian Cottrell, golang-co...@googlegroups.com

                      TryBots beginning. Status page: https://farmer.golang.org/try?commit=80b23c41

                      View Change

                        To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                        Gerrit-Project: go
                        Gerrit-Branch: master
                        Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                        Gerrit-Change-Number: 125296
                        Gerrit-PatchSet: 4
                        Gerrit-Owner: Russ Cox <r...@golang.org>
                        Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                        Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                        Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                        Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                        Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                        Gerrit-Reviewer: Russ Cox <r...@golang.org>
                        Gerrit-Comment-Date: Tue, 24 Jul 2018 19:12:27 +0000

                        Gobot Gobot (Gerrit)

                        unread,
                        Jul 24, 2018, 3:27:49 PM7/24/18
                        to Russ Cox, goph...@pubsubhelper.golang.org, Bryan C. Mills, Ian Lance Taylor, Michael Matloob, Ian Cottrell, golang-co...@googlegroups.com

                        TryBots are happy.

                        Patch set 4:TryBot-Result +1

                        View Change

                          To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                          Gerrit-Project: go
                          Gerrit-Branch: master
                          Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                          Gerrit-Change-Number: 125296
                          Gerrit-PatchSet: 4
                          Gerrit-Owner: Russ Cox <r...@golang.org>
                          Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                          Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                          Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                          Gerrit-Reviewer: Russ Cox <r...@golang.org>
                          Gerrit-Comment-Date: Tue, 24 Jul 2018 19:27:47 +0000

                          Michael Matloob (Gerrit)

                          unread,
                          Jul 26, 2018, 11:31:46 AM7/26/18
                          to Russ Cox, goph...@pubsubhelper.golang.org, Gobot Gobot, Bryan C. Mills, Ian Lance Taylor, Ian Cottrell, golang-co...@googlegroups.com

                          Patch set 4:Code-Review +2

                          View Change

                          2 comments:

                          To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                          Gerrit-Project: go
                          Gerrit-Branch: master
                          Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                          Gerrit-Change-Number: 125296
                          Gerrit-PatchSet: 4
                          Gerrit-Owner: Russ Cox <r...@golang.org>
                          Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                          Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                          Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                          Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                          Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                          Gerrit-Reviewer: Russ Cox <r...@golang.org>
                          Gerrit-Comment-Date: Thu, 26 Jul 2018 15:31:42 +0000

                          Paul Jolly (Gerrit)

                          unread,
                          Jul 27, 2018, 6:52:55 AM7/27/18
                          to Russ Cox, goph...@pubsubhelper.golang.org, Michael Matloob, Gobot Gobot, Bryan C. Mills, Ian Lance Taylor, Ian Cottrell, golang-co...@googlegroups.com

                          github.com/kisielk/gotool is a fairly commonly used package amongst CLI tools (GopherJS et al https://godoc.org/github.com/kisielk/gotool?importers). That package will need a Go 1.11 implementation to work nicely with modules.

                          It would seem to make sense for that Go 1.11 implementation to call *go/build.Context.Import in order to do this.

                          But with multiple patterns we would end up os/exec-ing multiple times.

                          Would it therefore make sense to introduce a "plural" version of *Context.Import for Go 1.11?

                          func (ctxt *Context) ImportPkgs(paths []string, srcDir string, mode ImportMode) ([]*Package, error)

                          Alternatively, and maybe this is the better thing to do in any case, we introduce some level of caching in *Context (caching that is a function of *Context and srcDir), with some sort of reset method. But this feels like a bigger (too big a) change for Go 1.11?

                          View Change

                            To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                            Gerrit-Project: go
                            Gerrit-Branch: master
                            Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                            Gerrit-Change-Number: 125296
                            Gerrit-PatchSet: 4
                            Gerrit-Owner: Russ Cox <r...@golang.org>
                            Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                            Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                            Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                            Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                            Gerrit-Reviewer: Russ Cox <r...@golang.org>
                            Gerrit-CC: Paul Jolly <pa...@myitcv.org.uk>
                            Gerrit-Comment-Date: Fri, 27 Jul 2018 10:52:51 +0000

                            Paul Jolly (Gerrit)

                            unread,
                            Jul 27, 2018, 7:47:15 AM7/27/18
                            to Russ Cox, goph...@pubsubhelper.golang.org, Daniel Martí, Michael Matloob, Gobot Gobot, Bryan C. Mills, Ian Lance Taylor, Ian Cottrell, golang-co...@googlegroups.com

                            View Change

                            1 comment:

                            • File src/go/build/build.go:

                              • Patch Set #4, Line 1026: return false

                                Don't we need to return an error here (and below)? Because if we are in module mode (as opposed to GOPATH) we need an error that is specific to go list. If we return false here we get an error message relating to "cannot find ... in GOROOT, GOPATH". Which is not very helpful and misleading given we are in module mode.

                            To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                            Gerrit-Project: go
                            Gerrit-Branch: master
                            Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                            Gerrit-Change-Number: 125296
                            Gerrit-PatchSet: 4
                            Gerrit-Owner: Russ Cox <r...@golang.org>
                            Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                            Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                            Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                            Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                            Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                            Gerrit-Reviewer: Russ Cox <r...@golang.org>
                            Gerrit-CC: Daniel Martí <mv...@mvdan.cc>
                            Gerrit-CC: Paul Jolly <pa...@myitcv.org.uk>
                            Gerrit-Comment-Date: Fri, 27 Jul 2018 11:47:11 +0000
                            Gerrit-HasComments: Yes
                            Gerrit-Has-Labels: No
                            Gerrit-MessageType: comment

                            Russ Cox (Gerrit)

                            unread,
                            Jul 27, 2018, 7:56:19 PM7/27/18
                            to Russ Cox, goph...@pubsubhelper.golang.org, Daniel Martí, Paul Jolly, Michael Matloob, Gobot Gobot, Bryan C. Mills, Ian Lance Taylor, Ian Cottrell, golang-co...@googlegroups.com

                            Patch Set 4:

                            github.com/kisielk/gotool is a fairly commonly used package amongst CLI tools (GopherJS et al https://godoc.org/github.com/kisielk/gotool?importers). That package will need a Go 1.11 implementation to work nicely with modules.

                            It would seem to make sense for that Go 1.11 implementation to call *go/build.Context.Import in order to do this.

                            But with multiple patterns we would end up os/exec-ing multiple times.

                            Would it therefore make sense to introduce a "plural" version of *Context.Import for Go 1.11?

                            func (ctxt *Context) ImportPkgs(paths []string, srcDir string, mode ImportMode) ([]*Package, error)

                            Alternatively, and maybe this is the better thing to do in any case, we introduce some level of caching in *Context (caching that is a function of *Context and srcDir), with some sort of reset method. But this feels like a bigger (too big a) change for Go 1.11?

                            The Go 1.11 implementation of github.com/kisielk/gotool should probably be a very small wrapper around golang.org/x/tools/go/packages.

                            Eventually (probably Go 1.12) golang.org/x/tools/go/packages will become go/packages and then we'll deprecate use of go/build (but leave it with this implementation).

                            View Change

                              To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                              Gerrit-Project: go
                              Gerrit-Branch: master
                              Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                              Gerrit-Change-Number: 125296
                              Gerrit-PatchSet: 4
                              Gerrit-Owner: Russ Cox <r...@golang.org>
                              Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                              Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                              Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                              Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                              Gerrit-Reviewer: Russ Cox <r...@golang.org>
                              Gerrit-CC: Daniel Martí <mv...@mvdan.cc>
                              Gerrit-CC: Paul Jolly <pa...@myitcv.org.uk>
                              Gerrit-Comment-Date: Fri, 27 Jul 2018 23:56:16 +0000

                              Russ Cox (Gerrit)

                              unread,
                              Jul 27, 2018, 9:14:40 PM7/27/18
                              to Russ Cox, goph...@pubsubhelper.golang.org, Daniel Martí, Paul Jolly, Michael Matloob, Gobot Gobot, Bryan C. Mills, Ian Lance Taylor, Ian Cottrell, golang-co...@googlegroups.com

                              Uploaded patch set 5.

                              (7 comments)

                              View Change

                              7 comments:

                                • env GO111MODULE=on
                                  exec $WORK/testimport.exe other/x/y/z/w .
                                  stdout w2.go

                                  # GO111MODUL

                                  shouldn't there be a case for (GO111MODULE=auto, cwd=z, exec $WORK/testimport.exe x/y/z/w)? […]

                                  Done although I don't know why users would care so much (it correctly fails).

                              • File src/go/build/build.go:

                                • Patch Set #3, Line 592: mode,

                                  A comment would be helpful here: given that we're invoking a method on ctxt, why do we need to pass […]

                                  Done

                                • Patch Set #3, Line 998: if err == nil && !info.IsDir() {

                                  Ironically, this is very nearly the loop I suggested in this comment thread: […]

                                  Almost, and maybe I was channeling you, but note that the loop in that CL must stop at a particular directory, so it's easy and bad to be off-by-one. Here I'm really just concerned that the loop terminates (doesn't run forever). I don't actually care whether it looks at /go.mod or not (looks like it does), so the off-by-one is not as important. :-)

                              • File src/go/build/build.go:

                                • it's a little hard to parse this comment because of the repetition of the word 'own'

                                • It's supposed to say "our own".

                                • Patch Set #4, Line 1026: if err := cmd.Run(); err != nil {

                                  Don't we need to return an error here (and below)? Because if we are in module mode (as opposed to G […]

                                  Good point, thanks. Done.

                              To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                              Gerrit-Project: go
                              Gerrit-Branch: master
                              Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                              Gerrit-Change-Number: 125296
                              Gerrit-PatchSet: 5
                              Gerrit-Owner: Russ Cox <r...@golang.org>
                              Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                              Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                              Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                              Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                              Gerrit-Reviewer: Russ Cox <r...@golang.org>
                              Gerrit-CC: Daniel Martí <mv...@mvdan.cc>
                              Gerrit-CC: Paul Jolly <pa...@myitcv.org.uk>
                              Gerrit-Comment-Date: Sat, 28 Jul 2018 01:14:36 +0000
                              Gerrit-HasComments: Yes
                              Gerrit-Has-Labels: No
                              Comment-In-Reply-To: Michael Matloob <mat...@golang.org>
                              Comment-In-Reply-To: Paul Jolly <pa...@myitcv.org.uk>
                              Comment-In-Reply-To: Bryan C. Mills <bcm...@google.com>
                              Gerrit-MessageType: comment

                              Russ Cox (Gerrit)

                              unread,
                              Jul 27, 2018, 9:14:40 PM7/27/18
                              to Russ Cox, Michael Matloob, Ian Lance Taylor, Gobot Gobot, Bryan C. Mills, Ian Cottrell, goph...@pubsubhelper.golang.org, Paul Jolly, Daniel Martí, golang-co...@googlegroups.com

                              Russ Cox uploaded patch set #5 to this change.

                              View Change

                              go/build: invoke go command to find modules during Import, Context.Import

                              The introduction of modules has broken (intentionally) the rule
                              that the source code for a package x/y/z is in GOPATH/src/x/y/z
                              (or GOROOT/src/x/y/z). This breaks the code in go/build.Import,
                              which uses that rule to find the directory for a package.

                              In the long term, the fix is to move programs that load packages
                              off of go/build and onto golang.org/x/tools/go/packages, which
                              we hope will eventually become go/packages. That code invokes
                              the go command to learn what it needs to know about where
                              packages are.

                              In the short term, though, there are lots of programs that use go/build
                              and will not be able to find code in module dependencies.
                              To help those programs, go/build now runs the go command to
                              ask where a package's source code can be found, if it sees that
                              modules are in use. (If modules are not in use, it falls back to the
                              usual lookup code and does not invoke the go command, so that
                              existing uses are unaffected and not slowed down.)

                              Helps #24661.
                              Fixes #26504.

                              Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                              ---
                              M src/cmd/go/go_test.go
                              M src/cmd/go/internal/cfg/cfg.go
                              M src/cmd/go/internal/modload/init.go

                              M src/cmd/go/script_test.go
                              A src/cmd/go/testdata/script/mod_gobuild_import.txt
                              M src/go/build/build.go
                              6 files changed, 211 insertions(+), 11 deletions(-)

                              To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                              Gerrit-Project: go
                              Gerrit-Branch: master
                              Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                              Gerrit-Change-Number: 125296
                              Gerrit-PatchSet: 5
                              Gerrit-Owner: Russ Cox <r...@golang.org>
                              Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                              Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                              Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                              Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                              Gerrit-Reviewer: Russ Cox <r...@golang.org>
                              Gerrit-CC: Daniel Martí <mv...@mvdan.cc>
                              Gerrit-CC: Paul Jolly <pa...@myitcv.org.uk>
                              Gerrit-MessageType: newpatchset

                              Russ Cox (Gerrit)

                              unread,
                              Jul 27, 2018, 9:14:43 PM7/27/18
                              to Russ Cox, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Daniel Martí, Paul Jolly, Michael Matloob, Gobot Gobot, Bryan C. Mills, Ian Lance Taylor, Ian Cottrell, golang-co...@googlegroups.com

                              Russ Cox merged this change.

                              View Change

                              Approvals: Bryan C. Mills: Looks good to me, approved Michael Matloob: Looks good to me, approved
                              go/build: invoke go command to find modules during Import, Context.Import

                              The introduction of modules has broken (intentionally) the rule
                              that the source code for a package x/y/z is in GOPATH/src/x/y/z
                              (or GOROOT/src/x/y/z). This breaks the code in go/build.Import,
                              which uses that rule to find the directory for a package.

                              In the long term, the fix is to move programs that load packages
                              off of go/build and onto golang.org/x/tools/go/packages, which
                              we hope will eventually become go/packages. That code invokes
                              the go command to learn what it needs to know about where
                              packages are.

                              In the short term, though, there are lots of programs that use go/build
                              and will not be able to find code in module dependencies.
                              To help those programs, go/build now runs the go command to
                              ask where a package's source code can be found, if it sees that
                              modules are in use. (If modules are not in use, it falls back to the
                              usual lookup code and does not invoke the go command, so that
                              existing uses are unaffected and not slowed down.)

                              Helps #24661.
                              Fixes #26504.

                              Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                              Reviewed-on: https://go-review.googlesource.com/125296
                              Reviewed-by: Michael Matloob <mat...@golang.org>
                              Reviewed-by: Bryan C. Mills <bcm...@google.com>

                              ---
                              M src/cmd/go/go_test.go
                              M src/cmd/go/internal/cfg/cfg.go
                              M src/cmd/go/internal/modload/init.go

                              M src/cmd/go/script_test.go
                              A src/cmd/go/testdata/script/mod_gobuild_import.txt
                              M src/go/build/build.go
                              6 files changed, 211 insertions(+), 11 deletions(-)

                              diff --git a/src/cmd/go/go_test.go b/src/cmd/go/go_test.go
                              index b894284..adf17b8 100644
                              diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
                              index 759b5a7..7838af2 100644
                              --- a/src/cmd/go/internal/modload/init.go
                              +++ b/src/cmd/go/internal/modload/init.go
                              @@ -94,12 +94,6 @@
                              }
                              }

                              - // If this is testgo - the test binary during cmd/go tests -
                              - // then do not let it look for a go.mod unless GO111MODULE has an explicit setting or this is 'go mod -init'.
                              - if base := filepath.Base(os.Args[0]); (base == "testgo" || base == "testgo.exe") && env == "" && !CmdModInit {
                              - return
                              - }
                              -
                              // Disable any prompting for passwords by Git.
                              // Only has an effect for 2.3.0 or later, but avoiding
                              // the prompt in earlier versions is just too hard.

                              diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
                              index d8bcd07..263e26f 100644
                              --- a/src/cmd/go/script_test.go
                              +++ b/src/cmd/go/script_test.go
                              @@ -85,7 +85,7 @@
                              ts.cd = filepath.Join(ts.workdir, "gopath/src")
                              ts.env = []string{
                              "WORK=" + ts.workdir, // must be first for ts.abbrev
                              - "PATH=" + os.Getenv("PATH"),
                              + "PATH=" + testBin + string(filepath.ListSeparator) + os.Getenv("PATH"),
                              homeEnvName() + "=/no-home",
                              "GOARCH=" + runtime.GOARCH,
                              "GOCACHE=" + testGOCACHE,
                              @@ -702,7 +702,7 @@
                              // exec runs the given command line (an actual subprocess, not simulated)
                              // in ts.cd with environment ts.env and then returns collected standard output and standard error.
                              func (ts *testScript) exec(command string, args ...string) (stdout, stderr string, err error) {
                              - cmd := exec.Command(testGo, args...)
                              + cmd := exec.Command(command, args...)
                              cmd.Dir = ts.cd
                              cmd.Env = append(ts.env, "PWD="+ts.cd)
                              var stdoutBuf, stderrBuf strings.Builder
                              diff --git a/src/cmd/go/testdata/script/mod_gobuild_import.txt b/src/cmd/go/testdata/script/mod_gobuild_import.txt
                              new file mode 100644
                              index 0000000..932b8b6
                              --- /dev/null
                              +++ b/src/cmd/go/testdata/script/mod_gobuild_import.txt
                              @@ -0,0 +1,74 @@

                              +# go/build's Import should find modules by invoking the go command
                              +
                              +go build -o $WORK/testimport.exe ./testimport
                              +
                              +# GO111MODULE=off
                              +env GO111MODULE=off
                              +! exec $WORK/testimport.exe x/y/z/w .

                              +
                              +# GO111MODULE=auto in GOPATH/src
                              +env GO111MODULE=
                              +! exec $WORK/testimport.exe x/y/z/w .
                              +env GO111MODULE=auto
                              +! exec $WORK/testimport.exe x/y/z/w .

                              +
                              +# GO111MODULE=auto outside GOPATH/src
                              +cd $GOPATH/other
                              +env GO111MODULE=
                              +exec $WORK/testimport.exe other/x/y/z/w .
                              +stdout w2.go
                              +
                              +! exec $WORK/testimport.exe x/y/z/w .
                              +stderr 'cannot find module providing package x/y/z/w'
                              +
                              +cd z
                              +env GO111MODULE=auto
                              +exec $WORK/testimport.exe other/x/y/z/w .

                              +stdout w2.go
                              +
                              +# GO111MODULE=on outside GOPATH/src
                              +env GO111MODULE=on
                              +exec $WORK/testimport.exe other/x/y/z/w .

                              +stdout w2.go
                              +
                              +# GO111MODULE=on in GOPATH/src
                              +cd $GOPATH/src
                              +exec $WORK/testimport.exe x/y/z/w .
                              +stdout w1.go
                              +cd w
                              +exec $WORK/testimport.exe x/y/z/w ..

                              +stdout w1.go
                              +
                              +-- go.mod --
                              +module x/y/z
                              +
                              +-- z.go --
                              +package z
                              +
                              +-- w/w1.go --
                              +package w
                              +
                              +-- testimport/x.go --
                              +package main
                              +
                              +import (
                              + "fmt"
                              + "go/build"
                              + "log"
                              + "os"
                              + "strings"
                              +)
                              +
                              +func main() {
                              +	p, err := build.Import(os.Args[1], os.Args[2], 0)

                              + if err != nil {
                              + log.Fatal(err)
                              + }
                              + fmt.Printf("%s\n%s\n", p.Dir, strings.Join(p.GoFiles, " "))
                              +}
                              +
                              +-- $GOPATH/other/go.mod --
                              +module other/x/y
                              +
                              +-- $GOPATH/other/z/w/w2.go --
                              +package w
                              diff --git a/src/go/build/build.go b/src/go/build/build.go
                              index b19df28..0ed5b82 100644

                              --- a/src/go/build/build.go
                              +++ b/src/go/build/build.go
                              @@ -16,6 +16,7 @@
                              "io/ioutil"
                              "log"
                              "os"
                              + "os/exec"
                              pathpkg "path"
                              "path/filepath"
                              "runtime"
                              @@ -277,6 +278,8 @@
                              return ""
                              }

                              +var defaultReleaseTags []string
                              +
                              func defaultContext() Context {
                              var c Context

                              @@ -297,6 +300,8 @@
                              c.ReleaseTags = append(c.ReleaseTags, "go1."+strconv.Itoa(i))
                              }

                              +	defaultReleaseTags = append([]string{}, c.ReleaseTags...) // our own private copy

                              +
                              env := os.Getenv("CGO_ENABLED")
                              if env == "" {
                              env = defaultCGO_ENABLED
                              @@ -583,13 +588,19 @@

                              return p, fmt.Errorf("import %q: cannot import absolute path", path)
                              }

                              +		gopath := ctxt.gopath() // needed by both importGo and below; avoid computing twice
                              + if err := ctxt.importGo(p, path, srcDir, mode, gopath); err == nil {
                              + goto Found
                              + } else if err != errNoModules {
                              + return p, err

                              + }
                              +
                              // tried records the location of unsuccessful package lookups
                              var tried struct {
                              vendor []string
                              goroot string
                              gopath []string
                              }
                              - gopath := ctxt.gopath()

                              // Vendor directories get first chance to satisfy import.
                              if mode&IgnoreVendor == 0 && srcDir != "" {
                              @@ -930,6 +941,116 @@
                              return p, pkgerr
                              }

                              +var errNoModules = errors.New("not using modules")
                              +

                              +// importGo checks whether it can use the go command to find the directory for path.
                              +// If using the go command is not appopriate, importGo returns errNoModules.
                              +// Otherwise, importGo tries using the go command and reports whether that succeeded.

                              +// Using the go command lets build.Import and build.Context.Import find code
                              +// in Go modules. In the long term we want tools to use go/packages (currently golang.org/x/tools/go/packages),
                              +// which will also use the go command.
                              +// Invoking the go command here is not very efficient in that it computes information
                              +// about the requested package and all dependencies and then only reports about the requested package.
                              +// Then we reinvoke it for every dependency. But this is still better than not working at all.
                              +// See golang.org/issue/26504.
                              +func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode, gopath []string) error {

                              + const debugImportGo = false
                              +
                              + // To invoke the go command, we must know the source directory,
                              + // we must not being doing special things like AllowBinary or IgnoreVendor,
                              + // and all the file system callbacks must be nil (we're meant to use the local file system).
                              + if srcDir == "" || mode&AllowBinary != 0 || mode&IgnoreVendor != 0 ||
                              + ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ReleaseTags, defaultReleaseTags) {
                              +		return errNoModules

                              + }
                              +
                              + // If modules are not enabled, then the in-process code works fine and we should keep using it.
                              + switch os.Getenv("GO111MODULE") {
                              + case "off":
                              +		return errNoModules

                              + case "on":
                              + // ok
                              + default: // "", "auto", anything else
                              + // Automatic mode: no module use in $GOPATH/src.
                              + for _, root := range gopath {
                              + sub, ok := ctxt.hasSubdir(root, srcDir)
                              + if ok && strings.HasPrefix(sub, "src/") {
                              +				return errNoModules

                              + }
                              + }
                              + }
                              +
                              + // For efficiency, if path is a standard library package, let the usual lookup code handle it.
                              + if ctxt.GOROOT != "" {
                              + dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
                              + if ctxt.isDir(dir) {
                              +			return errNoModules

                              + }
                              + }
                              +
                              + // Look to see if there is a go.mod.
                              + abs, err := filepath.Abs(srcDir)
                              + if err != nil {
                              +		return errNoModules

                              + }
                              + for {
                              + info, err := os.Stat(filepath.Join(abs, "go.mod"))
                              + if err == nil && !info.IsDir() {
                              + break
                              + }
                              + d := filepath.Dir(abs)
                              + if len(d) >= len(abs) {
                              +			return errNoModules // reached top of file system, no go.mod
                              + }
                              + abs = d

                              + }
                              +
                              + cmd := exec.Command("go", "list", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n", path)
                              + cmd.Dir = srcDir
                              + var stdout, stderr strings.Builder
                              + cmd.Stdout = &stdout
                              + cmd.Stderr = &stderr
                              +
                              + cgo := "0"
                              + if ctxt.CgoEnabled {
                              + cgo = "1"
                              + }
                              + cmd.Env = append(os.Environ(),
                              + "GOOS="+ctxt.GOOS,
                              + "GOARCH="+ctxt.GOARCH,
                              + "GOROOT="+ctxt.GOROOT,
                              + "GOPATH="+ctxt.GOPATH,
                              + "CGO_ENABLED="+cgo,
                              + )
                              +
                              + if err := cmd.Run(); err != nil {
                              +		return fmt.Errorf("go/build: importGo %s: %v\n%s\n", path, err, stderr.String())
                              + }
                              +

                              + f := strings.Split(stdout.String(), "\n")
                              + if len(f) != 5 || f[4] != "" {
                              +		return fmt.Errorf("go/build: importGo %s: unexpected output:\n%s\n", path, stdout.String())
                              + }
                              +

                              + p.Dir = f[0]
                              + p.ImportPath = f[1]
                              + p.Root = f[2]
                              + p.Goroot = f[3] == "true"
                              +	return nil

                              +}
                              +
                              +func equal(x, y []string) bool {
                              + if len(x) != len(y) {
                              + return false
                              + }
                              + for i, xi := range x {
                              + if xi != y[i] {
                              + return false
                              + }
                              + }
                              + return true
                              +}
                              +
                              // hasGoFiles reports whether dir contains any files with names ending in .go.
                              // For a vendor check we must exclude directories that contain no .go files.
                              // Otherwise it is not possible to vendor just a/b/c and still import the

                              To view, visit change 125296. To unsubscribe, or for help writing mail filters, visit settings.

                              Gerrit-Project: go
                              Gerrit-Branch: master
                              Gerrit-Change-Id: I0dac68854cf5011005c3b2272810245d81b7cc5a
                              Gerrit-Change-Number: 125296
                              Gerrit-PatchSet: 6
                              Gerrit-Owner: Russ Cox <r...@golang.org>
                              Gerrit-Reviewer: Bryan C. Mills <bcm...@google.com>
                              Gerrit-Reviewer: Gobot Gobot <go...@golang.org>
                              Gerrit-Reviewer: Ian Cottrell <ianco...@google.com>
                              Gerrit-Reviewer: Ian Lance Taylor <ia...@golang.org>
                              Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
                              Gerrit-Reviewer: Russ Cox <r...@golang.org>
                              Gerrit-CC: Daniel Martí <mv...@mvdan.cc>
                              Gerrit-CC: Paul Jolly <pa...@myitcv.org.uk>
                              Gerrit-MessageType: merged
                              Reply all
                              Reply to author
                              Forward
                              0 new messages