forked from anchore/syft
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 <alex.goodman@anchore.com> * add syftjson format Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add internal formats helper Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add SBOM encode/decode to lib API Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * remove json presenter + update presenter tests to use common utils Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * remove presenter format enum type + add formats shim in presenter helper Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add MustCPE helper for tests Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * update usage of format enum Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * add test fixtures for encode/decode tests Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * fix integration test Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * migrate format detection to use reader Signed-off-by: Alex Goodman <alex.goodman@anchore.com> * address review comments Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
- 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.