feat: 3626 add option enable license content; disable by default (#3631)

---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
This commit is contained in:
Christopher Angelo Phillips
2025-02-05 20:41:03 +00:00
committed by GitHub
parent 7bab6e9851
commit e584c9f416
25 changed files with 436 additions and 98 deletions
+45
View File
@@ -0,0 +1,45 @@
package cli
import "testing"
func Test_Licenses(t *testing.T) {
testImage := getFixtureImage(t, "image-unknown-licenses")
tests := []struct {
name string
args []string
env map[string]string
assertions []traitAssertion
}{
{
name: "licenses default with no content",
args: []string{"scan", "-o", "json", testImage, "--from", "docker-archive"},
env: map[string]string{"SYFT_FORMAT_PRETTY": "true"},
assertions: []traitAssertion{
assertJsonReport,
assertUnknownLicenseContent(false),
assertSuccessfulReturnCode,
},
},
{
name: "licenses with content",
args: []string{"scan", "-o", "json", testImage, "--from", "docker-archive"},
env: map[string]string{"SYFT_FORMAT_PRETTY": "true", "SYFT_LICENSE_INCLUDE_UNKNOWN_LICENSE_CONTENT": "true"},
assertions: []traitAssertion{
assertJsonReport,
assertUnknownLicenseContent(true),
assertSuccessfulReturnCode,
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
cmd, stdout, stderr := runSyft(t, test.env, test.args...)
for _, traitFn := range test.assertions {
traitFn(t, stdout, stderr, cmd.ProcessState.ExitCode())
}
logOutputOnFailure(t, cmd, stdout, stderr)
})
}
}
@@ -0,0 +1,3 @@
FROM alpine@sha256:c5c5fda71656f28e49ac9c5416b3643eaa6a108a8093151d6d1afc9463be8e33
RUN rm -rf /lib/apk/db/installed
COPY . /home/files
+31
View File
@@ -10,7 +10,10 @@ import (
"testing"
"github.com/acarl005/stripansi"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anchore/syft/syft/format/syftjson/model"
)
type traitAssertion func(tb testing.TB, stdout, stderr string, rc int)
@@ -148,6 +151,34 @@ func assertPackageCount(length uint) traitAssertion {
}
}
func assertUnknownLicenseContent(required bool) traitAssertion {
return func(tb testing.TB, stdout, _ string, _ int) {
tb.Helper()
type NameAndLicense struct {
Name string `json:"name"`
Licenses []model.License `json:"Licenses"`
}
type partial struct {
Artifacts []NameAndLicense `json:"artifacts"`
}
var data partial
if err := json.Unmarshal([]byte(stdout), &data); err != nil {
tb.Errorf("expected to find a JSON report, but was unmarshalable: %+v", err)
}
for _, pkg := range data.Artifacts {
for _, lic := range pkg.Licenses {
if strings.Contains(lic.SPDXExpression, "UNKNOWN") && required {
assert.NotZero(tb, len(lic.Contents))
} else {
assert.Empty(tb, lic.Contents)
}
}
}
}
}
func assertFailingReturnCode(tb testing.TB, _, _ string, rc int) {
tb.Helper()
if rc == 0 {