go/packages/packagestest: make versioned modules

If a Module's Name ends with a version suffix (v2), create its module
with an appropriate version number (v2.0.0).

Change-Id: I1a16f054fac5717e79871ba1bf9a6343c0ce2f5b
Reviewed-on: https://go-review.googlesource.com/c/146097
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/go/packages/packagestest/export_test.go b/go/packages/packagestest/export_test.go
index 0e0b53a..decfd7c 100644
--- a/go/packages/packagestest/export_test.go
+++ b/go/packages/packagestest/export_test.go
@@ -24,6 +24,11 @@
 	Files: map[string]interface{}{
 		"other/a.go": "package fake2",
 	},
+}, {
+	Name: "golang.org/fake2/v2",
+	Files: map[string]interface{}{
+		"other/a.go": "package fake2",
+	},
 }}
 
 type fileTest struct {
diff --git a/go/packages/packagestest/gopath.go b/go/packages/packagestest/gopath.go
index 4a086c5..5401685 100644
--- a/go/packages/packagestest/gopath.go
+++ b/go/packages/packagestest/gopath.go
@@ -66,5 +66,9 @@
 }
 
 func gopathDir(exported *Exported, module string) string {
-	return filepath.Join(exported.temp, path.Base(module))
+	dir := path.Base(module)
+	if versionSuffixRE.MatchString(dir) {
+		dir = path.Base(path.Dir(module)) + "_" + dir
+	}
+	return filepath.Join(exported.temp, dir)
 }
diff --git a/go/packages/packagestest/gopath_test.go b/go/packages/packagestest/gopath_test.go
index bc6f62c..a251dbc 100644
--- a/go/packages/packagestest/gopath_test.go
+++ b/go/packages/packagestest/gopath_test.go
@@ -23,5 +23,6 @@
 		{"golang.org/fake1", "a.go", "fake1/src/golang.org/fake1/a.go", checkLink("testdata/a.go")},
 		{"golang.org/fake1", "b.go", "fake1/src/golang.org/fake1/b.go", checkContent("package fake1")},
 		{"golang.org/fake2", "other/a.go", "fake2/src/golang.org/fake2/other/a.go", checkContent("package fake2")},
+		{"golang.org/fake2/v2", "other/a.go", "fake2_v2/src/golang.org/fake2/v2/other/a.go", checkContent("package fake2")},
 	})
 }
diff --git a/go/packages/packagestest/modules.go b/go/packages/packagestest/modules.go
index f928831..58137bc 100644
--- a/go/packages/packagestest/modules.go
+++ b/go/packages/packagestest/modules.go
@@ -13,6 +13,7 @@
 	"os/exec"
 	"path"
 	"path/filepath"
+	"regexp"
 
 	"golang.org/x/tools/go/packages"
 )
@@ -37,8 +38,6 @@
 //     /sometemporarydirectory/repoa
 var Modules = modules{}
 
-const theVersion = "v1.0.0"
-
 type modules struct{}
 
 func (modules) Name() string {
@@ -64,7 +63,7 @@
 		if other == exported.primary {
 			continue
 		}
-		primaryGomod += fmt.Sprintf("\t%v %v\n", other, theVersion)
+		primaryGomod += fmt.Sprintf("\t%v %v\n", other, moduleVersion(other))
 	}
 	primaryGomod += ")\n"
 	if err := ioutil.WriteFile(filepath.Join(primaryDir, "go.mod"), []byte(primaryGomod), 0644); err != nil {
@@ -124,12 +123,13 @@
 
 // writeModuleProxy creates a directory in the proxy dir for a module.
 func writeModuleProxy(dir, module string, files map[string]string) error {
+	ver := moduleVersion(module)
 	if err := os.MkdirAll(dir, 0755); err != nil {
 		return err
 	}
 
 	// list file. Just the single version.
-	if err := ioutil.WriteFile(filepath.Join(dir, "list"), []byte(theVersion+"\n"), 0644); err != nil {
+	if err := ioutil.WriteFile(filepath.Join(dir, "list"), []byte(ver+"\n"), 0644); err != nil {
 		return err
 	}
 
@@ -138,24 +138,24 @@
 	if err != nil {
 		return err
 	}
-	if err := ioutil.WriteFile(filepath.Join(dir, theVersion+".mod"), modContents, 0644); err != nil {
+	if err := ioutil.WriteFile(filepath.Join(dir, ver+".mod"), modContents, 0644); err != nil {
 		return err
 	}
 
 	// info file, just the bare bones.
-	infoContents := []byte(fmt.Sprintf(`{"Version": "%v", "Time":"2017-12-14T13:08:43Z"}`, theVersion))
-	if err := ioutil.WriteFile(filepath.Join(dir, theVersion+".info"), infoContents, 0644); err != nil {
+	infoContents := []byte(fmt.Sprintf(`{"Version": "%v", "Time":"2017-12-14T13:08:43Z"}`, ver))
+	if err := ioutil.WriteFile(filepath.Join(dir, ver+".info"), infoContents, 0644); err != nil {
 		return err
 	}
 
 	// zip of all the source files.
-	f, err := os.OpenFile(filepath.Join(dir, theVersion+".zip"), os.O_CREATE|os.O_WRONLY, 0644)
+	f, err := os.OpenFile(filepath.Join(dir, ver+".zip"), os.O_CREATE|os.O_WRONLY, 0644)
 	if err != nil {
 		return err
 	}
 	z := zip.NewWriter(f)
 	for name, path := range files {
-		zf, err := z.Create(module + "@" + theVersion + "/" + name)
+		zf, err := z.Create(module + "@" + ver + "/" + name)
 		if err != nil {
 			return err
 		}
@@ -197,5 +197,14 @@
 }
 
 func moduleDir(exported *Exported, module string) string {
-	return filepath.Join(modCache(exported), path.Dir(module), path.Base(module)+"@"+theVersion)
+	return filepath.Join(modCache(exported), path.Dir(module), path.Base(module)+"@"+moduleVersion(module))
+}
+
+var versionSuffixRE = regexp.MustCompile(`v\d+`)
+
+func moduleVersion(module string) string {
+	if versionSuffixRE.MatchString(path.Base(module)) {
+		return path.Base(module) + ".0.0"
+	}
+	return "v1.0.0"
 }
diff --git a/go/packages/packagestest/modules_test.go b/go/packages/packagestest/modules_test.go
index c4868a5..8a85ae1 100644
--- a/go/packages/packagestest/modules_test.go
+++ b/go/packages/packagestest/modules_test.go
@@ -27,5 +27,6 @@
 		{"golang.org/fake1", "b.go", "primarymod/fake1/b.go", checkContent("package fake1")},
 		{"golang.org/fake2", "go.mod", "modcache/pkg/mod/golang.org/fake2@v1.0.0/go.mod", nil},
 		{"golang.org/fake2", "other/a.go", "modcache/pkg/mod/golang.org/fake2@v1.0.0/other/a.go", checkContent("package fake2")},
+		{"golang.org/fake2/v2", "other/a.go", "modcache/pkg/mod/golang.org/fake2/v2@v2.0.0/other/a.go", checkContent("package fake2")},
 	})
 }