package planr import ( "fmt" "os" "path/filepath" "io" ) func Exists(filePath string) bool { if _, err := os.Stat(filePath); os.IsNotExist(err) { return false } return true } func CreateIfNotExists(dir string, perm os.FileMode) error { if Exists(dir) { return nil } if err := os.MkdirAll(dir, perm); err != nil { return fmt.Errorf("failed to create directory: '%s', error: '%s'", dir, err.Error()) } return nil } func CopySymlink(src, dst string, perm os.FileMode) error { link, err := os.Readlink(src) if err != nil { return err } if err := os.Chmod(src, perm); err != nil { return err } return os.Symlink(link, dst) } func Copy(srcFile, dstFile string, perm os.FileMode) error { src, err := os.Open(srcFile) if err != nil { return err } defer src.Close() dst, err := os.OpenFile(dstFile, os.O_CREATE | os.O_WRONLY | os.O_TRUNC, perm) if err != nil { return err } defer dst.Close() _, err = io.Copy(dst, src) if err != nil { return err } return nil } func RecursiveCopyDir(source, destination string) error { err := filepath.Walk(source, func(path string, info os.FileInfo, err error) error { relPath, err := filepath.Rel(source, path) if err != nil { return err } dst := filepath.Join(destination, relPath) src := filepath.Join(source, relPath) mode := info.Mode() if relPath == "" { return nil } switch info.Mode() & os.ModeType { case os.ModeDir: return CreateIfNotExists(dst, mode) case os.ModeSymlink: return CopySymlink(src, dst, mode) default: return Copy(src, dst, mode) } }); return err }