summaryrefslogtreecommitdiffstats
path: root/src/cmd/go/internal/toolchain/path_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/go/internal/toolchain/path_windows.go')
-rw-r--r--src/cmd/go/internal/toolchain/path_windows.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/cmd/go/internal/toolchain/path_windows.go b/src/cmd/go/internal/toolchain/path_windows.go
new file mode 100644
index 0000000..086c591
--- /dev/null
+++ b/src/cmd/go/internal/toolchain/path_windows.go
@@ -0,0 +1,78 @@
+// Copyright 2023 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 toolchain
+
+import (
+ "io/fs"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+
+ "cmd/go/internal/gover"
+)
+
+// pathExts is a cached PATHEXT list.
+var pathExts struct {
+ once sync.Once
+ list []string
+}
+
+func initPathExts() {
+ var exts []string
+ x := os.Getenv(`PATHEXT`)
+ if x != "" {
+ for _, e := range strings.Split(strings.ToLower(x), `;`) {
+ if e == "" {
+ continue
+ }
+ if e[0] != '.' {
+ e = "." + e
+ }
+ exts = append(exts, e)
+ }
+ } else {
+ exts = []string{".com", ".exe", ".bat", ".cmd"}
+ }
+ pathExts.list = exts
+}
+
+// pathDirs returns the directories in the system search path.
+func pathDirs() []string {
+ return filepath.SplitList(os.Getenv("PATH"))
+}
+
+// pathVersion returns the Go version implemented by the file
+// described by de and info in directory dir.
+// The analysis only uses the name itself; it does not run the program.
+func pathVersion(dir string, de fs.DirEntry, info fs.FileInfo) (string, bool) {
+ pathExts.once.Do(initPathExts)
+ name, _, ok := cutExt(de.Name(), pathExts.list)
+ if !ok {
+ return "", false
+ }
+ v := gover.FromToolchain(name)
+ if v == "" {
+ return "", false
+ }
+ return v, true
+}
+
+// cutExt looks for any of the known extensions at the end of file.
+// If one is found, cutExt returns the file name with the extension trimmed,
+// the extension itself, and true to signal that an extension was found.
+// Otherwise cutExt returns file, "", false.
+func cutExt(file string, exts []string) (name, ext string, found bool) {
+ i := strings.LastIndex(file, ".")
+ if i < 0 {
+ return file, "", false
+ }
+ for _, x := range exts {
+ if strings.EqualFold(file[i:], x) {
+ return file[:i], file[i:], true
+ }
+ }
+ return file, "", false
+}