Source file src/cmd/go/internal/toolchain/path_windows.go

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     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  // pathDirs returns the directories in the system search path.
    37  func pathDirs() []string {
    38  	return filepath.SplitList(os.Getenv("PATH"))
    39  }
    40  
    41  // pathVersion returns the Go version implemented by the file
    42  // described by de and info in directory dir.
    43  // The analysis only uses the name itself; it does not run the program.
    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  // cutExt looks for any of the known extensions at the end of file.
    57  // If one is found, cutExt returns the file name with the extension trimmed,
    58  // the extension itself, and true to signal that an extension was found.
    59  // Otherwise cutExt returns file, "", false.
    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