rename scope to source

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2020-11-13 11:30:24 -05:00
parent 495fb0a45f
commit 9668341a14
No known key found for this signature in database
GPG key ID: 5CB45AE22BAB7EA7
55 changed files with 340 additions and 334 deletions

View file

@ -7,7 +7,7 @@ import (
"github.com/spf13/cobra"
"github.com/anchore/syft/syft/presenter"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/anchore/stereoscope"
"github.com/anchore/syft/internal/config"
@ -49,8 +49,8 @@ func setGlobalCliOptions() {
// scan options
flag := "scope"
rootCmd.Flags().StringP(
"scope", "s", scope.SquashedScope.String(),
fmt.Sprintf("selection of layers to catalog, options=%v", scope.Options))
"scope", "s", source.SquashedScope.String(),
fmt.Sprintf("selection of layers to catalog, options=%v", source.Options))
if err := viper.BindPFlag(flag, rootCmd.Flags().Lookup(flag)); err != nil {
fmt.Printf("unable to bind flag '%s': %+v", flag, err)
os.Exit(1)

View file

@ -8,7 +8,7 @@ import (
"github.com/adrg/xdg"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/syft/presenter"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/mitchellh/go-homedir"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
@ -23,7 +23,7 @@ type Application struct {
ConfigPath string
PresenterOpt presenter.Option
Output string `mapstructure:"output"`
ScopeOpt scope.Option
ScopeOpt source.Scope
Scope string `mapstructure:"scope"`
Quiet bool `mapstructure:"quiet"`
Log Logging `mapstructure:"log"`
@ -79,9 +79,9 @@ func (cfg *Application) Build() error {
}
cfg.PresenterOpt = presenterOption
// set the scope
scopeOption := scope.ParseOption(cfg.Scope)
if scopeOption == scope.UnknownScope {
// set the source
scopeOption := source.ParseOption(cfg.Scope)
if scopeOption == source.UnknownScope {
return fmt.Errorf("bad --scope value '%s'", cfg.Scope)
}
cfg.ScopeOpt = scopeOption

View file

@ -5,7 +5,7 @@ import (
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/event"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/hashicorp/go-multierror"
"github.com/wagoodman/go-partybus"
"github.com/wagoodman/go-progress"
@ -32,11 +32,11 @@ func newMonitor() (*progress.Manual, *progress.Manual) {
return &filesProcessed, &packagesDiscovered
}
// Catalog a given scope (container image or filesystem) with the given catalogers, returning all discovered packages.
// Catalog a given source (container image or filesystem) with the given catalogers, returning all discovered packages.
// In order to efficiently retrieve contents from a underlying container image the content fetch requests are
// done in bulk. Specifically, all files of interest are collected from each catalogers and accumulated into a single
// request.
func Catalog(resolver scope.Resolver, catalogers ...Cataloger) (*pkg.Catalog, error) {
func Catalog(resolver source.Resolver, catalogers ...Cataloger) (*pkg.Catalog, error) {
catalog := pkg.NewCatalog()
filesProcessed, packagesDiscovered := newMonitor()
@ -54,6 +54,8 @@ func Catalog(resolver scope.Resolver, catalogers ...Cataloger) (*pkg.Catalog, er
log.Debugf("cataloger '%s' discovered '%d' packages", theCataloger.Name(), catalogedPackages)
packagesDiscovered.N += int64(catalogedPackages)
// helper function to add synthesized information...
for _, p := range packages {
catalog.Add(p)
}

View file

@ -15,7 +15,7 @@ import (
"github.com/anchore/syft/syft/cataloger/rpmdb"
"github.com/anchore/syft/syft/cataloger/ruby"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
// Cataloger describes behavior for an object to participate in parsing container image or file system
@ -25,7 +25,7 @@ type Cataloger interface {
// Name returns a string that uniquely describes a cataloger
Name() string
// Catalog is given an object to resolve file references and content, this function returns any discovered Packages after analyzing the catalog source.
Catalog(resolver scope.Resolver) ([]pkg.Package, error)
Catalog(resolver source.Resolver) ([]pkg.Package, error)
}
// ImageCatalogers returns a slice of locally implemented catalogers that are fit for detecting installations of packages.

View file

@ -9,7 +9,7 @@ import (
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
// GenericCataloger implements the Catalog interface and is responsible for dispatching the proper parser function for
@ -53,7 +53,7 @@ func (c *GenericCataloger) clear() {
}
// Catalog is given an object to resolve file references and content, this function returns any discovered Packages after analyzing the catalog source.
func (c *GenericCataloger) Catalog(resolver scope.Resolver) ([]pkg.Package, error) {
func (c *GenericCataloger) Catalog(resolver source.Resolver) ([]pkg.Package, error) {
fileSelection := c.selectFiles(resolver)
contents, err := resolver.MultipleFileContentsByRef(fileSelection...)
if err != nil {
@ -63,7 +63,7 @@ func (c *GenericCataloger) Catalog(resolver scope.Resolver) ([]pkg.Package, erro
}
// SelectFiles takes a set of file trees and resolves and file references of interest for future cataloging
func (c *GenericCataloger) selectFiles(resolver scope.FileResolver) []file.Reference {
func (c *GenericCataloger) selectFiles(resolver source.FileResolver) []file.Reference {
// select by exact path
for path, parser := range c.pathParsers {
files, err := resolver.FilesByPath(file.Path(path))

View file

@ -11,7 +11,7 @@ import (
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
const (
@ -33,7 +33,7 @@ func (c *Cataloger) Name() string {
}
// Catalog is given an object to resolve file references and content, this function returns any discovered Packages after analyzing dpkg support files.
func (c *Cataloger) Catalog(resolver scope.Resolver) ([]pkg.Package, error) {
func (c *Cataloger) Catalog(resolver source.Resolver) ([]pkg.Package, error) {
dbFileMatches, err := resolver.FilesByGlob(dpkgStatusGlob)
if err != nil {
return nil, fmt.Errorf("failed to find dpkg status files's by glob: %w", err)
@ -93,7 +93,7 @@ func (c *Cataloger) Catalog(resolver scope.Resolver) ([]pkg.Package, error) {
return pkgs, nil
}
func fetchMd5Contents(resolver scope.Resolver, dbRef file.Reference, pkgs []pkg.Package) (map[string]io.Reader, map[string]file.Reference, error) {
func fetchMd5Contents(resolver source.Resolver, dbRef file.Reference, pkgs []pkg.Package) (map[string]io.Reader, map[string]file.Reference, error) {
// fetch all MD5 file contents. This approach is more efficient than fetching each MD5 file one at a time
var md5FileMatches []file.Reference
@ -146,7 +146,7 @@ func fetchMd5Contents(resolver scope.Resolver, dbRef file.Reference, pkgs []pkg.
return contentsByName, refsByName, nil
}
func fetchCopyrightContents(resolver scope.Resolver, dbRef file.Reference, pkgs []pkg.Package) (map[string]io.Reader, map[string]file.Reference, error) {
func fetchCopyrightContents(resolver source.Resolver, dbRef file.Reference, pkgs []pkg.Package) (map[string]io.Reader, map[string]file.Reference, error) {
// fetch all copyright file contents. This approach is more efficient than fetching each copyright file one at a time
var copyrightFileMatches []file.Reference

View file

@ -5,7 +5,7 @@ import (
"github.com/anchore/stereoscope/pkg/imagetest"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/go-test/deep"
)
@ -54,7 +54,7 @@ func TestDpkgCataloger(t *testing.T) {
img, cleanup := imagetest.GetFixtureImage(t, "docker-archive", "image-dpkg")
defer cleanup()
s, err := scope.NewScopeFromImage(img, scope.AllLayersScope)
s, err := source.NewFromImage(img, source.AllLayersScope)
if err != nil {
t.Fatal(err)
}

View file

@ -12,7 +12,7 @@ import (
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
const (
@ -33,7 +33,7 @@ func (c *PackageCataloger) Name() string {
}
// Catalog is given an object to resolve file references and content, this function returns any discovered Packages after analyzing python egg and wheel installations.
func (c *PackageCataloger) Catalog(resolver scope.Resolver) ([]pkg.Package, error) {
func (c *PackageCataloger) Catalog(resolver source.Resolver) ([]pkg.Package, error) {
// nolint:prealloc
var fileMatches []file.Reference
@ -59,7 +59,7 @@ func (c *PackageCataloger) Catalog(resolver scope.Resolver) ([]pkg.Package, erro
}
// catalogEggOrWheel takes the primary metadata file reference and returns the python package it represents.
func (c *PackageCataloger) catalogEggOrWheel(resolver scope.Resolver, metadataRef file.Reference) (*pkg.Package, error) {
func (c *PackageCataloger) catalogEggOrWheel(resolver source.Resolver, metadataRef file.Reference) (*pkg.Package, error) {
metadata, sources, err := c.assembleEggOrWheelMetadata(resolver, metadataRef)
if err != nil {
return nil, err
@ -84,7 +84,7 @@ func (c *PackageCataloger) catalogEggOrWheel(resolver scope.Resolver, metadataRe
}
// fetchRecordFiles finds a corresponding RECORD file for the given python package metadata file and returns the set of file records contained.
func (c *PackageCataloger) fetchRecordFiles(resolver scope.Resolver, metadataRef file.Reference) (files []pkg.PythonFileRecord, sources []file.Reference, err error) {
func (c *PackageCataloger) fetchRecordFiles(resolver source.Resolver, metadataRef file.Reference) (files []pkg.PythonFileRecord, sources []file.Reference, err error) {
// we've been given a file reference to a specific wheel METADATA file. note: this may be for a directory
// or for an image... for an image the METADATA file may be present within multiple layers, so it is important
// to reconcile the RECORD path to the same layer (or the next adjacent lower layer).
@ -116,7 +116,7 @@ func (c *PackageCataloger) fetchRecordFiles(resolver scope.Resolver, metadataRef
}
// fetchTopLevelPackages finds a corresponding top_level.txt file for the given python package metadata file and returns the set of package names contained.
func (c *PackageCataloger) fetchTopLevelPackages(resolver scope.Resolver, metadataRef file.Reference) (pkgs []string, sources []file.Reference, err error) {
func (c *PackageCataloger) fetchTopLevelPackages(resolver source.Resolver, metadataRef file.Reference) (pkgs []string, sources []file.Reference, err error) {
// a top_level.txt file specifies the python top-level packages (provided by this python package) installed into site-packages
parentDir := filepath.Dir(string(metadataRef.Path))
topLevelPath := filepath.Join(parentDir, "top_level.txt")
@ -149,7 +149,7 @@ func (c *PackageCataloger) fetchTopLevelPackages(resolver scope.Resolver, metada
}
// assembleEggOrWheelMetadata discovers and accumulates python package metadata from multiple file sources and returns a single metadata object as well as a list of files where the metadata was derived from.
func (c *PackageCataloger) assembleEggOrWheelMetadata(resolver scope.Resolver, metadataRef file.Reference) (*pkg.PythonPackageMetadata, []file.Reference, error) {
func (c *PackageCataloger) assembleEggOrWheelMetadata(resolver source.Resolver, metadataRef file.Reference) (*pkg.PythonPackageMetadata, []file.Reference, error) {
var sources = []file.Reference{metadataRef}
metadataContents, err := resolver.FileContentsByRef(metadataRef)

View file

@ -8,7 +8,7 @@ import (
"strings"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
const (
@ -28,7 +28,7 @@ func (c *Cataloger) Name() string {
}
// Catalog is given an object to resolve file references and content, this function returns any discovered Packages after analyzing rpm db installation.
func (c *Cataloger) Catalog(resolver scope.Resolver) ([]pkg.Package, error) {
func (c *Cataloger) Catalog(resolver source.Resolver) ([]pkg.Package, error) {
fileMatches, err := resolver.FilesByGlob(packagesGlob)
if err != nil {
return nil, fmt.Errorf("failed to find rpmdb's by glob: %w", err)

View file

@ -9,6 +9,7 @@ import (
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
rpmdb "github.com/anchore/go-rpmdb/pkg"
"github.com/anchore/syft/internal"
@ -80,7 +81,7 @@ func parseRpmDB(resolver scope.FileResolver, dbRef file.Reference, reader io.Rea
return allPkgs, nil
}
func extractRpmdbFileRecords(resolver scope.FileResolver, entry *rpmdb.PackageInfo) ([]pkg.RpmdbFileRecord, error) {
func extractRpmdbFileRecords(resolver source.FileResolver, entry *rpmdb.PackageInfo) ([]pkg.RpmdbFileRecord, error) {
var records = make([]pkg.RpmdbFileRecord, 0)
for _, record := range entry.Files {

View file

@ -6,7 +6,7 @@ import (
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
// returns a distro or nil
@ -18,7 +18,7 @@ type parseEntry struct {
}
// Identify parses distro-specific files to determine distro metadata like version and release.
func Identify(resolver scope.Resolver) Distro {
func Identify(resolver source.Resolver) Distro {
distro := NewUnknownDistro()
identityFiles := []parseEntry{

View file

@ -8,7 +8,7 @@ import (
"github.com/anchore/syft/internal"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
func TestIdentifyDistro(t *testing.T) {
@ -84,9 +84,9 @@ func TestIdentifyDistro(t *testing.T) {
for _, test := range tests {
t.Run(test.fixture, func(t *testing.T) {
s, err := scope.NewScopeFromDir(test.fixture)
s, err := source.NewFromDirectory(test.fixture)
if err != nil {
t.Fatalf("unable to produce a new scope for testing: %s", test.fixture)
t.Fatalf("unable to produce a new source for testing: %s", test.fixture)
}
d := Identify(s.Resolver)

View file

@ -7,8 +7,8 @@ Here is what the main execution path for syft does:
2. Invoke all catalogers to catalog the image, adding discovered packages to a single catalog object
3. Invoke a single presenter to show the contents of the catalog
A Scope object encapsulates the image object to be cataloged and the user options (catalog all layers vs. squashed layer),
providing a way to inspect paths and file content within the image. The Scope object, not the image object, is used
A Source object encapsulates the image object to be cataloged and the user options (catalog all layers vs. squashed layer),
providing a way to inspect paths and file content within the image. The Source object, not the image object, is used
throughout the main execution path. This abstraction allows for decoupling of what is cataloged (a docker image, an OCI
image, a filesystem, etc) and how it is cataloged (the individual catalogers).
@ -28,15 +28,15 @@ import (
"github.com/anchore/syft/syft/logger"
"github.com/anchore/syft/syft/pkg"
jsonPresenter "github.com/anchore/syft/syft/presenter/json"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/wagoodman/go-partybus"
)
// Catalog the given image from a particular perspective (e.g. squashed scope, all-layers scope). Returns the discovered
// set of packages, the identified Linux distribution, and the scope object used to wrap the data source.
func Catalog(userInput string, scoptOpt scope.Option) (*pkg.Catalog, *scope.Scope, *distro.Distro, error) {
// Catalog the given image from a particular perspective (e.g. squashed source, all-layers source). Returns the discovered
// set of packages, the identified Linux distribution, and the source object used to wrap the data source.
func Catalog(userInput string, scoptOpt source.Scope) (*pkg.Catalog, *source.Source, *distro.Distro, error) {
log.Info("cataloging image")
s, cleanup, err := scope.NewScope(userInput, scoptOpt)
s, cleanup, err := source.NewSource(userInput, scoptOpt)
defer cleanup()
if err != nil {
return nil, nil, nil, err
@ -53,8 +53,8 @@ func Catalog(userInput string, scoptOpt scope.Option) (*pkg.Catalog, *scope.Scop
}
// IdentifyDistro attempts to discover what the underlying Linux distribution may be from the available flat files
// provided by the given scope object. If results are inconclusive a "UnknownDistro" Type is returned.
func IdentifyDistro(s scope.Scope) distro.Distro {
// provided by the given source object. If results are inconclusive a "UnknownDistro" Type is returned.
func IdentifyDistro(s source.Source) distro.Distro {
d := distro.Identify(s.Resolver)
if d.Type != distro.UnknownDistroType {
log.Infof("identified distro: %s", d.String())
@ -64,16 +64,16 @@ func IdentifyDistro(s scope.Scope) distro.Distro {
return d
}
// Catalog the given scope, which may represent a container image or filesystem. Returns the discovered set of packages.
func CatalogFromScope(s scope.Scope) (*pkg.Catalog, error) {
// Catalog the given source, which may represent a container image or filesystem. Returns the discovered set of packages.
func CatalogFromScope(s source.Source) (*pkg.Catalog, error) {
log.Info("building the catalog")
// conditionally have two sets of catalogers
var catalogers []cataloger.Cataloger
switch s.Scheme {
case scope.ImageScheme:
case source.ImageScheme:
catalogers = cataloger.ImageCatalogers()
case scope.DirectoryScheme:
case source.DirectoryScheme:
catalogers = cataloger.DirectoryCatalogers()
default:
return nil, fmt.Errorf("unable to determine cataloger set from scheme=%+v", s.Scheme)

View file

@ -17,11 +17,12 @@ type ID int64
// Package represents an application or library that has been bundled into a distributable format.
type Package struct {
id ID // uniquely identifies a package, set by the cataloger
Name string `json:"manifest"` // the package name
Version string `json:"version"` // the version of the package
FoundBy string `json:"foundBy"` // the specific cataloger that discovered this package
Source []file.Reference `json:"sources"` // the locations that lead to the discovery of this package (note: this is not necessarily the locations that make up this package)
id ID // uniquely identifies a package, set by the cataloger
Name string `json:"manifest"` // the package name
Version string `json:"version"` // the version of the package
FoundBy string `json:"foundBy"` // the specific cataloger that discovered this package
Source []file.Reference `json:"-"` // the locations that lead to the discovery of this package (note: this is not necessarily the locations that make up this package)
Location interface{} `json:"locations"`
// TODO: should we move licenses into metadata?
Licenses []string `json:"licenses"` // licenses discovered with the package metadata
Language Language `json:"language"` // the language ecosystem this package belongs to (e.g. JavaScript, Python, etc)

View file

@ -15,7 +15,7 @@ type Component struct {
Description string `xml:"description,omitempty"` // A description of the component
Licenses *[]License `xml:"licenses>license"` // A node describing zero or more license names, SPDX license IDs or expressions
PackageURL string `xml:"purl,omitempty"` // Specifies the package-url (PackageURL). The purl, if specified, must be valid and conform to the specification defined at: https://github.com/package-url/purl-spec
// TODO: scope, hashes, copyright, cpe, purl, swid, modified, pedigree, externalReferences
// TODO: source, hashes, copyright, cpe, purl, swid, modified, pedigree, externalReferences
// TODO: add user-defined parameters for syft-specific values (image layer index, cataloger, location path, etc.)
}

View file

@ -11,21 +11,21 @@ import (
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
// Presenter writes a CycloneDX report from the given Catalog and Scope contents
// Presenter writes a CycloneDX report from the given Catalog and Source contents
type Presenter struct {
catalog *pkg.Catalog
scope scope.Scope
source source.Source
distro distro.Distro
}
// NewPresenter creates a CycloneDX presenter from the given Catalog and Scope objects.
func NewPresenter(catalog *pkg.Catalog, s scope.Scope, d distro.Distro) *Presenter {
// NewPresenter creates a CycloneDX presenter from the given Catalog and Source objects.
func NewPresenter(catalog *pkg.Catalog, s source.Source, d distro.Distro) *Presenter {
return &Presenter{
catalog: catalog,
scope: s,
source: s,
distro: d,
}
}
@ -34,8 +34,8 @@ 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)
switch src := pres.scope.Source.(type) {
case scope.DirSource:
switch src := pres.source.Target.(type) {
case source.DirSource:
bom.BomDescriptor.Component = &BdComponent{
Component: Component{
Type: "file",
@ -43,7 +43,7 @@ func (pres *Presenter) Present(output io.Writer) error {
Version: "",
},
}
case scope.ImageSource:
case source.ImageSource:
var imageID string
var versionStr string
if len(src.Img.Metadata.Tags) > 0 {

View file

@ -12,7 +12,7 @@ import (
"github.com/anchore/go-testutils"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/sergi/go-diff/diffmatchpatch"
)
@ -57,7 +57,7 @@ func TestCycloneDxDirsPresenter(t *testing.T) {
},
})
s, err := scope.NewScopeFromDir("/some/path")
s, err := source.NewFromDirectory("/some/path")
if err != nil {
t.Fatal(err)
}
@ -147,7 +147,7 @@ func TestCycloneDxImgsPresenter(t *testing.T) {
},
})
s, err := scope.NewScopeFromImage(img, scope.AllLayersScope)
s, err := source.NewFromImage(img, source.AllLayersScope)
if err != nil {
t.Fatal(err)
}

View file

@ -5,7 +5,7 @@ import (
"fmt"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
type Artifact struct {
@ -33,7 +33,7 @@ type ArtifactMetadataUnpacker struct {
Metadata json.RawMessage `json:"metadata"`
}
func NewArtifact(p *pkg.Package, s scope.Scope) (Artifact, error) {
func NewArtifact(p *pkg.Package, s source.Source) (Artifact, error) {
locations, err := NewLocations(p, s)
if err != nil {
return Artifact{}, err

View file

@ -7,7 +7,7 @@ import (
"github.com/anchore/syft/internal/version"
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
type Document struct {
@ -22,7 +22,7 @@ type Descriptor struct {
Name string `json:"name"`
Version string `json:"version"`
ReportTimestamp string `json:"reportTimestamp"`
// TODO: we should include scope option here as well (or in source)
// TODO: we should include source option here as well (or in source)
}
// Distribution provides information about a detected Linux Distribution
@ -32,7 +32,7 @@ type Distribution struct {
IDLike string `json:"idLike"`
}
func NewDocument(catalog *pkg.Catalog, s scope.Scope, d distro.Distro) (Document, error) {
func NewDocument(catalog *pkg.Catalog, s source.Source, d distro.Distro) (Document, error) {
src, err := NewSource(s)
if err != nil {
return Document{}, nil

View file

@ -1,7 +1,7 @@
package json
import (
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
type Image struct {
@ -18,7 +18,7 @@ type Layer struct {
Size int64 `json:"size"`
}
func NewImage(src scope.ImageSource) *Image {
func NewImage(src source.ImageSource) *Image {
// populate artifacts...
tags := make([]string, len(src.Img.Metadata.Tags))
for idx, tag := range src.Img.Metadata.Tags {

View file

@ -4,7 +4,7 @@ import (
"fmt"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
type Locations interface{}
@ -14,9 +14,9 @@ type ImageLocation struct {
LayerIndex uint `json:"layerIndex"`
}
func NewLocations(p *pkg.Package, s scope.Scope) (Locations, error) {
switch src := s.Source.(type) {
case scope.ImageSource:
func NewLocations(p *pkg.Package, s source.Source) (Locations, error) {
switch src := s.Target.(type) {
case source.ImageSource:
locations := make([]ImageLocation, len(p.Source))
for idx := range p.Source {
entry, err := src.Img.FileCatalog.Get(p.Source[idx])
@ -33,7 +33,7 @@ func NewLocations(p *pkg.Package, s scope.Scope) (Locations, error) {
}
return locations, nil
case scope.DirSource:
case source.DirSource:
locations := make([]string, len(p.Source))
for idx := range p.Source {
locations[idx] = string(p.Source[idx].Path)

View file

@ -6,25 +6,25 @@ import (
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
type Presenter struct {
catalog *pkg.Catalog
scope scope.Scope
source source.Source
distro distro.Distro
}
func NewPresenter(catalog *pkg.Catalog, s scope.Scope, d distro.Distro) *Presenter {
func NewPresenter(catalog *pkg.Catalog, s source.Source, d distro.Distro) *Presenter {
return &Presenter{
catalog: catalog,
scope: s,
source: s,
distro: d,
}
}
func (pres *Presenter) Present(output io.Writer) error {
doc, err := NewDocument(pres.catalog, pres.scope, pres.distro)
doc, err := NewDocument(pres.catalog, pres.source, pres.distro)
if err != nil {
return err
}

View file

@ -10,7 +10,7 @@ import (
"github.com/anchore/stereoscope/pkg/imagetest"
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/sergi/go-diff/diffmatchpatch"
)
@ -53,7 +53,7 @@ func TestJsonDirsPresenter(t *testing.T) {
},
})
d := distro.NewUnknownDistro()
s, err := scope.NewScopeFromDir("/some/path")
s, err := source.NewFromDirectory("/some/path")
if err != nil {
t.Fatal(err)
}
@ -124,7 +124,7 @@ func TestJsonImgsPresenter(t *testing.T) {
},
})
s, err := scope.NewScopeFromImage(img, scope.AllLayersScope)
s, err := source.NewFromImage(img, source.AllLayersScope)
d := distro.NewUnknownDistro()
pres := NewPresenter(catalog, s, d)

View file

@ -4,7 +4,7 @@ import (
"encoding/json"
"fmt"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
type Source struct {
@ -17,14 +17,14 @@ type SourceUnpacker struct {
Target json.RawMessage `json:"target"`
}
func NewSource(s scope.Scope) (Source, error) {
switch src := s.Source.(type) {
case scope.ImageSource:
func NewSource(s source.Source) (Source, error) {
switch src := s.Target.(type) {
case source.ImageSource:
return Source{
Type: "image",
Target: NewImage(src),
}, nil
case scope.DirSource:
case source.DirSource:
return Source{
Type: "directory",
Target: src.Path,

View file

@ -15,7 +15,7 @@ import (
"github.com/anchore/syft/syft/presenter/json"
"github.com/anchore/syft/syft/presenter/table"
"github.com/anchore/syft/syft/presenter/text"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
// Presenter defines the expected behavior for an object responsible for displaying arbitrary input and processed data
@ -25,7 +25,7 @@ type Presenter interface {
}
// GetPresenter returns a presenter for images or directories
func GetPresenter(option Option, s scope.Scope, catalog *pkg.Catalog, d *distro.Distro) Presenter {
func GetPresenter(option Option, s source.Source, catalog *pkg.Catalog, d *distro.Distro) Presenter {
switch option {
case JSONPresenter:
return json.NewPresenter(catalog, s, *d)

View file

@ -9,18 +9,18 @@ import (
"github.com/olekukonko/tablewriter"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
type Presenter struct {
catalog *pkg.Catalog
scope scope.Scope
source source.Source
}
func NewPresenter(catalog *pkg.Catalog, s scope.Scope) *Presenter {
func NewPresenter(catalog *pkg.Catalog, s source.Source) *Presenter {
return &Presenter{
catalog: catalog,
scope: s,
source: s,
}
}

View file

@ -3,14 +3,15 @@ package table
import (
"bytes"
"flag"
"github.com/go-test/deep"
"testing"
"github.com/go-test/deep"
"github.com/anchore/go-testutils"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/stereoscope/pkg/imagetest"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/sergi/go-diff/diffmatchpatch"
)
@ -43,7 +44,7 @@ func TestTablePresenter(t *testing.T) {
Type: pkg.DebPkg,
})
s, err := scope.NewScopeFromImage(img, scope.AllLayersScope)
s, err := source.NewFromImage(img, source.AllLayersScope)
pres := NewPresenter(catalog, s)
// run presenter

View file

@ -7,18 +7,18 @@ import (
"text/tabwriter"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
type Presenter struct {
catalog *pkg.Catalog
scope scope.Scope
source source.Source
}
func NewPresenter(catalog *pkg.Catalog, s scope.Scope) *Presenter {
func NewPresenter(catalog *pkg.Catalog, s source.Source) *Presenter {
return &Presenter{
catalog: catalog,
scope: s,
source: s,
}
}
@ -28,10 +28,10 @@ func (pres *Presenter) Present(output io.Writer) error {
w := new(tabwriter.Writer)
w.Init(output, 0, 8, 0, '\t', tabwriter.AlignRight)
switch src := pres.scope.Source.(type) {
case scope.DirSource:
switch src := pres.source.Target.(type) {
case source.DirSource:
fmt.Fprintln(w, fmt.Sprintf("[Path: %s]", src.Path))
case scope.ImageSource:
case source.ImageSource:
fmt.Fprintln(w, "[Image]")
for idx, l := range src.Img.Layers {

View file

@ -9,7 +9,7 @@ import (
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/stereoscope/pkg/imagetest"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/sergi/go-diff/diffmatchpatch"
)
@ -32,9 +32,9 @@ func TestTextDirPresenter(t *testing.T) {
Type: pkg.DebPkg,
})
s, err := scope.NewScopeFromDir("/some/path")
s, err := source.NewFromDirectory("/some/path")
if err != nil {
t.Fatalf("unable to create scope: %+v", err)
t.Fatalf("unable to create source: %+v", err)
}
pres := NewPresenter(catalog, s)
@ -98,7 +98,7 @@ func TestTextImgPresenter(t *testing.T) {
l.Metadata.Digest = "sha256:ad8ecdc058976c07e7e347cb89fa9ad86a294b5ceaae6d09713fb035f84115abf3c4a2388a4af3aa60f13b94f4c6846930bdf53"
}
s, err := scope.NewScopeFromImage(img, scope.AllLayersScope)
s, err := source.NewFromImage(img, source.AllLayersScope)
if err != nil {
t.Fatal(err)
}

View file

@ -1,4 +0,0 @@
/*
Package resolvers provides concrete implementations for the scope.Resolver interface for all supported data sources and scope options.
*/
package resolvers

View file

@ -1,166 +0,0 @@
/*
Package scope provides an abstraction to allow a user to loosely define a data source to catalog and expose a common interface that
catalogers and use explore and analyze data from the data source. All valid (cataloggable) data sources are defined
within this package.
*/
package scope
import (
"fmt"
"strings"
"github.com/mitchellh/go-homedir"
"github.com/spf13/afero"
"github.com/anchore/stereoscope"
"github.com/anchore/stereoscope/pkg/image"
"github.com/anchore/syft/syft/scope/resolvers"
)
const (
UnknownScheme Scheme = "unknown-scheme"
DirectoryScheme Scheme = "directory-scheme"
ImageScheme Scheme = "image-scheme"
)
type Scheme string
// ImageSource represents a data source that is a container image
type ImageSource struct {
Img *image.Image // the image object to be cataloged
}
// DirSource represents a data source that is a filesystem directory tree
type DirSource struct {
Path string // the root path to be cataloged
}
// Scope is an object that captures the data source to be cataloged, configuration, and a specific resolver used
// in cataloging (based on the data source and configuration)
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
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
func NewScope(userInput string, o Option) (Scope, func(), error) {
fs := afero.NewOsFs()
parsedScheme, location, err := detectScheme(fs, image.DetectSource, userInput)
if err != nil {
return Scope{}, func() {}, fmt.Errorf("unable to parse input=%q: %w", userInput, err)
}
switch parsedScheme {
case DirectoryScheme:
fileMeta, err := fs.Stat(location)
if err != nil {
return Scope{}, func() {}, fmt.Errorf("unable to stat dir=%q: %w", location, err)
}
if !fileMeta.IsDir() {
return Scope{}, func() {}, fmt.Errorf("given path is not a directory (path=%q): %w", location, err)
}
s, err := NewScopeFromDir(location)
if err != nil {
return Scope{}, func() {}, fmt.Errorf("could not populate scope from path=%q: %w", location, err)
}
return s, func() {}, nil
case ImageScheme:
img, err := stereoscope.GetImage(location)
cleanup := func() {
stereoscope.Cleanup()
}
if err != nil || img == nil {
return Scope{}, cleanup, fmt.Errorf("could not fetch image '%s': %w", location, err)
}
s, err := NewScopeFromImage(img, o)
if err != nil {
return Scope{}, cleanup, fmt.Errorf("could not populate scope with image: %w", err)
}
return s, cleanup, nil
}
return Scope{}, func() {}, fmt.Errorf("unable to process input for scanning: '%s'", userInput)
}
// NewScopeFromDir creates a new scope object tailored to catalog a given filesystem directory recursively.
func NewScopeFromDir(path string) (Scope, error) {
return Scope{
Resolver: &resolvers.DirectoryResolver{
Path: path,
},
Source: DirSource{
Path: path,
},
Scheme: DirectoryScheme,
}, nil
}
// NewScopeFromImage creates a new scope object tailored to catalog a given container image, relative to the
// option given (e.g. all-layers, squashed, etc)
func NewScopeFromImage(img *image.Image, option Option) (Scope, error) {
if img == nil {
return Scope{}, fmt.Errorf("no image given")
}
resolver, err := getImageResolver(img, option)
if err != nil {
return Scope{}, fmt.Errorf("could not determine file resolver: %w", err)
}
return Scope{
Option: option,
Resolver: resolver,
Source: ImageSource{
Img: img,
},
Scheme: ImageScheme,
}, nil
}
type sourceDetector func(string) (image.Source, 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 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)
}
if source == image.UnknownSource {
dirLocation, err := homedir.Expand(userInput)
if err != nil {
return UnknownScheme, "", fmt.Errorf("unable to expand potential directory path: %w", err)
}
fileMeta, err := fs.Stat(dirLocation)
if err != nil {
return UnknownScheme, "", nil
}
if fileMeta.IsDir() {
return DirectoryScheme, dirLocation, nil
}
return UnknownScheme, "", nil
}
return ImageScheme, imageSpec, nil
}

View file

@ -1,4 +1,4 @@
package resolvers
package source
import (
"archive/tar"
@ -8,7 +8,7 @@ import (
"github.com/anchore/stereoscope/pkg/image"
)
// AllLayersResolver implements path and content access for the AllLayers scope option for container image data sources.
// AllLayersResolver implements path and content access for the AllLayers source option for container image data sources.
type AllLayersResolver struct {
img *image.Image
layers []int
@ -41,7 +41,7 @@ func (r *AllLayersResolver) fileByRef(ref file.Reference, uniqueFileIDs file.Ref
if entry.Metadata.TypeFlag == tar.TypeLink || entry.Metadata.TypeFlag == tar.TypeSymlink {
// a link may resolve in this layer or higher, assuming a squashed tree is used to search
// we should search all possible resolutions within the valid scope
// we should search all possible resolutions within the valid source
for _, subLayerIdx := range r.layers[layerIdx:] {
resolvedRef, err := r.img.ResolveLinkByLayerSquash(ref, subLayerIdx)
if err != nil {

View file

@ -1,4 +1,4 @@
package resolvers
package source
import (
"testing"

View file

@ -1,4 +1,4 @@
package resolvers
package source
import (
"fmt"

View file

@ -1,4 +1,4 @@
package resolvers
package source
import (
"testing"

View file

@ -1,4 +1,4 @@
package resolvers
package source
import (
"fmt"
@ -7,7 +7,7 @@ import (
"github.com/anchore/stereoscope/pkg/image"
)
// ImageSquashResolver implements path and content access for the Squashed scope option for container image data sources.
// ImageSquashResolver implements path and content access for the Squashed source option for container image data sources.
type ImageSquashResolver struct {
img *image.Image
}

View file

@ -1,4 +1,4 @@
package resolvers
package source
import (
"testing"

View file

@ -1,11 +1,10 @@
package scope
package source
import (
"fmt"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/stereoscope/pkg/image"
"github.com/anchore/syft/syft/scope/resolvers"
)
// Resolver is an interface that encompasses how to get specific file references and file contents for a generic data source.
@ -32,13 +31,13 @@ type FileResolver interface {
RelativeFileByPath(reference file.Reference, path string) (*file.Reference, error)
}
// getImageResolver returns the appropriate resolve for a container image given the scope option
func getImageResolver(img *image.Image, option Option) (Resolver, error) {
// getImageResolver returns the appropriate resolve for a container image given the source option
func getImageResolver(img *image.Image, option Scope) (Resolver, error) {
switch option {
case SquashedScope:
return resolvers.NewImageSquashResolver(img)
return NewImageSquashResolver(img)
case AllLayersScope:
return resolvers.NewAllLayersResolver(img)
return NewAllLayersResolver(img)
default:
return nil, fmt.Errorf("bad option provided: %+v", option)
}

55
syft/source/scheme.go Normal file
View file

@ -0,0 +1,55 @@
package source
import (
"fmt"
"strings"
"github.com/anchore/stereoscope/pkg/image"
"github.com/mitchellh/go-homedir"
"github.com/spf13/afero"
)
type Scheme string
const (
UnknownScheme Scheme = "unknown-scheme"
DirectoryScheme Scheme = "directory-scheme"
ImageScheme Scheme = "image-scheme"
)
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 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)
}
if source == image.UnknownSource {
dirLocation, err := homedir.Expand(userInput)
if err != nil {
return UnknownScheme, "", fmt.Errorf("unable to expand potential directory path: %w", err)
}
fileMeta, err := fs.Stat(dirLocation)
if err != nil {
return UnknownScheme, "", nil
}
if fileMeta.IsDir() {
return DirectoryScheme, dirLocation, nil
}
return UnknownScheme, "", nil
}
return ImageScheme, imageSpec, nil
}

View file

@ -1,14 +1,14 @@
package scope
package source
import "strings"
const (
UnknownScope Option = iota
UnknownScope Scope = iota
SquashedScope
AllLayersScope
)
type Option int
type Scope int
var optionStr = []string{
"UnknownScope",
@ -16,12 +16,12 @@ var optionStr = []string{
"AllLayers",
}
var Options = []Option{
var Options = []Scope{
SquashedScope,
AllLayersScope,
}
func ParseOption(userStr string) Option {
func ParseOption(userStr string) Scope {
switch strings.ToLower(userStr) {
case strings.ToLower(SquashedScope.String()):
return SquashedScope
@ -31,7 +31,7 @@ func ParseOption(userStr string) Option {
return UnknownScope
}
func (o Option) String() string {
func (o Scope) String() string {
if int(o) >= len(optionStr) || o < 0 {
return optionStr[0]
}

View file

@ -1,4 +1,4 @@
package scope
package source
import (
"fmt"
@ -6,12 +6,12 @@ import (
)
func TestOptionStringerBoundary(t *testing.T) {
var _ fmt.Stringer = Option(0)
var _ fmt.Stringer = Scope(0)
for _, c := range []int{-1, 0, 3} {
option := Option(c)
option := Scope(c)
if option.String() != UnknownScope.String() {
t.Errorf("expected Option(%d) to be unknown, found '%+v'", c, option)
t.Errorf("expected Scope(%d) to be unknown, found '%+v'", c, option)
}
}
}

117
syft/source/source.go Normal file
View file

@ -0,0 +1,117 @@
/*
Package source provides an abstraction to allow a user to loosely define a data source to catalog and expose a common interface that
catalogers and use explore and analyze data from the data source. All valid (cataloggable) data sources are defined
within this package.
*/
package source
import (
"fmt"
"github.com/spf13/afero"
"github.com/anchore/stereoscope"
"github.com/anchore/stereoscope/pkg/image"
)
// ImageSource represents a data source that is a container image
type ImageSource struct {
Img *image.Image // the image object to be cataloged
}
// DirSource represents a data source that is a filesystem directory tree
type DirSource struct {
Path string // the root path to be cataloged
}
// Source is an object that captures the data source to be cataloged, configuration, and a specific resolver used
// in cataloging (based on the data source and configuration)
type Source struct {
Scope Scope // specific perspective to catalog
Resolver Resolver // a Resolver object to use in file path/glob resolution and file contents resolution
Target interface{} // the specific source object to be cataloged
Scheme Scheme // the source data scheme type (directory or image)
}
type sourceDetector func(string) (image.Source, string, error)
// NewSource produces a Source based on userInput like dir: or image:tag
func NewSource(userInput string, o Scope) (Source, func(), error) {
fs := afero.NewOsFs()
parsedScheme, location, err := detectScheme(fs, image.DetectSource, userInput)
if err != nil {
return Source{}, func() {}, fmt.Errorf("unable to parse input=%q: %w", userInput, err)
}
switch parsedScheme {
case DirectoryScheme:
fileMeta, err := fs.Stat(location)
if err != nil {
return Source{}, func() {}, fmt.Errorf("unable to stat dir=%q: %w", location, err)
}
if !fileMeta.IsDir() {
return Source{}, func() {}, fmt.Errorf("given path is not a directory (path=%q): %w", location, err)
}
s, err := NewFromDirectory(location)
if err != nil {
return Source{}, func() {}, fmt.Errorf("could not populate source from path=%q: %w", location, err)
}
return s, func() {}, nil
case ImageScheme:
img, err := stereoscope.GetImage(location)
cleanup := func() {
stereoscope.Cleanup()
}
if err != nil || img == nil {
return Source{}, cleanup, fmt.Errorf("could not fetch image '%s': %w", location, err)
}
s, err := NewFromImage(img, o)
if err != nil {
return Source{}, cleanup, fmt.Errorf("could not populate source with image: %w", err)
}
return s, cleanup, nil
}
return Source{}, func() {}, fmt.Errorf("unable to process input for scanning: '%s'", userInput)
}
// NewFromDirectory creates a new source object tailored to catalog a given filesystem directory recursively.
func NewFromDirectory(path string) (Source, error) {
return Source{
Resolver: &DirectoryResolver{
Path: path,
},
Target: DirSource{
Path: path,
},
Scheme: DirectoryScheme,
}, nil
}
// NewFromImage creates a new source object tailored to catalog a given container image, relative to the
// option given (e.g. all-layers, squashed, etc)
func NewFromImage(img *image.Image, option Scope) (Source, error) {
if img == nil {
return Source{}, fmt.Errorf("no image given")
}
resolver, err := getImageResolver(img, option)
if err != nil {
return Source{}, fmt.Errorf("could not determine file resolver: %w", err)
}
return Source{
Scope: option,
Resolver: resolver,
Target: ImageSource{
Img: img,
},
Scheme: ImageScheme,
}, nil
}

View file

@ -1,4 +1,4 @@
package scope
package source
import (
"os"
@ -12,7 +12,7 @@ import (
func TestNewScopeFromImageFails(t *testing.T) {
t.Run("no image given", func(t *testing.T) {
_, err := NewScopeFromImage(nil, AllLayersScope)
_, err := NewFromImage(nil, AllLayersScope)
if err == nil {
t.Errorf("expected an error condition but none was given")
}
@ -23,7 +23,7 @@ func TestNewScopeFromImageUnknownOption(t *testing.T) {
img := image.Image{}
t.Run("unknown option is an error", func(t *testing.T) {
_, err := NewScopeFromImage(&img, UnknownScope)
_, err := NewFromImage(&img, UnknownScope)
if err == nil {
t.Errorf("expected an error condition but none was given")
}
@ -36,10 +36,10 @@ func TestNewScopeFromImage(t *testing.T) {
Layers: []*image.Layer{layer},
}
t.Run("create a new Scope object from image", func(t *testing.T) {
_, err := NewScopeFromImage(&img, AllLayersScope)
t.Run("create a new Source object from image", func(t *testing.T) {
_, err := NewFromImage(&img, AllLayersScope)
if err != nil {
t.Errorf("unexpected error when creating a new Scope from img: %w", err)
t.Errorf("unexpected error when creating a new Source from img: %w", err)
}
})
}
@ -79,13 +79,13 @@ func TestDirectoryScope(t *testing.T) {
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
p, err := NewScopeFromDir(test.input)
p, err := NewFromDirectory(test.input)
if err != nil {
t.Errorf("could not create NewDirScope: %w", err)
}
if p.Source.(DirSource).Path != test.input {
t.Errorf("mismatched stringer: '%s' != '%s'", p.Source.(DirSource).Path, test.input)
if p.Target.(DirSource).Path != test.input {
t.Errorf("mismatched stringer: '%s' != '%s'", p.Target.(DirSource).Path, test.input)
}
refs, err := p.Resolver.FilesByPath(test.inputPaths...)
@ -123,7 +123,7 @@ func TestMultipleFileContentsByRefContents(t *testing.T) {
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
p, err := NewScopeFromDir(test.input)
p, err := NewFromDirectory(test.input)
if err != nil {
t.Errorf("could not create NewDirScope: %w", err)
}
@ -163,7 +163,7 @@ func TestMultipleFileContentsByRefNoContents(t *testing.T) {
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
p, err := NewScopeFromDir(test.input)
p, err := NewFromDirectory(test.input)
if err != nil {
t.Errorf("could not create NewDirScope: %w", err)
}
@ -208,7 +208,7 @@ func TestFilesByGlob(t *testing.T) {
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
p, err := NewScopeFromDir(test.input)
p, err := NewFromDirectory(test.input)
if err != nil {
t.Errorf("could not create NewDirScope: %w", err)
}

View file

@ -6,7 +6,7 @@ import (
"github.com/anchore/stereoscope/pkg/imagetest"
"github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/go-test/deep"
)
@ -16,7 +16,7 @@ func TestDistroImage(t *testing.T) {
tarPath := imagetest.GetFixtureImageTarPath(t, fixtureImageName)
defer cleanup()
_, _, actualDistro, err := syft.Catalog("docker-archive:"+tarPath, scope.AllLayersScope)
_, _, actualDistro, err := syft.Catalog("docker-archive:"+tarPath, source.AllLayersScope)
if err != nil {
t.Fatalf("failed to catalog image: %+v", err)
}

View file

@ -8,7 +8,7 @@ import (
"github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/presenter/json"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/go-test/deep"
)
@ -31,7 +31,7 @@ func TestCatalogFromJSON(t *testing.T) {
tarPath := imagetest.GetFixtureImageTarPath(t, test.fixture)
defer cleanup()
expectedCatalog, s, expectedDistro, err := syft.Catalog("docker-archive:"+tarPath, scope.AllLayersScope)
expectedCatalog, s, expectedDistro, err := syft.Catalog("docker-archive:"+tarPath, source.AllLayersScope)
if err != nil {
t.Fatalf("failed to catalog image: %+v", err)
}

View file

@ -15,7 +15,7 @@ import (
"github.com/anchore/syft/syft/distro"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/presenter"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
"github.com/xeipuuv/gojsonschema"
)
@ -53,7 +53,7 @@ func validateAgainstV1Schema(t *testing.T, json string) {
}
}
func testJsonSchema(t *testing.T, catalog *pkg.Catalog, theScope *scope.Scope, prefix string) {
func testJsonSchema(t *testing.T, catalog *pkg.Catalog, theScope *source.Source, prefix string) {
// make the json output example dir if it does not exist
absJsonSchemaExamplesPath := path.Join(repoRoot(t), jsonSchemaExamplesPath)
if _, err := os.Stat(absJsonSchemaExamplesPath); os.IsNotExist(err) {
@ -101,7 +101,7 @@ func TestJsonSchemaImg(t *testing.T) {
tarPath := imagetest.GetFixtureImageTarPath(t, fixtureImageName)
defer cleanup()
catalog, theScope, _, err := syft.Catalog("docker-archive:"+tarPath, scope.AllLayersScope)
catalog, theScope, _, err := syft.Catalog("docker-archive:"+tarPath, source.AllLayersScope)
if err != nil {
t.Fatalf("failed to catalog image: %+v", err)
}
@ -118,9 +118,9 @@ func TestJsonSchemaImg(t *testing.T) {
}
func TestJsonSchemaDirs(t *testing.T) {
catalog, theScope, _, err := syft.Catalog("dir:test-fixtures/image-pkg-coverage", scope.AllLayersScope)
catalog, theScope, _, err := syft.Catalog("dir:test-fixtures/image-pkg-coverage", source.AllLayersScope)
if err != nil {
t.Errorf("unable to create scope from dir: %+v", err)
t.Errorf("unable to create source from dir: %+v", err)
}
var cases []testCase

View file

@ -9,7 +9,7 @@ import (
"github.com/anchore/syft/internal"
"github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
func TestPkgCoverageImage(t *testing.T) {
@ -18,7 +18,7 @@ func TestPkgCoverageImage(t *testing.T) {
tarPath := imagetest.GetFixtureImageTarPath(t, fixtureImageName)
defer cleanup()
catalog, _, _, err := syft.Catalog("docker-archive:"+tarPath, scope.AllLayersScope)
catalog, _, _, err := syft.Catalog("docker-archive:"+tarPath, source.AllLayersScope)
if err != nil {
t.Fatalf("failed to catalog image: %+v", err)
}
@ -100,10 +100,10 @@ func TestPkgCoverageImage(t *testing.T) {
}
func TestPkgCoverageDirectory(t *testing.T) {
catalog, _, _, err := syft.Catalog("dir:test-fixtures/image-pkg-coverage", scope.AllLayersScope)
catalog, _, _, err := syft.Catalog("dir:test-fixtures/image-pkg-coverage", source.AllLayersScope)
if err != nil {
t.Errorf("unable to create scope from dir: %+v", err)
t.Errorf("unable to create source from dir: %+v", err)
}
observedLanguages := internal.NewStringSet()

View file

@ -9,7 +9,7 @@ import (
"github.com/anchore/stereoscope/pkg/imagetest"
"github.com/anchore/syft/syft"
"github.com/anchore/syft/syft/scope"
"github.com/anchore/syft/syft/source"
)
func TestRegression212ApkBufferSize(t *testing.T) {
@ -21,7 +21,7 @@ func TestRegression212ApkBufferSize(t *testing.T) {
tarPath := imagetest.GetFixtureImageTarPath(t, fixtureImageName)
defer cleanup()
catalog, _, _, err := syft.Catalog("docker-archive:"+tarPath, scope.SquashedScope)
catalog, _, _, err := syft.Catalog("docker-archive:"+tarPath, source.SquashedScope)
if err != nil {
t.Fatalf("failed to catalog image: %+v", err)
}