bump stereoscope to pull in content API refactors

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman
2021-01-04 14:07:14 -05:00
committed by Dan Luhring
parent e299a5355f
commit d475e6280a
18 changed files with 99 additions and 94 deletions
+7 -6
View File
@@ -3,6 +3,7 @@ package source
import (
"archive/tar"
"fmt"
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/stereoscope/pkg/image"
@@ -150,7 +151,7 @@ func (r *AllLayersResolver) RelativeFileByPath(location Location, path string) *
return nil
}
relativeRef := entry.Source.SquashedTree.File(file.Path(path))
relativeRef := entry.Layer.SquashedTree.File(file.Path(path))
if relativeRef == nil {
return nil
}
@@ -162,22 +163,22 @@ func (r *AllLayersResolver) RelativeFileByPath(location Location, path string) *
// MultipleFileContentsByLocation returns the file contents for all file.References relative to the image. Note that a
// file.Reference is a path relative to a particular layer.
func (r *AllLayersResolver) MultipleFileContentsByLocation(locations []Location) (map[Location]string, error) {
func (r *AllLayersResolver) MultipleFileContentsByLocation(locations []Location) (map[Location]io.ReadCloser, error) {
return mapLocationRefs(r.img.MultipleFileContentsByRef, locations)
}
// FileContentsByLocation fetches file contents for a single file reference, irregardless of the source layer.
// If the path does not exist an error is returned.
func (r *AllLayersResolver) FileContentsByLocation(location Location) (string, error) {
func (r *AllLayersResolver) FileContentsByLocation(location Location) (io.ReadCloser, error) {
return r.img.FileContentsByRef(location.ref)
}
type multiContentFetcher func(refs ...file.Reference) (map[file.Reference]string, error)
type multiContentFetcher func(refs ...file.Reference) (map[file.Reference]io.ReadCloser, error)
func mapLocationRefs(callback multiContentFetcher, locations []Location) (map[Location]string, error) {
func mapLocationRefs(callback multiContentFetcher, locations []Location) (map[Location]io.ReadCloser, error) {
var fileRefs = make([]file.Reference, len(locations))
var locationByRefs = make(map[file.Reference]Location)
var results = make(map[Location]string)
var results = make(map[Location]io.ReadCloser)
for i, location := range locations {
locationByRefs[location.ref] = location
+4 -4
View File
@@ -116,8 +116,8 @@ func TestAllLayersResolver_FilesByPath(t *testing.T) {
t.Fatalf("failed to get metadata: %+v", err)
}
if entry.Source.Metadata.Index != expected.layer {
t.Errorf("bad resolve layer: '%d'!='%d'", entry.Source.Metadata.Index, expected.layer)
if entry.Layer.Metadata.Index != expected.layer {
t.Errorf("bad resolve layer: '%d'!='%d'", entry.Layer.Metadata.Index, expected.layer)
}
}
})
@@ -229,8 +229,8 @@ func TestAllLayersResolver_FilesByGlob(t *testing.T) {
t.Fatalf("failed to get metadata: %+v", err)
}
if entry.Source.Metadata.Index != expected.layer {
t.Errorf("bad resolve layer: '%d'!='%d'", entry.Source.Metadata.Index, expected.layer)
if entry.Layer.Metadata.Index != expected.layer {
t.Errorf("bad resolve layer: '%d'!='%d'", entry.Layer.Metadata.Index, expected.layer)
}
}
})
+7 -2
View File
@@ -1,6 +1,7 @@
package source
import (
"io/ioutil"
"testing"
"github.com/anchore/stereoscope/pkg/imagetest"
@@ -54,10 +55,14 @@ func TestContentRequester(t *testing.T) {
for _, entry := range data {
if expected, ok := test.expectedContents[entry.Location.Path]; ok {
for expected != entry.Contents {
actualBytes, err := ioutil.ReadAll(entry.Contents)
if err != nil {
t.Fatalf("could not read %q: %+v", entry.Location.Path, err)
}
for expected != string(actualBytes) {
t.Errorf("mismatched contents for %q", entry.Location.Path)
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(expected, entry.Contents, true)
diffs := dmp.DiffMain(expected, string(actualBytes), true)
t.Errorf("diff: %s", dmp.DiffPrettyText(diffs))
}
continue
+8 -25
View File
@@ -2,11 +2,13 @@ package source
import (
"fmt"
"io/ioutil"
"io"
"os"
"path"
"path/filepath"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/internal/log"
"github.com/bmatcuk/doublestar"
)
@@ -96,35 +98,16 @@ func (s *DirectoryResolver) RelativeFileByPath(_ Location, path string) *Locatio
}
// MultipleFileContentsByLocation returns the file contents for all file.References relative a directory.
func (s DirectoryResolver) MultipleFileContentsByLocation(locations []Location) (map[Location]string, error) {
refContents := make(map[Location]string)
func (s DirectoryResolver) MultipleFileContentsByLocation(locations []Location) (map[Location]io.ReadCloser, error) {
refContents := make(map[Location]io.ReadCloser)
for _, location := range locations {
contents, err := fileContents(location.Path)
if err != nil {
return nil, fmt.Errorf("could not read contents of file: %s", location.Path)
}
refContents[location] = string(contents)
refContents[location] = file.NewDeferredReadCloser(location.Path)
}
return refContents, nil
}
// FileContentsByLocation fetches file contents for a single file reference relative to a directory.
// If the path does not exist an error is returned.
func (s DirectoryResolver) FileContentsByLocation(location Location) (string, error) {
contents, err := fileContents(location.Path)
if err != nil {
return "", fmt.Errorf("could not read contents of file: %s", location.Path)
}
return string(contents), nil
}
func fileContents(path string) ([]byte, error) {
contents, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return contents, nil
func (s DirectoryResolver) FileContentsByLocation(location Location) (io.ReadCloser, error) {
return file.NewDeferredReadCloser(location.Path), nil
}
+3 -1
View File
@@ -1,6 +1,8 @@
package source
import "io"
type FileData struct {
Location Location
Contents string
Contents io.ReadCloser
}
+3 -2
View File
@@ -2,6 +2,7 @@ package source
import (
"fmt"
"io"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/stereoscope/pkg/image"
@@ -121,12 +122,12 @@ func (r *ImageSquashResolver) RelativeFileByPath(_ Location, path string) *Locat
// MultipleFileContentsByLocation returns the file contents for all file.References relative to the image. Note that a
// file.Reference is a path relative to a particular layer, in this case only from the squashed representation.
func (r *ImageSquashResolver) MultipleFileContentsByLocation(locations []Location) (map[Location]string, error) {
func (r *ImageSquashResolver) MultipleFileContentsByLocation(locations []Location) (map[Location]io.ReadCloser, error) {
return mapLocationRefs(r.img.MultipleFileContentsByRef, locations)
}
// FileContentsByLocation fetches file contents for a single file reference, irregardless of the source layer.
// If the path does not exist an error is returned.
func (r *ImageSquashResolver) FileContentsByLocation(location Location) (string, error) {
func (r *ImageSquashResolver) FileContentsByLocation(location Location) (io.ReadCloser, error) {
return r.img.FileContentsByRef(location.ref)
}
+4 -4
View File
@@ -89,8 +89,8 @@ func TestImageSquashResolver_FilesByPath(t *testing.T) {
t.Fatalf("failed to get metadata: %+v", err)
}
if entry.Source.Metadata.Index != c.resolveLayer {
t.Errorf("bad resolve layer: '%d'!='%d'", entry.Source.Metadata.Index, c.resolveLayer)
if entry.Layer.Metadata.Index != c.resolveLayer {
t.Errorf("bad resolve layer: '%d'!='%d'", entry.Layer.Metadata.Index, c.resolveLayer)
}
})
}
@@ -179,8 +179,8 @@ func TestImageSquashResolver_FilesByGlob(t *testing.T) {
t.Fatalf("failed to get metadata: %+v", err)
}
if entry.Source.Metadata.Index != c.resolveLayer {
t.Errorf("bad resolve layer: '%d'!='%d'", entry.Source.Metadata.Index, c.resolveLayer)
if entry.Layer.Metadata.Index != c.resolveLayer {
t.Errorf("bad resolve layer: '%d'!='%d'", entry.Layer.Metadata.Index, c.resolveLayer)
}
})
}
+1 -1
View File
@@ -34,7 +34,7 @@ func NewLocationFromImage(ref file.Reference, img *image.Image) Location {
return Location{
Path: string(ref.Path),
FileSystemID: entry.Source.Metadata.Digest,
FileSystemID: entry.Layer.Metadata.Digest,
ref: ref,
}
}
+3 -2
View File
@@ -2,6 +2,7 @@ package source
import (
"fmt"
"io"
"github.com/anchore/stereoscope/pkg/image"
)
@@ -14,8 +15,8 @@ type Resolver interface {
// ContentResolver knows how to get file content for given file.References
type ContentResolver interface {
FileContentsByLocation(Location) (string, error)
MultipleFileContentsByLocation([]Location) (map[Location]string, error)
FileContentsByLocation(Location) (io.ReadCloser, error)
MultipleFileContentsByLocation([]Location) (map[Location]io.ReadCloser, error)
// TODO: we should consider refactoring to return a set of io.Readers or file.Openers instead of the full contents themselves (allow for optional buffering).
}
+8 -2
View File
@@ -1,6 +1,7 @@
package source
import (
"io/ioutil"
"os"
"testing"
@@ -137,9 +138,14 @@ func TestMultipleFileContentsByLocation(t *testing.T) {
location := locations[0]
contents, err := p.Resolver.MultipleFileContentsByLocation([]Location{location})
content := contents[location]
contentReader := contents[location]
if content != test.expected {
content, err := ioutil.ReadAll(contentReader)
if err != nil {
t.Fatalf("cannot read contents: %+v", err)
}
if string(content) != test.expected {
t.Errorf("unexpected contents from file: '%s' != '%s'", content, test.expected)
}