forked from mouuff/go-rocket-update
/
provider_zip.go
101 lines (89 loc) · 1.81 KB
/
provider_zip.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
package provider
import (
"archive/zip"
"errors"
"io"
"os"
)
// Zip provider
type Zip struct {
Path string // Path of the zip file (provider.GlobNewestFile might help)
reader *zip.ReadCloser // reader for the current zip file
}
// Open opens the provider
func (c *Zip) Open() error {
_, err := os.Stat(c.Path)
if os.IsNotExist(err) {
return ErrProviderUnavailable
}
c.reader, err = zip.OpenReader(c.Path)
if err != nil {
c.reader = nil
return err
}
return nil
}
// Close closes the provider
func (c *Zip) Close() error {
if c.reader == nil {
return nil
}
return c.reader.Close()
}
// GetLatestVersion gets the latest version
func (c *Zip) GetLatestVersion() (string, error) {
return GetLatestVersionFromPath(c.Path)
}
// Walk walks all the files provided
func (c *Zip) Walk(walkFn WalkFunc) error {
if c.reader == nil {
return errors.New("nil reader zip.ReadCloser")
}
for _, f := range c.reader.File {
if f != nil {
err := walkFn(&FileInfo{
Path: f.Name,
Mode: f.Mode(),
})
if err != nil {
return err
}
}
}
return nil
}
// findFileByPath finds a file in the currend zip by the path
// returns nil if file does not exists
func (c *Zip) findFileByPath(path string) *zip.File {
for _, f := range c.reader.File {
if f.Name == path {
return f
}
}
return nil
}
// Retrieve file relative to "provider" to destination
func (c *Zip) Retrieve(src string, dest string) error {
zipFile := c.findFileByPath(src)
if zipFile == nil {
return ErrFileNotFound
}
inputFile, err := zipFile.Open()
if err != nil {
return err
}
outputFile, err := os.OpenFile(
dest,
os.O_WRONLY|os.O_CREATE|os.O_TRUNC,
zipFile.Mode(),
)
if err != nil {
return err
}
defer outputFile.Close()
_, err = io.Copy(outputFile, inputFile)
if err != nil {
return err
}
return nil
}