Add SPDX support (#445)

* add initial spdx support

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* expose FileOwner and use in SPDX presenter

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add initial json support for SPDX

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add remaining package fields

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add spdx license list generation + tests

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* keep fileOwner unexported from pkg

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* restore cli test util

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add external refs to spdx tag-value format

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add golang support to CPE generation

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* use tag-value format as default "spdx" format flavor

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add tests around spdx presenters + refactor presenter tests

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* add bouncer exception for spdx tools-golang repo

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* remove spdx model questions

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman
2021-06-25 16:30:41 -04:00
committed by GitHub
parent 66e71c39e2
commit 706322f826
60 changed files with 4290 additions and 581 deletions
+4 -4
View File
@@ -60,18 +60,18 @@ func TestJSONSchema(t *testing.T) {
args = append(args, a)
}
_, stdout, _ := runSyftCommand(t, nil, args...)
_, stdout, stderr := runSyftCommand(t, nil, args...)
if len(strings.Trim(stdout, "\n ")) < 100 {
t.Fatalf("bad syft output: %q", stdout)
t.Fatalf("bad syft run:\noutput: %q\n:error: %q", stdout, stderr)
}
validateAgainstV1Schema(t, stdout)
validateJsonAgainstSchema(t, stdout)
})
}
}
func validateAgainstV1Schema(t testing.TB, json string) {
func validateJsonAgainstSchema(t testing.TB, json string) {
fullSchemaPath := path.Join(repoRoot(t), jsonSchemaPath, fmt.Sprintf("schema-%s.json", internal.JSONSchemaVersion))
schemaLoader := gojsonschema.NewReferenceLoader(fmt.Sprintf("file://%s", fullSchemaPath))
documentLoader := gojsonschema.NewStringLoader(json)
+90
View File
@@ -0,0 +1,90 @@
package cli
import (
"fmt"
"path"
"strings"
"testing"
"github.com/anchore/stereoscope/pkg/imagetest"
"github.com/xeipuuv/gojsonschema"
)
// this is the path to the json schema directory relative to the root of the repo
const spdxJsonSchemaPath = "schema/spdx-json"
func TestSPDXJSONSchema(t *testing.T) {
imageFixture := func(t *testing.T) string {
fixtureImageName := "image-pkg-coverage"
imagetest.GetFixtureImage(t, "docker-archive", fixtureImageName)
tarPath := imagetest.GetFixtureImageTarPath(t, fixtureImageName)
return "docker-archive:" + tarPath
}
tests := []struct {
name string
subcommand string
args []string
fixture func(*testing.T) string
}{
{
name: "packages:image:docker-archive:pkg-coverage",
subcommand: "packages",
args: []string{"-o", "spdx-json"},
fixture: imageFixture,
},
{
name: "power-user:image:docker-archive:pkg-coverage",
subcommand: "power-user",
fixture: imageFixture,
},
{
name: "packages:dir:pkg-coverage",
subcommand: "packages",
args: []string{"-o", "spdx-json"},
fixture: func(t *testing.T) string {
return "dir:test-fixtures/image-pkg-coverage"
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fixtureRef := test.fixture(t)
args := []string{
test.subcommand, fixtureRef, "-q",
}
for _, a := range test.args {
args = append(args, a)
}
_, stdout, _ := runSyftCommand(t, nil, args...)
if len(strings.Trim(stdout, "\n ")) < 100 {
t.Fatalf("bad syft output: %q", stdout)
}
validateSpdxJsonAgainstSchema(t, stdout)
})
}
}
func validateSpdxJsonAgainstSchema(t testing.TB, json string) {
fullSchemaPath := path.Join(repoRoot(t), spdxJsonSchemaPath, fmt.Sprintf("spdx-schema-2.2.json"))
schemaLoader := gojsonschema.NewReferenceLoader(fmt.Sprintf("file://%s", fullSchemaPath))
documentLoader := gojsonschema.NewStringLoader(json)
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
if err != nil {
t.Fatal("unable to validate json schema:", err.Error())
}
if !result.Valid() {
t.Errorf("failed json schema validation:")
t.Errorf("JSON:\n%s\n", json)
for _, desc := range result.Errors() {
t.Errorf(" - %s\n", desc)
}
}
}
+1
View File
@@ -59,6 +59,7 @@ func getSyftCommand(t testing.TB, args ...string) *exec.Cmd {
}
}
return exec.Command(binaryLocation, args...)
}