mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 08:53:15 +01:00
port dart cataloger to new generic cataloger pattern (#1285)
Signed-off-by: Alex Goodman <alex.goodman@anchore.com> Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
eb8ebd9ffc
commit
fbdde6d4f4
@ -1,14 +1,13 @@
|
||||
package dart
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/common"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
)
|
||||
|
||||
// NewPubspecLockCataloger returns a new Dartlang cataloger object base on pubspec lock files.
|
||||
func NewPubspecLockCataloger() *common.GenericCataloger {
|
||||
globParsers := map[string]common.ParserFn{
|
||||
"**/pubspec.lock": parsePubspecLock,
|
||||
}
|
||||
const catalogerName = "dartlang-lock-cataloger"
|
||||
|
||||
return common.NewGenericCataloger(nil, globParsers, "dartlang-lock-cataloger")
|
||||
// NewPubspecLockCataloger returns a new Dartlang cataloger object base on pubspec lock files.
|
||||
func NewPubspecLockCataloger() *generic.Cataloger {
|
||||
return generic.NewCataloger(catalogerName).
|
||||
WithParserByGlobs(parsePubspecLock, "**/pubspec.lock")
|
||||
}
|
||||
|
||||
56
syft/pkg/cataloger/dart/package.go
Normal file
56
syft/pkg/cataloger/dart/package.go
Normal file
@ -0,0 +1,56 @@
|
||||
package dart
|
||||
|
||||
import (
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
func newPubspecLockPackage(name string, raw pubspecLockPackage, locations ...source.Location) pkg.Package {
|
||||
metadata := pkg.DartPubMetadata{
|
||||
Name: name,
|
||||
Version: raw.Version,
|
||||
HostedURL: raw.getHostedURL(),
|
||||
VcsURL: raw.getVcsURL(),
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: raw.Version,
|
||||
Locations: source.NewLocationSet(locations...),
|
||||
PURL: packageURL(metadata),
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
MetadataType: pkg.DartPubMetadataType,
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func packageURL(m pkg.DartPubMetadata) string {
|
||||
var qualifiers packageurl.Qualifiers
|
||||
|
||||
if m.HostedURL != "" {
|
||||
qualifiers = append(qualifiers, packageurl.Qualifier{
|
||||
Key: "hosted_url",
|
||||
Value: m.HostedURL,
|
||||
})
|
||||
} else if m.VcsURL != "" { // Default to using Hosted if somehow both are provided
|
||||
qualifiers = append(qualifiers, packageurl.Qualifier{
|
||||
Key: "vcs_url",
|
||||
Value: m.VcsURL,
|
||||
})
|
||||
}
|
||||
|
||||
return packageurl.NewPackageURL(
|
||||
packageurl.TypePub,
|
||||
"",
|
||||
m.Name,
|
||||
m.Version,
|
||||
qualifiers,
|
||||
"",
|
||||
).ToString()
|
||||
}
|
||||
@ -2,19 +2,19 @@ package dart
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"sort"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/common"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
// integrity check
|
||||
var _ common.ParserFn = parsePubspecLock
|
||||
var _ generic.Parser = parsePubspecLock
|
||||
|
||||
const defaultPubRegistry string = "https://pub.dartlang.org"
|
||||
|
||||
@ -38,8 +38,8 @@ type pubspecLockDescription struct {
|
||||
ResolvedRef string `yaml:"resolved-ref" mapstructure:"resolved-ref"`
|
||||
}
|
||||
|
||||
func parsePubspecLock(path string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) {
|
||||
var packages []*pkg.Package
|
||||
func parsePubspecLock(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
var pkgs []pkg.Package
|
||||
|
||||
dec := yaml.NewDecoder(reader)
|
||||
|
||||
@ -48,27 +48,20 @@ func parsePubspecLock(path string, reader io.Reader) ([]*pkg.Package, []artifact
|
||||
return nil, nil, fmt.Errorf("failed to parse pubspec.lock file: %w", err)
|
||||
}
|
||||
|
||||
for name, pubPkg := range p.Packages {
|
||||
packages = append(packages, newPubspecLockPackage(name, pubPkg))
|
||||
var names []string
|
||||
for name := range p.Packages {
|
||||
names = append(names, name)
|
||||
}
|
||||
|
||||
return packages, nil, nil
|
||||
// always ensure there is a stable ordering of packages
|
||||
sort.Strings(names)
|
||||
|
||||
for _, name := range names {
|
||||
pubPkg := p.Packages[name]
|
||||
pkgs = append(pkgs, newPubspecLockPackage(name, pubPkg, reader.Location))
|
||||
}
|
||||
|
||||
func newPubspecLockPackage(name string, p pubspecLockPackage) *pkg.Package {
|
||||
return &pkg.Package{
|
||||
Name: name,
|
||||
Version: p.Version,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
MetadataType: pkg.DartPubMetadataType,
|
||||
Metadata: &pkg.DartPubMetadata{
|
||||
Name: name,
|
||||
Version: p.Version,
|
||||
HostedURL: p.getHostedURL(),
|
||||
VcsURL: p.getVcsURL(),
|
||||
},
|
||||
}
|
||||
return pkgs, nil, nil
|
||||
}
|
||||
|
||||
func (p *pubspecLockPackage) getVcsURL() string {
|
||||
|
||||
@ -4,20 +4,19 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/go-test/deep"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
func assertPackagesEqual(t *testing.T, actual []*pkg.Package, expected map[string]*pkg.Package) {
|
||||
assert.Len(t, actual, len(expected))
|
||||
}
|
||||
|
||||
func TestParsePubspecLock(t *testing.T) {
|
||||
expected := map[string]*pkg.Package{
|
||||
"ale": {
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "ale",
|
||||
Version: "3.3.0",
|
||||
PURL: "pkg:pub/ale@3.3.0?hosted_url=pub.hosted.org",
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
MetadataType: pkg.DartPubMetadataType,
|
||||
@ -27,9 +26,10 @@ func TestParsePubspecLock(t *testing.T) {
|
||||
HostedURL: "pub.hosted.org",
|
||||
},
|
||||
},
|
||||
"analyzer": {
|
||||
{
|
||||
Name: "analyzer",
|
||||
Version: "0.40.7",
|
||||
PURL: "pkg:pub/analyzer@0.40.7",
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
MetadataType: pkg.DartPubMetadataType,
|
||||
@ -38,9 +38,10 @@ func TestParsePubspecLock(t *testing.T) {
|
||||
Version: "0.40.7",
|
||||
},
|
||||
},
|
||||
"ansicolor": {
|
||||
{
|
||||
Name: "ansicolor",
|
||||
Version: "1.1.1",
|
||||
PURL: "pkg:pub/ansicolor@1.1.1",
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
MetadataType: pkg.DartPubMetadataType,
|
||||
@ -49,9 +50,10 @@ func TestParsePubspecLock(t *testing.T) {
|
||||
Version: "1.1.1",
|
||||
},
|
||||
},
|
||||
"archive": {
|
||||
{
|
||||
Name: "archive",
|
||||
Version: "2.0.13",
|
||||
PURL: "pkg:pub/archive@2.0.13",
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
MetadataType: pkg.DartPubMetadataType,
|
||||
@ -60,9 +62,10 @@ func TestParsePubspecLock(t *testing.T) {
|
||||
Version: "2.0.13",
|
||||
},
|
||||
},
|
||||
"args": {
|
||||
{
|
||||
Name: "args",
|
||||
Version: "1.6.0",
|
||||
PURL: "pkg:pub/args@1.6.0",
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
MetadataType: pkg.DartPubMetadataType,
|
||||
@ -71,29 +74,33 @@ func TestParsePubspecLock(t *testing.T) {
|
||||
Version: "1.6.0",
|
||||
},
|
||||
},
|
||||
"key_binder": {
|
||||
{
|
||||
Name: "key_binder",
|
||||
Version: "1.11.20",
|
||||
PURL: "pkg:pub/key_binder@1.11.20?vcs_url=git%40github.com:Workiva/key_binder.git%403f7b3a6350e73c7dcac45301c0e18fbd42af02f7",
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
MetadataType: pkg.DartPubMetadataType,
|
||||
Metadata: pkg.DartPubMetadata{
|
||||
Name: "key_binder",
|
||||
Version: "1.11.20",
|
||||
VcsURL: "git@github.com:Workiva/key_binder.git#3f7b3a6350e73c7dcac45301c0e18fbd42af02f7",
|
||||
VcsURL: "git@github.com:Workiva/key_binder.git@3f7b3a6350e73c7dcac45301c0e18fbd42af02f7",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
fixture, err := os.Open("test-fixtures/pubspec.lock")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open fixture: %+v", err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
actual, _, err := parsePubspecLock(fixture.Name(), fixture)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse pubspec.lock: %+v", err)
|
||||
}
|
||||
// TODO: no relationships are under test yet
|
||||
actual, _, err := parsePubspecLock(nil, nil, source.LocationReadCloser{
|
||||
Location: source.NewLocation(fixture.Name()),
|
||||
ReadCloser: fixture,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assertPackagesEqual(t, actual, expected)
|
||||
differences := deep.Equal(expected, actual)
|
||||
if differences != nil {
|
||||
t.Errorf("returned package list differed from expectation: %+v", differences)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,38 +1,8 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/syft/linux"
|
||||
)
|
||||
|
||||
type DartPubMetadata struct {
|
||||
Name string `mapstructure:"name" json:"name"`
|
||||
Version string `mapstructure:"version" json:"version"`
|
||||
HostedURL string `mapstructure:"hosted_url" json:"hosted_url,omitempty"`
|
||||
VcsURL string `mapstructure:"vcs_url" json:"vcs_url,omitempty"`
|
||||
}
|
||||
|
||||
func (m DartPubMetadata) PackageURL(_ *linux.Release) string {
|
||||
var qualifiers packageurl.Qualifiers
|
||||
|
||||
if m.HostedURL != "" {
|
||||
qualifiers = append(qualifiers, packageurl.Qualifier{
|
||||
Key: "hosted_url",
|
||||
Value: m.HostedURL,
|
||||
})
|
||||
} else if m.VcsURL != "" { // Default to using Hosted if somehow both are provided
|
||||
qualifiers = append(qualifiers, packageurl.Qualifier{
|
||||
Key: "vcs_url",
|
||||
Value: m.VcsURL,
|
||||
})
|
||||
}
|
||||
|
||||
return packageurl.NewPackageURL(
|
||||
packageurl.TypePub,
|
||||
"",
|
||||
m.Name,
|
||||
m.Version,
|
||||
qualifiers,
|
||||
"",
|
||||
).ToString()
|
||||
}
|
||||
|
||||
@ -35,21 +35,6 @@ func TestPackageURL(t *testing.T) {
|
||||
},
|
||||
expected: "pkg:golang/go.opencensus.io@v0.23.0",
|
||||
},
|
||||
{
|
||||
name: "pub",
|
||||
pkg: Package{
|
||||
Name: "bad-name",
|
||||
Version: "0.1.0",
|
||||
Type: DartPubPkg,
|
||||
Metadata: DartPubMetadata{
|
||||
Name: "name",
|
||||
Version: "0.2.0",
|
||||
HostedURL: "pub.hosted.org",
|
||||
},
|
||||
},
|
||||
expected: "pkg:pub/name@0.2.0?hosted_url=pub.hosted.org",
|
||||
},
|
||||
|
||||
{
|
||||
name: "dotnet",
|
||||
pkg: Package{
|
||||
@ -225,6 +210,7 @@ func TestPackageURL(t *testing.T) {
|
||||
expectedTypes.Remove(string(AlpmPkg))
|
||||
expectedTypes.Remove(string(ApkPkg))
|
||||
expectedTypes.Remove(string(ConanPkg))
|
||||
expectedTypes.Remove(string(DartPubPkg))
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user