diff --git a/cyclonedx.go b/cyclonedx.go
index f995afe..cca1f62 100644
--- a/cyclonedx.go
+++ b/cyclonedx.go
@@ -184,8 +184,8 @@ const (
)
type Dependency struct {
- Ref string `xml:"ref,attr"`
- Dependencies *[]Dependency `xml:"dependency,omitempty"`
+ Ref string `json:"ref"`
+ Dependencies *[]string `json:"dependsOn,omitempty"`
}
type Diff struct {
diff --git a/cyclonedx_json.go b/cyclonedx_json.go
index 3efdbde..013578f 100644
--- a/cyclonedx_json.go
+++ b/cyclonedx_json.go
@@ -19,52 +19,6 @@ package cyclonedx
import "encoding/json"
-// dependencyJSON is temporarily used for marshalling and unmarshalling Dependency instances to and from JSON
-type dependencyJSON struct {
- Ref string `json:"ref"`
- DependsOn []string `json:"dependsOn,omitempty"`
-}
-
-func (d Dependency) MarshalJSON() ([]byte, error) {
- if d.Dependencies == nil || len(*d.Dependencies) == 0 {
- return json.Marshal(&dependencyJSON{
- Ref: d.Ref,
- })
- }
-
- dependencyRefs := make([]string, len(*d.Dependencies))
- for i, dependency := range *d.Dependencies {
- dependencyRefs[i] = dependency.Ref
- }
-
- return json.Marshal(&dependencyJSON{
- Ref: d.Ref,
- DependsOn: dependencyRefs,
- })
-}
-
-func (d *Dependency) UnmarshalJSON(bytes []byte) error {
- dependency := new(dependencyJSON)
- if err := json.Unmarshal(bytes, dependency); err != nil {
- return err
- }
- d.Ref = dependency.Ref
-
- if len(dependency.DependsOn) == 0 {
- return nil
- }
-
- dependencies := make([]Dependency, len(dependency.DependsOn))
- for i, dep := range dependency.DependsOn {
- dependencies[i] = Dependency{
- Ref: dep,
- }
- }
- d.Dependencies = &dependencies
-
- return nil
-}
-
func (sv SpecVersion) MarshalJSON() ([]byte, error) {
return json.Marshal(sv.String())
}
diff --git a/cyclonedx_json_test.go b/cyclonedx_json_test.go
index 7d0099e..2c09340 100644
--- a/cyclonedx_json_test.go
+++ b/cyclonedx_json_test.go
@@ -16,62 +16,3 @@
// Copyright (c) OWASP Foundation. All Rights Reserved.
package cyclonedx
-
-import (
- "encoding/json"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestDependency_MarshalJSON(t *testing.T) {
- // Marshal empty dependency
- dependency := Dependency{}
- jsonBytes, err := json.Marshal(dependency)
- assert.NoError(t, err)
- assert.Equal(t, "{\"ref\":\"\"}", string(jsonBytes))
-
- // Marshal dependency with empty dependencies
- dependency = Dependency{
- Ref: "dependencyRef",
- Dependencies: &[]Dependency{},
- }
- jsonBytes, err = json.Marshal(dependency)
- assert.NoError(t, err)
- assert.Equal(t, "{\"ref\":\"dependencyRef\"}", string(jsonBytes))
-
- // Marshal dependency with dependencies
- dependency = Dependency{
- Ref: "dependencyRef",
- Dependencies: &[]Dependency{
- {Ref: "transitiveDependencyRef"},
- },
- }
- jsonBytes, err = json.Marshal(dependency)
- assert.NoError(t, err)
- assert.Equal(t, "{\"ref\":\"dependencyRef\",\"dependsOn\":[\"transitiveDependencyRef\"]}", string(jsonBytes))
-}
-
-func TestDependency_UnmarshalJSON(t *testing.T) {
- // Unmarshal empty dependency
- dependency := new(Dependency)
- err := json.Unmarshal([]byte("{}"), dependency)
- assert.NoError(t, err)
- assert.Equal(t, "", dependency.Ref)
- assert.Nil(t, dependency.Dependencies)
-
- // Unmarshal dependency with empty dependencies
- dependency = new(Dependency)
- err = json.Unmarshal([]byte("{\"ref\":\"dependencyRef\",\"dependsOn\":[]}"), dependency)
- assert.NoError(t, err)
- assert.Equal(t, "dependencyRef", dependency.Ref)
- assert.Nil(t, dependency.Dependencies)
-
- // Unmarshal dependency with dependencies
- dependency = new(Dependency)
- err = json.Unmarshal([]byte("{\"ref\":\"dependencyRef\",\"dependsOn\":[\"transitiveDependencyRef\"]}"), dependency)
- assert.NoError(t, err)
- assert.Equal(t, "dependencyRef", dependency.Ref)
- assert.Equal(t, 1, len(*dependency.Dependencies))
- assert.Equal(t, "transitiveDependencyRef", (*dependency.Dependencies)[0].Ref)
-}
diff --git a/cyclonedx_xml.go b/cyclonedx_xml.go
index 83db3c5..655e1bd 100644
--- a/cyclonedx_xml.go
+++ b/cyclonedx_xml.go
@@ -24,7 +24,8 @@ import (
"io"
)
-// bomReferenceXML is temporarily used for marshalling and unmarshalling BOMReference instances to and from XML
+// bomReferenceXML is temporarily used for marshalling and unmarshalling
+// BOMReference instances to and from XML.
type bomReferenceXML struct {
Ref string `json:"-" xml:"ref,attr"`
}
@@ -55,6 +56,47 @@ func (c *Copyright) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
return nil
}
+// dependencyXML is temporarily used for marshalling and unmarshalling
+// Dependency instances to and from XML.
+type dependencyXML struct {
+ Ref string `xml:"ref,attr"`
+ Dependencies *[]dependencyXML `xml:"dependency,omitempty"`
+}
+
+func (d Dependency) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
+ xmlDep := dependencyXML{Ref: d.Ref}
+
+ if d.Dependencies != nil && len(*d.Dependencies) > 0 {
+ xmlDeps := make([]dependencyXML, len(*d.Dependencies))
+ for i := range *d.Dependencies {
+ xmlDeps[i] = dependencyXML{Ref: (*d.Dependencies)[i]}
+ }
+ xmlDep.Dependencies = &xmlDeps
+ }
+
+ return e.EncodeElement(xmlDep, start)
+}
+
+func (d *Dependency) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error {
+ xmlDep := dependencyXML{}
+ err := dec.DecodeElement(&xmlDep, &start)
+ if err != nil {
+ return err
+ }
+
+ dep := Dependency{Ref: xmlDep.Ref}
+ if xmlDep.Dependencies != nil && len(*xmlDep.Dependencies) > 0 {
+ deps := make([]string, len(*xmlDep.Dependencies))
+ for i := range *xmlDep.Dependencies {
+ deps[i] = (*xmlDep.Dependencies)[i].Ref
+ }
+ dep.Dependencies = &deps
+ }
+
+ *d = dep
+ return nil
+}
+
func (l Licenses) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
if len(l) == 0 {
return nil
diff --git a/cyclonedx_xml_test.go b/cyclonedx_xml_test.go
index a7f332e..25c1e4a 100644
--- a/cyclonedx_xml_test.go
+++ b/cyclonedx_xml_test.go
@@ -79,6 +79,64 @@ func TestCopyright_UnmarshalXML(t *testing.T) {
require.Equal(t, "copyright", copyright.Text)
}
+func TestDependency_MarshalXML(t *testing.T) {
+ t.Run("Empty", func(t *testing.T) {
+ dependency := Dependency{}
+ xmlBytes, err := xml.Marshal(dependency)
+ require.NoError(t, err)
+ require.Equal(t, ``, string(xmlBytes))
+ })
+
+ t.Run("EmptyDependencies", func(t *testing.T) {
+ dependency := Dependency{
+ Ref: "dependencyRef",
+ Dependencies: &[]string{},
+ }
+ xmlBytes, err := xml.Marshal(dependency)
+ require.NoError(t, err)
+ require.Equal(t, ``, string(xmlBytes))
+ })
+
+ t.Run("WithDependencies", func(t *testing.T) {
+ dependency := Dependency{
+ Ref: "dependencyRef",
+ Dependencies: &[]string{
+ "transitiveDependencyRef",
+ },
+ }
+ xmlBytes, err := xml.Marshal(dependency)
+ require.NoError(t, err)
+ require.Equal(t, ``, string(xmlBytes))
+ })
+}
+
+func TestDependency_UnmarshalXML(t *testing.T) {
+ t.Run("Empty", func(t *testing.T) {
+ dependency := Dependency{}
+ err := xml.Unmarshal([]byte(``), &dependency)
+ require.NoError(t, err)
+ require.Equal(t, "", dependency.Ref)
+ require.Nil(t, dependency.Dependencies)
+ })
+
+ t.Run("EmptyDependencies", func(t *testing.T) {
+ dependency := Dependency{}
+ err := xml.Unmarshal([]byte(``), &dependency)
+ require.NoError(t, err)
+ require.Equal(t, "dependencyRef", dependency.Ref)
+ require.Nil(t, dependency.Dependencies)
+ })
+
+ t.Run("WithDependencies", func(t *testing.T) {
+ dependency := Dependency{}
+ err := xml.Unmarshal([]byte(``), &dependency)
+ require.NoError(t, err)
+ require.Equal(t, "dependencyRef", dependency.Ref)
+ require.Equal(t, 1, len(*dependency.Dependencies))
+ require.Equal(t, "transitiveDependencyRef", (*dependency.Dependencies)[0])
+ })
+}
+
func TestLicenses_MarshalXML(t *testing.T) {
// Marshal license and expressions
licenses := Licenses{
diff --git a/example_test.go b/example_test.go
index 4b7e64a..f52d7de 100644
--- a/example_test.go
+++ b/example_test.go
@@ -64,8 +64,8 @@ func Example_encode() {
dependencies := []cdx.Dependency{
{
Ref: "pkg:golang/acme-inc/acme-app@v1.0.0",
- Dependencies: &[]cdx.Dependency{
- {Ref: "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.3.0"},
+ Dependencies: &[]string{
+ "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.3.0",
},
},
{
diff --git a/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-dependency.json b/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-dependency.json
index 4ca67e9..a908a7b 100644
--- a/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-dependency.json
+++ b/testdata/snapshots/cyclonedx-go-TestRoundTripJSON-func1-valid-dependency.json
@@ -25,7 +25,8 @@
],
"dependencies": [
{
- "ref": "library-a"
+ "ref": "library-a",
+ "dependsOn": []
},
{
"ref": "library-b",