github.com/bshelton229/agent@v3.5.4+incompatible/bootstrap/shell/lookpath_windows.go (about) 1 // This file (along with it's *nix counterpart) have been taken from: 2 // 3 // https://github.com/golang/go/blob/master/src/os/exec/lp_windows.go 4 // 5 // Their implemenations are exactly the same, however in this version - the 6 // paths to search in (along with file extensions to look at) can be 7 // customized. 8 9 package shell 10 11 import ( 12 "os" 13 "os/exec" 14 "path/filepath" 15 "strings" 16 ) 17 18 func chkStat(file string) error { 19 d, err := os.Stat(file) 20 if err != nil { 21 return err 22 } 23 if d.IsDir() { 24 return os.ErrPermission 25 } 26 return nil 27 } 28 29 func hasExt(file string) bool { 30 i := strings.LastIndex(file, ".") 31 if i < 0 { 32 return false 33 } 34 return strings.LastIndexAny(file, `:\/`) < i 35 } 36 37 func findExecutable(file string, exts []string) (string, error) { 38 if len(exts) == 0 { 39 return file, chkStat(file) 40 } 41 if hasExt(file) { 42 if chkStat(file) == nil { 43 return file, nil 44 } 45 } 46 for _, e := range exts { 47 if f := file + e; chkStat(f) == nil { 48 return f, nil 49 } 50 } 51 return "", os.ErrNotExist 52 } 53 54 // LookPath searches for an executable binary named file in the directories within the path variable, 55 // which is a semi-colon delimited path. 56 // If file contains a slash, it is tried directly 57 // LookPath also uses PATHEXT environment variable to match a suitable candidate. 58 // The result may be an absolute path or a path relative to the current directory. 59 func LookPath(file string, path string, fileExtensions string) (string, error) { 60 var exts []string 61 if fileExtensions != "" { 62 for _, e := range strings.Split(strings.ToLower(fileExtensions), `;`) { 63 if e == "" { 64 continue 65 } 66 if e[0] != '.' { 67 e = "." + e 68 } 69 exts = append(exts, e) 70 } 71 } else { 72 exts = []string{".com", ".exe", ".bat", ".cmd"} 73 } 74 75 if strings.ContainsAny(file, `:\/`) { 76 if f, err := findExecutable(file, exts); err == nil { 77 return f, nil 78 } else { 79 return "", &exec.Error{file, err} 80 } 81 } 82 if f, err := findExecutable(filepath.Join(".", file), exts); err == nil { 83 return f, nil 84 } 85 for _, dir := range filepath.SplitList(path) { 86 if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil { 87 return f, nil 88 } 89 } 90 return "", &exec.Error{file, exec.ErrNotFound} 91 }