port golang cataloger to new generic cataloger pattern (#1289)

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2022-10-25 12:42:50 -04:00 committed by GitHub
parent 52cb7269bf
commit 6826d7603b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 294 additions and 239 deletions

View file

@ -1,61 +0,0 @@
/*
Package golang provides a concrete Cataloger implementation for go.mod files.
*/
package golang
import (
"fmt"
"github.com/anchore/syft/internal"
"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/internal/unionreader"
"github.com/anchore/syft/syft/source"
)
const catalogerName = "go-module-binary-cataloger"
type Cataloger struct{}
// NewGoModuleBinaryCataloger returns a new Golang cataloger object.
func NewGoModuleBinaryCataloger() *Cataloger {
return &Cataloger{}
}
// Name returns a string that uniquely describes a cataloger
func (c *Cataloger) Name() string {
return catalogerName
}
// 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 source.FileResolver) ([]pkg.Package, []artifact.Relationship, error) {
var pkgs []pkg.Package
fileMatches, err := resolver.FilesByMIMEType(internal.ExecutableMIMETypeSet.List()...)
if err != nil {
return pkgs, nil, fmt.Errorf("failed to find bin by mime types: %w", err)
}
for _, location := range fileMatches {
readerCloser, err := resolver.FileContentsByLocation(location)
if err != nil {
log.Warnf("golang cataloger: opening file: %v", err)
continue
}
reader, err := unionreader.GetUnionReader(readerCloser)
if err != nil {
return nil, nil, err
}
mods, archs := scanFile(reader, location.RealPath)
internal.CloseAndLogError(readerCloser, location.RealPath)
for i, mod := range mods {
pkgs = append(pkgs, buildGoPkgInfo(location, mod, archs[i])...)
}
}
return pkgs, nil, nil
}

View file

@ -0,0 +1,21 @@
/*
Package golang provides a concrete Cataloger implementation for go.mod files.
*/
package golang
import (
"github.com/anchore/syft/internal"
"github.com/anchore/syft/syft/pkg/cataloger/generic"
)
// NewGoModFileCataloger returns a new Go module cataloger object.
func NewGoModFileCataloger() *generic.Cataloger {
return generic.NewCataloger("go-mod-file-cataloger").
WithParserByGlobs(parseGoModFile, "**/go.mod")
}
// NewGoModuleBinaryCataloger returns a new Golang cataloger object.
func NewGoModuleBinaryCataloger() *generic.Cataloger {
return generic.NewCataloger("go-module-binary-cataloger").
WithParserByMimeTypes(parseGoBinary, internal.ExecutableMIMETypeSet.List()...)
}

View file

@ -1,17 +0,0 @@
/*
Package golang provides a concrete Cataloger implementation for go.mod files.
*/
package golang
import (
"github.com/anchore/syft/syft/pkg/cataloger/common"
)
// NewGoModFileCataloger returns a new Go module cataloger object.
func NewGoModFileCataloger() *common.GenericCataloger {
globParsers := map[string]common.ParserFn{
"**/go.mod": parseGoMod,
}
return common.NewGenericCataloger(nil, globParsers, "go-mod-file-cataloger")
}

View file

@ -0,0 +1,69 @@
package golang
import (
"regexp"
"runtime/debug"
"strings"
"github.com/anchore/packageurl-go"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/source"
)
func newGoBinaryPackage(dep *debug.Module, mainModule, goVersion, architecture string, buildSettings map[string]string, locations ...source.Location) pkg.Package {
if dep.Replace != nil {
dep = dep.Replace
}
p := pkg.Package{
Name: dep.Path,
Version: dep.Version,
PURL: packageURL(dep.Path, dep.Version),
Language: pkg.Go,
Type: pkg.GoModulePkg,
Locations: source.NewLocationSet(locations...),
MetadataType: pkg.GolangBinMetadataType,
Metadata: pkg.GolangBinMetadata{
GoCompiledVersion: goVersion,
H1Digest: dep.Sum,
Architecture: architecture,
BuildSettings: buildSettings,
MainModule: mainModule,
},
}
p.SetID()
return p
}
func packageURL(moduleName, moduleVersion string) string {
// source: https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst#golang
// note: "The version is often empty when a commit is not specified and should be the commit in most cases when available."
re := regexp.MustCompile(`(/)[^/]*$`)
fields := re.Split(moduleName, -1)
if len(fields) == 0 {
return ""
}
namespace := fields[0]
name := strings.TrimPrefix(strings.TrimPrefix(moduleName, namespace), "/")
if name == "" {
// this is a "short" url (with no namespace)
name = namespace
namespace = ""
}
// The subpath is used to point to a subpath inside a package (e.g. pkg:golang/google.golang.org/genproto#googleapis/api/annotations)
subpath := "" // TODO: not implemented
return packageurl.NewPackageURL(
packageurl.TypeGolang,
namespace,
name,
moduleVersion,
nil,
subpath,
).ToString()
}

View file

@ -0,0 +1,41 @@
package golang
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/pkg"
)
func Test_packageURL(t *testing.T) {
tests := []struct {
name string
pkg pkg.Package
expected string
}{
{
name: "gocase",
pkg: pkg.Package{
Name: "github.com/anchore/syft",
Version: "v0.1.0",
},
expected: "pkg:golang/github.com/anchore/syft@v0.1.0",
},
{
name: "golang short name",
pkg: pkg.Package{
Name: "go.opencensus.io",
Version: "v0.23.0",
},
expected: "pkg:golang/go.opencensus.io@v0.23.0",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
assert.Equal(t, test.expected, packageURL(test.pkg.Name, test.pkg.Version))
})
}
}

View file

@ -14,9 +14,13 @@ import (
"golang.org/x/mod/module"
"github.com/anchore/syft/internal"
"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/generic"
"github.com/anchore/syft/syft/pkg/cataloger/golang/internal/xcoff"
"github.com/anchore/syft/syft/pkg/cataloger/internal/unionreader"
"github.com/anchore/syft/syft/source"
)
@ -34,9 +38,27 @@ var (
const devel = "(devel)"
// Catalog is given an object to resolve file references and content, this function returns any discovered Packages after analyzing rpm db installation.
func parseGoBinary(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
var pkgs []pkg.Package
unionReader, err := unionreader.GetUnionReader(reader.ReadCloser)
if err != nil {
return nil, nil, err
}
mods, archs := scanFile(unionReader, reader.RealPath)
internal.CloseAndLogError(reader.ReadCloser, reader.RealPath)
for i, mod := range mods {
pkgs = append(pkgs, buildGoPkgInfo(reader.Location, mod, archs[i])...)
}
return pkgs, nil, nil
}
func makeGoMainPackage(mod *debug.BuildInfo, arch string, location source.Location) pkg.Package {
gbs := getBuildSettings(mod.Settings)
main := newGoBinaryPackage(&mod.Main, mod.Main.Path, mod.GoVersion, arch, location, gbs)
main := newGoBinaryPackage(&mod.Main, mod.Main.Path, mod.GoVersion, arch, gbs, location)
if main.Version == devel {
if version, ok := gbs["vcs.revision"]; ok {
if timestamp, ok := gbs["vcs.time"]; ok {
@ -50,39 +72,14 @@ func makeGoMainPackage(mod *debug.BuildInfo, arch string, location source.Locati
version = module.PseudoVersion("", "", ts, version)
}
main.Version = version
main.PURL = packageURL(main.Name, main.Version)
main.SetID()
}
}
return main
}
func newGoBinaryPackage(dep *debug.Module, mainModule, goVersion, architecture string, location source.Location, buildSettings map[string]string) pkg.Package {
if dep.Replace != nil {
dep = dep.Replace
}
p := pkg.Package{
FoundBy: catalogerName,
Name: dep.Path,
Version: dep.Version,
Language: pkg.Go,
Type: pkg.GoModulePkg,
Locations: source.NewLocationSet(location),
MetadataType: pkg.GolangBinMetadataType,
Metadata: pkg.GolangBinMetadata{
GoCompiledVersion: goVersion,
H1Digest: dep.Sum,
Architecture: architecture,
BuildSettings: buildSettings,
MainModule: mainModule,
},
}
p.SetID()
return p
}
// getArchs finds a binary architecture by two ways:
// 1) reading build info from binaries compiled by go1.18+
// 2) reading file headers from binaries compiled by < go1.18
@ -192,7 +189,7 @@ func buildGoPkgInfo(location source.Location, mod *debug.BuildInfo, arch string)
if dep == nil {
continue
}
p := newGoBinaryPackage(dep, mod.Main.Path, mod.GoVersion, arch, location, nil)
p := newGoBinaryPackage(dep, mod.Main.Path, mod.GoVersion, arch, nil, location)
if pkg.IsValid(&p) {
pkgs = append(pkgs, p)
}

View file

@ -123,18 +123,18 @@ func TestBuildGoPkgInfo(t *testing.T) {
goCompiledVersion = "1.18"
archDetails = "amd64"
)
buildSettings := map[string]string{
defaultBuildSettings := map[string]string{
"GOARCH": "amd64",
"GOOS": "darwin",
"GOAMD64": "v1",
}
expectedMain := pkg.Package{
unmodifiedMain := pkg.Package{
Name: "github.com/anchore/syft",
FoundBy: catalogerName,
Language: pkg.Go,
Type: pkg.GoModulePkg,
Version: "(devel)",
PURL: "pkg:golang/github.com/anchore/syft@(devel)",
Locations: source.NewLocationSet(
source.Location{
Coordinates: source.Coordinates{
@ -147,7 +147,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
Metadata: pkg.GolangBinMetadata{
GoCompiledVersion: goCompiledVersion,
Architecture: archDetails,
BuildSettings: buildSettings,
BuildSettings: defaultBuildSettings,
MainModule: "github.com/anchore/syft",
},
}
@ -159,7 +159,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
expected []pkg.Package
}{
{
name: "buildGoPkgInfo parses a nil mod",
name: "parse an empty mod",
mod: nil,
expected: []pkg.Package(nil),
},
@ -179,7 +179,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
expected: []pkg.Package{
{
Name: "github.com/adrg/xdg",
FoundBy: catalogerName,
PURL: "pkg:golang/github.com/adrg/xdg",
Language: pkg.Go,
Type: pkg.GoModulePkg,
Locations: source.NewLocationSet(
@ -201,7 +201,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
expected: []pkg.Package(nil),
},
{
name: "buildGoPkgInfo parses a mod without main module",
name: "parse a mod without main module",
arch: archDetails,
mod: &debug.BuildInfo{
GoVersion: goCompiledVersion,
@ -221,8 +221,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
expected: []pkg.Package{
{
Name: "github.com/adrg/xdg",
FoundBy: catalogerName,
Version: "v0.2.1",
PURL: "pkg:golang/github.com/adrg/xdg@v0.2.1",
Language: pkg.Go,
Type: pkg.GoModulePkg,
Locations: source.NewLocationSet(
@ -243,7 +243,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
},
},
{
name: "buildGoPkgInfo parses a mod without packages",
name: "parse a mod without packages",
arch: archDetails,
mod: &debug.BuildInfo{
GoVersion: goCompiledVersion,
@ -254,10 +254,55 @@ func TestBuildGoPkgInfo(t *testing.T) {
{Key: "GOAMD64", Value: "v1"},
},
},
expected: []pkg.Package{expectedMain},
expected: []pkg.Package{unmodifiedMain},
},
{
name: "buildGoPkgInfo parses a populated mod string and returns packages but no source info",
name: "parse main mod and replace devel version",
arch: archDetails,
mod: &debug.BuildInfo{
GoVersion: goCompiledVersion,
Main: debug.Module{Path: "github.com/anchore/syft", Version: "(devel)"},
Settings: []debug.BuildSetting{
{Key: "GOARCH", Value: archDetails},
{Key: "GOOS", Value: "darwin"},
{Key: "GOAMD64", Value: "v1"},
{Key: "vcs.revision", Value: "41bc6bb410352845f22766e27dd48ba93aa825a4"},
{Key: "vcs.time", Value: "2022-10-14T19:54:57Z"},
},
},
expected: []pkg.Package{
{
Name: "github.com/anchore/syft",
Language: pkg.Go,
Type: pkg.GoModulePkg,
Version: "v0.0.0-20221014195457-41bc6bb41035",
PURL: "pkg:golang/github.com/anchore/syft@v0.0.0-20221014195457-41bc6bb41035",
Locations: source.NewLocationSet(
source.Location{
Coordinates: source.Coordinates{
RealPath: "/a-path",
FileSystemID: "layer-id",
},
},
),
MetadataType: pkg.GolangBinMetadataType,
Metadata: pkg.GolangBinMetadata{
GoCompiledVersion: goCompiledVersion,
Architecture: archDetails,
BuildSettings: map[string]string{
"GOARCH": archDetails,
"GOOS": "darwin",
"GOAMD64": "v1",
"vcs.revision": "41bc6bb410352845f22766e27dd48ba93aa825a4",
"vcs.time": "2022-10-14T19:54:57Z",
},
MainModule: "github.com/anchore/syft",
},
},
},
},
{
name: "parse a populated mod string and returns packages but no source info",
arch: archDetails,
mod: &debug.BuildInfo{
GoVersion: goCompiledVersion,
@ -283,8 +328,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
expected: []pkg.Package{
{
Name: "github.com/adrg/xdg",
FoundBy: catalogerName,
Version: "v0.2.1",
PURL: "pkg:golang/github.com/adrg/xdg@v0.2.1",
Language: pkg.Go,
Type: pkg.GoModulePkg,
Locations: source.NewLocationSet(
@ -305,8 +350,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
},
{
Name: "github.com/anchore/client-go",
FoundBy: catalogerName,
Version: "v0.0.0-20210222170800-9c70f9b80bcf",
PURL: "pkg:golang/github.com/anchore/client-go@v0.0.0-20210222170800-9c70f9b80bcf",
Language: pkg.Go,
Type: pkg.GoModulePkg,
Locations: source.NewLocationSet(
@ -325,11 +370,11 @@ func TestBuildGoPkgInfo(t *testing.T) {
MainModule: "github.com/anchore/syft",
},
},
expectedMain,
unmodifiedMain,
},
},
{
name: "buildGoPkgInfo parses a populated mod string and returns packages when a replace directive exists",
name: "parse a populated mod string and returns packages when a replace directive exists",
arch: archDetails,
mod: &debug.BuildInfo{
GoVersion: goCompiledVersion,
@ -360,8 +405,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
expected: []pkg.Package{
{
Name: "golang.org/x/sys",
FoundBy: catalogerName,
Version: "v0.0.0-20211006194710-c8a6f5223071",
PURL: "pkg:golang/golang.org/x/sys@v0.0.0-20211006194710-c8a6f5223071",
Language: pkg.Go,
Type: pkg.GoModulePkg,
Locations: source.NewLocationSet(
@ -381,8 +426,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
}},
{
Name: "golang.org/x/term",
FoundBy: catalogerName,
Version: "v0.0.0-20210916214954-140adaaadfaf",
PURL: "pkg:golang/golang.org/x/term@v0.0.0-20210916214954-140adaaadfaf",
Language: pkg.Go,
Type: pkg.GoModulePkg,
Locations: source.NewLocationSet(
@ -401,7 +446,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
MainModule: "github.com/anchore/syft",
},
},
expectedMain,
unmodifiedMain,
},
},
}

View file

@ -9,38 +9,44 @@ import (
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/generic"
"github.com/anchore/syft/syft/source"
)
// parseGoMod takes a go.mod and lists all packages discovered.
func parseGoMod(path string, reader io.Reader) ([]*pkg.Package, []artifact.Relationship, error) {
packages := make(map[string]*pkg.Package)
// parseGoModFile takes a go.mod and lists all packages discovered.
func parseGoModFile(_ source.FileResolver, _ *generic.Environment, reader source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
packages := make(map[string]pkg.Package)
contents, err := io.ReadAll(reader)
if err != nil {
return nil, nil, fmt.Errorf("failed to read go module: %w", err)
}
file, err := modfile.Parse(path, contents, nil)
file, err := modfile.Parse(reader.RealPath, contents, nil)
if err != nil {
return nil, nil, fmt.Errorf("failed to parse go module: %w", err)
}
for _, m := range file.Require {
packages[m.Mod.Path] = &pkg.Package{
Name: m.Mod.Path,
Version: m.Mod.Version,
Language: pkg.Go,
Type: pkg.GoModulePkg,
packages[m.Mod.Path] = pkg.Package{
Name: m.Mod.Path,
Version: m.Mod.Version,
Locations: source.NewLocationSet(reader.Location),
PURL: packageURL(m.Mod.Path, m.Mod.Version),
Language: pkg.Go,
Type: pkg.GoModulePkg,
}
}
// remove any old packages and replace with new ones...
for _, m := range file.Replace {
packages[m.New.Path] = &pkg.Package{
Name: m.New.Path,
Version: m.New.Version,
Language: pkg.Go,
Type: pkg.GoModulePkg,
packages[m.New.Path] = pkg.Package{
Name: m.New.Path,
Version: m.New.Version,
Locations: source.NewLocationSet(reader.Location),
PURL: packageURL(m.New.Path, m.New.Version),
Language: pkg.Go,
Type: pkg.GoModulePkg,
}
}
@ -49,9 +55,10 @@ func parseGoMod(path string, reader io.Reader) ([]*pkg.Package, []artifact.Relat
delete(packages, m.Mod.Path)
}
pkgsSlice := make([]*pkg.Package, len(packages))
pkgsSlice := make([]pkg.Package, len(packages))
idx := 0
for _, p := range packages {
p.SetID()
pkgsSlice[idx] = p
idx++
}

View file

@ -1,63 +1,74 @@
package golang
import (
"os"
"testing"
"github.com/go-test/deep"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
"github.com/anchore/syft/syft/source"
)
func TestParseGoMod(t *testing.T) {
tests := []struct {
fixture string
expected map[string]pkg.Package
expected []pkg.Package
}{
{
fixture: "test-fixtures/one-package",
expected: map[string]pkg.Package{
"github.com/bmatcuk/doublestar": {
Name: "github.com/bmatcuk/doublestar",
Version: "v1.3.1",
Language: pkg.Go,
Type: pkg.GoModulePkg,
expected: []pkg.Package{
{
Name: "github.com/bmatcuk/doublestar",
Version: "v1.3.1",
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v1.3.1",
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/one-package")),
Language: pkg.Go,
Type: pkg.GoModulePkg,
},
},
},
{
fixture: "test-fixtures/many-packages",
expected: map[string]pkg.Package{
"github.com/anchore/go-testutils": {
Name: "github.com/anchore/go-testutils",
Version: "v0.0.0-20200624184116-66aa578126db",
Language: pkg.Go,
Type: pkg.GoModulePkg,
expected: []pkg.Package{
{
Name: "github.com/anchore/go-testutils",
Version: "v0.0.0-20200624184116-66aa578126db",
PURL: "pkg:golang/github.com/anchore/go-testutils@v0.0.0-20200624184116-66aa578126db",
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go,
Type: pkg.GoModulePkg,
},
"github.com/anchore/go-version": {
Name: "github.com/anchore/go-version",
Version: "v1.2.2-0.20200701162849-18adb9c92b9b",
Language: pkg.Go,
Type: pkg.GoModulePkg,
{
Name: "github.com/anchore/go-version",
Version: "v1.2.2-0.20200701162849-18adb9c92b9b",
PURL: "pkg:golang/github.com/anchore/go-version@v1.2.2-0.20200701162849-18adb9c92b9b",
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go,
Type: pkg.GoModulePkg,
},
"github.com/anchore/stereoscope": {
Name: "github.com/anchore/stereoscope",
Version: "v0.0.0-20200706164556-7cf39d7f4639",
Language: pkg.Go,
Type: pkg.GoModulePkg,
{
Name: "github.com/anchore/stereoscope",
Version: "v0.0.0-20200706164556-7cf39d7f4639",
PURL: "pkg:golang/github.com/anchore/stereoscope@v0.0.0-20200706164556-7cf39d7f4639",
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go,
Type: pkg.GoModulePkg,
},
"github.com/bmatcuk/doublestar": {
Name: "github.com/bmatcuk/doublestar",
Version: "v8.8.8",
Language: pkg.Go,
Type: pkg.GoModulePkg,
{
Name: "github.com/bmatcuk/doublestar",
Version: "v8.8.8",
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v8.8.8",
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go,
Type: pkg.GoModulePkg,
},
"github.com/go-test/deep": {
Name: "github.com/go-test/deep",
Version: "v1.0.6",
Language: pkg.Go,
Type: pkg.GoModulePkg,
{
Name: "github.com/go-test/deep",
Version: "v1.0.6",
PURL: "pkg:golang/github.com/go-test/deep@v1.0.6",
Locations: source.NewLocationSet(source.NewLocation("test-fixtures/many-packages")),
Language: pkg.Go,
Type: pkg.GoModulePkg,
},
},
},
@ -65,43 +76,10 @@ func TestParseGoMod(t *testing.T) {
for _, test := range tests {
t.Run(test.fixture, func(t *testing.T) {
f, err := os.Open(test.fixture)
if err != nil {
t.Fatalf(err.Error())
}
// TODO: no relationships are under test yet
actual, _, err := parseGoMod(test.fixture, f)
if err != nil {
t.Fatalf(err.Error())
}
if len(actual) != len(test.expected) {
t.Fatalf("unexpected length: %d", len(actual))
}
for _, a := range actual {
e, ok := test.expected[a.Name]
if !ok {
t.Errorf("extra package: %s", a.Name)
continue
}
diffs := deep.Equal(a, &e)
if len(diffs) > 0 {
t.Errorf("diffs found for %q", a.Name)
for _, d := range diffs {
t.Errorf("diff: %+v", d)
}
}
}
if t.Failed() {
for _, a := range actual {
t.Logf("Found: %+v", a)
}
}
pkgtest.NewCatalogTester().
FromFile(t, test.fixture).
Expects(test.expected, nil).
TestParser(t, parseGoModFile)
})
}
}

View file

@ -1,7 +1,6 @@
package pkg
import (
"regexp"
"sort"
"strings"
@ -42,13 +41,6 @@ func URL(p Package, release *linux.Release) string {
switch {
case purlType == "":
purlType = packageurl.TypeGeneric
case p.Type == GoModulePkg:
re := regexp.MustCompile(`(/)[^/]*$`)
fields := re.Split(p.Name, -1)
if len(fields) > 1 {
namespace = fields[0]
name = strings.TrimPrefix(p.Name, namespace+"/")
}
case p.Type == NpmPkg:
fields := strings.SplitN(p.Name, "/", 2)
if len(fields) > 1 {

View file

@ -17,24 +17,6 @@ func TestPackageURL(t *testing.T) {
distro *linux.Release
expected string
}{
{
name: "golang",
pkg: Package{
Name: "github.com/anchore/syft",
Version: "v0.1.0",
Type: GoModulePkg,
},
expected: "pkg:golang/github.com/anchore/syft@v0.1.0",
},
{
name: "golang short name",
pkg: Package{
Name: "go.opencensus.io",
Version: "v0.23.0",
Type: GoModulePkg,
},
expected: "pkg:golang/go.opencensus.io@v0.23.0",
},
{
name: "python",
pkg: Package{
@ -182,6 +164,7 @@ func TestPackageURL(t *testing.T) {
expectedTypes.Remove(string(DartPubPkg))
expectedTypes.Remove(string(DotnetPkg))
expectedTypes.Remove(string(DebPkg))
expectedTypes.Remove(string(GoModulePkg))
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {