package fileutil import ( "io/ioutil" "os" "os/user" "path" "path/filepath" "strings" log "github.com/sirupsen/logrus" "github.com/pkg/errors" ) // ExpandPath given a string which may be a relative path. // 1. replace tilde with users home dir // 2. expands embedded environment variables // 3. cleans the path, e.g. /a/b/../c -> /a/c // Note, it has limitations, e.g. ~someuser/tmp will not be expanded func ExpandPath(p string) (string, error) { if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") { if home := HomeDir(); home != "" { p = home + p[1:] } } return filepath.Abs(path.Clean(os.ExpandEnv(p))) } // HomeDir for a user. func HomeDir() string { if home := os.Getenv("HOME"); home != "" { return home } if usr, err := user.Current(); err == nil { return usr.HomeDir } return "" } // HasDir checks if a directory indeed exists at the specified path. func HasDir(dirPath string) (bool, error) { fullPath, err := ExpandPath(dirPath) if err != nil { return false, err } info, err := os.Stat(fullPath) if os.IsNotExist(err) { return false, nil } if info == nil { return false, err } return info.IsDir(), err } // FileExists returns true if a file is not a directory and exists // at the specified path. func FileExists(filename string) bool { filePath, err := ExpandPath(filename) if err != nil { return false } info, err := os.Stat(filePath) if err != nil { if !os.IsNotExist(err) { log.WithError(err).Info("Checking for file existence returned an error") } return false } return info != nil && !info.IsDir() } // ReadFileAsBytes expands a file name's absolute path and reads it as bytes from disk. func ReadFileAsBytes(filename string) ([]byte, error) { filePath, err := ExpandPath(filename) if err != nil { return nil, errors.Wrap(err, "could not determine absolute path of password file") } return ioutil.ReadFile(filePath) }