github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/integration-tests/file.go (about)

     1  package integration_tests
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  )
    10  
    11  // CopyFile copies the contents of the file named src to the file named
    12  // by dst. The file will be created if it does not already exist. If the
    13  // destination file exists, all it's contents will be replaced by the contents
    14  // of the source file. The file mode will be copied from the source and
    15  // the copied data is synced/flushed to stable storage.
    16  func CopyFile(src, dst string) (err error) {
    17  	in, err := os.Open(src)
    18  	if err != nil {
    19  		return
    20  	}
    21  	defer in.Close()
    22  
    23  	out, err := os.Create(dst)
    24  	if err != nil {
    25  		return
    26  	}
    27  	defer func() {
    28  		if e := out.Close(); e != nil {
    29  			err = e
    30  		}
    31  	}()
    32  
    33  	_, err = io.Copy(out, in)
    34  	if err != nil {
    35  		return
    36  	}
    37  
    38  	err = out.Sync()
    39  	if err != nil {
    40  		return
    41  	}
    42  
    43  	si, err := os.Stat(src)
    44  	if err != nil {
    45  		return
    46  	}
    47  	err = os.Chmod(dst, si.Mode())
    48  	if err != nil {
    49  		return
    50  	}
    51  
    52  	return
    53  }
    54  
    55  // CopyDir recursively copies a directory tree, attempting to preserve permissions.
    56  // Source directory must exist, destination directory must *not* exist.
    57  // Symlinks are ignored and skipped.
    58  func CopyDir(src string, dst string) (err error) {
    59  	src = filepath.Clean(src)
    60  	dst = filepath.Clean(dst)
    61  
    62  	si, err := os.Stat(src)
    63  	if err != nil {
    64  		return err
    65  	}
    66  	if !si.IsDir() {
    67  		return fmt.Errorf("source is not a directory")
    68  	}
    69  	_, err = os.Stat(dst)
    70  	if err != nil && !os.IsNotExist(err) {
    71  		return
    72  	}
    73  	if err == nil {
    74  		return fmt.Errorf("destination already exists")
    75  	}
    76  	err = os.MkdirAll(dst, si.Mode())
    77  	if err != nil {
    78  		return
    79  	}
    80  	entries, err := ioutil.ReadDir(src)
    81  	if err != nil {
    82  		return
    83  	}
    84  
    85  	for _, entry := range entries {
    86  		srcPath := filepath.Join(src, entry.Name())
    87  		dstPath := filepath.Join(dst, entry.Name())
    88  		if entry.IsDir() {
    89  			err = CopyDir(srcPath, dstPath)
    90  			if err != nil {
    91  				return
    92  			}
    93  		} else {
    94  			// Skip symlinks.
    95  			if entry.Mode()&os.ModeSymlink != 0 {
    96  				continue
    97  			}
    98  			err = CopyFile(srcPath, dstPath)
    99  			if err != nil {
   100  				return
   101  			}
   102  		}
   103  	}
   104  	return
   105  }