Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,23 @@ type BOMEncoder interface {

// SetEscapeHTML toggles escaped HTML output.
SetEscapeHTML(escapeHTML bool) BOMEncoder

// SetIndent sets the indent string for pretty printing.
SetIndent(indent string) BOMEncoder
}

func NewBOMEncoder(writer io.Writer, format BOMFileFormat) BOMEncoder {
if format == BOMFileFormatJSON {
return &jsonBOMEncoder{writer: writer, escapeHTML: true}
return &jsonBOMEncoder{writer: writer, escapeHTML: true, indent: " "}
}
return &xmlBOMEncoder{writer: writer}
return &xmlBOMEncoder{writer: writer, indent: " "}
}

type jsonBOMEncoder struct {
writer io.Writer
pretty bool
escapeHTML bool
indent string
}

// Encode implements the BOMEncoder interface.
Expand All @@ -62,7 +66,7 @@ func (j jsonBOMEncoder) Encode(bom *BOM) error {
encoder := json.NewEncoder(j.writer)
encoder.SetEscapeHTML(j.escapeHTML)
if j.pretty {
encoder.SetIndent("", " ")
encoder.SetIndent("", j.indent)
}

return encoder.Encode(bom)
Expand All @@ -78,6 +82,12 @@ func (j jsonBOMEncoder) EncodeVersion(bom *BOM, specVersion SpecVersion) (err er
return j.Encode(bom)
}

// SetIndent implements the BOMEncoder interface.
func (j *jsonBOMEncoder) SetIndent(indent string) BOMEncoder {
j.indent = indent
return j
}

// SetPretty implements the BOMEncoder interface.
func (j *jsonBOMEncoder) SetPretty(pretty bool) BOMEncoder {
j.pretty = pretty
Expand All @@ -93,6 +103,7 @@ func (j *jsonBOMEncoder) SetEscapeHTML(escapeHTML bool) BOMEncoder {
type xmlBOMEncoder struct {
writer io.Writer
pretty bool
indent string
}

// Encode implements the BOMEncoder interface.
Expand All @@ -103,7 +114,7 @@ func (x xmlBOMEncoder) Encode(bom *BOM) error {

encoder := xml.NewEncoder(x.writer)
if x.pretty {
encoder.Indent("", " ")
encoder.Indent("", x.indent)
}

return encoder.Encode(bom)
Expand All @@ -130,3 +141,9 @@ func (j *xmlBOMEncoder) SetEscapeHTML(escapeHTML bool) BOMEncoder {
// NOOP -- XML always needs to escape HTML
return j
}

// SetIndent implements the BOMEncoder interface.
func (x *xmlBOMEncoder) SetIndent(indent string) BOMEncoder {
x.indent = indent
return x
}
76 changes: 76 additions & 0 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,39 @@ func TestJsonBOMEncoder_SetPretty(t *testing.T) {
`, buf.String())
}

func TestJsonBOMEncoder_SetIndentTab(t *testing.T) {
buf := new(bytes.Buffer)
encoder := NewBOMEncoder(buf, BOMFileFormatJSON)
encoder.SetPretty(true)
encoder.SetIndent("\t")

bom := NewBOM()
bom.Metadata = &Metadata{
Authors: &[]OrganizationalContact{
{
Name: "authorName",
},
},
}

require.NoError(t, encoder.Encode(bom))

assert.Equal(t, `{
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
"bomFormat": "CycloneDX",
"specVersion": "1.6",
"version": 1,
"metadata": {
"authors": [
{
"name": "authorName"
}
]
}
}
`, buf.String())
}

func TestJsonBOMEncoder_SetEscapeHTML_true(t *testing.T) {
buf := new(bytes.Buffer)
encoder := NewBOMEncoder(buf, BOMFileFormatJSON)
Expand Down Expand Up @@ -173,6 +206,49 @@ func TestXmlBOMEncoder_SetPretty(t *testing.T) {
</bom>`, buf.String())
}

func TestXmlBOMEncoder_SetIndentTab(t *testing.T) {
buf := new(bytes.Buffer)
encoder := NewBOMEncoder(buf, BOMFileFormatXML)
encoder.SetPretty(true)
encoder.SetIndent("\t")

bom := NewBOM()
bom.Metadata = &Metadata{
Authors: &[]OrganizationalContact{
{
Name: "authorName",
},
},
Properties: &[]Property{
{
Name: "XML",
Value: "<xml>in here</xml>",
},
{
Name: "Specials",
Value: "Special chars: < & > \"",
},
},
}

require.NoError(t, encoder.Encode(bom))

assert.Equal(t, `<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.6" version="1">
<metadata>
<authors>
<author>
<name>authorName</name>
</author>
</authors>
<properties>
<property name="XML">&lt;xml&gt;in here&lt;/xml&gt;</property>
<property name="Specials">Special chars: &lt; &amp; &gt; &#34;</property>
</properties>
</metadata>
</bom>`, buf.String())
}

func TestJsonBOMEncoder_EncodeVersion(t *testing.T) {
t.Run(SpecVersion1_0.String(), func(t *testing.T) {
err := NewBOMEncoder(io.Discard, BOMFileFormatJSON).EncodeVersion(NewBOM(), SpecVersion1_0)
Expand Down