-
Notifications
You must be signed in to change notification settings - Fork 19
/
zip.go
104 lines (82 loc) · 2.18 KB
/
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
102
103
104
package containerarchiver
import (
"io"
"os"
"time"
"github.com/itchio/arkive/zip"
"github.com/itchio/headway/counter"
"github.com/itchio/headway/state"
"github.com/itchio/wharf/archiver"
"github.com/itchio/lake"
"github.com/itchio/lake/tlc"
"github.com/pkg/errors"
)
func CompressZip(archiveWriter io.Writer, container *tlc.Container, pool lake.Pool, consumer *state.Consumer) (*archiver.CompressResult, error) {
var err error
var uncompressedSize int64
var compressedSize int64
archiveCounter := counter.NewWriter(archiveWriter)
zipWriter := zip.NewWriter(archiveCounter)
defer zipWriter.Close()
defer func() {
if zipWriter != nil {
if zErr := zipWriter.Close(); err == nil && zErr != nil {
err = errors.WithStack(zErr)
}
}
}()
for _, dir := range container.Dirs {
fh := zip.FileHeader{
Name: dir.Path + "/",
}
fh.SetMode(os.FileMode(dir.Mode))
fh.SetModTime(time.Now())
_, hErr := zipWriter.CreateHeader(&fh)
if hErr != nil {
return nil, errors.WithStack(hErr)
}
}
for fileIndex, file := range container.Files {
fh := zip.FileHeader{
Name: file.Path,
UncompressedSize64: uint64(file.Size),
Method: zip.Deflate,
}
fh.SetMode(os.FileMode(file.Mode))
fh.SetModTime(time.Now())
entryWriter, eErr := zipWriter.CreateHeader(&fh)
if eErr != nil {
return nil, errors.WithStack(eErr)
}
entryReader, eErr := pool.GetReader(int64(fileIndex))
if eErr != nil {
return nil, errors.WithStack(eErr)
}
copiedBytes, eErr := io.Copy(entryWriter, entryReader)
if eErr != nil {
return nil, errors.WithStack(eErr)
}
uncompressedSize += copiedBytes
}
for _, symlink := range container.Symlinks {
fh := zip.FileHeader{
Name: symlink.Path,
}
fh.SetMode(os.FileMode(symlink.Mode))
entryWriter, eErr := zipWriter.CreateHeader(&fh)
if eErr != nil {
return nil, errors.WithStack(eErr)
}
entryWriter.Write([]byte(symlink.Dest))
}
err = zipWriter.Close()
if err != nil {
return nil, errors.WithStack(err)
}
zipWriter = nil
compressedSize = archiveCounter.Count()
return &archiver.CompressResult{
UncompressedSize: uncompressedSize,
CompressedSize: compressedSize,
}, nil
}