Skip to content
Merged
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
12 changes: 10 additions & 2 deletions sbom/builders.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func Go(version, path string) (cdx.Component, error) {
if err != nil {
return cdx.Component{}, err
}
deps := Modules(info)
deps := Modules(info, version)
return cdx.Component{
Type: cdx.ComponentTypeApplication, Name: filepath.Base(path), Version: version,
PackageURL: "pkg:golang/" + info.Main.Path + "@" + version, Hashes: sha(sum), Components: &deps,
Expand All @@ -68,15 +68,23 @@ func Go(version, path string) (cdx.Component, error) {
// Modules is what a Go build info says the binary is made of: the standard library of its
// toolchain, and each module - the replacement where there is one, since that is what was
// compiled - with the go.sum hash it was checked against.
func Modules(info *debug.BuildInfo) []cdx.Component {
//
// A module of the binary's own tree - replaced by a directory of it (Alloy's `=> ../syntax`), or a
// workspace's (Grafana's apps) - is stamped (devel), which no scanner matches: it was compiled
// from the tree at the binary's version, so it is that, under the path it is published by.
func Modules(info *debug.BuildInfo, version string) []cdx.Component {
deps := []cdx.Component{{
Type: cdx.ComponentTypeLibrary, Name: "stdlib", Version: strings.TrimPrefix(info.GoVersion, "go"),
PackageURL: "pkg:golang/stdlib@" + strings.TrimPrefix(info.GoVersion, "go"),
}}
for _, d := range info.Deps {
published := d.Path
if d.Replace != nil {
d = d.Replace
}
if d.Version == "(devel)" {
d = &debug.Module{Path: published, Version: version}
}
c := cdx.Component{Type: cdx.ComponentTypeLibrary, Name: d.Path, Version: d.Version, PackageURL: "pkg:golang/" + d.Path + "@" + d.Version}
if d.Sum != "" {
c.Properties = &[]cdx.Property{{Name: "go:sum", Value: d.Sum}}
Expand Down
8 changes: 6 additions & 2 deletions sbom/sbom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,17 @@ func TestDpkgListingIsTheDistributions(t *testing.T) {
}

// A module replaced is the replacement, which is what was compiled, with the go.sum hash it was
// checked against; the standard library is the toolchain's.
// checked against; the standard library is the toolchain's; and a module of the binary's own tree,
// which Go stamps (devel), is the binary's version under the path it is published by.
func TestModulesAreWhatWasCompiled(t *testing.T) {
info := &debug.BuildInfo{GoVersion: "go1.27.2", Deps: []*debug.Module{
{Path: "golang.org/x/net", Version: "v0.60.0", Sum: "h1:abc="},
{Path: "github.com/a/b", Version: "v1.0.0", Replace: &debug.Module{Path: "github.com/fork/b", Version: "v1.0.1", Sum: "h1:def="}},
{Path: "github.com/grafana/alloy/syntax", Version: "v0.1.0", Replace: &debug.Module{Path: "../syntax", Version: "(devel)"}},
{Path: "github.com/grafana/grafana/apps/playlist", Version: "(devel)"},
}}
got := map[string]string{}
for _, c := range sbom.Modules(info) {
for _, c := range sbom.Modules(info, "v13.2.4") {
sum := ""
if c.Properties != nil {
sum = (*c.Properties)[0].Value
Expand All @@ -276,6 +279,7 @@ func TestModulesAreWhatWasCompiled(t *testing.T) {
}
assert.Equal(t, map[string]string{
"pkg:golang/stdlib@1.27.2": "", "pkg:golang/golang.org/x/net@v0.60.0": "h1:abc=", "pkg:golang/github.com/fork/b@v1.0.1": "h1:def=",
"pkg:golang/github.com/grafana/alloy/syntax@v13.2.4": "", "pkg:golang/github.com/grafana/grafana/apps/playlist@v13.2.4": "",
}, got)
}

Expand Down