github.com/aca02djr/gb@v0.4.1/fileutils/fileutils.go (about) 1 // package fileutils provides utililty methods to copy and move files and directories. 2 package fileutils 3 4 import ( 5 "fmt" 6 "io" 7 "os" 8 "path/filepath" 9 "runtime" 10 "strings" 11 ) 12 13 const debugCopypath = false 14 const debugCopyfile = false 15 16 // Copypath copies the contents of src to dst, excluding any file or 17 // directory that starts with a period. 18 func Copypath(dst string, src string) error { 19 err := filepath.Walk(src, func(path string, info os.FileInfo, err error) error { 20 if err != nil { 21 return err 22 } 23 24 if strings.HasPrefix(filepath.Base(path), ".") { 25 if info.IsDir() { 26 return filepath.SkipDir 27 } 28 return nil 29 } 30 31 if info.IsDir() { 32 return nil 33 } 34 35 if info.Mode()&os.ModeSymlink != 0 { 36 if debugCopypath { 37 fmt.Printf("skipping symlink: %v\n", path) 38 } 39 return nil 40 } 41 42 dst := filepath.Join(dst, path[len(src):]) 43 return Copyfile(dst, path) 44 }) 45 if err != nil { 46 // if there was an error during copying, remove the partial copy. 47 RemoveAll(dst) 48 } 49 return err 50 } 51 52 func Copyfile(dst, src string) error { 53 err := mkdir(filepath.Dir(dst)) 54 if err != nil { 55 return fmt.Errorf("copyfile: mkdirall: %v", err) 56 } 57 r, err := os.Open(src) 58 if err != nil { 59 return fmt.Errorf("copyfile: open(%q): %v", src, err) 60 } 61 defer r.Close() 62 w, err := os.Create(dst) 63 if err != nil { 64 return fmt.Errorf("copyfile: create(%q): %v", dst, err) 65 } 66 defer w.Close() 67 if debugCopyfile { 68 fmt.Printf("copyfile(dst: %v, src: %v)\n", dst, src) 69 } 70 _, err = io.Copy(w, r) 71 return err 72 } 73 74 // RemoveAll removes path and any children it contains. Unlike os.RemoveAll it 75 // deletes read only files on Windows. 76 func RemoveAll(path string) error { 77 if runtime.GOOS == "windows" { 78 // Simple case: if Remove works, we're done. 79 err := os.Remove(path) 80 if err == nil || os.IsNotExist(err) { 81 return nil 82 } 83 // make sure all files are writable so we can delete them 84 filepath.Walk(path, func(path string, info os.FileInfo, err error) error { 85 if err != nil { 86 // walk gave us some error, give it back. 87 return err 88 } 89 mode := info.Mode() 90 if mode|0200 == mode { 91 return nil 92 } 93 return os.Chmod(path, mode|0200) 94 }) 95 } 96 return os.RemoveAll(path) 97 } 98 99 func mkdir(path string) error { 100 return os.MkdirAll(path, 0755) 101 }