Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions syft/pkg/cataloger/cataloger.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func DirectoryCatalogers(cfg Config) []Cataloger {
dart.NewPubspecLockCataloger(),
dotnet.NewDotnetDepsCataloger(),
swift.NewCocoapodsCataloger(),
cpp.NewConanfileCataloger(),
cpp.NewConanCataloger(),
portage.NewPortageCataloger(),
haskell.NewHackageCataloger(),
}, cfg.Catalogers)
Expand Down Expand Up @@ -113,7 +113,7 @@ func AllCatalogers(cfg Config) []Cataloger {
php.NewPHPComposerInstalledCataloger(),
php.NewPHPComposerLockCataloger(),
swift.NewCocoapodsCataloger(),
cpp.NewConanfileCataloger(),
cpp.NewConanCataloger(),
portage.NewPortageCataloger(),
haskell.NewHackageCataloger(),
}, cfg.Catalogers)
Expand Down
15 changes: 7 additions & 8 deletions syft/pkg/cataloger/cpp/cataloger.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package cpp

import (
"github.com/anchore/syft/syft/pkg/cataloger/common"
"github.com/anchore/syft/syft/pkg/cataloger/generic"
)

// NewConanfileCataloger returns a new C++ Conanfile cataloger object.
func NewConanfileCataloger() *common.GenericCataloger {
globParsers := map[string]common.ParserFn{
"**/conanfile.txt": parseConanfile,
"**/conan.lock": parseConanlock,
}
const catalogerName = "conan-cataloger"

return common.NewGenericCataloger(nil, globParsers, "conan-cataloger")
// NewConanCataloger returns a new C++ conanfile.txt and conan.lock cataloger object.
func NewConanCataloger() *generic.Cataloger {
return generic.NewCataloger(catalogerName).
WithParserByGlobs(parseConanfile, "**/conanfile.txt").
WithParserByGlobs(parseConanlock, "**/conan.lock")
}
76 changes: 76 additions & 0 deletions syft/pkg/cataloger/cpp/package.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package cpp

import (
"strings"

"github.com/anchore/packageurl-go"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/source"
)

func newConanfilePackage(m pkg.ConanMetadata, locations ...source.Location) *pkg.Package {
fields := strings.Split(strings.TrimSpace(m.Ref), "/")
if len(fields) < 2 {
return nil
}

pkgName, pkgVersion := fields[0], fields[1]

if pkgName == "" || pkgVersion == "" {
return nil
}

p := pkg.Package{
Name: pkgName,
Version: pkgVersion,
Locations: source.NewLocationSet(locations...),
PURL: packageURL(pkgName, pkgVersion),
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanMetadataType,
Metadata: m,
}

p.SetID()

return &p
}

func newConanlockPackage(m pkg.ConanLockMetadata, locations ...source.Location) *pkg.Package {
fields := strings.Split(strings.Split(m.Ref, "@")[0], "/")
if len(fields) < 2 {
return nil
}

pkgName, pkgVersion := fields[0], fields[1]

if pkgName == "" || pkgVersion == "" {
return nil
}

p := pkg.Package{
Name: pkgName,
Version: pkgVersion,
Locations: source.NewLocationSet(locations...),
PURL: packageURL(pkgName, pkgVersion),
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanLockMetadataType,
Metadata: m,
}

p.SetID()

return &p
}

func packageURL(name, version string) string {
return packageurl.NewPackageURL(
packageurl.TypeConan,
"",
name,
version,
nil, // TODO: no qualifiers (...yet)
"",
).ToString()
}
26 changes: 11 additions & 15 deletions syft/pkg/cataloger/cpp/parse_conanfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ import (

"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 = parseConanfile
var _ generic.Parser = parseConanfile

type Conanfile struct {
Requires []string `toml:"requires"`
}

// parseConanfile is a parser function for conanfile.txt contents, returning all packages discovered.
func parseConanfile(_ string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) {
func parseConanfile(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
r := bufio.NewReader(reader)
inRequirements := false
pkgs := []*pkg.Package{}
var pkgs []pkg.Package
for {
line, err := r.ReadString('\n')
switch {
Expand All @@ -44,19 +44,15 @@ func parseConanfile(_ string, reader io.Reader) ([]*pkg.Package, []artifact.Rela
Ref: strings.Trim(line, "\n"),
}

pkgName, pkgVersion := m.NameAndVersion()
if !inRequirements {
continue
}

if pkgName == "" || pkgVersion == "" || !inRequirements {
p := newConanfilePackage(m, reader.Location)
if p == nil {
continue
}

pkgs = append(pkgs, &pkg.Package{
Name: pkgName,
Version: pkgVersion,
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanMetadataType,
Metadata: m,
})
pkgs = append(pkgs, *p)
}
}
23 changes: 15 additions & 8 deletions syft/pkg/cataloger/cpp/parse_conanfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import (
"testing"

"github.com/go-test/deep"
"github.com/stretchr/testify/require"

"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/source"
)

func TestParseConanfile(t *testing.T) {
expected := []*pkg.Package{
expected := []pkg.Package{
{
Name: "catch2",
Version: "2.13.8",
PURL: "pkg:conan/catch2@2.13.8",
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanMetadataType,
Expand All @@ -24,6 +27,7 @@ func TestParseConanfile(t *testing.T) {
{
Name: "docopt.cpp",
Version: "0.6.3",
PURL: "pkg:conan/docopt.cpp@0.6.3",
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanMetadataType,
Expand All @@ -34,6 +38,7 @@ func TestParseConanfile(t *testing.T) {
{
Name: "fmt",
Version: "8.1.1",
PURL: "pkg:conan/fmt@8.1.1",
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanMetadataType,
Expand All @@ -44,6 +49,7 @@ func TestParseConanfile(t *testing.T) {
{
Name: "spdlog",
Version: "1.9.2",
PURL: "pkg:conan/spdlog@1.9.2",
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanMetadataType,
Expand All @@ -54,6 +60,7 @@ func TestParseConanfile(t *testing.T) {
{
Name: "sdl",
Version: "2.0.20",
PURL: "pkg:conan/sdl@2.0.20",
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanMetadataType,
Expand All @@ -64,6 +71,7 @@ func TestParseConanfile(t *testing.T) {
{
Name: "fltk",
Version: "1.3.8",
PURL: "pkg:conan/fltk@1.3.8",
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanMetadataType,
Expand All @@ -74,15 +82,14 @@ func TestParseConanfile(t *testing.T) {
}

fixture, err := os.Open("test-fixtures/conanfile.txt")
if err != nil {
t.Fatalf("failed to open fixture: %+v", err)
}
require.NoError(t, err)

// TODO: no relationships are under test yet
actual, _, err := parseConanfile(fixture.Name(), fixture)
if err != nil {
t.Error(err)
}
actual, _, err := parseConanfile(nil, nil, source.LocationReadCloser{
Location: source.NewLocation(fixture.Name()),
ReadCloser: fixture,
})
require.NoError(t, err)

differences := deep.Equal(expected, actual)
if differences != nil {
Expand Down
27 changes: 9 additions & 18 deletions syft/pkg/cataloger/cpp/parse_conanlock.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,15 @@ package cpp

import (
"encoding/json"
"io"
"strings"

"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 = parseConanlock
var _ generic.Parser = parseConanlock

type conanLock struct {
GraphLock struct {
Expand All @@ -31,8 +30,8 @@ type conanLock struct {
}

// parseConanlock is a parser function for conan.lock contents, returning all packages discovered.
func parseConanlock(_ string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) {
pkgs := []*pkg.Package{}
func parseConanlock(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
var pkgs []pkg.Package
var cl conanLock
if err := json.NewDecoder(reader).Decode(&cl); err != nil {
return nil, nil, err
Expand All @@ -45,19 +44,11 @@ func parseConanlock(_ string, reader io.Reader) ([]*pkg.Package, []artifact.Rela
Context: node.Context,
}

pkgName, pkgVersion := metadata.NameAndVersion()
if pkgName == "" || pkgVersion == "" {
continue
}
p := newConanlockPackage(metadata, reader.Location)

pkgs = append(pkgs, &pkg.Package{
Name: pkgName,
Version: pkgVersion,
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanLockMetadataType,
Metadata: metadata,
})
if p != nil {
pkgs = append(pkgs, *p)
}
}

return pkgs, nil, nil
Expand Down
18 changes: 10 additions & 8 deletions syft/pkg/cataloger/cpp/parse_conanlock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import (
"testing"

"github.com/go-test/deep"
"github.com/stretchr/testify/require"

"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/source"
)

func TestParseConanlock(t *testing.T) {
expected := []*pkg.Package{
expected := []pkg.Package{
{
Name: "zlib",
Version: "1.2.12",
PURL: "pkg:conan/zlib@1.2.12",
Language: pkg.CPP,
Type: pkg.ConanPkg,
MetadataType: pkg.ConanLockMetadataType,
Expand All @@ -30,15 +33,14 @@ func TestParseConanlock(t *testing.T) {
}

fixture, err := os.Open("test-fixtures/conan.lock")
if err != nil {
t.Fatalf("failed to open fixture: %+v", err)
}
require.NoError(t, err)

// TODO: no relationships are under test yet
actual, _, err := parseConanlock(fixture.Name(), fixture)
if err != nil {
t.Error(err)
}
actual, _, err := parseConanlock(nil, nil, source.LocationReadCloser{
Location: source.NewLocation(fixture.Name()),
ReadCloser: fixture,
})
require.NoError(t, err)

differences := deep.Equal(expected, actual)
if differences != nil {
Expand Down
39 changes: 0 additions & 39 deletions syft/pkg/conan_metadata.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,5 @@
package pkg

import (
"strings"

"github.com/anchore/packageurl-go"
"github.com/anchore/syft/syft/linux"
)

type ConanMetadata struct {
Ref string `mapstructure:"ref" json:"ref"`
}

func (m ConanMetadata) PackageURL(_ *linux.Release) string {
var qualifiers packageurl.Qualifiers

name, version := m.NameAndVersion()

return packageurl.NewPackageURL(
packageurl.TypeConan,
"",
name,
version,
qualifiers,
"",
).ToString()
}

// NameAndVersion tries to return the name and version of a cpp package
// given the ref format: pkg/version
// it returns empty strings if ref is empty or parsing is unsuccessful
func (m ConanMetadata) NameAndVersion() (name, version string) {
if len(m.Ref) < 1 {
return name, version
}

splits := strings.Split(strings.TrimSpace(m.Ref), "/")

if len(splits) < 2 {
return name, version
}

return splits[0], splits[1]
}
Loading