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  }