-
Notifications
You must be signed in to change notification settings - Fork 260
Expand file tree
/
Copy pathutil.go
More file actions
129 lines (110 loc) · 3.22 KB
/
Copy pathutil.go
File metadata and controls
129 lines (110 loc) · 3.22 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package os
import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"github.com/crc-org/crc/v2/pkg/crc/logging"
)
// ReplaceOrAddEnv changes the value of an environment variable if it exists otherwise add the new variable
// It drops the existing value and appends the new value in-place
func ReplaceOrAddEnv(variables []string, varName string, value string) []string {
var result []string
found := false
for _, e := range variables {
pair := strings.Split(e, "=")
if pair[0] != varName {
result = append(result, e)
} else {
found = true
result = append(result, fmt.Sprintf("%s=%s", varName, value))
}
}
if !found {
result = append(result, fmt.Sprintf("%s=%s", varName, value))
}
return result
}
func CopyFileContents(src string, dst string, permission os.FileMode) error {
logging.Debugf("Copying '%s' to '%s'", src, dst)
srcFile, err := os.Open(filepath.Clean(src))
if err != nil {
return fmt.Errorf("[%v] Cannot open src file '%s'", err, src)
}
defer srcFile.Close()
destFile, err := os.OpenFile(dst, os.O_RDWR|os.O_CREATE, permission)
if err != nil {
return fmt.Errorf("[%v] Cannot create dst file '%s'", err, dst)
}
defer destFile.Close()
_, err = io.Copy(destFile, srcFile)
if err != nil {
return fmt.Errorf("[%v] Cannot copy '%s' to '%s'", err, src, dst)
}
err = destFile.Sync()
if err != nil {
return fmt.Errorf("[%v] Cannot sync '%s' to '%s'", err, src, dst)
}
return destFile.Close()
}
func FileContentMatches(path string, expectedContent []byte) error {
_, err := os.Stat(path)
if err != nil {
return fmt.Errorf("File not found: %s: %s", path, err.Error())
}
content, err := os.ReadFile(filepath.Clean(path))
if err != nil {
return fmt.Errorf("Error opening file: %s: %s", path, err.Error())
}
if !bytes.Equal(content, expectedContent) {
return fmt.Errorf("File has unexpected content: %s", path)
}
return nil
}
func WriteFileIfContentChanged(path string, newContent []byte, perm os.FileMode) (bool, error) {
err := FileContentMatches(path, newContent)
if err == nil {
return false, nil
}
/* Intentionally ignore errors, just try to write the file if we can't read it */
err = os.WriteFile(path, newContent, perm)
if err != nil {
return false, err
}
return true, nil
}
// FileExists returns true if the file at path exists.
// It returns false if it does not exist, or if there was an error when checking for its existence.
// This means there can be false negatives if Lstat fails because of permission issues (file exists,
// but is not reachable by the current user)
func FileExists(path string) bool {
info, err := os.Lstat(path)
if err != nil {
return false
}
return !info.IsDir()
}
func RemoveFileIfExists(path string) error {
if FileExists(path) {
return os.Remove(path)
}
return nil
}
func RunningUsingSSH() bool {
return os.Getenv("SSH_TTY") != ""
}
// RemoveFileGlob takes a glob pattern as string to remove the files and directories that matches
func RemoveFileGlob(glob string) error {
matchedFiles, err := filepath.Glob(glob)
if err != nil {
return fmt.Errorf("Unable to find matches: %w", err)
}
for _, file := range matchedFiles {
if err = os.RemoveAll(file); err != nil {
return fmt.Errorf("Failed to delete file: %w", err)
}
}
return nil
}