/
copy_file.go
85 lines (69 loc) · 1.71 KB
/
copy_file.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package fileutils
import (
"os"
"path/filepath"
"github.com/pkg/errors"
)
type copyOpts struct {
recursive bool
depth int
overwrite bool
}
// Opt is a functional option
type Opt func(*copyOpts)
// NoRecursive will not recursively traverse directories if the function supports it
func NoRecursive() Opt {
return func(c *copyOpts) {
c.recursive = false
}
}
// Depth determines how far to recursively traverse if the function supports it
func Depth(depth int) Opt {
return func(c *copyOpts) {
c.depth = depth
}
}
// Overwrite will overwrite the file and/or directory and files
func Overwrite() Opt {
return func(c *copyOpts) {
c.overwrite = true
}
}
// CopyFile copies the file at the src into the dst path
func CopyFile(srcPath, dstPath string, options ...Opt) error {
opts := ©Opts{}
for _, o := range options {
o(opts)
}
return copyFile(srcPath, dstPath, opts)
}
func copyFile(srcPath, dstPath string, opts *copyOpts) error {
srcPath = filepath.Clean(srcPath)
dstPath = filepath.Clean(dstPath)
src, err := os.Open(srcPath)
if err != nil {
return err
}
defer src.Close() // nolint errcheck
srcInfo, err := os.Stat(srcPath)
if err != nil {
return err
}
_, err = os.Stat(dstPath)
if err != nil {
if !os.IsNotExist(err) {
return err
}
} else {
if !opts.overwrite {
return errors.Errorf("%s already exists", dstPath)
}
}
return AtomicWrite(dstPath, src, WithAtomicWriteFileMode(srcInfo.Mode()))
}
func CreateDestinationAndCopy(binarySrcPath, binaryDestPath string) error {
if err := os.MkdirAll(filepath.Dir(binaryDestPath), 0755); err != nil {
return errors.Wrap(err, "Error creating destination folder")
}
return CopyFile(binarySrcPath, binaryDestPath, Overwrite())
}