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