forked from anchore/syft
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cataloger.go
77 lines (65 loc) · 2.06 KB
/
cataloger.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
package filecontent
import (
"bytes"
"encoding/base64"
"fmt"
"io"
"github.com/gsoc2/syft/internal"
"github.com/gsoc2/syft/internal/log"
"github.com/gsoc2/syft/syft/file"
)
type Cataloger struct {
globs []string
skipFilesAboveSizeInBytes int64
}
func NewCataloger(globs []string, skipFilesAboveSize int64) (*Cataloger, error) {
return &Cataloger{
globs: globs,
skipFilesAboveSizeInBytes: skipFilesAboveSize,
}, nil
}
func (i *Cataloger) Catalog(resolver file.Resolver) (map[file.Coordinates]string, error) {
results := make(map[file.Coordinates]string)
var locations []file.Location
locations, err := resolver.FilesByGlob(i.globs...)
if err != nil {
return nil, err
}
for _, location := range locations {
metadata, err := resolver.FileMetadataByLocation(location)
if err != nil {
return nil, err
}
if i.skipFilesAboveSizeInBytes > 0 && metadata.Size() > i.skipFilesAboveSizeInBytes {
continue
}
result, err := i.catalogLocation(resolver, location)
if internal.IsErrPathPermission(err) {
log.Debugf("file contents cataloger skipping - %+v", err)
continue
}
if err != nil {
return nil, err
}
results[location.Coordinates] = result
}
log.Debugf("file contents cataloger processed %d files", len(results))
return results, nil
}
func (i *Cataloger) catalogLocation(resolver file.Resolver, location file.Location) (string, error) {
contentReader, err := resolver.FileContentsByLocation(location)
if err != nil {
return "", err
}
defer internal.CloseAndLogError(contentReader, location.AccessPath)
buf := &bytes.Buffer{}
encoder := base64.NewEncoder(base64.StdEncoding, buf)
if _, err = io.Copy(encoder, contentReader); err != nil {
return "", internal.ErrPath{Context: "contents-cataloger", Path: location.RealPath, Err: err}
}
// note: it's important to close the reader before reading from the buffer since closing will flush the remaining bytes
if err := encoder.Close(); err != nil {
return "", fmt.Errorf("unable to close base64 encoder: %w", err)
}
return buf.String(), nil
}