cmd/go/internal/modcmd: implement -verify, dropping 'vgo verify'

Change-Id: Ib6f68875595da748de1c6940cd6ed7a5b460e1a8
Reviewed-on: https://go-review.googlesource.com/118875
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/vendor/cmd/go/internal/modcmd/mod.go b/vendor/cmd/go/internal/modcmd/mod.go
index f8b36d4..194ba02 100644
--- a/vendor/cmd/go/internal/modcmd/mod.go
+++ b/vendor/cmd/go/internal/modcmd/mod.go
@@ -261,7 +261,7 @@
 	}
 
 	if *modVerify {
-		panic("TODO: move runVerify over")
+		runVerify()
 	}
 }
 
diff --git a/vendor/cmd/go/internal/vgo/verify.go b/vendor/cmd/go/internal/modcmd/verify.go
similarity index 60%
rename from vendor/cmd/go/internal/vgo/verify.go
rename to vendor/cmd/go/internal/modcmd/verify.go
index 0938092..60a9871 100644
--- a/vendor/cmd/go/internal/vgo/verify.go
+++ b/vendor/cmd/go/internal/modcmd/verify.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package vgo
+package modcmd
 
 import (
 	"bytes"
@@ -14,40 +14,12 @@
 	"cmd/go/internal/base"
 	"cmd/go/internal/dirhash"
 	"cmd/go/internal/module"
+	"cmd/go/internal/vgo"
 )
 
-var CmdVerify = &base.Command{
-	UsageLine: "verify",
-	Run:       runVerify,
-	Short:     "verify downloaded modules against expected hashes",
-	Long: `
-Verify checks that the dependencies of the current module,
-which are stored in a local downloaded source cache,
-have not been modified since being downloaded.
-
-If all the modules are unmodified, verify prints
-
-	all modules verified
-
-and exits successfully (status 0). Otherwise, verify reports
-which modules have been changed and exits with a non-zero status.
-	`,
-}
-
-func runVerify(cmd *base.Command, args []string) {
-	if Init(); !Enabled() {
-		base.Fatalf("vgo verify: cannot use outside module")
-	}
-	if len(args) != 0 {
-		// TODO: take arguments
-		base.Fatalf("vgo verify: verify takes no arguments")
-	}
-
-	// Make go.mod consistent but don't load any packages.
-	LoadBuildList()
-
+func runVerify() {
 	ok := true
-	for _, mod := range buildList[1:] {
+	for _, mod := range vgo.LoadBuildList()[1:] {
 		ok = verifyMod(mod) && ok
 	}
 	if ok {
@@ -57,9 +29,9 @@
 
 func verifyMod(mod module.Version) bool {
 	ok := true
-	zip := filepath.Join(srcV, "cache", mod.Path, "/@v/", mod.Version+".zip")
+	zip := filepath.Join(vgo.SrcV, "cache", mod.Path, "/@v/", mod.Version+".zip")
 	_, zipErr := os.Stat(zip)
-	dir := filepath.Join(srcV, mod.Path+"@"+mod.Version)
+	dir := filepath.Join(vgo.SrcV, mod.Path+"@"+mod.Version)
 	_, dirErr := os.Stat(dir)
 	data, err := ioutil.ReadFile(zip + "hash")
 	if err != nil {
diff --git a/vendor/cmd/go/internal/vgo/fetch.go b/vendor/cmd/go/internal/vgo/fetch.go
index c28353c..7cec65a 100644
--- a/vendor/cmd/go/internal/vgo/fetch.go
+++ b/vendor/cmd/go/internal/vgo/fetch.go
@@ -38,16 +38,16 @@
 	}
 
 	modpath := mod.Path + "@" + mod.Version
-	dir = filepath.Join(srcV, modpath)
+	dir = filepath.Join(SrcV, modpath)
 	if files, _ := ioutil.ReadDir(dir); len(files) == 0 {
-		zipfile := filepath.Join(srcV, "cache", mod.Path, "@v", mod.Version+".zip")
+		zipfile := filepath.Join(SrcV, "cache", mod.Path, "@v", mod.Version+".zip")
 		if _, err := os.Stat(zipfile); err == nil {
 			// Use it.
 			// This should only happen if the v/cache directory is preinitialized
 			// or if src/v/modpath was removed but not src/v/cache.
 			fmt.Fprintf(os.Stderr, "vgo: extracting %s %s\n", mod.Path, mod.Version)
 		} else {
-			if err := os.MkdirAll(filepath.Join(srcV, "cache", mod.Path, "@v"), 0777); err != nil {
+			if err := os.MkdirAll(filepath.Join(SrcV, "cache", mod.Path, "@v"), 0777); err != nil {
 				return "", err
 			}
 			fmt.Fprintf(os.Stderr, "vgo: downloading %s %s\n", mod.Path, mod.Version)
@@ -159,7 +159,7 @@
 		return
 	}
 
-	data, err := ioutil.ReadFile(filepath.Join(srcV, "cache", mod.Path, "@v", mod.Version+".ziphash"))
+	data, err := ioutil.ReadFile(filepath.Join(SrcV, "cache", mod.Path, "@v", mod.Version+".ziphash"))
 	if err != nil {
 		base.Fatalf("vgo: verifying %s %s: %v", mod.Path, mod.Version, err)
 	}
@@ -183,7 +183,7 @@
 }
 
 func findModHash(mod module.Version) string {
-	data, err := ioutil.ReadFile(filepath.Join(srcV, "cache", mod.Path, "@v", mod.Version+".ziphash"))
+	data, err := ioutil.ReadFile(filepath.Join(SrcV, "cache", mod.Path, "@v", mod.Version+".ziphash"))
 	if err != nil {
 		return ""
 	}
diff --git a/vendor/cmd/go/internal/vgo/init.go b/vendor/cmd/go/internal/vgo/init.go
index 1b6beb4..5af38cc 100644
--- a/vendor/cmd/go/internal/vgo/init.go
+++ b/vendor/cmd/go/internal/vgo/init.go
@@ -40,7 +40,7 @@
 	Target   module.Version
 
 	gopath string
-	srcV   string
+	SrcV   string // GOPATH/src/v directory where versioned cache lives
 
 	CmdModInit   bool   // go mod -init flag
 	CmdModModule string // go mod -module flag
@@ -170,8 +170,8 @@
 	if _, err := os.Stat(filepath.Join(gopath, "go.mod")); err == nil {
 		base.Fatalf("$GOPATH/go.mod exists but should not")
 	}
-	srcV = filepath.Join(list[0], "src/v")
-	codehost.WorkRoot = filepath.Join(srcV, "cache/vcswork")
+	SrcV = filepath.Join(list[0], "src/v")
+	codehost.WorkRoot = filepath.Join(SrcV, "cache/vcswork")
 
 	if CmdModInit {
 		// Running go mod -init: do legacy module conversion
diff --git a/vendor/cmd/go/internal/vgo/load.go b/vendor/cmd/go/internal/vgo/load.go
index c56838f..09dd0d5 100644
--- a/vendor/cmd/go/internal/vgo/load.go
+++ b/vendor/cmd/go/internal/vgo/load.go
@@ -63,18 +63,19 @@
 	WriteGoMod()
 }
 
-// LoadBuildList loads the build list from go.mod.
+// LoadBuildList loads and returns the build list from go.mod.
 // The loading of the build list happens automatically in ImportPaths:
 // LoadBuildList need only be called if ImportPaths is not
 // (typically in commands that care about the module but
 // no particular package).
-func LoadBuildList() {
+func LoadBuildList() []module.Version {
 	if Init(); !Enabled() {
 		base.Fatalf("vgo: LoadBuildList called but vgo not enabled")
 	}
 	InitMod()
 	iterate(func(*loader) {})
 	WriteGoMod()
+	return buildList
 }
 
 // PkgMod returns a map from package import path to the module supplying that package.
@@ -455,8 +456,8 @@
 		// TODO: return nil, fmt.Errorf("invalid semantic version %q", mod.Version)
 	}
 
-	gomod := filepath.Join(srcV, "cache", mod.Path, "@v", mod.Version+".mod")
-	infofile := filepath.Join(srcV, "cache", mod.Path, "@v", mod.Version+".info")
+	gomod := filepath.Join(SrcV, "cache", mod.Path, "@v", mod.Version+".mod")
+	infofile := filepath.Join(SrcV, "cache", mod.Path, "@v", mod.Version+".info")
 	var f *modfile.File
 	if data, err := ioutil.ReadFile(gomod); err == nil {
 		// If go.mod has a //vgo comment at the start,
diff --git a/vendor/cmd/go/main.go b/vendor/cmd/go/main.go
index d8c6b22..3f3518f 100644
--- a/vendor/cmd/go/main.go
+++ b/vendor/cmd/go/main.go
@@ -55,7 +55,6 @@
 		test.CmdTest,
 		tool.CmdTool,
 		vgo.CmdVendor,
-		vgo.CmdVerify,
 		version.CmdVersion,
 		vet.CmdVet,
 
@@ -126,14 +125,16 @@
 		os.Exit(2)
 	}
 
-	// Run vgo.Init so that each subcommand doesn't have to worry about it.
-	// Also install the vgo get command instead of the old go get command in vgo mode.
-	//
-	// If we should be vgo (if the command is named vgo or if invoked as go -vgo),
-	// and there is no go.mod file, vgo.Init will treat that as a fatal error.
-	// Normally that's fine, but if this is 'go mod -init' we need to give it a
-	// chance to create that go.mod file, so skip the init dance for 'go mod'.
-	if args[0] != "mod" {
+	switch args[0] {
+	case "verify":
+		fmt.Fprintf(os.Stderr, "go verify is now go mod -verify\n")
+		os.Exit(2)
+	case "mod":
+		// Skip vgo.Init (which may insist on go.mod existing)
+		// so that go mod -init has a chance to write the file.
+	default:
+		// Run vgo.Init so that each subcommand doesn't have to worry about it.
+		// Also install the vgo get command instead of the old go get command in vgo mode.
 		vgo.Init()
 		if !vgo.MustBeVgo && vgo.Enabled() {
 			// Didn't do this above, so do it now.