cmd/go: integrate vgo into main command
diff --git a/vendor/cmd/go/internal/envcmd/env.go b/vendor/cmd/go/internal/envcmd/env.go
index 603f7b5..d2de069 100644
--- a/vendor/cmd/go/internal/envcmd/env.go
+++ b/vendor/cmd/go/internal/envcmd/env.go
@@ -16,6 +16,7 @@
 	"cmd/go/internal/cache"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
+	"cmd/go/internal/vgo"
 	"cmd/go/internal/work"
 )
 
@@ -129,6 +130,7 @@
 		{Name: "CGO_LDFLAGS", Value: strings.Join(ldflags, " ")},
 		{Name: "PKG_CONFIG", Value: b.PkgconfigCmd()},
 		{Name: "GOGCCFLAGS", Value: strings.Join(cmd[3:], " ")},
+		{Name: "VGOMODROOT", Value: vgo.ModRoot},
 	}
 }
 
diff --git a/vendor/cmd/go/internal/get/get.go b/vendor/cmd/go/internal/get/get.go
index 0fee5f0..6e9b498 100644
--- a/vendor/cmd/go/internal/get/get.go
+++ b/vendor/cmd/go/internal/get/get.go
@@ -18,6 +18,7 @@
 	"cmd/go/internal/load"
 	"cmd/go/internal/search"
 	"cmd/go/internal/str"
+	"cmd/go/internal/vgo"
 	"cmd/go/internal/web"
 	"cmd/go/internal/work"
 )
@@ -91,6 +92,10 @@
 }
 
 func runGet(cmd *base.Command, args []string) {
+	if vgo.Enabled() {
+		base.Fatalf("go get: vgo not implemented")
+	}
+
 	work.BuildInit()
 
 	if *getF && !*getU {
diff --git a/vendor/cmd/go/internal/help/help.go b/vendor/cmd/go/internal/help/help.go
index b4c5217..488ef7b 100644
--- a/vendor/cmd/go/internal/help/help.go
+++ b/vendor/cmd/go/internal/help/help.go
@@ -64,6 +64,10 @@
 
 var usageTemplate = `Go is a tool for managing Go source code.
 
+This is vgo, an experimental go command with support for package versioning.
+Even though you are invoking it as vgo, most of the messages printed will
+still say "go", not "vgo". Sorry.
+
 Usage:
 
 	go command [arguments]
diff --git a/vendor/cmd/go/internal/list/list.go b/vendor/cmd/go/internal/list/list.go
index 7435273..bf52614 100644
--- a/vendor/cmd/go/internal/list/list.go
+++ b/vendor/cmd/go/internal/list/list.go
@@ -16,6 +16,7 @@
 	"cmd/go/internal/base"
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
+	"cmd/go/internal/vgo"
 	"cmd/go/internal/work"
 )
 
@@ -149,6 +150,10 @@
 var listE = CmdList.Flag.Bool("e", false, "")
 var listFmt = CmdList.Flag.String("f", "{{.ImportPath}}", "")
 var listJson = CmdList.Flag.Bool("json", false, "")
+var listM = CmdList.Flag.Bool("m", false, "")
+var listU = CmdList.Flag.Bool("u", false, "")
+var listT = CmdList.Flag.Bool("t", false, "")
+
 var nl = []byte{'\n'}
 
 func runList(cmd *base.Command, args []string) {
@@ -156,6 +161,19 @@
 	out := newTrackingWriter(os.Stdout)
 	defer out.w.Flush()
 
+	if *listM {
+		if *listU {
+			vgo.ListMU()
+			return
+		}
+		vgo.ListM()
+		return
+	}
+	if *listT {
+		vgo.ListT(args)
+		return
+	}
+
 	var do func(*load.PackagePublic)
 	if *listJson {
 		do = func(p *load.PackagePublic) {
diff --git a/vendor/cmd/go/internal/load/icfg.go b/vendor/cmd/go/internal/load/icfg.go
deleted file mode 100644
index d8dd664..0000000
--- a/vendor/cmd/go/internal/load/icfg.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2017 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package load
-
-import (
-	"bytes"
-	"encoding/json"
-	"errors"
-	"io/ioutil"
-)
-
-// DebugDeprecatedImportcfg is installed as the undocumented -debug-deprecated-importcfg build flag.
-// It is useful for debugging subtle problems in the go command logic but not something
-// we want users to depend on. The hope is that the "deprecated" will make that clear.
-// We intend to remove this flag in Go 1.11.
-var DebugDeprecatedImportcfg debugDeprecatedImportcfgFlag
-
-type debugDeprecatedImportcfgFlag struct {
-	enabled bool
-	Import  map[string]string
-	Pkg     map[string]*debugDeprecatedImportcfgPkg
-}
-
-type debugDeprecatedImportcfgPkg struct {
-	Dir    string
-	Import map[string]string
-}
-
-var (
-	debugDeprecatedImportcfgMagic = []byte("# debug-deprecated-importcfg\n")
-	errImportcfgSyntax            = errors.New("malformed syntax")
-)
-
-func (f *debugDeprecatedImportcfgFlag) String() string { return "" }
-
-func (f *debugDeprecatedImportcfgFlag) Set(x string) error {
-	if x == "" {
-		*f = debugDeprecatedImportcfgFlag{}
-		return nil
-	}
-	data, err := ioutil.ReadFile(x)
-	if err != nil {
-		return err
-	}
-
-	if !bytes.HasPrefix(data, debugDeprecatedImportcfgMagic) {
-		return errImportcfgSyntax
-	}
-	data = data[len(debugDeprecatedImportcfgMagic):]
-
-	f.Import = nil
-	f.Pkg = nil
-	if err := json.Unmarshal(data, &f); err != nil {
-		return errImportcfgSyntax
-	}
-	f.enabled = true
-	return nil
-}
-
-func (f *debugDeprecatedImportcfgFlag) lookup(parent *Package, path string) (dir, newPath string) {
-	newPath = path
-	if p := f.Import[path]; p != "" {
-		newPath = p
-	}
-	if parent != nil {
-		if p1 := f.Pkg[parent.ImportPath]; p1 != nil {
-			if p := p1.Import[path]; p != "" {
-				newPath = p
-			}
-		}
-	}
-	if p2 := f.Pkg[newPath]; p2 != nil {
-		return p2.Dir, newPath
-	}
-	return "", ""
-}
diff --git a/vendor/cmd/go/internal/load/pkg.go b/vendor/cmd/go/internal/load/pkg.go
index 9f5f858..f49dfdb 100644
--- a/vendor/cmd/go/internal/load/pkg.go
+++ b/vendor/cmd/go/internal/load/pkg.go
@@ -22,6 +22,7 @@
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/search"
 	"cmd/go/internal/str"
+	"cmd/go/internal/vgo"
 )
 
 var IgnoreImports bool // control whether we ignore imports in packages
@@ -137,6 +138,8 @@
 	OmitDebug    bool                 // tell linker not to write debug information
 	GobinSubdir  bool                 // install target would be subdir of GOBIN
 
+	ModuleInfo string // add this ModuleInfo to package main
+
 	Asmflags   []string // -asmflags for this package
 	Gcflags    []string // -gcflags for this package
 	Ldflags    []string // -ldflags for this package
@@ -400,13 +403,19 @@
 	importPath := path
 	origPath := path
 	isLocal := build.IsLocalImport(path)
-	var debugDeprecatedImportcfgDir string
+	var vgoDir string
+	var vgoErr error
 	if isLocal {
 		importPath = dirToImportPath(filepath.Join(srcDir, path))
-	} else if DebugDeprecatedImportcfg.enabled {
-		if d, i := DebugDeprecatedImportcfg.lookup(parent, path); d != "" {
-			debugDeprecatedImportcfgDir = d
-			importPath = i
+	} else if vgo.Enabled() {
+		parentPath := ""
+		if parent != nil {
+			parentPath = parent.ImportPath
+		}
+		var p string
+		vgoDir, p, vgoErr = vgo.Lookup(parentPath, path)
+		if vgoErr == nil {
+			importPath = p
 		}
 	} else if mode&UseVendor != 0 {
 		// We do our own vendor resolution, because we want to
@@ -431,11 +440,11 @@
 		// in order to return partial information.
 		var bp *build.Package
 		var err error
-		if debugDeprecatedImportcfgDir != "" {
-			bp, err = cfg.BuildContext.ImportDir(debugDeprecatedImportcfgDir, 0)
-		} else if DebugDeprecatedImportcfg.enabled {
+		if vgoDir != "" {
+			bp, err = cfg.BuildContext.ImportDir(vgoDir, 0)
+		} else if vgoErr != nil {
 			bp = new(build.Package)
-			err = fmt.Errorf("unknown import path %q: not in import cfg", importPath)
+			err = fmt.Errorf("unknown import path %q: %v", importPath, vgoErr)
 		} else {
 			buildMode := build.ImportComment
 			if mode&UseVendor == 0 || path != origPath {
@@ -448,7 +457,7 @@
 		if cfg.GOBIN != "" {
 			bp.BinDir = cfg.GOBIN
 		}
-		if debugDeprecatedImportcfgDir == "" && err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path &&
+		if vgoDir == "" && err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path &&
 			!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
 			err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
 		}
@@ -457,7 +466,7 @@
 			p = setErrorPos(p, importPos)
 		}
 
-		if debugDeprecatedImportcfgDir == "" && origPath != cleanImport(origPath) {
+		if vgoDir == "" && origPath != cleanImport(origPath) {
 			p.Error = &PackageError{
 				ImportStack: stk.Copy(),
 				Err:         fmt.Sprintf("non-canonical import path: %q should be %q", origPath, pathpkg.Clean(origPath)),
@@ -534,9 +543,13 @@
 // x/vendor/path, vendor/path, or else stay path if none of those exist.
 // VendoredImportPath returns the expanded path or, if no expansion is found, the original.
 func VendoredImportPath(parent *Package, path string) (found string) {
-	if DebugDeprecatedImportcfg.enabled {
-		if d, i := DebugDeprecatedImportcfg.lookup(parent, path); d != "" {
-			return i
+	if vgo.Enabled() {
+		parentPath := ""
+		if parent != nil {
+			parentPath = parent.ImportPath
+		}
+		if _, p, e := vgo.Lookup(parentPath, path); e == nil {
+			return p
 		}
 		return path
 	}
@@ -1184,6 +1197,10 @@
 		setError(fmt.Sprintf("case-insensitive import collision: %q and %q", p.ImportPath, other))
 		return
 	}
+
+	if p.Name == "main" {
+		p.Internal.ModuleInfo = vgo.PackageModuleInfo(p.ImportPath, p.Deps)
+	}
 }
 
 // SafeArg reports whether arg is a "safe" command-line argument,
@@ -1456,7 +1473,7 @@
 	if cmdlineMatchers == nil {
 		SetCmdlinePatterns(search.CleanImportPaths(args))
 	}
-	return search.ImportPaths(args)
+	return vgo.ImportPaths(args)
 }
 
 func ImportPathsForGoGet(args []string) []string {
@@ -1550,6 +1567,8 @@
 	}
 	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
 
+	vgo.AddImports(gofiles)
+
 	var err error
 	if dir == "" {
 		dir = base.Cwd
diff --git a/vendor/cmd/go/internal/work/build.go b/vendor/cmd/go/internal/work/build.go
index 191e45c..c6ab084 100644
--- a/vendor/cmd/go/internal/work/build.go
+++ b/vendor/cmd/go/internal/work/build.go
@@ -230,7 +230,6 @@
 
 	// Undocumented, unstable debugging flags.
 	cmd.Flag.StringVar(&cfg.DebugActiongraph, "debug-actiongraph", "", "")
-	cmd.Flag.Var(&load.DebugDeprecatedImportcfg, "debug-deprecated-importcfg", "")
 }
 
 // fileExtSplit expects a filename and returns the name
diff --git a/vendor/cmd/go/internal/work/exec.go b/vendor/cmd/go/internal/work/exec.go
index c4c1500..1c47bfd 100644
--- a/vendor/cmd/go/internal/work/exec.go
+++ b/vendor/cmd/go/internal/work/exec.go
@@ -29,8 +29,15 @@
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/load"
 	"cmd/go/internal/str"
+	"cmd/go/internal/vgo"
 )
 
+func init() {
+	vgo.InstallHook = func(args []string) {
+		CmdInstall.Run(CmdInstall, args)
+	}
+}
+
 // actionList returns the list of actions in the dag rooted at root
 // as visited in a depth-first post-order traversal.
 func actionList(root *Action) []*Action {
@@ -292,6 +299,8 @@
 		}
 	}
 
+	fmt.Fprintf(h, "moduleinfo %q\n", p.Internal.ModuleInfo)
+
 	return h.Sum()
 }
 
@@ -569,6 +578,14 @@
 		return nil
 	}
 
+	// TODO(vgo): If have module info, write file to objdir, add to gofiles.
+	if p.Internal.ModuleInfo != "" {
+		if err := b.writeFile(objdir+"_gomod_.go", vgo.ModInfoProg(p.Internal.ModuleInfo)); err != nil {
+			return err
+		}
+		gofiles = append(gofiles, objdir+"_gomod_.go")
+	}
+
 	// Compile Go.
 	objpkg := objdir + "_pkg_.a"
 	ofile, out, err := BuildToolchain.gc(b, a, objpkg, icfg.Bytes(), len(sfiles) > 0, gofiles)
diff --git a/vendor/cmd/go/main.go b/vendor/cmd/go/main.go
index dbe6b78..c5a6df4 100644
--- a/vendor/cmd/go/main.go
+++ b/vendor/cmd/go/main.go
@@ -32,6 +32,7 @@
 	"cmd/go/internal/tool"
 	"cmd/go/internal/version"
 	"cmd/go/internal/vet"
+	"cmd/go/internal/vgo"
 	"cmd/go/internal/work"
 )
 
@@ -51,6 +52,8 @@
 		run.CmdRun,
 		test.CmdTest,
 		tool.CmdTool,
+		vgo.CmdVendor,
+		vgo.CmdVerify,
 		version.CmdVersion,
 		vet.CmdVet,
 
@@ -78,6 +81,11 @@
 		base.Usage()
 	}
 
+	if vgo.MustBeVgo {
+		// If running as vgo or with -vgo, change get now to change help message.
+		*get.CmdGet = *vgo.CmdGet
+	}
+
 	cfg.CmdName = args[0] // for error messages
 	if args[0] == "help" {
 		help.Help(args[1:])
@@ -115,6 +123,13 @@
 		os.Exit(2)
 	}
 
+	if !vgo.MustBeVgo {
+		if vgo.Init(); vgo.Enabled() {
+			// Didn't do this above, so do it now.
+			*get.CmdGet = *vgo.CmdGet
+		}
+	}
+
 	// Set environment (GOOS, GOARCH, etc) explicitly.
 	// In theory all the commands we invoke should have
 	// the same default computation of these as we do,
diff --git a/vendor/cmd/go/vgo_test.go b/vendor/cmd/go/vgo_test.go
index a6ccd26..6cc8297 100644
--- a/vendor/cmd/go/vgo_test.go
+++ b/vendor/cmd/go/vgo_test.go
@@ -5,7 +5,12 @@
 package Main_test
 
 import (
+	"cmd/go/internal/modconv"
+	"cmd/go/internal/vgo"
+	"io/ioutil"
+	"os"
 	"runtime"
+	"sort"
 	"testing"
 )
 
@@ -19,3 +24,30 @@
 	tg.setenv("VGOROOT", runtime.GOROOT())
 	tg.run("env")
 }
+
+func TestFindModRoot(t *testing.T) {
+	tg := testgo(t)
+	defer tg.cleanup()
+	tg.makeTempdir()
+
+	tg.must(os.MkdirAll(tg.path("x/Godeps"), 0777))
+	tg.must(os.MkdirAll(tg.path("x/vendor"), 0777))
+	tg.must(os.MkdirAll(tg.path("x/y/z"), 0777))
+	tg.must(os.MkdirAll(tg.path("x/.git"), 0777))
+	var files []string
+	for file := range modconv.Converters {
+		files = append(files, file)
+	}
+	files = append(files, "go.mod")
+	files = append(files, ".git/config")
+	sort.Strings(files)
+
+	for file := range modconv.Converters {
+		tg.must(ioutil.WriteFile(tg.path("x/"+file), []byte{}, 0666))
+		root, file1 := vgo.FindModuleRoot(tg.path("x/y/z"), tg.path("."), true)
+		if root != tg.path("x") || file1 != file {
+			t.Errorf("%s: findModuleRoot = %q, %q, want %q, %q", file, root, file1, tg.path("x"), file)
+		}
+		tg.must(os.Remove(tg.path("x/" + file)))
+	}
+}