1
2
3
4
5 package toolchain
6
7 import (
8 "io/fs"
9 "os"
10 "path/filepath"
11 "strings"
12 "sync"
13
14 "cmd/go/internal/gover"
15 )
16
17 var pathExts = sync.OnceValue(func() []string {
18 x := os.Getenv(`PATHEXT`)
19 if x == "" {
20 return []string{".com", ".exe", ".bat", ".cmd"}
21 }
22
23 var exts []string
24 for _, e := range strings.Split(strings.ToLower(x), `;`) {
25 if e == "" {
26 continue
27 }
28 if e[0] != '.' {
29 e = "." + e
30 }
31 exts = append(exts, e)
32 }
33 return exts
34 })
35
36
37 func pathDirs() []string {
38 return filepath.SplitList(os.Getenv("PATH"))
39 }
40
41
42
43
44 func pathVersion(dir string, de fs.DirEntry, info fs.FileInfo) (string, bool) {
45 name, _, ok := cutExt(de.Name(), pathExts())
46 if !ok {
47 return "", false
48 }
49 v := gover.FromToolchain(name)
50 if v == "" {
51 return "", false
52 }
53 return v, true
54 }
55
56
57
58
59
60 func cutExt(file string, exts []string) (name, ext string, found bool) {
61 i := strings.LastIndex(file, ".")
62 if i < 0 {
63 return file, "", false
64 }
65 for _, x := range exts {
66 if strings.EqualFold(file[i:], x) {
67 return file[:i], file[i:], true
68 }
69 }
70 return file, "", false
71 }
72
View as plain text