mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
add cyclone-json output format (#635)
* add cyclone json format Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * adapt format to sbom.SBOM structure Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * cycloneDX json output with official lib Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * add cycloneDX 1.3 schema output in xml Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * fix lints errors Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * tidying go mod Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * remove cycloneDX 1.2 format Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * update cycloneDX xml schema Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * fix cyclone according to schema Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * use RFC 2141 URN form of uuid for serial number add schema validation for cycloneDX 1.3 JSON output add yajsv cli for JSON schema validation during tests Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * tidying go mod up Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * go get json schema validator Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * install yajsv without mess with go mod Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * reuse code between cycloneDX json & xml encoders Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * add output options for cyclone XML add bom.json to .gitignore Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * add cyclone json format Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * adapt format to sbom.SBOM structure Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * cycloneDX json output with official lib Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * add cycloneDX 1.3 schema output in xml Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * fix lints errors Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * tidying go mod Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * remove cycloneDX 1.2 format Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * update cycloneDX xml schema Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * fix cyclone according to schema Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * use RFC 2141 URN form of uuid for serial number add schema validation for cycloneDX 1.3 JSON output add yajsv cli for JSON schema validation during tests Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * tidying go mod up Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * go get json schema validator Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * install yajsv without mess with go mod Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * reuse code between cycloneDX json & xml encoders Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * add output options for cyclone XML add bom.json to .gitignore Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * fix cyclone12xml removal Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * feedback changes Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com> * go mod tidy Signed-off-by: Jonas Galvão Xavier <jonas.agx@gmail.com>
This commit is contained in:
parent
22c4b275e7
commit
5374a1dc6f
2
Makefile
2
Makefile
@ -82,7 +82,7 @@ help:
|
|||||||
|
|
||||||
.PHONY: ci-bootstrap
|
.PHONY: ci-bootstrap
|
||||||
ci-bootstrap:
|
ci-bootstrap:
|
||||||
DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y bc jq libxml2-utils
|
DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y bc jq libxml2-utils && go install github.com/neilpa/yajsv@latest
|
||||||
|
|
||||||
.PHONY:
|
.PHONY:
|
||||||
ci-bootstrap-mac:
|
ci-bootstrap-mac:
|
||||||
|
|||||||
1
go.mod
1
go.mod
@ -3,6 +3,7 @@ module github.com/anchore/syft
|
|||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/CycloneDX/cyclonedx-go v0.4.0
|
||||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
|
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
|
||||||
github.com/adrg/xdg v0.2.1
|
github.com/adrg/xdg v0.2.1
|
||||||
github.com/alecthomas/jsonschema v0.0.0-20210301060011-54c507b6f074
|
github.com/alecthomas/jsonschema v0.0.0-20210301060011-54c507b6f074
|
||||||
|
|||||||
4
go.sum
4
go.sum
@ -60,6 +60,8 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
|
|||||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
github.com/CycloneDX/cyclonedx-go v0.4.0 h1:Wz4QZ9B4RXGWIWTypVLEOVJgOdFfy5mcS5PGNzUkZxU=
|
||||||
|
github.com/CycloneDX/cyclonedx-go v0.4.0/go.mod h1:rmRcf//gT7PIzovatusbWi377xqCg1FS4jyST0GH20E=
|
||||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||||
@ -138,6 +140,8 @@ github.com/bmatcuk/doublestar/v2 v2.0.4/go.mod h1:QMmcs3H2AUQICWhfzLXz+IYln8lRQm
|
|||||||
github.com/bmatcuk/doublestar/v4 v4.0.2 h1:X0krlUVAVmtr2cRoTqR8aDMrDqnB36ht8wpWTiQ3jsA=
|
github.com/bmatcuk/doublestar/v4 v4.0.2 h1:X0krlUVAVmtr2cRoTqR8aDMrDqnB36ht8wpWTiQ3jsA=
|
||||||
github.com/bmatcuk/doublestar/v4 v4.0.2/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
github.com/bmatcuk/doublestar/v4 v4.0.2/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||||
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
|
||||||
|
github.com/bradleyjkemp/cupaloy/v2 v2.6.0 h1:knToPYa2xtfg42U3I6punFEjaGFKWQRXJwj0JTv4mTs=
|
||||||
|
github.com/bradleyjkemp/cupaloy/v2 v2.6.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
|
||||||
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
|
||||||
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||||
|
|||||||
93
internal/formats/common/cyclonedxhelpers/format.go
Normal file
93
internal/formats/common/cyclonedxhelpers/format.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package cyclonedxhelpers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/CycloneDX/cyclonedx-go"
|
||||||
|
"github.com/anchore/syft/internal"
|
||||||
|
"github.com/anchore/syft/internal/version"
|
||||||
|
"github.com/anchore/syft/syft/pkg"
|
||||||
|
"github.com/anchore/syft/syft/sbom"
|
||||||
|
"github.com/anchore/syft/syft/source"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ToFormatModel(s sbom.SBOM) *cyclonedx.BOM {
|
||||||
|
cdxBOM := cyclonedx.NewBOM()
|
||||||
|
versionInfo := version.FromBuild()
|
||||||
|
|
||||||
|
// NOTE(jonasagx): cycloneDX requires URN uuids (URN returns the RFC 2141 URN form of uuid):
|
||||||
|
// https://github.com/CycloneDX/specification/blob/master/schema/bom-1.3-strict.schema.json#L36
|
||||||
|
// "pattern": "^urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
|
||||||
|
cdxBOM.SerialNumber = uuid.New().URN()
|
||||||
|
cdxBOM.Metadata = toBomDescriptor(internal.ApplicationName, versionInfo.Version, s.Source)
|
||||||
|
|
||||||
|
packages := s.Artifacts.PackageCatalog.Sorted()
|
||||||
|
components := make([]cyclonedx.Component, len(packages))
|
||||||
|
for i, p := range packages {
|
||||||
|
components[i] = toComponent(p)
|
||||||
|
}
|
||||||
|
cdxBOM.Components = &components
|
||||||
|
|
||||||
|
return cdxBOM
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBomDescriptor returns a new BomDescriptor tailored for the current time and "syft" tool details.
|
||||||
|
func toBomDescriptor(name, version string, srcMetadata source.Metadata) *cyclonedx.Metadata {
|
||||||
|
return &cyclonedx.Metadata{
|
||||||
|
Timestamp: time.Now().Format(time.RFC3339),
|
||||||
|
Tools: &[]cyclonedx.Tool{
|
||||||
|
{
|
||||||
|
Vendor: "anchore",
|
||||||
|
Name: name,
|
||||||
|
Version: version,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Component: toBomDescriptorComponent(srcMetadata),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toComponent(p pkg.Package) cyclonedx.Component {
|
||||||
|
return cyclonedx.Component{
|
||||||
|
Type: cyclonedx.ComponentTypeLibrary,
|
||||||
|
Name: p.Name,
|
||||||
|
Version: p.Version,
|
||||||
|
PackageURL: p.PURL,
|
||||||
|
Licenses: toLicenses(p.Licenses),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toBomDescriptorComponent(srcMetadata source.Metadata) *cyclonedx.Component {
|
||||||
|
switch srcMetadata.Scheme {
|
||||||
|
case source.ImageScheme:
|
||||||
|
return &cyclonedx.Component{
|
||||||
|
Type: cyclonedx.ComponentTypeContainer,
|
||||||
|
Name: srcMetadata.ImageMetadata.UserInput,
|
||||||
|
Version: srcMetadata.ImageMetadata.ManifestDigest,
|
||||||
|
}
|
||||||
|
case source.DirectoryScheme, source.FileScheme:
|
||||||
|
return &cyclonedx.Component{
|
||||||
|
Type: cyclonedx.ComponentTypeFile,
|
||||||
|
Name: srcMetadata.Path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func toLicenses(ls []string) *cyclonedx.Licenses {
|
||||||
|
if len(ls) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
lc := make(cyclonedx.Licenses, len(ls))
|
||||||
|
for i, licenseName := range ls {
|
||||||
|
lc[i] = cyclonedx.LicenseChoice{
|
||||||
|
License: &cyclonedx.License{
|
||||||
|
Name: licenseName,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &lc
|
||||||
|
}
|
||||||
@ -60,6 +60,8 @@ func AssertPresenterAgainstGoldenImageSnapshot(t *testing.T, pres presenter.Pres
|
|||||||
if !bytes.Equal(expected, actual) {
|
if !bytes.Equal(expected, actual) {
|
||||||
dmp := diffmatchpatch.New()
|
dmp := diffmatchpatch.New()
|
||||||
diffs := dmp.DiffMain(string(expected), string(actual), true)
|
diffs := dmp.DiffMain(string(expected), string(actual), true)
|
||||||
|
t.Logf("len: %d\nexpected: %v", len(expected), expected)
|
||||||
|
t.Logf("len: %d\nactual: %v", len(actual), actual)
|
||||||
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,6 +89,8 @@ func AssertPresenterAgainstGoldenSnapshot(t *testing.T, pres presenter.Presenter
|
|||||||
if !bytes.Equal(expected, actual) {
|
if !bytes.Equal(expected, actual) {
|
||||||
dmp := diffmatchpatch.New()
|
dmp := diffmatchpatch.New()
|
||||||
diffs := dmp.DiffMain(string(expected), string(actual), true)
|
diffs := dmp.DiffMain(string(expected), string(actual), true)
|
||||||
|
t.Logf("len: %d\nexpected: %s", len(expected), expected)
|
||||||
|
t.Logf("len: %d\nactual: %s", len(actual), actual)
|
||||||
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
t.Errorf("mismatched output:\n%s", dmp.DiffPrettyText(diffs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
package cyclonedx12xml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/xml"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/anchore/syft/syft/sbom"
|
|
||||||
)
|
|
||||||
|
|
||||||
func encoder(output io.Writer, s sbom.SBOM) error {
|
|
||||||
enc := xml.NewEncoder(output)
|
|
||||||
enc.Indent("", " ")
|
|
||||||
|
|
||||||
_, err := output.Write([]byte(xml.Header))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = enc.Encode(toFormatModel(s))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = output.Write([]byte("\n"))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/xml"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Source: https://cyclonedx.org/ext/bom-descriptor/
|
|
||||||
|
|
||||||
// BomDescriptor represents all metadata surrounding the BOM report (such as when the BOM was made, with which tool, and the item being cataloged).
|
|
||||||
type BomDescriptor struct {
|
|
||||||
XMLName xml.Name `xml:"metadata"`
|
|
||||||
Timestamp string `xml:"timestamp,omitempty"` // The date and time (timestamp) when the document was created
|
|
||||||
Tools []BomDescriptorTool `xml:"tools>tool"` // The tool used to create the BOM.
|
|
||||||
Component *BomDescriptorComponent `xml:"component"` // The component that the BOM describes.
|
|
||||||
}
|
|
||||||
|
|
||||||
// BomDescriptorTool represents the tool that created the BOM report.
|
|
||||||
type BomDescriptorTool struct {
|
|
||||||
XMLName xml.Name `xml:"tool"`
|
|
||||||
Vendor string `xml:"vendor,omitempty"` // The vendor of the tool used to create the BOM.
|
|
||||||
Name string `xml:"name,omitempty"` // The name of the tool used to create the BOM.
|
|
||||||
Version string `xml:"version,omitempty"` // The version of the tool used to create the BOM.
|
|
||||||
// TODO: hashes, author, manufacture, supplier
|
|
||||||
// TODO: add user-defined fields for the remaining build/version parameters
|
|
||||||
}
|
|
||||||
|
|
||||||
// BomDescriptorComponent represents the software/package being cataloged.
|
|
||||||
type BomDescriptorComponent struct {
|
|
||||||
XMLName xml.Name `xml:"component"`
|
|
||||||
Component
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import "encoding/xml"
|
|
||||||
|
|
||||||
// Component represents a single element in the CycloneDX BOM
|
|
||||||
type Component struct {
|
|
||||||
XMLName xml.Name `xml:"component"`
|
|
||||||
Type string `xml:"type,attr"` // Required; Describes if the component is a library, framework, application, container, operating system, firmware, hardware device, or file
|
|
||||||
Supplier string `xml:"supplier,omitempty"` // The organization that supplied the component. The supplier may often be the manufacture, but may also be a distributor or repackager.
|
|
||||||
Author string `xml:"author,omitempty"` // The person(s) or organization(s) that authored the component
|
|
||||||
Publisher string `xml:"publisher,omitempty"` // The person(s) or organization(s) that published the component
|
|
||||||
Group string `xml:"group,omitempty"` // The high-level classification that a project self-describes as. This will often be a shortened, single name of the company or project that produced the component, or the source package or domain name.
|
|
||||||
Name string `xml:"name"` // Required; The name of the component as defined by the project
|
|
||||||
Version string `xml:"version"` // Required; The version of the component as defined by the project
|
|
||||||
Description string `xml:"description,omitempty"` // A description of the component
|
|
||||||
Licenses *[]License `xml:"licenses>license"` // A node describing zero or more license names, SPDX license IDs or expressions
|
|
||||||
PackageURL string `xml:"purl,omitempty"` // Specifies the package-url (PackageURL). The purl, if specified, must be valid and conform to the specification defined at: https://github.com/package-url/purl-spec
|
|
||||||
// TODO: source, hashes, copyright, cpe, purl, swid, modified, pedigree, externalReferences
|
|
||||||
// TODO: add user-defined parameters for syft-specific values (image layer index, cataloger, location path, etc.)
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/xml"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Source: https://github.com/CycloneDX/specification
|
|
||||||
|
|
||||||
// Document represents a CycloneDX BOM Document.
|
|
||||||
type Document struct {
|
|
||||||
XMLName xml.Name `xml:"bom"`
|
|
||||||
XMLNs string `xml:"xmlns,attr"`
|
|
||||||
Version int `xml:"version,attr"`
|
|
||||||
SerialNumber string `xml:"serialNumber,attr"`
|
|
||||||
BomDescriptor *BomDescriptor `xml:"metadata"` // The BOM descriptor extension
|
|
||||||
Components []Component `xml:"components>component"` // The BOM contents
|
|
||||||
}
|
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
import "encoding/xml"
|
|
||||||
|
|
||||||
// License represents a single software license for a Component
|
|
||||||
type License struct {
|
|
||||||
XMLName xml.Name `xml:"license"`
|
|
||||||
ID string `xml:"id,omitempty"` // A valid SPDX license ID
|
|
||||||
Name string `xml:"name,omitempty"` // If SPDX does not define the license used, this field may be used to provide the license name
|
|
||||||
}
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
package cyclonedx12xml
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/xml"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/anchore/syft/syft/sbom"
|
|
||||||
|
|
||||||
"github.com/anchore/syft/internal"
|
|
||||||
"github.com/anchore/syft/internal/formats/cyclonedx12xml/model"
|
|
||||||
"github.com/anchore/syft/internal/version"
|
|
||||||
"github.com/anchore/syft/syft/pkg"
|
|
||||||
"github.com/anchore/syft/syft/source"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
)
|
|
||||||
|
|
||||||
// toFormatModel creates and populates a new in-memory representation of a CycloneDX 1.2 document
|
|
||||||
func toFormatModel(s sbom.SBOM) model.Document {
|
|
||||||
versionInfo := version.FromBuild()
|
|
||||||
|
|
||||||
doc := model.Document{
|
|
||||||
XMLNs: "http://cyclonedx.org/schema/bom/1.2",
|
|
||||||
Version: 1,
|
|
||||||
SerialNumber: uuid.New().URN(),
|
|
||||||
BomDescriptor: toBomDescriptor(internal.ApplicationName, versionInfo.Version, s.Source),
|
|
||||||
}
|
|
||||||
|
|
||||||
// attach components
|
|
||||||
for _, p := range s.Artifacts.PackageCatalog.Sorted() {
|
|
||||||
doc.Components = append(doc.Components, toComponent(p))
|
|
||||||
}
|
|
||||||
|
|
||||||
return doc
|
|
||||||
}
|
|
||||||
|
|
||||||
func toComponent(p pkg.Package) model.Component {
|
|
||||||
return model.Component{
|
|
||||||
Type: "library", // TODO: this is not accurate
|
|
||||||
Name: p.Name,
|
|
||||||
Version: p.Version,
|
|
||||||
PackageURL: p.PURL,
|
|
||||||
Licenses: toLicenses(p.Licenses),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBomDescriptor returns a new BomDescriptor tailored for the current time and "syft" tool details.
|
|
||||||
func toBomDescriptor(name, version string, srcMetadata source.Metadata) *model.BomDescriptor {
|
|
||||||
return &model.BomDescriptor{
|
|
||||||
XMLName: xml.Name{},
|
|
||||||
Timestamp: time.Now().Format(time.RFC3339),
|
|
||||||
Tools: []model.BomDescriptorTool{
|
|
||||||
{
|
|
||||||
Vendor: "anchore",
|
|
||||||
Name: name,
|
|
||||||
Version: version,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Component: toBomDescriptorComponent(srcMetadata),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toBomDescriptorComponent(srcMetadata source.Metadata) *model.BomDescriptorComponent {
|
|
||||||
switch srcMetadata.Scheme {
|
|
||||||
case source.ImageScheme:
|
|
||||||
return &model.BomDescriptorComponent{
|
|
||||||
Component: model.Component{
|
|
||||||
Type: "container",
|
|
||||||
Name: srcMetadata.ImageMetadata.UserInput,
|
|
||||||
Version: srcMetadata.ImageMetadata.ManifestDigest,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
case source.DirectoryScheme, source.FileScheme:
|
|
||||||
return &model.BomDescriptorComponent{
|
|
||||||
Component: model.Component{
|
|
||||||
Type: "file",
|
|
||||||
Name: srcMetadata.Path,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func toLicenses(licenses []string) *[]model.License {
|
|
||||||
if len(licenses) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var result []model.License
|
|
||||||
for _, licenseName := range licenses {
|
|
||||||
result = append(result, model.License{
|
|
||||||
Name: licenseName,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return &result
|
|
||||||
}
|
|
||||||
18
internal/formats/cyclonedx13json/encoder.go
Normal file
18
internal/formats/cyclonedx13json/encoder.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package cyclonedx13json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/CycloneDX/cyclonedx-go"
|
||||||
|
"github.com/anchore/syft/internal/formats/common/cyclonedxhelpers"
|
||||||
|
"github.com/anchore/syft/syft/sbom"
|
||||||
|
)
|
||||||
|
|
||||||
|
func encoder(output io.Writer, s sbom.SBOM) error {
|
||||||
|
bom := cyclonedxhelpers.ToFormatModel(s)
|
||||||
|
enc := cyclonedx.NewBOMEncoder(output, cyclonedx.BOMFileFormatJSON)
|
||||||
|
enc.SetPretty(true)
|
||||||
|
|
||||||
|
err := enc.Encode(bom)
|
||||||
|
return err
|
||||||
|
}
|
||||||
39
internal/formats/cyclonedx13json/encoder_test.go
Normal file
39
internal/formats/cyclonedx13json/encoder_test.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package cyclonedx13json
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/internal/formats/common/testutils"
|
||||||
|
)
|
||||||
|
|
||||||
|
var updateCycloneDx = flag.Bool("update-cyclonedx", false, "update the *.golden files for cyclone-dx presenters")
|
||||||
|
|
||||||
|
func TestCycloneDxDirectoryPresenter(t *testing.T) {
|
||||||
|
testutils.AssertPresenterAgainstGoldenSnapshot(t,
|
||||||
|
Format().Presenter(testutils.DirectoryInput(t)),
|
||||||
|
*updateCycloneDx,
|
||||||
|
cycloneDxRedactor,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCycloneDxImagePresenter(t *testing.T) {
|
||||||
|
testImage := "image-simple"
|
||||||
|
testutils.AssertPresenterAgainstGoldenImageSnapshot(t,
|
||||||
|
Format().Presenter(testutils.ImageInput(t, testImage)),
|
||||||
|
testImage,
|
||||||
|
*updateCycloneDx,
|
||||||
|
cycloneDxRedactor,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func cycloneDxRedactor(s []byte) []byte {
|
||||||
|
serialPattern := regexp.MustCompile(`urn:uuid:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`)
|
||||||
|
rfc3339Pattern := regexp.MustCompile(`([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([\+|\-]([01][0-9]|2[0-3]):[0-5][0-9]))`)
|
||||||
|
|
||||||
|
for _, pattern := range []*regexp.Regexp{serialPattern, rfc3339Pattern} {
|
||||||
|
s = pattern.ReplaceAll(s, []byte("redacted"))
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
12
internal/formats/cyclonedx13json/format.go
Normal file
12
internal/formats/cyclonedx13json/format.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package cyclonedx13json
|
||||||
|
|
||||||
|
import "github.com/anchore/syft/syft/format"
|
||||||
|
|
||||||
|
func Format() format.Format {
|
||||||
|
return format.NewFormat(
|
||||||
|
format.CycloneDxJSONOption,
|
||||||
|
encoder,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"bomFormat": "CycloneDX",
|
||||||
|
"specVersion": "1.3",
|
||||||
|
"serialNumber": "urn:uuid:a81dc685-cf22-48e0-bda5-65ea1a8bca5b",
|
||||||
|
"version": 1,
|
||||||
|
"metadata": {
|
||||||
|
"timestamp": "2021-12-03T13:17:26-08:00",
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"vendor": "anchore",
|
||||||
|
"name": "syft",
|
||||||
|
"version": "[not provided]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"component": {
|
||||||
|
"type": "file",
|
||||||
|
"name": "/some/path",
|
||||||
|
"version": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"type": "library",
|
||||||
|
"name": "package-1",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"licenses": [
|
||||||
|
{
|
||||||
|
"license": {
|
||||||
|
"name": "MIT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"purl": "a-purl-2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "library",
|
||||||
|
"name": "package-2",
|
||||||
|
"version": "2.0.1",
|
||||||
|
"purl": "a-purl-2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"bomFormat": "CycloneDX",
|
||||||
|
"specVersion": "1.3",
|
||||||
|
"serialNumber": "urn:uuid:2156ac1f-c838-4e93-8dc5-a3874ffeb967",
|
||||||
|
"version": 1,
|
||||||
|
"metadata": {
|
||||||
|
"timestamp": "2021-12-03T13:17:26-08:00",
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"vendor": "anchore",
|
||||||
|
"name": "syft",
|
||||||
|
"version": "[not provided]"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"component": {
|
||||||
|
"type": "container",
|
||||||
|
"name": "user-image-input",
|
||||||
|
"version": "sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": [
|
||||||
|
{
|
||||||
|
"type": "library",
|
||||||
|
"name": "package-1",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"licenses": [
|
||||||
|
{
|
||||||
|
"license": {
|
||||||
|
"name": "MIT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"purl": "a-purl-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "library",
|
||||||
|
"name": "package-2",
|
||||||
|
"version": "2.0.1",
|
||||||
|
"purl": "a-purl-2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Binary file not shown.
18
internal/formats/cyclonedx13xml/encoder.go
Normal file
18
internal/formats/cyclonedx13xml/encoder.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package cyclonedx13xml
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/CycloneDX/cyclonedx-go"
|
||||||
|
"github.com/anchore/syft/internal/formats/common/cyclonedxhelpers"
|
||||||
|
"github.com/anchore/syft/syft/sbom"
|
||||||
|
)
|
||||||
|
|
||||||
|
func encoder(output io.Writer, s sbom.SBOM) error {
|
||||||
|
bom := cyclonedxhelpers.ToFormatModel(s)
|
||||||
|
enc := cyclonedx.NewBOMEncoder(output, cyclonedx.BOMFileFormatXML)
|
||||||
|
enc.SetPretty(true)
|
||||||
|
|
||||||
|
err := enc.Encode(bom)
|
||||||
|
return err
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package cyclonedx12xml
|
package cyclonedx13xml
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
@ -1,10 +1,10 @@
|
|||||||
package cyclonedx12xml
|
package cyclonedx13xml
|
||||||
|
|
||||||
import "github.com/anchore/syft/syft/format"
|
import "github.com/anchore/syft/syft/format"
|
||||||
|
|
||||||
func Format() format.Format {
|
func Format() format.Format {
|
||||||
return format.NewFormat(
|
return format.NewFormat(
|
||||||
format.CycloneDxOption,
|
format.CycloneDxXMLOption,
|
||||||
encoder,
|
encoder,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
# Note: changes to this file will result in updating several test values. Consider making a new image fixture instead of editing this one.
|
||||||
|
FROM scratch
|
||||||
|
ADD file-1.txt /somefile-1.txt
|
||||||
|
ADD file-2.txt /somefile-2.txt
|
||||||
@ -0,0 +1 @@
|
|||||||
|
this file has contents
|
||||||
@ -0,0 +1 @@
|
|||||||
|
file-2 contents!
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<bom xmlns="http://cyclonedx.org/schema/bom/1.2" version="1" serialNumber="urn:uuid:5404937f-72d6-44a2-8e9b-954305ecb4f6">
|
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:7b1c3b1d-ea3b-4022-9dcc-80f4b4cbce36" version="1">
|
||||||
<metadata>
|
<metadata>
|
||||||
<timestamp>2021-06-23T13:40:33-04:00</timestamp>
|
<timestamp>2021-12-03T13:16:45-08:00</timestamp>
|
||||||
<tools>
|
<tools>
|
||||||
<tool>
|
<tool>
|
||||||
<vendor>anchore</vendor>
|
<vendor>anchore</vendor>
|
||||||
@ -31,4 +31,4 @@
|
|||||||
<purl>a-purl-2</purl>
|
<purl>a-purl-2</purl>
|
||||||
</component>
|
</component>
|
||||||
</components>
|
</components>
|
||||||
</bom>
|
</bom>
|
||||||
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<bom xmlns="http://cyclonedx.org/schema/bom/1.2" version="1" serialNumber="urn:uuid:e34bad2e-cd27-483c-86dc-f4e26d6103b0">
|
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" serialNumber="urn:uuid:66bda3e1-888a-4d43-b906-7fd96d428753" version="1">
|
||||||
<metadata>
|
<metadata>
|
||||||
<timestamp>2021-06-23T13:40:33-04:00</timestamp>
|
<timestamp>2021-12-03T13:16:45-08:00</timestamp>
|
||||||
<tools>
|
<tools>
|
||||||
<tool>
|
<tool>
|
||||||
<vendor>anchore</vendor>
|
<vendor>anchore</vendor>
|
||||||
@ -31,4 +31,4 @@
|
|||||||
<purl>a-purl-2</purl>
|
<purl>a-purl-2</purl>
|
||||||
</component>
|
</component>
|
||||||
</components>
|
</components>
|
||||||
</bom>
|
</bom>
|
||||||
Binary file not shown.
@ -3,7 +3,8 @@ package formats
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
|
||||||
"github.com/anchore/syft/internal/formats/cyclonedx12xml"
|
"github.com/anchore/syft/internal/formats/cyclonedx13json"
|
||||||
|
"github.com/anchore/syft/internal/formats/cyclonedx13xml"
|
||||||
"github.com/anchore/syft/internal/formats/spdx22json"
|
"github.com/anchore/syft/internal/formats/spdx22json"
|
||||||
"github.com/anchore/syft/internal/formats/spdx22tagvalue"
|
"github.com/anchore/syft/internal/formats/spdx22tagvalue"
|
||||||
"github.com/anchore/syft/internal/formats/syftjson"
|
"github.com/anchore/syft/internal/formats/syftjson"
|
||||||
@ -17,7 +18,8 @@ func All() []format.Format {
|
|||||||
return []format.Format{
|
return []format.Format{
|
||||||
syftjson.Format(),
|
syftjson.Format(),
|
||||||
table.Format(),
|
table.Format(),
|
||||||
cyclonedx12xml.Format(),
|
cyclonedx13xml.Format(),
|
||||||
|
cyclonedx13json.Format(),
|
||||||
spdx22json.Format(),
|
spdx22json.Format(),
|
||||||
spdx22tagvalue.Format(),
|
spdx22tagvalue.Format(),
|
||||||
text.Format(),
|
text.Format(),
|
||||||
|
|||||||
3
schema/cyclonedx/.gitignore
vendored
3
schema/cyclonedx/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
bom.xml
|
bom.xml
|
||||||
|
bom.json
|
||||||
|
|||||||
@ -2,4 +2,6 @@
|
|||||||
.PHONY: validate-schema
|
.PHONY: validate-schema
|
||||||
validate-schema:
|
validate-schema:
|
||||||
go run ../../main.go ubuntu:latest -vv -o cyclonedx > bom.xml
|
go run ../../main.go ubuntu:latest -vv -o cyclonedx > bom.xml
|
||||||
xmllint --noout --schema ./cyclonedx.xsd bom.xml
|
xmllint --noout --schema ./cyclonedx.xsd bom.xml
|
||||||
|
go run ../../main.go ubuntu:latest -vv -o cyclonedx-json > bom.json
|
||||||
|
yajsv -s bom-1.3.schema.json bom.json
|
||||||
|
|||||||
1054
schema/cyclonedx/bom-1.3.schema.json
Normal file
1054
schema/cyclonedx/bom-1.3.schema.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -16,13 +16,13 @@ limitations under the License.
|
|||||||
-->
|
-->
|
||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
|
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
|
||||||
xmlns:bom="http://cyclonedx.org/schema/bom/1.2"
|
xmlns:bom="http://cyclonedx.org/schema/bom/1.3"
|
||||||
xmlns:spdx="http://cyclonedx.org/schema/spdx"
|
xmlns:spdx="http://cyclonedx.org/schema/spdx"
|
||||||
elementFormDefault="qualified"
|
elementFormDefault="qualified"
|
||||||
targetNamespace="http://cyclonedx.org/schema/bom/1.2"
|
targetNamespace="http://cyclonedx.org/schema/bom/1.3"
|
||||||
vc:minVersion="1.0"
|
vc:minVersion="1.0"
|
||||||
vc:maxVersion="1.1"
|
vc:maxVersion="1.1"
|
||||||
version="1.2">
|
version="1.3">
|
||||||
|
|
||||||
<xs:import namespace="http://cyclonedx.org/schema/spdx" schemaLocation="spdx.xsd"/>
|
<xs:import namespace="http://cyclonedx.org/schema/spdx" schemaLocation="spdx.xsd"/>
|
||||||
|
|
||||||
@ -32,9 +32,6 @@ limitations under the License.
|
|||||||
<url>https://cyclonedx.org/</url>
|
<url>https://cyclonedx.org/</url>
|
||||||
<license uri="http://www.apache.org/licenses/LICENSE-2.0"
|
<license uri="http://www.apache.org/licenses/LICENSE-2.0"
|
||||||
version="2.0">Apache License, Version 2.0</license>
|
version="2.0">Apache License, Version 2.0</license>
|
||||||
<authors>
|
|
||||||
<author>Steve Springett</author>
|
|
||||||
</authors>
|
|
||||||
</xs:documentation>
|
</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
|
|
||||||
@ -71,15 +68,23 @@ limitations under the License.
|
|||||||
<xs:documentation>The component that the BOM describes.</xs:documentation>
|
<xs:documentation>The component that the BOM describes.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="manufacture" type="bom:organizationalEntity" minOccurs="0" maxOccurs="unbounded">
|
<xs:element name="manufacture" type="bom:organizationalEntity" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>The organization that manufactured the component that the BOM describes.</xs:documentation>
|
<xs:documentation>The organization that manufactured the component that the BOM describes.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="supplier" type="bom:organizationalEntity" minOccurs="0" maxOccurs="unbounded">
|
<xs:element name="supplier" type="bom:organizationalEntity" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>The organization that supplied the component that the BOM describes. The
|
<xs:documentation>The organization that supplied the component that the BOM describes. The
|
||||||
supplier may often be the manufacture, but may also be a distributor or repackager.</xs:documentation>
|
supplier may often be the manufacturer, but may also be a distributor or repackager.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="licenses" type="bom:licenseChoiceType" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:element name="properties" type="bom:propertiesType" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Provides the ability to document properties in a key/value store.
|
||||||
|
This provides flexibility to include data not officially supported in the standard
|
||||||
|
without having to use additional namespaces or create extensions.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||||
@ -181,14 +186,14 @@ limitations under the License.
|
|||||||
<xs:documentation>The name of the contact</xs:documentation>
|
<xs:documentation>The name of the contact</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="email" type="xs:normalizedString" minOccurs="0" maxOccurs="unbounded">
|
<xs:element name="email" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>The email address of the contact. Multiple email addresses are allowed.</xs:documentation>
|
<xs:documentation>The email address of the contact.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="phone" type="xs:normalizedString" minOccurs="0" maxOccurs="unbounded">
|
<xs:element name="phone" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>The phone number of the contact. Multiple phone numbers are allowed.</xs:documentation>
|
<xs:documentation>The phone number of the contact.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||||
@ -231,7 +236,7 @@ limitations under the License.
|
|||||||
<xs:element name="supplier" type="bom:organizationalEntity" minOccurs="0" maxOccurs="1">
|
<xs:element name="supplier" type="bom:organizationalEntity" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>The organization that supplied the component. The supplier may often
|
<xs:documentation>The organization that supplied the component. The supplier may often
|
||||||
be the manufacture, but may also be a distributor or repackager.</xs:documentation>
|
be the manufacturer, but may also be a distributor or repackager.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="author" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
|
<xs:element name="author" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
|
||||||
@ -282,19 +287,7 @@ limitations under the License.
|
|||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="licenses" minOccurs="0" maxOccurs="1">
|
<xs:element name="licenses" type="bom:licenseChoiceType" minOccurs="0" maxOccurs="1"/>
|
||||||
<xs:complexType>
|
|
||||||
<xs:choice>
|
|
||||||
<xs:element name="license" type="bom:licenseType" minOccurs="0" maxOccurs="unbounded"/>
|
|
||||||
<xs:element name="expression" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>A valid SPDX license expression.
|
|
||||||
Refer to https://spdx.org/specifications for syntax requirements</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:element>
|
|
||||||
</xs:choice>
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
<xs:element name="copyright" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
|
<xs:element name="copyright" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>An optional copyright notice informing users of the underlying claims to
|
<xs:documentation>An optional copyright notice informing users of the underlying claims to
|
||||||
@ -349,6 +342,13 @@ limitations under the License.
|
|||||||
component or to the project the component describes.</xs:documentation>
|
component or to the project the component describes.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="properties" type="bom:propertiesType" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Provides the ability to document properties in a key/value store.
|
||||||
|
This provides flexibility to include data not officially supported in the standard
|
||||||
|
without having to use additional namespaces or create extensions.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
<xs:element name="components" minOccurs="0" maxOccurs="1">
|
<xs:element name="components" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>
|
<xs:documentation>
|
||||||
@ -370,6 +370,11 @@ limitations under the License.
|
|||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="evidence" type="bom:componentEvidenceType" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Provides the ability to document evidence collected through various forms of extraction or analysis.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>
|
<xs:documentation>
|
||||||
@ -512,45 +517,45 @@ limitations under the License.
|
|||||||
<xs:simpleType name="classification">
|
<xs:simpleType name="classification">
|
||||||
<xs:restriction base="xs:string">
|
<xs:restriction base="xs:string">
|
||||||
<xs:enumeration value="application">
|
<xs:enumeration value="application">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>A software application. Refer to https://en.wikipedia.org/wiki/Application_software
|
<xs:documentation>A software application. Refer to https://en.wikipedia.org/wiki/Application_software
|
||||||
for information about applications.</xs:documentation>
|
for information about applications.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:enumeration>
|
</xs:enumeration>
|
||||||
<xs:enumeration value="framework">
|
<xs:enumeration value="framework">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>A software framework. Refer to https://en.wikipedia.org/wiki/Software_framework
|
<xs:documentation>A software framework. Refer to https://en.wikipedia.org/wiki/Software_framework
|
||||||
for information on how frameworks vary slightly from libraries.</xs:documentation>
|
for information on how frameworks vary slightly from libraries.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:enumeration>
|
</xs:enumeration>
|
||||||
<xs:enumeration value="library">
|
<xs:enumeration value="library">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>A software library. Refer to https://en.wikipedia.org/wiki/Library_(computing)
|
<xs:documentation>A software library. Refer to https://en.wikipedia.org/wiki/Library_(computing)
|
||||||
for information about libraries. All third-party and open source reusable components will likely
|
for information about libraries. All third-party and open source reusable components will likely
|
||||||
be a library. If the library also has key features of a framework, then it should be classified
|
be a library. If the library also has key features of a framework, then it should be classified
|
||||||
as a framework. If not, or is unknown, then specifying library is recommended.</xs:documentation>
|
as a framework. If not, or is unknown, then specifying library is recommended.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:enumeration>
|
</xs:enumeration>
|
||||||
<xs:enumeration value="container">
|
<xs:enumeration value="container">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>A packaging and/or runtime format, not specific to any particular technology,
|
<xs:documentation>A packaging and/or runtime format, not specific to any particular technology,
|
||||||
which isolates software inside the container from software outside of a container through
|
which isolates software inside the container from software outside of a container through
|
||||||
virtualization technology. Refer to https://en.wikipedia.org/wiki/OS-level_virtualization</xs:documentation>
|
virtualization technology. Refer to https://en.wikipedia.org/wiki/OS-level_virtualization</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:enumeration>
|
</xs:enumeration>
|
||||||
<xs:enumeration value="operating-system">
|
<xs:enumeration value="operating-system">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>A software operating system without regard to deployment model
|
<xs:documentation>A software operating system without regard to deployment model
|
||||||
(i.e. installed on physical hardware, virtual machine, image, etc) Refer to
|
(i.e. installed on physical hardware, virtual machine, image, etc) Refer to
|
||||||
https://en.wikipedia.org/wiki/Operating_system</xs:documentation>
|
https://en.wikipedia.org/wiki/Operating_system</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:enumeration>
|
</xs:enumeration>
|
||||||
<xs:enumeration value="device">
|
<xs:enumeration value="device">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>A hardware device such as a processor, or chip-set. A hardware device
|
<xs:documentation>A hardware device such as a processor, or chip-set. A hardware device
|
||||||
containing firmware should include a component for the physical hardware itself, and another
|
containing firmware should include a component for the physical hardware itself, and another
|
||||||
component of type 'firmware' or 'operating-system' (whichever is relevant), describing
|
component of type 'firmware' or 'operating-system' (whichever is relevant), describing
|
||||||
information about the software running on the device.</xs:documentation>
|
information about the software running on the device.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:enumeration>
|
</xs:enumeration>
|
||||||
<xs:enumeration value="firmware">
|
<xs:enumeration value="firmware">
|
||||||
@ -562,7 +567,7 @@ limitations under the License.
|
|||||||
<xs:enumeration value="file">
|
<xs:enumeration value="file">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>A computer file. Refer to https://en.wikipedia.org/wiki/Computer_file
|
<xs:documentation>A computer file. Refer to https://en.wikipedia.org/wiki/Computer_file
|
||||||
for information about files.</xs:documentation>
|
for information about files.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:enumeration>
|
</xs:enumeration>
|
||||||
</xs:restriction>
|
</xs:restriction>
|
||||||
@ -782,6 +787,13 @@ limitations under the License.
|
|||||||
<xs:documentation xml:lang="en">An optional comment describing the external reference</xs:documentation>
|
<xs:documentation xml:lang="en">An optional comment describing the external reference</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="hashes" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element name="hash" type="bom:hashType"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
<xs:attribute name="type" type="bom:externalReferenceType" use="required">
|
<xs:attribute name="type" type="bom:externalReferenceType" use="required">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
@ -927,7 +939,7 @@ limitations under the License.
|
|||||||
<xs:enumeration value="backport">
|
<xs:enumeration value="backport">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>A patch which takes code from a newer version of software and applies
|
<xs:documentation>A patch which takes code from a newer version of software and applies
|
||||||
it to older versions of the same software. Refer to https://en.wikipedia.org/wiki/Backporting</xs:documentation>
|
it to older versions of the same software. Refer to https://en.wikipedia.org/wiki/Backporting</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:enumeration>
|
</xs:enumeration>
|
||||||
<xs:enumeration value="cherry-pick">
|
<xs:enumeration value="cherry-pick">
|
||||||
@ -1255,24 +1267,19 @@ limitations under the License.
|
|||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
<xs:element name="licenses" minOccurs="0" maxOccurs="1">
|
<xs:element name="licenses" type="bom:licenseChoiceType" minOccurs="0" maxOccurs="1"/>
|
||||||
<xs:complexType>
|
|
||||||
<xs:choice>
|
|
||||||
<xs:element name="license" type="bom:licenseType" minOccurs="0" maxOccurs="unbounded"/>
|
|
||||||
<xs:element name="expression" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>A valid SPDX license expression.
|
|
||||||
Refer to https://spdx.org/specifications for syntax requirements</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:element>
|
|
||||||
</xs:choice>
|
|
||||||
</xs:complexType>
|
|
||||||
</xs:element>
|
|
||||||
<xs:element name="externalReferences" type="bom:externalReferences" minOccurs="0" maxOccurs="1">
|
<xs:element name="externalReferences" type="bom:externalReferences" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>Provides the ability to document external references related to the service.</xs:documentation>
|
<xs:documentation>Provides the ability to document external references related to the service.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="properties" type="bom:propertiesType" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Provides the ability to document properties in a key/value store.
|
||||||
|
This provides flexibility to include data not officially supported in the standard
|
||||||
|
without having to use additional namespaces or create extensions.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
<xs:element name="services" minOccurs="0" maxOccurs="1">
|
<xs:element name="services" minOccurs="0" maxOccurs="1">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>
|
<xs:documentation>
|
||||||
@ -1349,6 +1356,199 @@ limitations under the License.
|
|||||||
</xs:restriction>
|
</xs:restriction>
|
||||||
</xs:simpleType>
|
</xs:simpleType>
|
||||||
|
|
||||||
|
<xs:complexType name="licenseChoiceType">
|
||||||
|
<xs:choice>
|
||||||
|
<xs:element name="license" type="bom:licenseType" minOccurs="0" maxOccurs="unbounded"/>
|
||||||
|
<xs:element name="expression" type="xs:normalizedString" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A valid SPDX license expression.
|
||||||
|
Refer to https://spdx.org/specifications for syntax requirements</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
</xs:choice>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="copyrightsType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="text" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="componentEvidenceType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="licenses" type="bom:licenseChoiceType" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:element name="copyright" type="bom:copyrightsType" minOccurs="0" maxOccurs="1"/>
|
||||||
|
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>
|
||||||
|
Allows any undeclared elements as long as the elements are placed in a different namespace.
|
||||||
|
</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:any>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:anyAttribute namespace="##any" processContents="lax">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>User-defined attributes may be used on this element as long as they
|
||||||
|
do not have the same name as an existing attribute used by the schema.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:anyAttribute>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="compositionsType">
|
||||||
|
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element name="composition" type="bom:compositionType"/>
|
||||||
|
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>
|
||||||
|
Allows any undeclared elements as long as the elements are placed in a different namespace.
|
||||||
|
</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:any>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:anyAttribute namespace="##any" processContents="lax">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>User-defined attributes may be used on this element as long as they
|
||||||
|
do not have the same name as an existing attribute used by the schema.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:anyAttribute>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="compositionType">
|
||||||
|
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element name="aggregate" type="bom:aggregateType" default="not_specified">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Specifies an aggregate type that describe how complete a relationship is.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="assemblies" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>
|
||||||
|
The bom-ref identifiers of the components or services being described. Assemblies refer to
|
||||||
|
nested relationships whereby a constituent part may include other constituent parts. References
|
||||||
|
do not cascade to child parts. References are explicit for the specified constituent part only.
|
||||||
|
</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element name="assembly" type="bom:bomReferenceType"/>
|
||||||
|
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>
|
||||||
|
Allows any undeclared elements as long as the elements are placed in a different namespace.
|
||||||
|
</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:any>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="dependencies" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>
|
||||||
|
The bom-ref identifiers of the components or services being described. Dependencies refer to a
|
||||||
|
relationship whereby an independent constituent part requires another independent constituent
|
||||||
|
part. References do not cascade to transitive dependencies. References are explicit for the
|
||||||
|
specified dependency only.
|
||||||
|
</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element name="dependency" type="bom:bomReferenceType"/>
|
||||||
|
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>
|
||||||
|
Allows any undeclared elements as long as the elements are placed in a different namespace.
|
||||||
|
</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:any>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:simpleType name="aggregateType">
|
||||||
|
<xs:restriction base="xs:string">
|
||||||
|
<xs:enumeration value="complete">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>The relationship is complete. No further relationships including constituent components, services, or dependencies exist.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:enumeration>
|
||||||
|
<xs:enumeration value="incomplete">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>The relationship is incomplete. Additional relationships exist and may include constituent components, services, or dependencies.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:enumeration>
|
||||||
|
<xs:enumeration value="incomplete_first_party_only">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>The relationship is incomplete. Only relationships for first-party components, services, or their dependencies are represented.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:enumeration>
|
||||||
|
<xs:enumeration value="incomplete_third_party_only">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>The relationship is incomplete. Only relationships for third-party components, services, or their dependencies are represented.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:enumeration>
|
||||||
|
<xs:enumeration value="unknown">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>The relationship may be complete or incomplete. This usually signifies a 'best-effort' to obtain constituent components, services, or dependencies but the completeness is inconclusive.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:enumeration>
|
||||||
|
<xs:enumeration value="not_specified">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>The relationship completeness is not specified.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:enumeration>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
|
||||||
|
<xs:complexType name="bomReferenceType">
|
||||||
|
<xs:attribute name="ref" type="xs:string" use="required">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>References a component or service by the its bom-ref attribute</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:anyAttribute namespace="##other" processContents="lax">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>User-defined attributes may be used on this element as long as they
|
||||||
|
do not have the same name as an existing attribute used by the schema.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:anyAttribute>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="propertiesType">
|
||||||
|
<xs:sequence minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element name="property" type="bom:propertyType"/>
|
||||||
|
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>
|
||||||
|
Allows any undeclared elements as long as the elements are placed in a different namespace.
|
||||||
|
</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:any>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:anyAttribute namespace="##any" processContents="lax">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>User-defined attributes may be used on this element as long as they
|
||||||
|
do not have the same name as an existing attribute used by the schema.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:anyAttribute>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="propertyType">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Specifies an individual property with a name and value.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
<xs:simpleContent>
|
||||||
|
<xs:extension base="xs:normalizedString">
|
||||||
|
<xs:attribute name="name" type="xs:string" use="required">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>The name of the property. Duplicate names are allowed, each potentially having a different value.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:extension>
|
||||||
|
</xs:simpleContent>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
<xs:element name="bom">
|
<xs:element name="bom">
|
||||||
<xs:complexType>
|
<xs:complexType>
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
@ -1378,6 +1578,19 @@ limitations under the License.
|
|||||||
<xs:documentation>Provides the ability to document dependency relationships.</xs:documentation>
|
<xs:documentation>Provides the ability to document dependency relationships.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="compositions" type="bom:compositionsType" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Compositions describe constituent parts (including components, services, and dependency relationships) and their completeness.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="properties" type="bom:propertiesType" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Provides the ability to document properties in a name-value store.
|
||||||
|
This provides flexibility to include data not officially supported in the standard
|
||||||
|
without having to use additional namespaces or create extensions. Unlike key-value
|
||||||
|
stores, properties support duplicate names, each potentially having different values.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:element>
|
||||||
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>
|
<xs:documentation>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,8 @@ const (
|
|||||||
JSONOption Option = "json"
|
JSONOption Option = "json"
|
||||||
TextOption Option = "text"
|
TextOption Option = "text"
|
||||||
TableOption Option = "table"
|
TableOption Option = "table"
|
||||||
CycloneDxOption Option = "cyclonedx"
|
CycloneDxXMLOption Option = "cyclonedx"
|
||||||
|
CycloneDxJSONOption Option = "cyclonedx-json"
|
||||||
SPDXTagValueOption Option = "spdx-tag-value"
|
SPDXTagValueOption Option = "spdx-tag-value"
|
||||||
SPDXJSONOption Option = "spdx-json"
|
SPDXJSONOption Option = "spdx-json"
|
||||||
)
|
)
|
||||||
@ -16,7 +17,8 @@ var AllOptions = []Option{
|
|||||||
JSONOption,
|
JSONOption,
|
||||||
TextOption,
|
TextOption,
|
||||||
TableOption,
|
TableOption,
|
||||||
CycloneDxOption,
|
CycloneDxXMLOption,
|
||||||
|
CycloneDxJSONOption,
|
||||||
SPDXTagValueOption,
|
SPDXTagValueOption,
|
||||||
SPDXJSONOption,
|
SPDXJSONOption,
|
||||||
}
|
}
|
||||||
@ -31,8 +33,12 @@ func ParseOption(userStr string) Option {
|
|||||||
return TextOption
|
return TextOption
|
||||||
case string(TableOption):
|
case string(TableOption):
|
||||||
return TableOption
|
return TableOption
|
||||||
case string(CycloneDxOption), "cyclone", "cyclone-dx":
|
case string(CycloneDxXMLOption), "cyclone", "cyclone-dx", "cyclone-dx-xml", "cyclone-xml":
|
||||||
return CycloneDxOption
|
// NOTE(jonasagx): setting "cyclone" to XML by default for retro-compatibility.
|
||||||
|
// If we want to show no preference between XML and JSON please remove it.
|
||||||
|
return CycloneDxXMLOption
|
||||||
|
case string(CycloneDxJSONOption), "cyclone-json", "cyclone-dx-json":
|
||||||
|
return CycloneDxJSONOption
|
||||||
case string(SPDXTagValueOption), "spdx", "spdx-tagvalue", "spdxtagvalue", "spdx-tv", "spdxtv":
|
case string(SPDXTagValueOption), "spdx", "spdx-tagvalue", "spdxtagvalue", "spdx-tv", "spdxtv":
|
||||||
return SPDXTagValueOption
|
return SPDXTagValueOption
|
||||||
case string(SPDXJSONOption), "spdxjson":
|
case string(SPDXJSONOption), "spdxjson":
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user