go/packages/packagestest: fix GOPROXY file URLs for Windows

Amends prematurely submitted CL 173918. We now use file:/// URLs for
go1.13 and later and file:// URLs for go1.12 and earlier.

Fixes golang/go#31675

Change-Id: I009c63a900bdfd091bf46def5cea5a0843639b47
Reviewed-on: https://go-review.googlesource.com/c/tools/+/173919
Run-TryBot: Jay Conrod <jayconrod@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/go/packages/packagestest/modules.go b/go/packages/packagestest/modules.go
index 1ca961a..0a660bb 100644
--- a/go/packages/packagestest/modules.go
+++ b/go/packages/packagestest/modules.go
@@ -14,7 +14,6 @@
 	"path"
 	"path/filepath"
 	"regexp"
-	"strings"
 
 	"golang.org/x/tools/go/packages"
 )
@@ -102,13 +101,6 @@
 			return fmt.Errorf("creating module proxy dir for %v: %v", module, err)
 		}
 	}
-	proxyURL := filepath.ToSlash(proxyDir)
-	if !strings.HasPrefix(proxyURL, "/") {
-		// Windows paths will look like C:/foo/bar. In the URL, the C: will be
-		// interpreted as the host, so add a leading /. See golang.org/issue/6027.
-		proxyURL = "/" + proxyURL
-	}
-	proxyURL = "file://" + proxyURL
 
 	// Discard the original mod cache dir, which contained the files written
 	// for us by Export.
@@ -118,7 +110,7 @@
 	exported.Config.Env = append(exported.Config.Env,
 		"GO111MODULE=on",
 		"GOPATH="+filepath.Join(exported.temp, "modcache"),
-		"GOPROXY=file://"+filepath.ToSlash(proxyDir))
+		"GOPROXY="+proxyDirToURL(proxyDir))
 
 	// Run go mod download to recreate the mod cache dir with all the extra
 	// stuff in cache. All the files created by Export should be recreated.
diff --git a/go/packages/packagestest/modules_112.go b/go/packages/packagestest/modules_112.go
new file mode 100644
index 0000000..e30d67d
--- /dev/null
+++ b/go/packages/packagestest/modules_112.go
@@ -0,0 +1,17 @@
+// +build !go1.13
+
+// Copyright 2019 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 packagestest
+
+import "path/filepath"
+
+func proxyDirToURL(dir string) string {
+	// Prior to go1.13, the Go command on Windows only accepted GOPROXY file URLs
+	// of the form file://C:/path/to/proxy. This was incorrect: when parsed, "C:"
+	// is interpreted as the host. See golang.org/issue/6027. This has been
+	// fixed in go1.13, but we emit the old format for old releases.
+	return "file://" + filepath.ToSlash(dir)
+}
diff --git a/go/packages/packagestest/modules_113.go b/go/packages/packagestest/modules_113.go
new file mode 100644
index 0000000..6b7c57f
--- /dev/null
+++ b/go/packages/packagestest/modules_113.go
@@ -0,0 +1,21 @@
+// +build go1.13
+
+// Copyright 2018 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 packagestest
+
+import (
+	"path/filepath"
+	"strings"
+)
+
+func proxyDirToURL(dir string) string {
+	// file URLs on Windows must start with file:///. See golang.org/issue/6027.
+	path := filepath.ToSlash(dir)
+	if !strings.HasPrefix(path, "/") {
+		path = "/" + path
+	}
+	return "file://" + path
+}
diff --git a/imports/mod_test.go b/imports/mod_test.go
index a6bf8d6..f2fb76e 100644
--- a/imports/mod_test.go
+++ b/imports/mod_test.go
@@ -519,7 +519,7 @@
 		GOROOT:      build.Default.GOROOT,
 		GOPATH:      filepath.Join(dir, "gopath"),
 		GO111MODULE: "on",
-		GOPROXY:     "file://" + filepath.ToSlash(proxyDir),
+		GOPROXY:     proxyDirToURL(proxyDir),
 		WorkingDir:  filepath.Join(mainDir, wd),
 	}
 
diff --git a/imports/proxy_112_test.go b/imports/proxy_112_test.go
new file mode 100644
index 0000000..732879a
--- /dev/null
+++ b/imports/proxy_112_test.go
@@ -0,0 +1,20 @@
+// +build !go1.13
+
+// Copyright 2019 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 imports
+
+import "path/filepath"
+
+// TODO: use proxy functionality in golang.org/x/tools/go/packages/packagestest
+// instead of copying it here.
+
+func proxyDirToURL(dir string) string {
+	// Prior to go1.13, the Go command on Windows only accepted GOPROXY file URLs
+	// of the form file://C:/path/to/proxy. This was incorrect: when parsed, "C:"
+	// is interpreted as the host. See golang.org/issue/6027. This has been
+	// fixed in go1.13, but we emit the old format for old releases.
+	return "file://" + filepath.ToSlash(dir)
+}
diff --git a/imports/proxy_113_test.go b/imports/proxy_113_test.go
new file mode 100644
index 0000000..f6f6be5
--- /dev/null
+++ b/imports/proxy_113_test.go
@@ -0,0 +1,24 @@
+// +build go1.13
+
+// Copyright 2018 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 imports
+
+import (
+	"path/filepath"
+	"strings"
+)
+
+// TODO: use proxy functionality in golang.org/x/tools/go/packages/packagestest
+// instead of copying it here.
+
+func proxyDirToURL(dir string) string {
+	// file URLs on Windows must start with file:///. See golang.org/issue/6027.
+	path := filepath.ToSlash(dir)
+	if !strings.HasPrefix(path, "/") {
+		path = "/" + path
+	}
+	return "file://" + path
+}