-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.go
245 lines (219 loc) · 5.36 KB
/
util.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
package main
import (
"archive/zip"
"bytes"
"encoding/json"
"fmt"
"github.com/aviddiviner/go-murmur"
"github.com/pterm/pterm"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"
)
func readBuildJson(buildJsonDir string) BuildJson {
// Open our jsonFile
jsonFile, err := os.Open(buildJsonDir)
// if we os.Open returns an error then handle it
if err != nil {
fmt.Println(err)
}
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
byteValue, _ := ioutil.ReadAll(jsonFile)
var buildCfg BuildJson
err = json.Unmarshal(byteValue, &buildCfg)
if err != nil {
pterm.Fatal.Println("Failed to parse build.json\n", err)
os.Exit(1)
}
return buildCfg
}
func intInSlice(a int64, list []int64) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
func CopyFile(src, dst string) error {
var err error
var srcfd *os.File
var dstfd *os.File
var srcinfo os.FileInfo
parentDir := filepath.Dir(dst)
if _, err := os.Stat(parentDir); os.IsNotExist(err) {
err := os.MkdirAll(parentDir, os.ModePerm)
if err != nil {
pterm.Error.Println("Failed to create temp copy directory:", err)
}
}
if srcfd, err = os.Open(src); err != nil {
return err
}
defer srcfd.Close()
if dstfd, err = os.Create(dst); err != nil {
return err
}
defer dstfd.Close()
if _, err = io.Copy(dstfd, srcfd); err != nil {
return err
}
if srcinfo, err = os.Stat(src); err != nil {
return err
}
return os.Chmod(dst, srcinfo.Mode())
}
func CopyDir(src string, dst string) error {
var err error
var fds []os.FileInfo
var srcinfo os.FileInfo
if srcinfo, err = os.Stat(src); err != nil {
return err
}
if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil {
return err
}
if fds, err = ioutil.ReadDir(src); err != nil {
return err
}
for _, fd := range fds {
srcfp := filepath.Join(src, fd.Name())
dstfp := filepath.Join(dst, fd.Name())
if fd.IsDir() {
if err = CopyDir(srcfp, dstfp); err != nil {
fmt.Println(err)
}
} else {
if err = CopyFile(srcfp, dstfp); err != nil {
fmt.Println(err)
}
}
}
return nil
}
func difference(a, b []int64) (diff []int64) {
m := make(map[int64]bool)
for _, item := range b {
m[item] = true
}
for _, item := range a {
if _, ok := m[item]; !ok {
diff = append(diff, item)
}
}
return
}
func getFileCount(path string) int64 {
var count int64
err := filepath.Walk(path, func(path string, f os.FileInfo, err error) error {
count++
return nil
})
if err != nil {
pterm.Error.Println("Error counting files:", err)
}
return count
}
func RecursiveZip(pathToZip, destinationPath string) error {
fileCount := getFileCount(pathToZip)
zipProgress, _ := pterm.DefaultProgressbar.WithTotal(int(fileCount)).WithTitle("Creating zip file").Start()
destinationFile, err := os.Create(destinationPath)
if err != nil {
return err
}
myZip := zip.NewWriter(destinationFile)
err = filepath.Walk(pathToZip, func(filePath string, info os.FileInfo, err error) error {
zipProgress.UpdateTitle("Adding " + info.Name() + " to zip")
if info.IsDir() {
pterm.Debug.Println("info.IsDir is Nil")
zipProgress.Increment()
return nil
}
if err != nil {
pterm.Error.Println("FilePath walk error")
zipProgress.Stop()
return err
}
relPath := strings.TrimPrefix(filepath.ToSlash(filePath), filepath.ToSlash(pathToZip+"/"))
zipFile, err := myZip.Create(relPath)
if err != nil {
pterm.Error.Println("Creating zip error")
return err
}
fsFile, err := os.Open(filePath)
if err != nil {
pterm.Error.Println("os.Open error")
return err
}
defer fsFile.Close()
_, err = io.Copy(zipFile, fsFile)
if err != nil {
pterm.Error.Println("io.copy error")
return err
}
zipProgress.Increment()
return nil
})
if err != nil {
pterm.Error.Println("File path walk error ln151")
return err
}
err = myZip.Close()
if err != nil {
pterm.Error.Println("Close zip error")
return err
}
return nil
}
func getProjectIds(addons []int64) (*FingerprintResponse, error) {
jsonPayload, _ := json.Marshal(FingerprintRequest{Fingerprints: addons})
response, err := GetHTTPResponse("POST", apiURL+"fingerprints", jsonPayload)
defer response.Body.Close()
if err != nil {
return nil, err
}
var addonResponse *FingerprintResponse
err = json.NewDecoder(response.Body).Decode(&addonResponse)
if err != nil {
return nil, err
}
return addonResponse, nil
}
// Credit goes to modmuss https://github.com/modmuss50/CAV2/blob/master/murmur.go
func GetByteArrayHash(bytes []byte) int64 {
return int64(murmur.MurmurHash2(computeNormalizedArray(bytes), 1))
}
func GetFileHash(file string) (int64, error) {
bytes, err := ioutil.ReadFile(file)
if err != nil {
return 0, err
}
result := GetByteArrayHash(bytes)
return result, nil
}
func computeNormalizedArray(bytes []byte) []byte {
var newArray []byte
for _, b := range bytes {
if !isWhitespaceCharacter(b) {
newArray = append(newArray, b)
}
}
return newArray
}
func isWhitespaceCharacter(b byte) bool {
return b == 9 || b == 10 || b == 13 || b == 32
}
func GetHTTPResponse(method, url string, b []byte) (*http.Response, error) {
client := &http.Client{}
req, err := http.NewRequest(method, url, bytes.NewReader(b))
if err != nil {
return nil, err
}
req.Header.Add("User-Agent", fmt.Sprintf("CFExporter-%s", appVersion))
req.Header.Add("Content-Type", "application/json")
return client.Do(req)
}