forked from anchore/syft
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce new format pattern + port json processing (anchore#550)
* add new format pattern Signed-off-by: Alex Goodman <[email protected]> * add syftjson format Signed-off-by: Alex Goodman <[email protected]> * add internal formats helper Signed-off-by: Alex Goodman <[email protected]> * add SBOM encode/decode to lib API Signed-off-by: Alex Goodman <[email protected]> * remove json presenter + update presenter tests to use common utils Signed-off-by: Alex Goodman <[email protected]> * remove presenter format enum type + add formats shim in presenter helper Signed-off-by: Alex Goodman <[email protected]> * add MustCPE helper for tests Signed-off-by: Alex Goodman <[email protected]> * update usage of format enum Signed-off-by: Alex Goodman <[email protected]> * add test fixtures for encode/decode tests Signed-off-by: Alex Goodman <[email protected]> * fix integration test Signed-off-by: Alex Goodman <[email protected]> * migrate format detection to use reader Signed-off-by: Alex Goodman <[email protected]> * address review comments Signed-off-by: Alex Goodman <[email protected]>
- Loading branch information
Showing
57 changed files
with
3,139 additions
and
421 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package formats | ||
|
||
import ( | ||
"bytes" | ||
|
||
"github.com/anchore/syft/internal/formats/syftjson" | ||
"github.com/anchore/syft/syft/format" | ||
) | ||
|
||
// TODO: eventually this is the source of truth for all formatters | ||
func All() []format.Format { | ||
return []format.Format{ | ||
syftjson.Format(), | ||
} | ||
} | ||
|
||
func Identify(by []byte) (*format.Format, error) { | ||
for _, f := range All() { | ||
if err := f.Validate(bytes.NewReader(by)); err != nil { | ||
continue | ||
} | ||
return &f, nil | ||
} | ||
return nil, nil | ||
} | ||
|
||
func ByOption(option format.Option) *format.Format { | ||
for _, f := range All() { | ||
if f.Option == option { | ||
return &f | ||
} | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package formats | ||
|
||
import ( | ||
"io" | ||
"os" | ||
"testing" | ||
|
||
"github.com/anchore/syft/syft/format" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestIdentify(t *testing.T) { | ||
tests := []struct { | ||
fixture string | ||
expected format.Option | ||
}{ | ||
{ | ||
fixture: "test-fixtures/alpine-syft.json", | ||
expected: format.JSONOption, | ||
}, | ||
} | ||
for _, test := range tests { | ||
t.Run(test.fixture, func(t *testing.T) { | ||
f, err := os.Open(test.fixture) | ||
assert.NoError(t, err) | ||
by, err := io.ReadAll(f) | ||
assert.NoError(t, err) | ||
frmt, err := Identify(by) | ||
assert.NoError(t, err) | ||
assert.NotNil(t, frmt) | ||
assert.Equal(t, test.expected, frmt.Option) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package syftjson | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
|
||
"github.com/anchore/syft/internal/formats/syftjson/model" | ||
"github.com/anchore/syft/syft/distro" | ||
"github.com/anchore/syft/syft/pkg" | ||
"github.com/anchore/syft/syft/source" | ||
) | ||
|
||
func decoder(reader io.Reader) (*pkg.Catalog, *source.Metadata, *distro.Distro, source.Scope, error) { | ||
dec := json.NewDecoder(reader) | ||
|
||
var doc model.Document | ||
err := dec.Decode(&doc) | ||
if err != nil { | ||
return nil, nil, nil, source.UnknownScope, fmt.Errorf("unable to decode syft-json: %w", err) | ||
} | ||
|
||
return toSyftModel(doc) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package syftjson | ||
|
||
import ( | ||
"bytes" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/anchore/syft/syft/source" | ||
|
||
"github.com/anchore/syft/internal/formats/common/testutils" | ||
"github.com/go-test/deep" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestEncodeDecodeCycle(t *testing.T) { | ||
testImage := "image-simple" | ||
originalCatalog, originalMetadata, _ := testutils.ImageInput(t, testImage) | ||
|
||
var buf bytes.Buffer | ||
assert.NoError(t, encoder(&buf, originalCatalog, &originalMetadata, nil, source.SquashedScope)) | ||
|
||
actualCatalog, actualMetadata, _, _, err := decoder(bytes.NewReader(buf.Bytes())) | ||
assert.NoError(t, err) | ||
|
||
for _, d := range deep.Equal(originalMetadata, *actualMetadata) { | ||
t.Errorf("metadata difference: %+v", d) | ||
} | ||
|
||
actualPackages := actualCatalog.Sorted() | ||
for idx, p := range originalCatalog.Sorted() { | ||
if !assert.Equal(t, p.Name, actualPackages[idx].Name) { | ||
t.Errorf("different package at idx=%d: %s vs %s", idx, p.Name, actualPackages[idx].Name) | ||
continue | ||
} | ||
|
||
// ids will never be equal | ||
p.ID = "" | ||
actualPackages[idx].ID = "" | ||
|
||
for _, d := range deep.Equal(*p, *actualPackages[idx]) { | ||
if strings.Contains(d, ".VirtualPath: ") { | ||
// location.Virtual path is not exposed in the json output | ||
continue | ||
} | ||
if strings.HasSuffix(d, "<nil slice> != []") { | ||
// semantically the same | ||
continue | ||
} | ||
t.Errorf("package difference (%s): %+v", p.Name, d) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package syftjson | ||
|
||
import ( | ||
"encoding/json" | ||
"io" | ||
|
||
"github.com/anchore/syft/syft/distro" | ||
|
||
"github.com/anchore/syft/syft/pkg" | ||
"github.com/anchore/syft/syft/source" | ||
) | ||
|
||
func encoder(output io.Writer, catalog *pkg.Catalog, srcMetadata *source.Metadata, d *distro.Distro, scope source.Scope) error { | ||
// TODO: application config not available yet | ||
doc := ToFormatModel(catalog, srcMetadata, d, scope, nil) | ||
|
||
enc := json.NewEncoder(output) | ||
// prevent > and < from being escaped in the payload | ||
enc.SetEscapeHTML(false) | ||
enc.SetIndent("", " ") | ||
|
||
return enc.Encode(&doc) | ||
} |
Oops, something went wrong.