feat: update syft license construction to be able to look up by URL (#4132)

---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
This commit is contained in:
Christopher Angelo Phillips
2025-08-12 14:30:32 -04:00
committed by GitHub
parent 104df88143
commit 89470ecdd3
10 changed files with 1446 additions and 15 deletions
@@ -62,6 +62,9 @@ func decodeLicenses(c *cyclonedx.Component) []pkg.License {
licenses = append(licenses, pkg.NewLicenseFromURLsWithContext(context.TODO(), l.License.ID, l.License.URL))
case l.License != nil && l.License.Name != "":
licenses = append(licenses, pkg.NewLicenseFromURLsWithContext(context.TODO(), l.License.Name, l.License.URL))
case l.License != nil && l.License.URL != "":
// Try to enrich license from URL when ID and Name are empty
licenses = append(licenses, pkg.NewLicenseFromURLsWithContext(context.TODO(), "", l.License.URL))
case l.Expression != "":
licenses = append(licenses, pkg.NewLicenseWithContext(context.TODO(), l.Expression))
default:
@@ -163,10 +166,18 @@ func processCustomLicense(l pkg.License) cyclonedx.Licenses {
func processLicenseURLs(l pkg.License, spdxID string, populate *cyclonedx.Licenses) {
for _, url := range l.URLs {
if spdxID == "" {
// CycloneDX requires either an id or name to be present for a license
// If l.Value is empty, use the URL as the name to ensure schema compliance
// at this point we've already tried to enrich the license we just don't want the format
// conversion to be lossy here
name := l.Value
if name == "" {
name = url
}
*populate = append(*populate, cyclonedx.LicenseChoice{
License: &cyclonedx.License{
URL: url,
Name: l.Value,
Name: name,
},
})
} else {
@@ -121,6 +121,22 @@ func Test_encodeLicense(t *testing.T) {
},
},
},
{
name: "with URL only and no name or SPDX ID",
input: pkg.Package{
Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromURLsWithContext(ctx, "", "http://jaxen.codehaus.org/license.html"),
),
},
expected: &cyclonedx.Licenses{
{
License: &cyclonedx.License{
Name: "http://jaxen.codehaus.org/license.html",
URL: "http://jaxen.codehaus.org/license.html",
},
},
},
},
{
name: "with multiple values licenses are deduplicated",
input: pkg.Package{