all: add go.mod
Copy golang.org/x/build/envutil.Dedup locally to avoid pulling in all
of x/build.
Commands run:
go mod init
go mod edit -go=1.11
go mod tidy
go list -m all
go test ./...
Updates golang/go#30228
Change-Id: I0fc24565c08a73db067daf080b46f4aa82a63c41
Reviewed-on: https://go-review.googlesource.com/c/dl/+/167703
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..63793e5
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module golang.org/dl
+
+go 1.11
diff --git a/internal/version/version.go b/internal/version/version.go
index 3704b39..cfb7128 100644
--- a/internal/version/version.go
+++ b/internal/version/version.go
@@ -24,8 +24,6 @@
"runtime"
"strings"
"time"
-
- "golang.org/x/build/envutil"
)
func init() {
@@ -62,10 +60,7 @@
if p := os.Getenv("PATH"); p != "" {
newPath += string(filepath.ListSeparator) + p
}
- // This envutil.Dedup call is unnecessary when the binary is
- // built with Go 1.9+, but keep it around for now until Go 1.8
- // is no longer seen in the wild in common distros.
- cmd.Env = envutil.Dedup(caseInsensitiveEnv, append(os.Environ(), "GOROOT="+root, "PATH="+newPath))
+ cmd.Env = dedupEnv(caseInsensitiveEnv, append(os.Environ(), "GOROOT="+root, "PATH="+newPath))
if err := cmd.Run(); err != nil {
// TODO: return the same exit status maybe.
os.Exit(1)
@@ -456,3 +451,37 @@
r.Header.Set("User-Agent", "golang-x-build-version/"+version)
return uat.rt.RoundTrip(r)
}
+
+// dedupEnv returns a copy of env with any duplicates removed, in favor of
+// later values.
+// Items are expected to be on the normal environment "key=value" form.
+// If caseInsensitive is true, the case of keys is ignored.
+//
+// This function is unnecessary when the binary is
+// built with Go 1.9+, but keep it around for now until Go 1.8
+// is no longer seen in the wild in common distros.
+//
+// This is copied verbatim from golang.org/x/build/envutil.Dedup at CL 10301
+// (commit a91ae26).
+func dedupEnv(caseInsensitive bool, env []string) []string {
+ out := make([]string, 0, len(env))
+ saw := map[string]int{} // to index in the array
+ for _, kv := range env {
+ eq := strings.Index(kv, "=")
+ if eq < 1 {
+ out = append(out, kv)
+ continue
+ }
+ k := kv[:eq]
+ if caseInsensitive {
+ k = strings.ToLower(k)
+ }
+ if dupIdx, isDup := saw[k]; isDup {
+ out[dupIdx] = kv
+ } else {
+ saw[k] = len(out)
+ out = append(out, kv)
+ }
+ }
+ return out
+}
diff --git a/internal/version/version_test.go b/internal/version/version_test.go
new file mode 100644
index 0000000..c08e211
--- /dev/null
+++ b/internal/version/version_test.go
@@ -0,0 +1,35 @@
+// 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 version
+
+import (
+ "reflect"
+ "testing"
+)
+
+func TestDedupEnv(t *testing.T) {
+ tests := []struct {
+ noCase bool
+ in []string
+ want []string
+ }{
+ {
+ noCase: true,
+ in: []string{"k1=v1", "k2=v2", "K1=v3"},
+ want: []string{"K1=v3", "k2=v2"},
+ },
+ {
+ noCase: false,
+ in: []string{"k1=v1", "K1=V2", "k1=v3"},
+ want: []string{"k1=v3", "K1=V2"},
+ },
+ }
+ for _, tt := range tests {
+ got := dedupEnv(tt.noCase, tt.in)
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("Dedup(%v, %q) = %q; want %q", tt.noCase, tt.in, got, tt.want)
+ }
+ }
+}