mirror of
https://github.com/anchore/syft.git
synced 2026-11-02 23:46:35 +01:00
feat: update syft license concept to complex struct (#1743)
this PR makes the following changes to update the underlying license model to have more expressive capabilities it also provides some guarantee's surrounding the license values themselves - Licenses are updated from string -> pkg.LicenseSet which contain pkg.License with the following fields: - original `Value` read by syft - If it's possible to construct licenses will always have a valid SPDX expression for downstream consumption - the above is run against a generated list of SPDX license ID to try and find the correct ID - SPDX concluded vs declared is added to the new struct - URL source for license is added to the new struct - Location source is added to the new struct to show where the expression was pulled from
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
// package license provides common methods for working with SPDX license data
|
||||
package license
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/github/go-spdx/v2/spdxexp"
|
||||
|
||||
"github.com/anchore/syft/internal/spdxlicense"
|
||||
)
|
||||
|
||||
type Type string
|
||||
|
||||
const (
|
||||
Declared Type = "declared"
|
||||
Concluded Type = "concluded"
|
||||
)
|
||||
|
||||
func ParseExpression(expression string) (string, error) {
|
||||
licenseID, exists := spdxlicense.ID(expression)
|
||||
if exists {
|
||||
return licenseID, nil
|
||||
}
|
||||
|
||||
// If it doesn't exist initially in the SPDX list it might be a more complex expression
|
||||
// ignored variable is any invalid expressions
|
||||
// TODO: contribute to spdxexp to expose deprecated license IDs
|
||||
// https://github.com/anchore/syft/issues/1814
|
||||
valid, _ := spdxexp.ValidateLicenses([]string{expression})
|
||||
if !valid {
|
||||
return "", fmt.Errorf("failed to validate spdx expression: %s", expression)
|
||||
}
|
||||
|
||||
return expression, nil
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package license
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseExpression(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
expression string
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid single ID expression returns SPDX ID",
|
||||
expression: "mit",
|
||||
want: "MIT",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Valid SPDX expression returns SPDX expression",
|
||||
expression: "MIT OR Apache-2.0",
|
||||
want: "MIT OR Apache-2.0",
|
||||
},
|
||||
{
|
||||
name: "Invalid SPDX expression returns error",
|
||||
expression: "MIT OR Apache-2.0 OR invalid",
|
||||
want: "",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := ParseExpression(tt.expression)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ParseExpression() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("ParseExpression() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user