package helpers import ( "io/fs" "os" "path" "path/filepath" "github.com/juju/errors" log "github.com/sirupsen/logrus" ) // IsGouickDirectory will check if we are in the same directory as the Gouick binary. func IsGouickDirectory(path string) (bool, error) { binPath, err := os.Executable() if err != nil { return false, errors.Trace(err) } gouickPath := filepath.Dir(binPath) if gouickPath != path { return false, nil } return true, nil } // IsGouickProject will check if a gouick config file exist and readeable. func IsGouickProject(path string) (bool, error) { exist, err := FileExists(filepath.Join(path, configFile)) if err != nil { return false, errors.Trace(err) } if !exist { return false, nil } return true, nil } // FileExists will check if a file exist and is readeable. func FileExists(path string) (bool, error) { fileInfo, err := os.Stat(path) if err != nil { if errors.Is(err, fs.ErrPermission) { return false, errors.NewForbidden(err, "file is not readeable") } else if errors.Is(err, fs.ErrNotExist) { return false, nil } else { return false, errors.Trace(err) } } if fileInfo.IsDir() { return false, errors.NotValidf("%s is actually a directory", path) } return true, nil } // isDirectoryWritable will check if a directory path is writable. func isDirectoryWritable(path string) (bool, error) { dirInfo, err := os.Stat(path) if err != nil { if errors.Is(err, fs.ErrPermission) { return false, errors.NewForbidden(err, "directory is not readeable") } else if errors.Is(err, fs.ErrNotExist) { return false, errors.NewNotFound(err, "directory does not exit") } else { return false, errors.Trace(err) } } if !dirInfo.IsDir() { return false, errors.NotSupportedf("given path is not a directory") } if dirInfo.Mode().Perm()&(1<<(uint(7))) == 0 { return false, nil } return true, nil } // createDirectory will create a new directory along with necessessary parents. func createDirectory(path string) error { // no need to check if path exist. // MkdirAll will do it for us. err := os.MkdirAll(path, os.ModePerm) if err != nil { return errors.Trace(err) } return nil } // CheckAndCreateDir will check if path is writable and create directory if needed // return a bool true if directory created, false if not. func CheckAndCreateDir(path string) (bool, error) { dirWritable, err := isDirectoryWritable(path) if dirWritable { return false, nil } else if err != nil && !errors.Is(err, errors.NotFound) { log.Warnf("impossible to check if the directory is writable") return false, err } else if err == nil && !dirWritable { log.Warnf("directory is not writable") return false, errors.Forbiddenf("directory is not writable") } err = createDirectory(path) if err != nil { log.Warnf("impossible to create directory (%s), please try again", err.Error()) return false, err } return true, nil } // RemoveDirectoryContent will delete the content of a provided directory path. func RemoveDirectoryContent(path string) error { dir, err := os.ReadDir(path) if err != nil { return errors.Trace(err) } for _, d := range dir { err := os.RemoveAll( filepath.Join(path, d.Name()), ) if err != nil { return errors.Trace(err) } } return nil } // GetExecutableDirectory will return the directory of Gouick. func GetExecutableDirectory() (string, error) { e, err := os.Executable() if err != nil { return "", errors.Trace(err) } return path.Dir(e), nil }