mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
package cyclonedxhelpers
|
|
|
|
import (
|
|
"reflect"
|
|
|
|
"github.com/CycloneDX/cyclonedx-go"
|
|
|
|
"github.com/anchore/syft/internal/formats/common"
|
|
"github.com/anchore/syft/syft/pkg"
|
|
"github.com/anchore/syft/syft/source"
|
|
)
|
|
|
|
func encodeComponent(p pkg.Package) cyclonedx.Component {
|
|
props := encodeProperties(p, "syft:package")
|
|
props = append(props, encodeCPEs(p)...)
|
|
if len(p.Locations) > 0 {
|
|
props = append(props, encodeProperties(p.Locations, "syft:location")...)
|
|
}
|
|
if hasMetadata(p) {
|
|
props = append(props, encodeProperties(p.Metadata, "syft:metadata")...)
|
|
}
|
|
|
|
var properties *[]cyclonedx.Property
|
|
if len(props) > 0 {
|
|
properties = &props
|
|
}
|
|
|
|
return cyclonedx.Component{
|
|
Type: cyclonedx.ComponentTypeLibrary,
|
|
Name: p.Name,
|
|
Group: encodeGroup(p),
|
|
Version: p.Version,
|
|
PackageURL: p.PURL,
|
|
Licenses: encodeLicenses(p),
|
|
CPE: encodeSingleCPE(p),
|
|
Author: encodeAuthor(p),
|
|
Publisher: encodePublisher(p),
|
|
Description: encodeDescription(p),
|
|
ExternalReferences: encodeExternalReferences(p),
|
|
Properties: properties,
|
|
}
|
|
}
|
|
|
|
func hasMetadata(p pkg.Package) bool {
|
|
return p.Metadata != nil
|
|
}
|
|
|
|
func decodeComponent(c *cyclonedx.Component) *pkg.Package {
|
|
values := map[string]string{}
|
|
if c.Properties != nil {
|
|
for _, p := range *c.Properties {
|
|
values[p.Name] = p.Value
|
|
}
|
|
}
|
|
|
|
p := &pkg.Package{
|
|
Name: c.Name,
|
|
Version: c.Version,
|
|
Locations: decodeLocations(values),
|
|
Licenses: decodeLicenses(c),
|
|
CPEs: decodeCPEs(c),
|
|
PURL: c.PackageURL,
|
|
}
|
|
|
|
common.DecodeInto(p, values, "syft:package", CycloneDXFields)
|
|
|
|
p.Metadata = decodePackageMetadata(values, c, p.MetadataType)
|
|
|
|
if p.Type == "" {
|
|
p.Type = pkg.TypeFromPURL(p.PURL)
|
|
}
|
|
|
|
return p
|
|
}
|
|
|
|
func decodeLocations(vals map[string]string) []source.Location {
|
|
v := common.Decode(reflect.TypeOf([]source.Location{}), vals, "syft:location", CycloneDXFields)
|
|
out, _ := v.([]source.Location)
|
|
return out
|
|
}
|
|
|
|
func decodePackageMetadata(vals map[string]string, c *cyclonedx.Component, typ pkg.MetadataType) interface{} {
|
|
if typ != "" && c.Properties != nil {
|
|
metaTyp, ok := pkg.MetadataTypeByName[typ]
|
|
if !ok {
|
|
return nil
|
|
}
|
|
metaPtrTyp := reflect.PtrTo(metaTyp)
|
|
metaPtr := common.Decode(metaPtrTyp, vals, "syft:metadata", CycloneDXFields)
|
|
|
|
// Map all explicit metadata properties
|
|
decodeAuthor(c.Author, metaPtr)
|
|
decodeGroup(c.Group, metaPtr)
|
|
decodePublisher(c.Publisher, metaPtr)
|
|
decodeDescription(c.Description, metaPtr)
|
|
decodeExternalReferences(c, metaPtr)
|
|
|
|
// return the actual interface{} -> struct ... not interface{} -> *struct
|
|
return common.PtrToStruct(metaPtr)
|
|
}
|
|
|
|
return nil
|
|
}
|