mirror of
https://github.com/anchore/syft
synced 2024-11-10 06:14:16 +00:00
split catalogers into two sets, one for images another for directory scans
Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
1c320a8382
commit
10b44f5311
19 changed files with 218 additions and 149 deletions
2
Makefile
2
Makefile
|
@ -130,7 +130,7 @@ unit: fixtures ## Run unit tests (with coverage)
|
|||
.PHONY: integration
|
||||
integration: ## Run integration tests
|
||||
$(call title,Running integration tests)
|
||||
go test -v -tags=integration ./test/integration
|
||||
go test -tags=integration ./test/integration
|
||||
|
||||
# note: this is used by CI to determine if the integration test fixture cache (docker image tars) should be busted
|
||||
integration-fingerprint:
|
||||
|
|
|
@ -44,7 +44,7 @@ func parseGemfileLockEntries(_ string, reader io.Reader) ([]pkg.Package, error)
|
|||
Name: candidate[0],
|
||||
Version: strings.Trim(candidate[1], "()"),
|
||||
Language: pkg.Ruby,
|
||||
Type: pkg.BundlerPkg,
|
||||
Type: pkg.GemPkg,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ func TestParseGemfileLockEntries(t *testing.T) {
|
|||
t.Errorf("bad language (pkg=%+v): %+v", a.Name, a.Language)
|
||||
}
|
||||
|
||||
if a.Type != pkg.BundlerPkg {
|
||||
if a.Type != pkg.GemPkg {
|
||||
t.Errorf("bad package type (pkg=%+v): %+v", a.Name, a.Type)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ func parseGemspecEntries(_ string, reader io.Reader) ([]pkg.Package, error) {
|
|||
Name: metadata.Name,
|
||||
Version: metadata.Version,
|
||||
Language: pkg.Ruby,
|
||||
Type: pkg.BundlerPkg,
|
||||
Type: pkg.GemPkg,
|
||||
Metadata: metadata,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func TestParseGemspec(t *testing.T) {
|
|||
t.Errorf("bad language (pkg=%+v): %+v", a.Name, a.Language)
|
||||
}
|
||||
|
||||
if a.Type != pkg.BundlerPkg {
|
||||
if a.Type != pkg.GemPkg {
|
||||
t.Errorf("bad package type (pkg=%+v): %+v", a.Name, a.Type)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,16 +33,30 @@ type Cataloger interface {
|
|||
// TODO: we should consider refactoring to return a set of io.Readers instead of the full contents themselves (allow for optional buffering).
|
||||
}
|
||||
|
||||
// All returns a slice of all locally defined catalogers (defined in child packages).
|
||||
func All() []Cataloger {
|
||||
// ImageCatalogers returns a slice of locally implemented catalogers that are fit for detecting installations of packages.
|
||||
func ImageCatalogers() []Cataloger {
|
||||
return []Cataloger{
|
||||
bundler.NewGemspecCataloger(),
|
||||
python.NewPythonCataloger(), // TODO: split and replace me
|
||||
javascript.NewJavascriptCataloger(), // TODO: split and replace me
|
||||
deb.NewDpkgdbCataloger(),
|
||||
rpmdb.NewRpmdbCataloger(),
|
||||
java.NewJavaCataloger(),
|
||||
apkdb.NewApkdbCataloger(),
|
||||
golang.NewGoModCataloger(),
|
||||
}
|
||||
}
|
||||
|
||||
// DirectoryCatalogers returns a slice of locally implemented catalogers that are fit for detecting packages from index files (and select installations)
|
||||
func DirectoryCatalogers() []Cataloger {
|
||||
return []Cataloger{
|
||||
bundler.NewGemfileLockCataloger(),
|
||||
python.NewPythonCataloger(), // TODO: split and replace me
|
||||
javascript.NewJavascriptCataloger(), // TODO: split and replace me
|
||||
deb.NewDpkgdbCataloger(),
|
||||
bundler.NewGemfileLockCataloger(),
|
||||
python.NewPythonCataloger(),
|
||||
rpmdb.NewRpmdbCataloger(),
|
||||
java.NewJavaCataloger(),
|
||||
apkdb.NewApkdbCataloger(),
|
||||
golang.NewGoModCataloger(),
|
||||
javascript.NewJavascriptCataloger(),
|
||||
}
|
||||
}
|
||||
|
|
20
syft/lib.go
20
syft/lib.go
|
@ -17,6 +17,8 @@ Similar to the cataloging process, Linux distribution identification is also per
|
|||
package syft
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/anchore/syft/internal/bus"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/cataloger"
|
||||
|
@ -64,15 +66,17 @@ func CatalogFromScope(s scope.Scope) (*pkg.Catalog, error) {
|
|||
log.Info("building the catalog")
|
||||
|
||||
// conditionally have two sets of catalogers
|
||||
//var catalogers []cataloger.Cataloger
|
||||
//// if image
|
||||
//// use one set of catalogers
|
||||
//catalogers = ...
|
||||
//
|
||||
//// if dir
|
||||
//// use another set of catalogers
|
||||
var catalogers []cataloger.Cataloger
|
||||
switch s.Scheme {
|
||||
case scope.ImageScheme:
|
||||
catalogers = cataloger.ImageCatalogers()
|
||||
case scope.DirectoryScheme:
|
||||
catalogers = cataloger.DirectoryCatalogers()
|
||||
default:
|
||||
return nil, fmt.Errorf("unable to determine cataloger set from scheme=%+v", s.Scheme)
|
||||
}
|
||||
|
||||
return cataloger.Catalog(s.Resolver, cataloger.All()...)
|
||||
return cataloger.Catalog(s.Resolver, catalogers...)
|
||||
}
|
||||
|
||||
// SetLogger sets the logger object used for all syft logging calls.
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/syft/distro"
|
||||
"github.com/sergi/go-diff/diffmatchpatch"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPackage_pURL(t *testing.T) {
|
||||
|
@ -56,7 +57,7 @@ func TestPackage_pURL(t *testing.T) {
|
|||
pkg: Package{
|
||||
Name: "name",
|
||||
Version: "v0.1.0",
|
||||
Type: BundlerPkg,
|
||||
Type: GemPkg,
|
||||
},
|
||||
expected: "pkg:gem/name@v0.1.0",
|
||||
},
|
||||
|
|
|
@ -8,7 +8,7 @@ type Type string
|
|||
const (
|
||||
UnknownPkg Type = "UnknownPackage"
|
||||
ApkPkg Type = "apk"
|
||||
BundlerPkg Type = "bundle"
|
||||
GemPkg Type = "gem"
|
||||
DebPkg Type = "deb"
|
||||
EggPkg Type = "egg"
|
||||
// PacmanPkg Type = "pacman"
|
||||
|
@ -26,7 +26,7 @@ const (
|
|||
|
||||
var AllPkgs = []Type{
|
||||
ApkPkg,
|
||||
BundlerPkg,
|
||||
GemPkg,
|
||||
DebPkg,
|
||||
EggPkg,
|
||||
// PacmanPkg,
|
||||
|
@ -45,7 +45,7 @@ func (t Type) PackageURLType() string {
|
|||
switch t {
|
||||
case ApkPkg:
|
||||
return "alpine"
|
||||
case BundlerPkg:
|
||||
case GemPkg:
|
||||
return packageurl.TypeGem
|
||||
case DebPkg:
|
||||
return "deb"
|
||||
|
|
|
@ -34,9 +34,7 @@ func NewPresenter(catalog *pkg.Catalog, s scope.Scope, d distro.Distro) *Present
|
|||
func (pres *Presenter) Present(output io.Writer) error {
|
||||
bom := NewDocumentFromCatalog(pres.catalog, pres.distro)
|
||||
|
||||
srcObj := pres.scope.Source()
|
||||
|
||||
switch src := srcObj.(type) {
|
||||
switch src := pres.scope.Source.(type) {
|
||||
case scope.DirSource:
|
||||
bom.BomDescriptor.Component = &BdComponent{
|
||||
Component: Component{
|
||||
|
|
|
@ -15,8 +15,7 @@ type ImageLocation struct {
|
|||
}
|
||||
|
||||
func NewLocations(p *pkg.Package, s scope.Scope) (Locations, error) {
|
||||
srcObj := s.Source()
|
||||
switch src := srcObj.(type) {
|
||||
switch src := s.Source.(type) {
|
||||
case scope.ImageSource:
|
||||
locations := make([]ImageLocation, len(p.Source))
|
||||
for idx := range p.Source {
|
||||
|
|
|
@ -12,8 +12,7 @@ type Source struct {
|
|||
}
|
||||
|
||||
func NewSource(s scope.Scope) (Source, error) {
|
||||
srcObj := s.Source()
|
||||
switch src := srcObj.(type) {
|
||||
switch src := s.Source.(type) {
|
||||
case scope.ImageSource:
|
||||
return Source{
|
||||
Type: "image",
|
||||
|
@ -22,7 +21,7 @@ func NewSource(s scope.Scope) (Source, error) {
|
|||
case scope.DirSource:
|
||||
return Source{
|
||||
Type: "directory",
|
||||
Target: s.DirSrc.Path,
|
||||
Target: src.Path,
|
||||
}, nil
|
||||
default:
|
||||
return Source{}, fmt.Errorf("unsupported source: %T", src)
|
||||
|
|
|
@ -27,9 +27,8 @@ func (pres *Presenter) Present(output io.Writer) error {
|
|||
// init the tabular writer
|
||||
w := new(tabwriter.Writer)
|
||||
w.Init(output, 0, 8, 0, '\t', tabwriter.AlignRight)
|
||||
srcObj := pres.scope.Source()
|
||||
|
||||
switch src := srcObj.(type) {
|
||||
switch src := pres.scope.Source.(type) {
|
||||
case scope.DirSource:
|
||||
fmt.Fprintln(w, fmt.Sprintf("[Path: %s]", src.Path))
|
||||
case scope.ImageSource:
|
||||
|
|
|
@ -20,12 +20,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
unknownScheme scheme = "unknown-scheme"
|
||||
directoryScheme scheme = "directory-scheme"
|
||||
imageScheme scheme = "image-scheme"
|
||||
UnknownScheme Scheme = "unknown-scheme"
|
||||
DirectoryScheme Scheme = "directory-scheme"
|
||||
ImageScheme Scheme = "image-scheme"
|
||||
)
|
||||
|
||||
type scheme string
|
||||
type Scheme string
|
||||
|
||||
// ImageSource represents a data source that is a container image
|
||||
type ImageSource struct {
|
||||
|
@ -42,8 +42,8 @@ type DirSource struct {
|
|||
type Scope struct {
|
||||
Option Option // specific perspective to catalog
|
||||
Resolver Resolver // a Resolver object to use in file path/glob resolution and file contents resolution
|
||||
ImgSrc ImageSource // the specific image to be cataloged
|
||||
DirSrc DirSource // the specific directory to be cataloged
|
||||
Source interface{} // the specific source object to be cataloged
|
||||
Scheme Scheme // the source data scheme type (directory or image)
|
||||
}
|
||||
|
||||
// NewScope produces a Scope based on userInput like dir: or image:tag
|
||||
|
@ -55,7 +55,7 @@ func NewScope(userInput string, o Option) (Scope, func(), error) {
|
|||
}
|
||||
|
||||
switch parsedScheme {
|
||||
case directoryScheme:
|
||||
case DirectoryScheme:
|
||||
fileMeta, err := fs.Stat(location)
|
||||
if err != nil {
|
||||
return Scope{}, func() {}, fmt.Errorf("unable to stat dir=%q: %w", location, err)
|
||||
|
@ -71,7 +71,7 @@ func NewScope(userInput string, o Option) (Scope, func(), error) {
|
|||
}
|
||||
return s, func() {}, nil
|
||||
|
||||
case imageScheme:
|
||||
case ImageScheme:
|
||||
img, err := stereoscope.GetImage(location)
|
||||
cleanup := func() {
|
||||
stereoscope.Cleanup()
|
||||
|
@ -97,9 +97,10 @@ func NewScopeFromDir(path string) (Scope, error) {
|
|||
Resolver: &resolvers.DirectoryResolver{
|
||||
Path: path,
|
||||
},
|
||||
DirSrc: DirSource{
|
||||
Source: DirSource{
|
||||
Path: path,
|
||||
},
|
||||
Scheme: DirectoryScheme,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -118,59 +119,48 @@ func NewScopeFromImage(img *image.Image, option Option) (Scope, error) {
|
|||
return Scope{
|
||||
Option: option,
|
||||
Resolver: resolver,
|
||||
ImgSrc: ImageSource{
|
||||
Source: ImageSource{
|
||||
Img: img,
|
||||
},
|
||||
Scheme: ImageScheme,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Source returns the configured data source (either a dir source or container image source)
|
||||
func (s Scope) Source() interface{} {
|
||||
if s.ImgSrc != (ImageSource{}) {
|
||||
return s.ImgSrc
|
||||
}
|
||||
if s.DirSrc != (DirSource{}) {
|
||||
return s.DirSrc
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type sourceDetector func(string) (image.Source, string, error)
|
||||
|
||||
func detectScheme(fs afero.Fs, imageDetector sourceDetector, userInput string) (scheme, string, error) {
|
||||
func detectScheme(fs afero.Fs, imageDetector sourceDetector, userInput string) (Scheme, string, error) {
|
||||
if strings.HasPrefix(userInput, "dir:") {
|
||||
// blindly trust the user's scheme
|
||||
dirLocation, err := homedir.Expand(strings.TrimPrefix(userInput, "dir:"))
|
||||
if err != nil {
|
||||
return unknownScheme, "", fmt.Errorf("unable to expand directory path: %w", err)
|
||||
return UnknownScheme, "", fmt.Errorf("unable to expand directory path: %w", err)
|
||||
}
|
||||
return directoryScheme, dirLocation, nil
|
||||
return DirectoryScheme, dirLocation, nil
|
||||
}
|
||||
|
||||
// we should attempt to let stereoscope determine what the source is first --just because the source is a valid directory
|
||||
// doesn't mean we yet know if it is an OCI layout directory (to be treated as an image) or if it is a generic filesystem directory.
|
||||
source, imageSpec, err := imageDetector(userInput)
|
||||
if err != nil {
|
||||
return unknownScheme, "", fmt.Errorf("unable to detect the scheme from %q: %w", userInput, err)
|
||||
return UnknownScheme, "", fmt.Errorf("unable to detect the scheme from %q: %w", userInput, err)
|
||||
}
|
||||
|
||||
if source == image.UnknownSource {
|
||||
dirLocation, err := homedir.Expand(userInput)
|
||||
if err != nil {
|
||||
return unknownScheme, "", fmt.Errorf("unable to expand potential directory path: %w", err)
|
||||
return UnknownScheme, "", fmt.Errorf("unable to expand potential directory path: %w", err)
|
||||
}
|
||||
|
||||
fileMeta, err := fs.Stat(dirLocation)
|
||||
if err != nil {
|
||||
return unknownScheme, "", nil
|
||||
return UnknownScheme, "", nil
|
||||
}
|
||||
|
||||
if fileMeta.IsDir() {
|
||||
return directoryScheme, dirLocation, nil
|
||||
return DirectoryScheme, dirLocation, nil
|
||||
}
|
||||
return unknownScheme, "", nil
|
||||
return UnknownScheme, "", nil
|
||||
}
|
||||
|
||||
return imageScheme, imageSpec, nil
|
||||
return ImageScheme, imageSpec, nil
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package scope
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/afero"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/stereoscope/pkg/file"
|
||||
"github.com/anchore/stereoscope/pkg/image"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
func TestNewScopeFromImageFails(t *testing.T) {
|
||||
|
@ -78,8 +78,8 @@ func TestDirectoryScope(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("could not create NewDirScope: %w", err)
|
||||
}
|
||||
if p.DirSrc.Path != test.input {
|
||||
t.Errorf("mismatched stringer: '%s' != '%s'", p.DirSrc.Path, test.input)
|
||||
if p.Source.(DirSource).Path != test.input {
|
||||
t.Errorf("mismatched stringer: '%s' != '%s'", p.Source.(DirSource).Path, test.input)
|
||||
}
|
||||
|
||||
refs, err := p.Resolver.FilesByPath(test.inputPaths...)
|
||||
|
@ -229,7 +229,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
userInput string
|
||||
dirs []string
|
||||
detection detectorResult
|
||||
expectedScheme scheme
|
||||
expectedScheme Scheme
|
||||
expectedLocation string
|
||||
}{
|
||||
{
|
||||
|
@ -239,7 +239,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.DockerDaemonSource,
|
||||
ref: "wagoodman/dive:latest",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
expectedLocation: "wagoodman/dive:latest",
|
||||
},
|
||||
{
|
||||
|
@ -249,7 +249,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.DockerDaemonSource,
|
||||
ref: "wagoodman/dive",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
expectedLocation: "wagoodman/dive",
|
||||
},
|
||||
{
|
||||
|
@ -259,7 +259,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.DockerDaemonSource,
|
||||
ref: "wagoodman/dive:latest",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
expectedLocation: "wagoodman/dive:latest",
|
||||
},
|
||||
{
|
||||
|
@ -269,7 +269,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.DockerDaemonSource,
|
||||
ref: "wagoodman/dive",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
expectedLocation: "wagoodman/dive",
|
||||
},
|
||||
{
|
||||
|
@ -279,7 +279,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.DockerDaemonSource,
|
||||
ref: "latest",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
// we want to be able to handle this case better, however, I don't see a way to do this
|
||||
// the user will need to provide more explicit input (docker:docker:latest)
|
||||
expectedLocation: "latest",
|
||||
|
@ -291,7 +291,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.DockerDaemonSource,
|
||||
ref: "docker:latest",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
// we want to be able to handle this case better, however, I don't see a way to do this
|
||||
// the user will need to provide more explicit input (docker:docker:latest)
|
||||
expectedLocation: "docker:latest",
|
||||
|
@ -303,7 +303,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.OciTarballSource,
|
||||
ref: "some/path-to-file",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
expectedLocation: "some/path-to-file",
|
||||
},
|
||||
{
|
||||
|
@ -314,7 +314,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
ref: "some/path-to-dir",
|
||||
},
|
||||
dirs: []string{"some/path-to-dir"},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
expectedLocation: "some/path-to-dir",
|
||||
},
|
||||
{
|
||||
|
@ -325,7 +325,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
ref: "",
|
||||
},
|
||||
dirs: []string{"some/path-to-dir"},
|
||||
expectedScheme: directoryScheme,
|
||||
expectedScheme: DirectoryScheme,
|
||||
expectedLocation: "some/path-to-dir",
|
||||
},
|
||||
{
|
||||
|
@ -335,7 +335,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.DockerDaemonSource,
|
||||
ref: "some/path-to-dir",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
expectedLocation: "some/path-to-dir",
|
||||
},
|
||||
{
|
||||
|
@ -346,7 +346,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
ref: "",
|
||||
},
|
||||
dirs: []string{"some/path-to-dir"},
|
||||
expectedScheme: directoryScheme,
|
||||
expectedScheme: DirectoryScheme,
|
||||
expectedLocation: "some/path-to-dir",
|
||||
},
|
||||
{
|
||||
|
@ -356,7 +356,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.UnknownSource,
|
||||
ref: "",
|
||||
},
|
||||
expectedScheme: directoryScheme,
|
||||
expectedScheme: DirectoryScheme,
|
||||
expectedLocation: ".",
|
||||
},
|
||||
{
|
||||
|
@ -366,7 +366,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.UnknownSource,
|
||||
ref: "",
|
||||
},
|
||||
expectedScheme: directoryScheme,
|
||||
expectedScheme: DirectoryScheme,
|
||||
expectedLocation: ".",
|
||||
},
|
||||
// we should support tilde expansion
|
||||
|
@ -377,7 +377,7 @@ func TestDetectScheme(t *testing.T) {
|
|||
src: image.OciDirectorySource,
|
||||
ref: "~/some-path",
|
||||
},
|
||||
expectedScheme: imageScheme,
|
||||
expectedScheme: ImageScheme,
|
||||
expectedLocation: "~/some-path",
|
||||
},
|
||||
{
|
||||
|
@ -388,26 +388,26 @@ func TestDetectScheme(t *testing.T) {
|
|||
ref: "",
|
||||
},
|
||||
dirs: []string{"~/some-path"},
|
||||
expectedScheme: directoryScheme,
|
||||
expectedScheme: DirectoryScheme,
|
||||
expectedLocation: "~/some-path",
|
||||
},
|
||||
{
|
||||
name: "tilde-expansion-dir-explicit-exists",
|
||||
userInput: "dir:~/some-path",
|
||||
dirs: []string{"~/some-path"},
|
||||
expectedScheme: directoryScheme,
|
||||
expectedScheme: DirectoryScheme,
|
||||
expectedLocation: "~/some-path",
|
||||
},
|
||||
{
|
||||
name: "tilde-expansion-dir-explicit-dne",
|
||||
userInput: "dir:~/some-path",
|
||||
expectedScheme: directoryScheme,
|
||||
expectedScheme: DirectoryScheme,
|
||||
expectedLocation: "~/some-path",
|
||||
},
|
||||
{
|
||||
name: "tilde-expansion-dir-implicit-dne",
|
||||
userInput: "~/some-path",
|
||||
expectedScheme: unknownScheme,
|
||||
expectedScheme: UnknownScheme,
|
||||
expectedLocation: "",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -108,6 +108,10 @@ func TestJsonSchemaImg(t *testing.T) {
|
|||
t.Fatalf("failed to catalog image: %+v", err)
|
||||
}
|
||||
|
||||
var cases []testCase
|
||||
cases = append(cases, commonTestCases...)
|
||||
cases = append(cases, imageOnlyTestCases...)
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
testJsonSchema(t, catalog, theScope, "img")
|
||||
|
@ -121,6 +125,10 @@ func TestJsonSchemaDirs(t *testing.T) {
|
|||
t.Errorf("unable to create scope from dir: %+v", err)
|
||||
}
|
||||
|
||||
var cases []testCase
|
||||
cases = append(cases, commonTestCases...)
|
||||
cases = append(cases, dirOnlyTestCases...)
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
testJsonSchema(t, catalog, theScope, "dir")
|
||||
|
|
|
@ -4,12 +4,86 @@ package integration
|
|||
|
||||
import "github.com/anchore/syft/syft/pkg"
|
||||
|
||||
var cases = []struct {
|
||||
type testCase struct {
|
||||
name string
|
||||
pkgType pkg.Type
|
||||
pkgLanguage pkg.Language
|
||||
pkgInfo map[string]string
|
||||
}{
|
||||
}
|
||||
|
||||
var imageOnlyTestCases = []testCase{
|
||||
{
|
||||
name: "find gemspec packages",
|
||||
pkgType: pkg.GemPkg,
|
||||
pkgLanguage: pkg.Ruby,
|
||||
pkgInfo: map[string]string{
|
||||
"bundler": "2.1.4",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var dirOnlyTestCases = []testCase{
|
||||
{
|
||||
name: "find gemfile packages",
|
||||
pkgType: pkg.GemPkg,
|
||||
pkgLanguage: pkg.Ruby,
|
||||
pkgInfo: map[string]string{
|
||||
"actionmailer": "4.1.1",
|
||||
"actionpack": "4.1.1",
|
||||
"actionview": "4.1.1",
|
||||
"activemodel": "4.1.1",
|
||||
"activerecord": "4.1.1",
|
||||
"activesupport": "4.1.1",
|
||||
"arel": "5.0.1.20140414130214",
|
||||
"bootstrap-sass": "3.1.1.1",
|
||||
"builder": "3.2.2",
|
||||
"coffee-rails": "4.0.1",
|
||||
"coffee-script": "2.2.0",
|
||||
"coffee-script-source": "1.7.0",
|
||||
"erubis": "2.7.0",
|
||||
"execjs": "2.0.2",
|
||||
"hike": "1.2.3",
|
||||
"i18n": "0.6.9",
|
||||
"jbuilder": "2.0.7",
|
||||
"jquery-rails": "3.1.0",
|
||||
"json": "1.8.1",
|
||||
"kgio": "2.9.2",
|
||||
"libv8": "3.16.14.3",
|
||||
"mail": "2.5.4",
|
||||
"mime-types": "1.25.1",
|
||||
"minitest": "5.3.4",
|
||||
"multi_json": "1.10.1",
|
||||
"mysql2": "0.3.16",
|
||||
"polyglot": "0.3.4",
|
||||
"rack": "1.5.2",
|
||||
"rack-test": "0.6.2",
|
||||
"rails": "4.1.1",
|
||||
"railties": "4.1.1",
|
||||
"raindrops": "0.13.0",
|
||||
"rake": "10.3.2",
|
||||
"rdoc": "4.1.1",
|
||||
"ref": "1.0.5",
|
||||
"sass": "3.2.19",
|
||||
"sass-rails": "4.0.3",
|
||||
"sdoc": "0.4.0",
|
||||
"spring": "1.1.3",
|
||||
"sprockets": "2.11.0",
|
||||
"sprockets-rails": "2.1.3",
|
||||
"sqlite3": "1.3.9",
|
||||
"therubyracer": "0.12.1",
|
||||
"thor": "0.19.1",
|
||||
"thread_safe": "0.3.3",
|
||||
"tilt": "1.4.1",
|
||||
"treetop": "1.4.15",
|
||||
"turbolinks": "2.2.2",
|
||||
"tzinfo": "1.2.0",
|
||||
"uglifier": "2.5.0",
|
||||
"unicorn": "4.8.3",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var commonTestCases = []testCase{
|
||||
{
|
||||
name: "find rpmdb packages",
|
||||
pkgType: pkg.RpmPkg,
|
||||
|
@ -98,64 +172,6 @@ var cases = []struct {
|
|||
"mypy": "v0.770",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find bundler packages",
|
||||
pkgType: pkg.BundlerPkg,
|
||||
pkgLanguage: pkg.Ruby,
|
||||
pkgInfo: map[string]string{
|
||||
"actionmailer": "4.1.1",
|
||||
"actionpack": "4.1.1",
|
||||
"actionview": "4.1.1",
|
||||
"activemodel": "4.1.1",
|
||||
"activerecord": "4.1.1",
|
||||
"activesupport": "4.1.1",
|
||||
"arel": "5.0.1.20140414130214",
|
||||
"bootstrap-sass": "3.1.1.1",
|
||||
"builder": "3.2.2",
|
||||
"coffee-rails": "4.0.1",
|
||||
"coffee-script": "2.2.0",
|
||||
"coffee-script-source": "1.7.0",
|
||||
"erubis": "2.7.0",
|
||||
"execjs": "2.0.2",
|
||||
"hike": "1.2.3",
|
||||
"i18n": "0.6.9",
|
||||
"jbuilder": "2.0.7",
|
||||
"jquery-rails": "3.1.0",
|
||||
"json": "1.8.1",
|
||||
"kgio": "2.9.2",
|
||||
"libv8": "3.16.14.3",
|
||||
"mail": "2.5.4",
|
||||
"mime-types": "1.25.1",
|
||||
"minitest": "5.3.4",
|
||||
"multi_json": "1.10.1",
|
||||
"mysql2": "0.3.16",
|
||||
"polyglot": "0.3.4",
|
||||
"rack": "1.5.2",
|
||||
"rack-test": "0.6.2",
|
||||
"rails": "4.1.1",
|
||||
"railties": "4.1.1",
|
||||
"raindrops": "0.13.0",
|
||||
"rake": "10.3.2",
|
||||
"rdoc": "4.1.1",
|
||||
"ref": "1.0.5",
|
||||
"sass": "3.2.19",
|
||||
"sass-rails": "4.0.3",
|
||||
"sdoc": "0.4.0",
|
||||
"spring": "1.1.3",
|
||||
"sprockets": "2.11.0",
|
||||
"sprockets-rails": "2.1.3",
|
||||
"sqlite3": "1.3.9",
|
||||
"therubyracer": "0.12.1",
|
||||
"thor": "0.19.1",
|
||||
"thread_safe": "0.3.3",
|
||||
"tilt": "1.4.1",
|
||||
"treetop": "1.4.15",
|
||||
"turbolinks": "2.2.2",
|
||||
"tzinfo": "1.2.0",
|
||||
"uglifier": "2.5.0",
|
||||
"unicorn": "4.8.3",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
name: "find apkdb packages",
|
||||
|
|
|
@ -3,9 +3,11 @@
|
|||
package integration
|
||||
|
||||
import (
|
||||
"github.com/anchore/stereoscope/pkg/imagetest"
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/stereoscope/pkg/imagetest"
|
||||
"github.com/go-test/deep"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/syft"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
|
@ -35,6 +37,10 @@ func TestPkgCoverageImage(t *testing.T) {
|
|||
definedPkgs.Add(string(p))
|
||||
}
|
||||
|
||||
var cases []testCase
|
||||
cases = append(cases, commonTestCases...)
|
||||
cases = append(cases, imageOnlyTestCases...)
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
pkgCount := 0
|
||||
|
@ -81,10 +87,16 @@ func TestPkgCoverageImage(t *testing.T) {
|
|||
// ensure that integration test cases stay in sync with the available catalogers
|
||||
if len(observedLanguages) < len(definedLanguages) {
|
||||
t.Errorf("language coverage incomplete (languages=%d, coverage=%d)", len(definedLanguages), len(observedLanguages))
|
||||
for _, d := range deep.Equal(observedLanguages, definedLanguages) {
|
||||
t.Errorf("diff: %+v", d)
|
||||
}
|
||||
}
|
||||
|
||||
if len(observedPkgs) < len(definedPkgs) {
|
||||
t.Errorf("package coverage incomplete (packages=%d, coverage=%d)", len(definedPkgs), len(observedPkgs))
|
||||
for _, d := range deep.Equal(observedPkgs, definedPkgs) {
|
||||
t.Errorf("diff: %+v", d)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,6 +119,10 @@ func TestPkgCoverageDirectory(t *testing.T) {
|
|||
definedPkgs.Add(string(p))
|
||||
}
|
||||
|
||||
var cases []testCase
|
||||
cases = append(cases, commonTestCases...)
|
||||
cases = append(cases, dirOnlyTestCases...)
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
pkgCount := 0
|
||||
|
@ -150,7 +166,7 @@ func TestPkgCoverageDirectory(t *testing.T) {
|
|||
observedPkgs.Remove(string(pkg.UnknownPkg))
|
||||
definedPkgs.Remove(string(pkg.UnknownPkg))
|
||||
|
||||
// ensure that integration test cases stay in sync with the available catalogers
|
||||
// ensure that integration test commonTestCases stay in sync with the available catalogers
|
||||
if len(observedLanguages) < len(definedLanguages) {
|
||||
t.Errorf("language coverage incomplete (languages=%d, coverage=%d)", len(definedLanguages), len(observedLanguages))
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
# -*- encoding: utf-8 -*-
|
||||
# stub: bundler 2.1.4 ruby lib
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "bundler".freeze
|
||||
s.version = "2.1.4"
|
||||
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 2.5.2".freeze) if s.respond_to? :required_rubygems_version=
|
||||
s.require_paths = ["lib".freeze]
|
||||
s.authors = ["Andr\u00E9 Arko".freeze, "Samuel Giddins".freeze, "Colby Swandale".freeze, "Hiroshi Shibata".freeze, "David Rodr\u00EDguez".freeze, "Grey Baker".f
|
||||
s.bindir = "exe".freeze
|
||||
s.date = "2020-01-05"
|
||||
s.description = "Bundler manages an application's dependencies through its entire life, across many machines, systematically and repeatably".freeze
|
||||
s.email = ["team@bundler.io".freeze]
|
||||
s.executables = ["bundle".freeze, "bundler".freeze]
|
||||
s.files = ["exe/bundle".freeze, "exe/bundler".freeze]
|
||||
s.homepage = "https://bundler.io".freeze
|
||||
s.licenses = ["MIT".freeze]
|
||||
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0".freeze)
|
||||
s.rubygems_version = "3.1.2".freeze
|
||||
s.summary = "The best way to manage your application's dependencies".freeze
|
||||
|
||||
s.installed_by_version = "3.1.2" if s.respond_to? :installed_by_version
|
||||
end
|
Loading…
Reference in a new issue