github.com/stevenmatthewt/agent@v3.5.4+incompatible/utils/path.go (about)

     1  package utils
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"os/user"
     7  	"path/filepath"
     8  )
     9  
    10  // NormalizeCommand has very similar semantics to `NormalizeFilePath`, except
    11  // we only "absolute" the path if it exists on the filesystem. This will ensure
    12  // that:
    13  //
    14  // "templates/bootstrap.sh" => "/Users/keithpitt/Development/.../templates/bootstrap.sh"
    15  // "~/.buildkite-agent/bootstrap.sh" => "/Users/keithpitt/.buildkite-agent/bootstrap.sh"
    16  // "cat Readme.md" => "cat Readme.md"
    17  
    18  func NormalizeCommand(commandPath string) (string, error) {
    19  	// don't normalize empty strings
    20  	if commandPath == "" {
    21  		return "", nil
    22  	}
    23  
    24  	// expand env and home directory
    25  	var err error
    26  	commandPath, err = ExpandHome(os.ExpandEnv(commandPath))
    27  	if err != nil {
    28  		return "", err
    29  	}
    30  
    31  	// if the file exists, absolute it
    32  	if _, err := os.Stat(commandPath); err == nil {
    33  		// make sure its absolute
    34  		absoluteCommandPath, err := filepath.Abs(commandPath)
    35  		if err != nil {
    36  			return "", err
    37  		}
    38  		commandPath = absoluteCommandPath
    39  	}
    40  
    41  	return commandPath, nil
    42  }
    43  
    44  // Normalizes a path and returns an clean absolute version. It correctly
    45  // expands environment variables inside paths, converts "~/" into the users
    46  // home directory, and replaces "./" with the current working directory.
    47  func NormalizeFilePath(path string) (string, error) {
    48  	// don't normalize empty strings
    49  	if path == "" {
    50  		return "", nil
    51  	}
    52  
    53  	// expand env and home directory
    54  	var err error
    55  	path, err = ExpandHome(os.ExpandEnv(path))
    56  	if err != nil {
    57  		return "", err
    58  	}
    59  
    60  	// make sure its absolute
    61  	absolutePath, err := filepath.Abs(path)
    62  	if err != nil {
    63  		return "", err
    64  	}
    65  
    66  	return absolutePath, nil
    67  }
    68  
    69  // ExpandHome expands the path to include the home directory if the path
    70  // is prefixed with `~`. If it isn't prefixed with `~`, the path is
    71  // returned as-is.
    72  // Via https://github.com/mitchellh/go-homedir/blob/master/homedir.go
    73  func ExpandHome(path string) (string, error) {
    74  	if len(path) == 0 {
    75  		return path, nil
    76  	}
    77  
    78  	if path[0] != '~' {
    79  		return path, nil
    80  	}
    81  
    82  	if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
    83  		return "", errors.New("cannot expand user-specific home dir")
    84  	}
    85  
    86  	usr, err := user.Current()
    87  	if err != nil {
    88  		return "", err
    89  	}
    90  
    91  	return filepath.Join(usr.HomeDir, path[1:]), nil
    92  }