diff --git a/syft/pkg/cataloger/golang/package.go b/syft/pkg/cataloger/golang/package.go index d159fe4fc..90ce0aa3e 100644 --- a/syft/pkg/cataloger/golang/package.go +++ b/syft/pkg/cataloger/golang/package.go @@ -1,7 +1,6 @@ package golang import ( - "regexp" "runtime/debug" "strings" @@ -48,22 +47,27 @@ 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) + fields := strings.Split(moduleName, "/") 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 = "" - } + namespace := "" + name := "" // 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 + subpath := "" + + switch len(fields) { + case 1: + name = fields[0] + case 2: + name = fields[1] + namespace = fields[0] + default: + name = fields[2] + namespace = strings.Join(fields[0:2], "/") + subpath = strings.Join(fields[3:], "/") + } return packageurl.NewPackageURL( packageurl.TypeGolang, diff --git a/syft/pkg/cataloger/golang/package_test.go b/syft/pkg/cataloger/golang/package_test.go index d08d239a9..548e6eeeb 100644 --- a/syft/pkg/cataloger/golang/package_test.go +++ b/syft/pkg/cataloger/golang/package_test.go @@ -31,6 +31,21 @@ func Test_packageURL(t *testing.T) { }, expected: "pkg:golang/go.opencensus.io@v0.23.0", }, + { + name: "golang with subpath", + pkg: pkg.Package{ + Name: "github.com/coreos/go-systemd/v22", + Version: "v22.1.0", + }, + expected: "pkg:golang/github.com/coreos/go-systemd@v22.1.0#v22", + }, + { + name: "golang with subpath deep", + pkg: pkg.Package{ + Name: "google.golang.org/genproto/googleapis/api/annotations", + }, + expected: "pkg:golang/google.golang.org/genproto/googleapis#api/annotations", + }, } for _, test := range tests { diff --git a/syft/pkg/cataloger/golang/parse_go_binary_test.go b/syft/pkg/cataloger/golang/parse_go_binary_test.go index 58fb090c9..533d0f33a 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary_test.go +++ b/syft/pkg/cataloger/golang/parse_go_binary_test.go @@ -260,7 +260,7 @@ func TestBuildGoPkgInfo(t *testing.T) { { Name: "github.com/a/b/c", Version: "(devel)", - PURL: "pkg:golang/github.com/a/b/c@(devel)", + PURL: "pkg:golang/github.com/a/b@(devel)#c", Language: pkg.Go, Type: pkg.GoModulePkg, Locations: file.NewLocationSet(