Skip to content

Commit bed9869

Browse files
erikvargacopybara-github
authored andcommitted
Move DPKG PURL generation into the PURL gen lib.
PiperOrigin-RevId: 760533539
1 parent 68fbc3b commit bed9869

File tree

9 files changed

+615
-303
lines changed

9 files changed

+615
-303
lines changed

binary/proto/proto.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import (
4242
"github.com/google/osv-scalibr/extractor/filesystem/misc/vscodeextensions"
4343
"github.com/google/osv-scalibr/extractor/filesystem/os/apk"
4444
"github.com/google/osv-scalibr/extractor/filesystem/os/cos"
45-
"github.com/google/osv-scalibr/extractor/filesystem/os/dpkg"
45+
dpkgmeta "github.com/google/osv-scalibr/extractor/filesystem/os/dpkg/metadata"
4646
"github.com/google/osv-scalibr/extractor/filesystem/os/flatpak"
4747
"github.com/google/osv-scalibr/extractor/filesystem/os/homebrew"
4848
"github.com/google/osv-scalibr/extractor/filesystem/os/kernel/module"
@@ -278,7 +278,7 @@ func setProtoMetadata(meta any, p *spb.Package) {
278278
License: m.License,
279279
},
280280
}
281-
case *dpkg.Metadata:
281+
case *dpkgmeta.Metadata:
282282
p.Metadata = &spb.Package_DpkgMetadata{
283283
DpkgMetadata: &spb.DPKGPackageMetadata{
284284
PackageName: m.PackageName,

binary/proto/proto_test.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import (
3838
"github.com/google/osv-scalibr/extractor/filesystem/language/python/requirements"
3939
"github.com/google/osv-scalibr/extractor/filesystem/language/python/wheelegg"
4040
"github.com/google/osv-scalibr/extractor/filesystem/os/dpkg"
41+
dpkgmeta "github.com/google/osv-scalibr/extractor/filesystem/os/dpkg/metadata"
4142
"github.com/google/osv-scalibr/extractor/filesystem/os/homebrew"
4243
"github.com/google/osv-scalibr/extractor/filesystem/os/nix"
4344
"github.com/google/osv-scalibr/extractor/filesystem/os/pacman"
@@ -168,9 +169,10 @@ func TestScanResultToProto(t *testing.T) {
168169
failure := &plugin.ScanStatus{Status: plugin.ScanStatusFailed, FailureReason: "failure"}
169170
failureProto := &spb.ScanStatus{Status: spb.ScanStatus_FAILED, FailureReason: "failure"}
170171
purlDPKGPackage := &extractor.Package{
171-
Name: "software",
172-
Version: "1.0.0",
173-
Metadata: &dpkg.Metadata{
172+
Name: "software",
173+
Version: "1.0.0",
174+
PURLType: purl.TypeDebian,
175+
Metadata: &dpkgmeta.Metadata{
174176
PackageName: "software",
175177
PackageVersion: "1.0.0",
176178
OSID: "debian",
@@ -182,9 +184,10 @@ func TestScanResultToProto(t *testing.T) {
182184
Extractor: dpkg.New(dpkg.DefaultConfig()),
183185
}
184186
purlDPKGAnnotationPackage := &extractor.Package{
185-
Name: "software",
186-
Version: "1.0.0",
187-
Metadata: &dpkg.Metadata{
187+
Name: "software",
188+
Version: "1.0.0",
189+
PURLType: purl.TypeDebian,
190+
Metadata: &dpkgmeta.Metadata{
188191
PackageName: "software",
189192
PackageVersion: "1.0.0",
190193
OSID: "debian",

extractor/convert.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
mavenpurl "github.com/google/osv-scalibr/extractor/filesystem/language/java/purl"
2121
npmpurl "github.com/google/osv-scalibr/extractor/filesystem/language/javascript/purl"
2222
"github.com/google/osv-scalibr/extractor/filesystem/language/python/pypipurl"
23+
ospurl "github.com/google/osv-scalibr/extractor/filesystem/os/purl"
2324
cdxmeta "github.com/google/osv-scalibr/extractor/filesystem/sbom/cdx/metadata"
2425
cdxpurl "github.com/google/osv-scalibr/extractor/filesystem/sbom/cdx/purl"
2526
spdxmeta "github.com/google/osv-scalibr/extractor/filesystem/sbom/spdx/metadata"
@@ -66,6 +67,8 @@ func typeSpecificPURL(p *Package) *purl.PackageURL {
6667
return gopurl.MakePackageURL(p.Name, p.Version)
6768
case purl.TypeHex:
6869
return hexpurl.MakePackageURL(p.Name, p.Version)
70+
case purl.TypeDebian, purl.TypeOpkg:
71+
return ospurl.MakePackageURL(p.Name, p.Version, p.PURLType, p.Metadata)
6972
case "windows":
7073
return winpurl.MakePackageURL(p.Name, p.Version, p.Metadata)
7174
}

extractor/convert_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/google/go-cmp/cmp"
2121
"github.com/google/osv-scalibr/extractor"
22+
dpkgmeta "github.com/google/osv-scalibr/extractor/filesystem/os/dpkg/metadata"
2223
cdxmeta "github.com/google/osv-scalibr/extractor/filesystem/sbom/cdx/metadata"
2324
spdxmeta "github.com/google/osv-scalibr/extractor/filesystem/sbom/spdx/metadata"
2425
"github.com/google/osv-scalibr/purl"
@@ -139,6 +140,50 @@ func TestToPURL(t *testing.T) {
139140
Version: "1.2.3",
140141
},
141142
},
143+
{
144+
name: "dpkg_purl",
145+
pkg: &extractor.Package{
146+
Name: "Name",
147+
Version: "1.2.3",
148+
PURLType: purl.TypeDebian,
149+
Metadata: &dpkgmeta.Metadata{
150+
PackageName: "pkg-name",
151+
OSVersionCodename: "jammy",
152+
},
153+
Locations: []string{"location"},
154+
},
155+
want: &purl.PackageURL{
156+
Type: purl.TypeDebian,
157+
Namespace: "linux",
158+
Name: "pkg-name",
159+
Version: "1.2.3",
160+
Qualifiers: purl.QualifiersFromMap(map[string]string{
161+
purl.Distro: "jammy",
162+
}),
163+
},
164+
},
165+
{
166+
name: "opkg_purl",
167+
pkg: &extractor.Package{
168+
Name: "Name",
169+
Version: "1.2.3",
170+
PURLType: purl.TypeOpkg,
171+
Metadata: &dpkgmeta.Metadata{
172+
PackageName: "pkg-name",
173+
OSVersionCodename: "jammy",
174+
},
175+
Locations: []string{"location"},
176+
},
177+
want: &purl.PackageURL{
178+
Type: purl.TypeOpkg,
179+
Namespace: "linux",
180+
Name: "pkg-name",
181+
Version: "1.2.3",
182+
Qualifiers: purl.QualifiersFromMap(map[string]string{
183+
purl.Distro: "jammy",
184+
}),
185+
},
186+
},
142187
}
143188

144189
for _, tt := range tests {

extractor/filesystem/os/dpkg/dpkg.go

Lines changed: 16 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/google/osv-scalibr/extractor"
2929
"github.com/google/osv-scalibr/extractor/filesystem"
3030
"github.com/google/osv-scalibr/extractor/filesystem/internal/units"
31+
dpkgmeta "github.com/google/osv-scalibr/extractor/filesystem/os/dpkg/metadata"
3132
"github.com/google/osv-scalibr/extractor/filesystem/os/osrelease"
3233
"github.com/google/osv-scalibr/inventory"
3334
"github.com/google/osv-scalibr/log"
@@ -239,10 +240,16 @@ func (e Extractor) extractFromInput(ctx context.Context, input *filesystem.ScanI
239240
annotations = append(annotations, extractor.Transitional)
240241
}
241242

243+
purlType := purl.TypeDebian
244+
if input.Path == "usr/lib/opkg/status" {
245+
purlType = purl.TypeOpkg
246+
}
247+
242248
p := &extractor.Package{
243-
Name: pkgName,
244-
Version: pkgVersion,
245-
Metadata: &Metadata{
249+
Name: pkgName,
250+
Version: pkgVersion,
251+
PURLType: purlType,
252+
Metadata: &dpkgmeta.Metadata{
246253
PackageName: pkgName,
247254
PackageVersion: pkgVersion,
248255
Status: h.Get("Status"),
@@ -260,8 +267,8 @@ func (e Extractor) extractFromInput(ctx context.Context, input *filesystem.ScanI
260267
return pkgs, fmt.Errorf("parseSourceNameVersion(%q): %w", h.Get("Source"), err)
261268
}
262269
if sourceName != "" {
263-
p.Metadata.(*Metadata).SourceName = sourceName
264-
p.Metadata.(*Metadata).SourceVersion = sourceVersion
270+
p.Metadata.(*dpkgmeta.Metadata).SourceName = sourceName
271+
p.Metadata.(*dpkgmeta.Metadata).SourceVersion = sourceVersion
265272
}
266273

267274
pkgs = append(pkgs, p)
@@ -296,75 +303,16 @@ func parseSourceNameVersion(source string) (string, string, error) {
296303
return source, "", nil
297304
}
298305

299-
func toNamespace(m *Metadata) string {
300-
if m.OSID != "" {
301-
return m.OSID
302-
}
303-
log.Errorf("os-release[ID] not set, fallback to 'linux'")
304-
// TODO(b/298152210): Implement metric
305-
return "linux"
306-
}
307-
308-
func toDistro(m *Metadata) string {
309-
// e.g. jammy
310-
if m.OSVersionCodename != "" {
311-
return m.OSVersionCodename
312-
}
313-
// fallback: e.g. 22.04
314-
if m.OSVersionID != "" {
315-
log.Warnf("VERSION_CODENAME not set in os-release, fallback to VERSION_ID")
316-
return m.OSVersionID
317-
}
318-
log.Errorf("VERSION_CODENAME and VERSION_ID not set in os-release")
319-
return ""
320-
}
321-
322306
// ToPURL converts a package created by this extractor into a PURL.
307+
// TODO(b/400910349): Remove and use Package.PURL() directly.
323308
func (e Extractor) ToPURL(p *extractor.Package) *purl.PackageURL {
324-
m := p.Metadata.(*Metadata)
325-
q := map[string]string{}
326-
distro := toDistro(m)
327-
if distro != "" {
328-
q[purl.Distro] = distro
329-
}
330-
if m.SourceName != "" {
331-
q[purl.Source] = m.SourceName
332-
}
333-
if m.SourceVersion != "" {
334-
q[purl.SourceVersion] = m.SourceVersion
335-
}
336-
if m.Architecture != "" {
337-
q[purl.Arch] = m.Architecture
338-
}
339-
340-
// Determine the package type (opkg or dpkg) based on file location
341-
typePurl := ""
342-
343-
for _, location := range p.Locations {
344-
if location == "usr/lib/opkg/status" {
345-
typePurl = purl.TypeOpkg
346-
break
347-
}
348-
}
349-
350-
// Default to dpkg if no specific file path matches
351-
if typePurl == "" {
352-
typePurl = purl.TypeDebian
353-
}
354-
355-
return &purl.PackageURL{
356-
Type: typePurl,
357-
Name: m.PackageName,
358-
Namespace: toNamespace(m),
359-
Version: p.Version,
360-
Qualifiers: purl.QualifiersFromMap(q),
361-
}
309+
return p.PURL()
362310
}
363311

364312
// Ecosystem returns the OSV Ecosystem of the software extracted by this extractor.
365313
func (Extractor) Ecosystem(p *extractor.Package) string {
366-
m := p.Metadata.(*Metadata)
367-
osID := cases.Title(language.English).String(toNamespace(m))
314+
m := p.Metadata.(*dpkgmeta.Metadata)
315+
osID := cases.Title(language.English).String(m.ToNamespace())
368316
if m.OSVersionID == "" {
369317
return osID
370318
}

0 commit comments

Comments
 (0)