github.com/joey-fossa/fossa-cli@v0.7.34-0.20190708193710-569f1e8679f0/exec/which.go (about) 1 package exec 2 3 import ( 4 "errors" 5 6 "github.com/apex/log" 7 ) 8 9 // Which picks a command out of a list of candidates. 10 func Which(arg string, cmds ...string) (cmd string, output string, err error) { 11 return WhichArgs([]string{arg}, cmds...) 12 } 13 14 // WhichArgs is `Which` but passes multiple arguments to each candidate. 15 func WhichArgs(argv []string, cmds ...string) (cmd string, output string, err error) { 16 return WhichWithResolver(cmds, func(cmd string) (string, bool, error) { 17 stdout, stderr, err := Run(Cmd{ 18 Name: cmd, 19 Argv: argv, 20 }) 21 if err != nil { 22 return "", false, err 23 } 24 if stdout == "" { 25 return stderr, true, nil 26 } 27 return stdout, true, nil 28 }) 29 } 30 31 // A WhichResolver takes a candidate command and returns whether to choose it. 32 type WhichResolver func(cmd string) (output string, ok bool, err error) 33 34 // WhichWithResolver is `Which` with a custom resolution strategy. 35 func WhichWithResolver(cmds []string, resolve WhichResolver) (string, string, error) { 36 for _, cmd := range cmds { 37 version, ok, err := resolve(cmd) 38 if ok { 39 return cmd, version, nil 40 } 41 log.WithError(err).WithFields(log.Fields{ 42 "cmd": cmd, 43 "version": version, 44 }) 45 } 46 return "", "", errors.New("could not resolve command") 47 }