forked from mikefarah/yq
-
Notifications
You must be signed in to change notification settings - Fork 0
/
file_utils.go
85 lines (75 loc) · 2.02 KB
/
file_utils.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 yqlib
import (
"fmt"
"io"
"os"
)
func tryRenameFile(from string, to string) error {
if renameError := os.Rename(from, to); renameError != nil {
log.Debugf("Error renaming from %v to %v, attempting to copy contents", from, to)
log.Debug(renameError.Error())
log.Debug("going to try copying instead")
// can't do this rename when running in docker to a file targeted in a mounted volume,
// so gracefully degrade to copying the entire contents.
if copyError := copyFileContents(from, to); copyError != nil {
return fmt.Errorf("failed copying from %v to %v: %w", from, to, copyError)
}
tryRemoveTempFile(from)
}
return nil
}
func tryRemoveTempFile(filename string) {
log.Debug("Removing temp file: %v", filename)
removeErr := os.Remove(filename)
if removeErr != nil {
log.Errorf("Failed to remove temp file: %v", filename)
}
}
// thanks https://stackoverflow.com/questions/21060945/simple-way-to-copy-a-file-in-golang
func copyFileContents(src, dst string) (err error) {
// ignore CWE-22 gosec issue - that's more targeted for http based apps that run in a public directory,
// and ensuring that it's not possible to give a path to a file outside thar directory.
in, err := os.Open(src) // #nosec
if err != nil {
return err
}
defer safelyCloseFile(in)
out, err := os.Create(dst) // #nosec
if err != nil {
return err
}
defer safelyCloseFile(out)
if _, err = io.Copy(out, in); err != nil {
return err
}
return out.Sync()
}
func SafelyCloseReader(reader io.Reader) {
switch reader := reader.(type) {
case *os.File:
safelyCloseFile(reader)
}
}
func safelyCloseFile(file *os.File) {
err := file.Close()
if err != nil {
log.Error("Error closing file!")
log.Error(err.Error())
}
}
func createTempFile() (*os.File, error) {
_, err := os.Stat(os.TempDir())
if os.IsNotExist(err) {
err = os.Mkdir(os.TempDir(), 0700)
if err != nil {
return nil, err
}
} else if err != nil {
return nil, err
}
file, err := os.CreateTemp("", "temp")
if err != nil {
return nil, err
}
return file, err
}