sorcery-go/pkg/legal/sbom.go

59 lines
1.9 KiB
Go
Executable File

// SBOM (Software Bill of Materials) export.
//
// Generates CycloneDX or SPDX reports from the Coven's Tomb. Used by the
// legal department to audit the fleet and by Portable Tool Bin consumers
// who need to redistribute static binaries with proper attribution.
package legal
import (
"encoding/json"
"encoding/xml"
"fmt"
)
// Component is one entry in the SBOM.
type Component struct {
Name string `json:"name" xml:"name"`
Version string `json:"version" xml:"version"`
License string `json:"license" xml:"license"`
Hash string `json:"hash" xml:"hash"`
Purl string `json:"purl" xml:"purl"`
}
// Sbom is the report itself.
type Sbom struct {
Components []Component `json:"components" xml:"component"`
}
// ExportCycloneDX produces a CycloneDX v1.4 JSON document for a set of
// Essences. `tree` is the dependency tree returned by the Tomb.
func ExportCycloneDX(tree []Component) ([]byte, error) {
s := Sbom{Components: tree}
return json.MarshalIndent(s, "", " ")
}
// ExportSPDX produces an SPDX 2.3 XML document for the same data.
func ExportSPDX(tree []Component) ([]byte, error) {
type spdxDoc struct {
XMLName struct{} `xml:"SpdxDocument"`
License string `xml:"License,attr"`
Comp []Component `xml:"component"`
}
return xml.MarshalIndent(spdxDoc{Comp: tree}, "", " ")
}
// AttributionBundle collects every LICENSE / COPYING file referenced by
// the given components. The Portable Tool Bin attaches this as
// CREDITS.md / LICENSE_BUNDLE.txt to every downloaded static ELF so the
// legal "notice" requirement of MIT/BSD/GPL is satisfied out-of-the-box.
func AttributionBundle(tree []Component) string {
var out string
out = "# Attribution Bundle\n\nGenerated by the Sorcery-Go Legal Sentinel.\n\n"
for _, c := range tree {
out += fmt.Sprintf("## %s %s\n", c.Name, c.Version)
out += fmt.Sprintf("- License: %s\n", c.License)
out += fmt.Sprintf("- Hash: %s\n\n", c.Hash)
}
return out
}