github.com/remind101/go-getter@v0.0.0-20180809191950-4bda8fa99001/copy_dir.go (about) 1 package getter 2 3 import ( 4 "io" 5 "os" 6 "path/filepath" 7 "strings" 8 ) 9 10 // copyDir copies the src directory contents into dst. Both directories 11 // should already exist. 12 // 13 // If ignoreDot is set to true, then dot-prefixed files/folders are ignored. 14 func copyDir(dst string, src string, ignoreDot bool) error { 15 src, err := filepath.EvalSymlinks(src) 16 if err != nil { 17 return err 18 } 19 20 walkFn := func(path string, info os.FileInfo, err error) error { 21 if err != nil { 22 return err 23 } 24 if path == src { 25 return nil 26 } 27 28 if ignoreDot && strings.HasPrefix(filepath.Base(path), ".") { 29 // Skip any dot files 30 if info.IsDir() { 31 return filepath.SkipDir 32 } else { 33 return nil 34 } 35 } 36 37 // The "path" has the src prefixed to it. We need to join our 38 // destination with the path without the src on it. 39 dstPath := filepath.Join(dst, path[len(src):]) 40 41 // If we have a directory, make that subdirectory, then continue 42 // the walk. 43 if info.IsDir() { 44 if path == filepath.Join(src, dst) { 45 // dst is in src; don't walk it. 46 return nil 47 } 48 49 if err := os.MkdirAll(dstPath, 0755); err != nil { 50 return err 51 } 52 53 return nil 54 } 55 56 // If we have a file, copy the contents. 57 srcF, err := os.Open(path) 58 if err != nil { 59 return err 60 } 61 defer srcF.Close() 62 63 dstF, err := os.Create(dstPath) 64 if err != nil { 65 return err 66 } 67 defer dstF.Close() 68 69 if _, err := io.Copy(dstF, srcF); err != nil { 70 return err 71 } 72 73 // Chmod it 74 return os.Chmod(dstPath, info.Mode()) 75 } 76 77 return filepath.Walk(src, walkFn) 78 }