From 79726b5d8e6ebc13d61e083a4f598d9356328e5e Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 13 Nov 2017 14:46:29 -0500 Subject: Replace os.Rename with directory copy util in plugin extraction (#7825) --- utils/file.go | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) (limited to 'utils/file.go') diff --git a/utils/file.go b/utils/file.go index c7e092a20..6472770a0 100644 --- a/utils/file.go +++ b/utils/file.go @@ -5,6 +5,8 @@ package utils import ( "bytes" + "fmt" + "io" "io/ioutil" "net/http" "os" @@ -367,3 +369,102 @@ func CopyMetadata(encrypt bool) map[string]string { metaData["x-amz-server-side-encryption"] = "AES256" return metaData } + +// CopyFile will copy a file from src path to dst path. +// Overwrites any existing files at dst. +// Permissions are copied from file at src to the new file at dst. +func CopyFile(src, dst string) (err error) { + in, err := os.Open(src) + if err != nil { + return + } + defer in.Close() + + out, err := os.Create(dst) + if err != nil { + return + } + defer func() { + if e := out.Close(); e != nil { + err = e + } + }() + + _, err = io.Copy(out, in) + if err != nil { + return + } + + err = out.Sync() + if err != nil { + return + } + + stat, err := os.Stat(src) + if err != nil { + return + } + err = os.Chmod(dst, stat.Mode()) + if err != nil { + return + } + + return +} + +// CopyDir will copy a directory and all contained files and directories. +// src must exist and dst must not exist. +// Permissions are preserved when possible. Symlinks are skipped. +func CopyDir(src string, dst string) (err error) { + src = filepath.Clean(src) + dst = filepath.Clean(dst) + + stat, err := os.Stat(src) + if err != nil { + return + } + if !stat.IsDir() { + return fmt.Errorf("source must be a directory") + } + + _, err = os.Stat(dst) + if err != nil && !os.IsNotExist(err) { + return + } + if err == nil { + return fmt.Errorf("destination already exists") + } + + err = os.MkdirAll(dst, stat.Mode()) + if err != nil { + return + } + + items, err := ioutil.ReadDir(src) + if err != nil { + return + } + + for _, item := range items { + srcPath := filepath.Join(src, item.Name()) + dstPath := filepath.Join(dst, item.Name()) + + if item.IsDir() { + err = CopyDir(srcPath, dstPath) + if err != nil { + return + } + } else { + if item.Mode()&os.ModeSymlink != 0 { + continue + } + + err = CopyFile(srcPath, dstPath) + if err != nil { + return + } + } + } + + return +} -- cgit v1.2.3-1-g7c22