@@ -3,6 +3,7 @@ package updater
3
3
import (
4
4
"archive/tar"
5
5
"archive/zip"
6
+ "bytes"
6
7
"compress/gzip"
7
8
"fmt"
8
9
"io"
@@ -32,6 +33,17 @@ const (
32
33
typeTarGzip
33
34
)
34
35
36
+ func (t compressionType ) String () string {
37
+ switch t {
38
+ case typeZip :
39
+ return "zip"
40
+ case typeTarGzip :
41
+ return "tar.gz"
42
+ default :
43
+ return "unknown"
44
+ }
45
+ }
46
+
35
47
var DefaultUiUpdater = & UIUpdater {}
36
48
37
49
func NewUiUpdater (externalUI , externalUIURL , externalUIName string ) * UIUpdater {
@@ -99,48 +111,35 @@ func detectFileType(data []byte) compressionType {
99
111
}
100
112
101
113
func (u * UIUpdater ) downloadUI () error {
102
- err := u .prepareUIPath ()
103
- if err != nil {
104
- return fmt .Errorf ("prepare UI path failed: %w" , err )
105
- }
106
-
107
114
data , err := downloadForBytes (u .externalUIURL )
108
115
if err != nil {
109
116
return fmt .Errorf ("can't download file: %w" , err )
110
117
}
111
118
112
- fileType := detectFileType (data )
113
- if fileType == typeUnknown {
114
- return fmt .Errorf ("unknown or unsupported file type" )
115
- }
116
-
117
- ext := ".zip"
118
- if fileType == typeTarGzip {
119
- ext = ".tgz"
120
- }
121
-
122
- saved := path .Join (C .Path .HomeDir (), "download" + ext )
123
- log .Debugln ("compression Type: %s" , ext )
124
- if err = saveFile (data , saved ); err != nil {
125
- return fmt .Errorf ("can't save compressed file: %w" , err )
119
+ tmpDir := C .Path .Resolve ("downloadUI.tmp" )
120
+ defer os .RemoveAll (tmpDir )
121
+ extractedFolder , err := extract (data , tmpDir )
122
+ if err != nil {
123
+ return fmt .Errorf ("can't extract compressed file: %w" , err )
126
124
}
127
- defer os .Remove (saved )
128
125
129
- err = cleanup (u .externalUIPath )
126
+ log .Debugln ("cleanupFolder: %s" , u .externalUIPath )
127
+ err = cleanup (u .externalUIPath ) // cleanup files in dir don't remove dir itself
130
128
if err != nil {
131
129
if ! os .IsNotExist (err ) {
132
130
return fmt .Errorf ("cleanup exist file error: %w" , err )
133
131
}
134
132
}
135
133
136
- extractedFolder , err := extract ( saved , C . Path . HomeDir () )
134
+ err = u . prepareUIPath ( )
137
135
if err != nil {
138
- return fmt .Errorf ("can't extract compressed file : %w" , err )
136
+ return fmt .Errorf ("prepare UI path failed : %w" , err )
139
137
}
140
138
141
- err = os .Rename (extractedFolder , u .externalUIPath )
139
+ log .Debugln ("moveFolder from %s to %s" , extractedFolder , u .externalUIPath )
140
+ err = moveDir (extractedFolder , u .externalUIPath ) // move files from tmp to target
142
141
if err != nil {
143
- return fmt .Errorf ("rename UI folder failed: %w" , err )
142
+ return fmt .Errorf ("move UI folder failed: %w" , err )
144
143
}
145
144
return nil
146
145
}
@@ -155,12 +154,11 @@ func (u *UIUpdater) prepareUIPath() error {
155
154
return nil
156
155
}
157
156
158
- func unzip (src , dest string ) (string , error ) {
159
- r , err := zip .OpenReader ( src )
157
+ func unzip (data [] byte , dest string ) (string , error ) {
158
+ r , err := zip .NewReader ( bytes . NewReader ( data ), int64 ( len ( data )) )
160
159
if err != nil {
161
160
return "" , err
162
161
}
163
- defer r .Close ()
164
162
165
163
// check whether or not only exists singleRoot dir
166
164
rootDir := ""
@@ -199,17 +197,7 @@ func unzip(src, dest string) (string, error) {
199
197
log .Debugln ("extractedFolder: %s" , extractedFolder )
200
198
} else {
201
199
log .Debugln ("Match the multiRoot" )
202
- // or put the files/dirs into new dir
203
- baseName := filepath .Base (src )
204
- baseName = strings .TrimSuffix (baseName , filepath .Ext (baseName ))
205
- extractedFolder = filepath .Join (dest , baseName )
206
-
207
- for i := 1 ; ; i ++ {
208
- if _ , err := os .Stat (extractedFolder ); os .IsNotExist (err ) {
209
- break
210
- }
211
- extractedFolder = filepath .Join (dest , fmt .Sprintf ("%s_%d" , baseName , i ))
212
- }
200
+ extractedFolder = dest
213
201
log .Debugln ("extractedFolder: %s" , extractedFolder )
214
202
}
215
203
@@ -253,14 +241,8 @@ func unzip(src, dest string) (string, error) {
253
241
return extractedFolder , nil
254
242
}
255
243
256
- func untgz (src , dest string ) (string , error ) {
257
- file , err := os .Open (src )
258
- if err != nil {
259
- return "" , err
260
- }
261
- defer file .Close ()
262
-
263
- gzr , err := gzip .NewReader (file )
244
+ func untgz (data []byte , dest string ) (string , error ) {
245
+ gzr , err := gzip .NewReader (bytes .NewReader (data ))
264
246
if err != nil {
265
247
return "" , err
266
248
}
@@ -303,8 +285,7 @@ func untgz(src, dest string) (string, error) {
303
285
isSingleRoot = false
304
286
}
305
287
306
- file .Seek (0 , 0 )
307
- gzr , _ = gzip .NewReader (file )
288
+ _ = gzr .Reset (bytes .NewReader (data ))
308
289
tr = tar .NewReader (gzr )
309
290
310
291
var extractedFolder string
@@ -314,17 +295,7 @@ func untgz(src, dest string) (string, error) {
314
295
log .Debugln ("extractedFolder: %s" , extractedFolder )
315
296
} else {
316
297
log .Debugln ("Match the multiRoot" )
317
- baseName := filepath .Base (src )
318
- baseName = strings .TrimSuffix (baseName , filepath .Ext (baseName ))
319
- baseName = strings .TrimSuffix (baseName , ".tar" )
320
- extractedFolder = filepath .Join (dest , baseName )
321
-
322
- for i := 1 ; ; i ++ {
323
- if _ , err := os .Stat (extractedFolder ); os .IsNotExist (err ) {
324
- break
325
- }
326
- extractedFolder = filepath .Join (dest , fmt .Sprintf ("%s_%d" , baseName , i ))
327
- }
298
+ extractedFolder = dest
328
299
log .Debugln ("extractedFolder: %s" , extractedFolder )
329
300
}
330
301
@@ -371,16 +342,16 @@ func untgz(src, dest string) (string, error) {
371
342
return extractedFolder , nil
372
343
}
373
344
374
- func extract (src , dest string ) (string , error ) {
375
- srcLower := strings . ToLower ( src )
376
- switch {
377
- case strings . HasSuffix ( srcLower , ".tar.gz" ) ||
378
- strings . HasSuffix ( srcLower , ".tgz" ) :
379
- return untgz ( src , dest )
380
- case strings . HasSuffix ( srcLower , ".zip" ) :
381
- return unzip ( src , dest )
345
+ func extract (data [] byte , dest string ) (string , error ) {
346
+ fileType := detectFileType ( data )
347
+ log . Debugln ( "compression Type: %s" , fileType )
348
+ switch fileType {
349
+ case typeZip :
350
+ return unzip ( data , dest )
351
+ case typeTarGzip :
352
+ return untgz ( data , dest )
382
353
default :
383
- return "" , fmt .Errorf ("unsupported file format: %s" , src )
354
+ return "" , fmt .Errorf ("unknown or unsupported file type" )
384
355
}
385
356
}
386
357
@@ -402,24 +373,33 @@ func cleanTarPath(path string) string {
402
373
}
403
374
404
375
func cleanup (root string ) error {
405
- if _ , err := os .Stat (root ); os .IsNotExist (err ) {
406
- return nil
376
+ dirEntryList , err := os .ReadDir (root )
377
+ if err != nil {
378
+ return err
407
379
}
408
- return filepath .Walk (root , func (path string , info os.FileInfo , err error ) error {
380
+
381
+ for _ , dirEntry := range dirEntryList {
382
+ err = os .RemoveAll (filepath .Join (root , dirEntry .Name ()))
409
383
if err != nil {
410
384
return err
411
385
}
412
- if info .IsDir () {
413
- if err := os .RemoveAll (path ); err != nil {
414
- return err
415
- }
416
- } else {
417
- if err := os .Remove (path ); err != nil {
418
- return err
419
- }
386
+ }
387
+ return nil
388
+ }
389
+
390
+ func moveDir (src string , dst string ) error {
391
+ dirEntryList , err := os .ReadDir (src )
392
+ if err != nil {
393
+ return err
394
+ }
395
+
396
+ for _ , dirEntry := range dirEntryList {
397
+ err = os .Rename (filepath .Join (src , dirEntry .Name ()), filepath .Join (dst , dirEntry .Name ()))
398
+ if err != nil {
399
+ return err
420
400
}
421
- return nil
422
- })
401
+ }
402
+ return nil
423
403
}
424
404
425
405
func inDest (fpath , dest string ) bool {
0 commit comments