github.com/mutagen-io/mutagen@v0.18.0-rc1/pkg/platform/find_command.go (about)

     1  package platform
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"runtime"
     9  )
    10  
    11  // FindCommand searches for a command with the specified name within the
    12  // specified list of directories. It's similar to os/exec.LookPath, except that
    13  // it allows one to manually specify paths, and it uses a slightly simpler
    14  // lookup mechanism.
    15  func FindCommand(name string, paths []string) (string, error) {
    16  	// Iterate through the directories.
    17  	for _, path := range paths {
    18  		// Compute the target name.
    19  		target := filepath.Join(path, ExecutableName(name, runtime.GOOS))
    20  
    21  		// Check if the target exists and has the correct type.
    22  		// TODO: Should we do more extensive (and platform-specific) testing on
    23  		// the resulting metadata? See, e.g., the implementation of
    24  		// os/exec.LookPath.
    25  		if metadata, err := os.Stat(target); err != nil {
    26  			if os.IsNotExist(err) {
    27  				continue
    28  			}
    29  			return "", fmt.Errorf("unable to query file metadata: %w", err)
    30  		} else if metadata.Mode()&os.ModeType != 0 {
    31  			continue
    32  		} else {
    33  			return target, nil
    34  		}
    35  	}
    36  
    37  	// Failure.
    38  	return "", errors.New("unable to locate command")
    39  }