mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 08:53:15 +01:00
* add unique namespace identifier Signed-off-by: Christopher Angelo Phillips <christopher.phillips@anchore.com>
This commit is contained in:
parent
4b7217f052
commit
f47a6a88b1
@ -4,6 +4,8 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/anchore/syft/internal"
|
"github.com/anchore/syft/internal"
|
||||||
@ -12,8 +14,11 @@ import (
|
|||||||
"github.com/anchore/syft/internal/version"
|
"github.com/anchore/syft/internal/version"
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
"github.com/anchore/syft/syft/source"
|
"github.com/anchore/syft/syft/source"
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const anchoreNamespace = "https://anchore.com/syft"
|
||||||
|
|
||||||
// SPDXJsonPresenter is a SPDX presentation object for the syft results (see https://github.com/spdx/spdx-spec)
|
// SPDXJsonPresenter is a SPDX presentation object for the syft results (see https://github.com/spdx/spdx-spec)
|
||||||
type SPDXJsonPresenter struct {
|
type SPDXJsonPresenter struct {
|
||||||
catalog *pkg.Catalog
|
catalog *pkg.Catalog
|
||||||
@ -41,14 +46,25 @@ func (pres *SPDXJsonPresenter) Present(output io.Writer) error {
|
|||||||
|
|
||||||
// newSPDXJsonDocument creates and populates a new JSON document struct that follows the SPDX 2.2 spec from the given cataloging results.
|
// newSPDXJsonDocument creates and populates a new JSON document struct that follows the SPDX 2.2 spec from the given cataloging results.
|
||||||
func newSPDXJsonDocument(catalog *pkg.Catalog, srcMetadata source.Metadata) spdx22.Document {
|
func newSPDXJsonDocument(catalog *pkg.Catalog, srcMetadata source.Metadata) spdx22.Document {
|
||||||
var name string
|
uniqueID := uuid.Must(uuid.NewRandom())
|
||||||
|
|
||||||
|
var name, input, identifier string
|
||||||
switch srcMetadata.Scheme {
|
switch srcMetadata.Scheme {
|
||||||
case source.ImageScheme:
|
case source.ImageScheme:
|
||||||
name = srcMetadata.ImageMetadata.UserInput
|
name = cleanSPDXName(srcMetadata.ImageMetadata.UserInput)
|
||||||
|
input = "image"
|
||||||
case source.DirectoryScheme:
|
case source.DirectoryScheme:
|
||||||
name = srcMetadata.Path
|
name = cleanSPDXName(srcMetadata.Path)
|
||||||
|
input = "dir"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if name != "." {
|
||||||
|
identifier = path.Join(input, fmt.Sprintf("%s-%s", name, uniqueID.String()))
|
||||||
|
} else {
|
||||||
|
identifier = path.Join(input, uniqueID.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace := path.Join(anchoreNamespace, identifier)
|
||||||
packages, files, relationships := newSPDXJsonElements(catalog)
|
packages, files, relationships := newSPDXJsonElements(catalog)
|
||||||
|
|
||||||
return spdx22.Document{
|
return spdx22.Document{
|
||||||
@ -67,7 +83,7 @@ func newSPDXJsonDocument(catalog *pkg.Catalog, srcMetadata source.Metadata) spdx
|
|||||||
LicenseListVersion: spdxlicense.Version,
|
LicenseListVersion: spdxlicense.Version,
|
||||||
},
|
},
|
||||||
DataLicense: "CC0-1.0",
|
DataLicense: "CC0-1.0",
|
||||||
DocumentNamespace: fmt.Sprintf("https://anchore.com/syft/image/%s", srcMetadata.ImageMetadata.UserInput),
|
DocumentNamespace: namespace,
|
||||||
Packages: packages,
|
Packages: packages,
|
||||||
Files: files,
|
Files: files,
|
||||||
Relationships: relationships,
|
Relationships: relationships,
|
||||||
@ -113,3 +129,14 @@ func newSPDXJsonElements(catalog *pkg.Catalog) ([]spdx22.Package, []spdx22.File,
|
|||||||
|
|
||||||
return packages, files, relationships
|
return packages, files, relationships
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cleanSPDXName(name string) string {
|
||||||
|
// remove # according to specification
|
||||||
|
name = strings.Replace(name, "#", "-", -1)
|
||||||
|
|
||||||
|
// remove : for url construction
|
||||||
|
name = strings.Replace(name, ":", "-", -1)
|
||||||
|
|
||||||
|
// clean relative pathing
|
||||||
|
return path.Clean(name)
|
||||||
|
}
|
||||||
|
|||||||
@ -31,6 +31,10 @@ func TestSPDXJSONImagePresenter(t *testing.T) {
|
|||||||
func spdxJsonRedactor(s []byte) []byte {
|
func spdxJsonRedactor(s []byte) []byte {
|
||||||
// each SBOM reports the time it was generated, which is not useful during snapshot testing
|
// each SBOM reports the time it was generated, which is not useful during snapshot testing
|
||||||
s = regexp.MustCompile(`"created": .*`).ReplaceAll(s, []byte("redacted"))
|
s = regexp.MustCompile(`"created": .*`).ReplaceAll(s, []byte("redacted"))
|
||||||
|
|
||||||
|
// each SBOM reports a unique documentNamespace when generated, this is not useful for snapshot testing
|
||||||
|
s = regexp.MustCompile(`"documentNamespace": .*`).ReplaceAll(s, []byte("redacted"))
|
||||||
|
|
||||||
// the license list will be updated periodically, the value here should not be directly tested in snapshot tests
|
// the license list will be updated periodically, the value here should not be directly tested in snapshot tests
|
||||||
return regexp.MustCompile(`"licenseListVersion": .*`).ReplaceAll(s, []byte("redacted"))
|
return regexp.MustCompile(`"licenseListVersion": .*`).ReplaceAll(s, []byte("redacted"))
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user