github.com/wtfutil/wtf@v0.43.0/cfg/copy.go (about)

     1  // Copied verbatim from:
     2  //
     3  //   https://github.com/otiai10/copy/blob/master/copy.go
     4  
     5  package cfg
     6  
     7  import (
     8  	"io"
     9  	"os"
    10  	"path/filepath"
    11  )
    12  
    13  // Copy copies src to dest, doesn't matter if src is a directory or a file
    14  func Copy(src, dest string) error {
    15  	info, err := os.Stat(src)
    16  	if err != nil {
    17  		return err
    18  	}
    19  	return locationCopy(src, dest, info)
    20  }
    21  
    22  // "info" must be given here, NOT nil.
    23  func locationCopy(src, dest string, info os.FileInfo) error {
    24  	if info.IsDir() {
    25  		return directoryCopy(src, dest, info)
    26  	}
    27  	return fileCopy(src, dest, info)
    28  }
    29  
    30  func fileCopy(src, dest string, info os.FileInfo) error {
    31  
    32  	f, err := os.Create(dest)
    33  	if err != nil {
    34  		return err
    35  	}
    36  	defer func() { _ = f.Close() }()
    37  
    38  	if err = os.Chmod(f.Name(), info.Mode()); err != nil {
    39  		return err
    40  	}
    41  
    42  	s, err := os.Open(filepath.Clean(src))
    43  	if err != nil {
    44  		return err
    45  	}
    46  	defer func() { _ = f.Close() }()
    47  
    48  	_, err = io.Copy(f, s)
    49  	return err
    50  }
    51  
    52  func directoryCopy(src, dest string, info os.FileInfo) error {
    53  
    54  	if err := os.MkdirAll(dest, info.Mode()); err != nil {
    55  		return err
    56  	}
    57  
    58  	entries, err := os.ReadDir(src)
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	for _, entry := range entries {
    64  		info, err := entry.Info()
    65  		if err != nil {
    66  			continue
    67  		}
    68  
    69  		if err := locationCopy(
    70  			filepath.Join(src, info.Name()),
    71  			filepath.Join(dest, info.Name()),
    72  			info,
    73  		); err != nil {
    74  			return err
    75  		}
    76  	}
    77  
    78  	return nil
    79  }