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))) + } +}