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  }