-
Notifications
You must be signed in to change notification settings - Fork 13
/
tar.go
106 lines (86 loc) · 2.23 KB
/
tar.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
package check
import (
"archive/tar"
"bytes"
"fmt"
"io"
"strings"
"github.com/ipfs/gateway-conformance/tooling/tmpl"
)
var _ Check[[]byte] = &CheckIsTarFile{}
type CheckIsTarFile struct {
fileNames []string
filesWithContent map[string]string
}
func IsTarFile() *CheckIsTarFile {
return &CheckIsTarFile{
fileNames: []string{},
filesWithContent: map[string]string{},
}
}
func (c *CheckIsTarFile) HasFile(format string, a ...interface{}) *CheckIsTarFile {
fileName := tmpl.Fmt(format, a...)
c.fileNames = append(c.fileNames, fileName)
return c
}
func (c *CheckIsTarFile) HasFileWithContent(fileName, content string) *CheckIsTarFile {
c.filesWithContent[fileName] = content
return c
}
func (c *CheckIsTarFile) Check(v []byte) CheckOutput {
r := bytes.NewReader(v)
tr := tar.NewReader(r)
searchedFiles := make(map[string]bool)
filenames := make([]string, 0, len(c.fileNames))
for _, fileName := range c.fileNames {
searchedFiles[fileName] = false
}
for fileName := range c.filesWithContent {
searchedFiles[fileName] = false
}
for {
hdr, err := tr.Next()
if err == io.EOF {
break // End of archive
}
if err != nil {
return CheckOutput{
Success: false,
Reason: fmt.Sprintf("failed to read tar header: %v", err),
}
}
buf := new(bytes.Buffer)
_, err = io.Copy(buf, tr)
if err != nil {
return CheckOutput{
Success: false,
Reason: fmt.Sprintf("failed to read file '%s' content: %v", hdr.Name, err),
}
}
filenames = append(filenames, hdr.Name)
if _, ok := searchedFiles[hdr.Name]; ok {
searchedFiles[hdr.Name] = true
}
if _, ok := c.filesWithContent[hdr.Name]; ok {
content := buf.String()
if content != c.filesWithContent[hdr.Name] {
return CheckOutput{
Success: false,
Reason: fmt.Sprintf("file '%s' with expected content '%s' not found in tar archive. Actual content: '%s'", hdr.Name, c.filesWithContent[hdr.Name], content),
}
}
}
}
for name, found := range searchedFiles {
if !found {
allFiles := strings.Join(filenames, ", ")
return CheckOutput{
Success: false,
Reason: fmt.Sprintf("file '%s' not found in tar archive. Found files: [%s]", name, allFiles),
}
}
}
return CheckOutput{
Success: true,
}
}