-
Notifications
You must be signed in to change notification settings - Fork 10
/
filecopy.go
112 lines (86 loc) · 2.3 KB
/
filecopy.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package filecopy
import (
"io"
"os"
"path/filepath"
"github.com/pkg/errors"
"github.com/simplesurance/baur/fs"
)
var defLogFn = func(string, ...interface{}) {}
// Client copies files from one path to another
type Client struct {
debugLogFn func(string, ...interface{})
}
// New returns a client
func New(debugLogFn func(string, ...interface{})) *Client {
logFn := defLogFn
if debugLogFn != nil {
logFn = debugLogFn
}
return &Client{debugLogFn: logFn}
}
func copyFile(src, dst string) error {
srcFd, err := os.Open(src)
if err != nil {
return errors.Wrapf(err, "opening %s failed", src)
}
// nolint: errcheck
defer srcFd.Close()
srcFi, err := os.Stat(src)
if err != nil {
return errors.Wrapf(err, "stat %s failed", src)
}
srcFileMode := srcFi.Mode().Perm()
dstFd, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, srcFileMode)
if err != nil {
return errors.Wrapf(err, "opening %s failed", dst)
}
_, err = io.Copy(dstFd, srcFd)
if err != nil {
_ = dstFd.Close()
return err
}
return dstFd.Close()
}
// Upload copies the file with src path to the dst path.
// If the destination directory does not exist, it is created.
// If the destination path exist and is not a regular file an error is returned.
// If it exist and is a file, the file is overwritten if it's not the same.
func (c *Client) Upload(src string, dst string) (string, error) {
destDir := filepath.Dir(dst)
isDir, err := fs.IsDir(destDir)
if err != nil {
if !os.IsNotExist(err) {
return "", err
}
err = fs.Mkdir(destDir)
if err != nil {
return "", errors.Wrapf(err, "creating directory '%s' failed", destDir)
}
c.debugLogFn("filecopy: created directory '%s'", destDir)
} else {
if !isDir {
return "", errors.Wrapf(err, "%s is not a directory", destDir)
}
}
regFile, err := fs.IsRegularFile(dst)
if err != nil {
if !os.IsNotExist(err) {
return "", err
}
return dst, copyFile(src, dst)
}
if !regFile {
return "", errors.Wrapf(err, "'%s' exist but is not a regular file", dst)
}
sameFile, err := fs.SameFile(src, dst)
if err != nil {
return "", err
}
if sameFile {
c.debugLogFn("filecopy: '%s' already exist and is the same then '%s'", dst, src)
return dst, nil
}
c.debugLogFn("filecopy: '%s' already exist, overwriting file", dst)
return dst, copyFile(src, dst)
}