mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
[CycloneDX] Add artifactID and groupID to the cycloneDX properties (support lower level struct as properties) (#758)
* [CycloneDX] Add artifactID and groupID to the cycloneDX properties Signed-off-by: Peter Balogh <p.balogh.sa@gmail.com> * update comment Signed-off-by: Peter Balogh <p.balogh.sa@gmail.com> * additional checks for value Signed-off-by: Peter Balogh <p.balogh.sa@gmail.com> * fill group filed with groupID in the case of Java Signed-off-by: Peter Balogh <p.balogh.sa@gmail.com> * fix linter warning Signed-off-by: Alex Goodman <alex.goodman@anchore.com> Co-authored-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
parent
6f0fad7ffd
commit
161fa7be4a
@ -9,6 +9,7 @@ func Component(p pkg.Package) cyclonedx.Component {
|
||||
return cyclonedx.Component{
|
||||
Type: cyclonedx.ComponentTypeLibrary,
|
||||
Name: p.Name,
|
||||
Group: Group(p),
|
||||
Version: p.Version,
|
||||
PackageURL: p.PURL,
|
||||
Licenses: Licenses(p),
|
||||
|
||||
12
internal/formats/common/cyclonedxhelpers/group.go
Normal file
12
internal/formats/common/cyclonedxhelpers/group.go
Normal file
@ -0,0 +1,12 @@
|
||||
package cyclonedxhelpers
|
||||
|
||||
import "github.com/anchore/syft/syft/pkg"
|
||||
|
||||
func Group(p pkg.Package) string {
|
||||
if hasMetadata(p) {
|
||||
if metadata, ok := p.Metadata.(pkg.JavaMetadata); ok && metadata.PomProperties != nil {
|
||||
return metadata.PomProperties.GroupID
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
52
internal/formats/common/cyclonedxhelpers/group_test.go
Normal file
52
internal/formats/common/cyclonedxhelpers/group_test.go
Normal file
@ -0,0 +1,52 @@
|
||||
package cyclonedxhelpers
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGroup(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input pkg.Package
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "no metadata",
|
||||
input: pkg.Package{},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "metadata is not Java",
|
||||
input: pkg.Package{
|
||||
Metadata: pkg.NpmPackageJSONMetadata{},
|
||||
},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "metadata is Java but pom properties is empty",
|
||||
input: pkg.Package{
|
||||
Metadata: pkg.JavaMetadata{},
|
||||
},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "metadata is Java and contains pomProperties",
|
||||
input: pkg.Package{
|
||||
Metadata: pkg.JavaMetadata{
|
||||
PomProperties: &pkg.PomProperties{
|
||||
GroupID: "test",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "test",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
assert.Equal(t, test.expected, Group(test.input))
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -28,17 +28,22 @@ func Properties(p pkg.Package) *[]cyclonedx.Property {
|
||||
func getCycloneDXProperties(m interface{}) *[]cyclonedx.Property {
|
||||
props := []cyclonedx.Property{}
|
||||
structValue := reflect.ValueOf(m)
|
||||
// we can only handle top level structs as interfaces for now
|
||||
if structValue.Kind() != reflect.Struct {
|
||||
return &props
|
||||
}
|
||||
structType := structValue.Type()
|
||||
for i := 0; i < structValue.NumField(); i++ {
|
||||
if name, value := getCycloneDXPropertyName(structType.Field(i)), getCycloneDXPropertyValue(structValue.Field(i)); name != "" && value != "" {
|
||||
props = append(props, cyclonedx.Property{
|
||||
Name: name,
|
||||
Value: value,
|
||||
})
|
||||
// In the case of the value is a struct and has cyclonedx tag with name "-"
|
||||
// call the getCycloneDXProperties recursively.
|
||||
if name == "-" && reflect.ValueOf(value).Kind() == reflect.Struct {
|
||||
props = append(props, *getCycloneDXProperties(value)...)
|
||||
} else if reflect.ValueOf(value).Kind() == reflect.String {
|
||||
props = append(props, cyclonedx.Property{
|
||||
Name: name,
|
||||
Value: fmt.Sprint(value),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return &props
|
||||
@ -51,7 +56,7 @@ func getCycloneDXPropertyName(field reflect.StructField) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func getCycloneDXPropertyValue(field reflect.Value) string {
|
||||
func getCycloneDXPropertyValue(field reflect.Value) interface{} {
|
||||
if field.IsZero() {
|
||||
return ""
|
||||
}
|
||||
@ -61,6 +66,11 @@ func getCycloneDXPropertyValue(field reflect.Value) string {
|
||||
return fmt.Sprint(field.Interface())
|
||||
}
|
||||
return ""
|
||||
case reflect.Struct:
|
||||
if field.CanInterface() {
|
||||
return field.Interface()
|
||||
}
|
||||
return ""
|
||||
case reflect.Ptr:
|
||||
return getCycloneDXPropertyValue(reflect.Indirect(field))
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ var JenkinsPluginPomPropertiesGroupIDs = []string{
|
||||
type JavaMetadata struct {
|
||||
VirtualPath string `json:"virtualPath"`
|
||||
Manifest *JavaManifest `mapstructure:"Manifest" json:"manifest,omitempty"`
|
||||
PomProperties *PomProperties `mapstructure:"PomProperties" json:"pomProperties,omitempty"`
|
||||
PomProperties *PomProperties `mapstructure:"PomProperties" json:"pomProperties,omitempty" cyclonedx:"-"`
|
||||
PomProject *PomProject `mapstructure:"PomProject" json:"pomProject,omitempty"`
|
||||
Parent *Package `hash:"ignore" json:"-"` // note: the parent cannot be included in the minimal definition of uniqueness since this field is not reproducible in an encode-decode cycle (is lossy).
|
||||
}
|
||||
@ -32,8 +32,8 @@ type JavaMetadata struct {
|
||||
type PomProperties struct {
|
||||
Path string `mapstructure:"path" json:"path"`
|
||||
Name string `mapstructure:"name" json:"name"`
|
||||
GroupID string `mapstructure:"groupId" json:"groupId"`
|
||||
ArtifactID string `mapstructure:"artifactId" json:"artifactId"`
|
||||
GroupID string `mapstructure:"groupId" json:"groupId" cyclonedx:"groupID"`
|
||||
ArtifactID string `mapstructure:"artifactId" json:"artifactId" cyclonedx:"artifactID"`
|
||||
Version string `mapstructure:"version" json:"version"`
|
||||
Extra map[string]string `mapstructure:",remain" json:"extraFields"`
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user