Skip to content

Commit

Permalink
feat: add GOOS and GOARCH into PURL (#217)
Browse files Browse the repository at this point in the history
* feat: add os and arch into PURL

	- keep bom-ref as is
	- only metadata.component.purl and components.component.purl are updated

Signed-off-by: Wen Zhou <wenzhou@redhat.com>

* update: change to use gocmd to get GOOS and GOARCH from "go env -json"

Signed-off-by: Wen Zhou <wenzhou@redhat.com>

* test: update testdata

Signed-off-by: Wen Zhou <wenzhou@redhat.com>

* style: gofmt and use logger NoP()

Signed-off-by: Wen Zhou <wenzhou@redhat.com>

Signed-off-by: Wen Zhou <wenzhou@redhat.com>
  • Loading branch information
zdtsw committed Dec 12, 2022
1 parent fb88664 commit 86d7a92
Show file tree
Hide file tree
Showing 24 changed files with 133 additions and 87 deletions.
23 changes: 18 additions & 5 deletions internal/gomod/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"path/filepath"
"strings"

"github.com/rs/zerolog"
"golang.org/x/exp/slices"
"golang.org/x/mod/semver"
"golang.org/x/mod/sumdb/dirhash"
"io"
"path/filepath"
"strings"
"sync"

"github.com/CycloneDX/cyclonedx-gomod/internal/gocmd"
"github.com/CycloneDX/cyclonedx-gomod/internal/util"
Expand Down Expand Up @@ -69,10 +69,23 @@ func (m Module) Hash() (string, error) {
return h1, nil
}

func (m Module) PackageURL() string {
func (m Module) BOMRef() string {
return fmt.Sprintf("pkg:golang/%s?type=module", m.Coordinates())
}

var (
envOnce sync.Once
envMap map[string]string
)

func (m Module) PackageURL() string {
envOnce.Do(func() {
envMap, _ = gocmd.GetEnv(zerolog.Nop())
})

return fmt.Sprintf("pkg:golang/%s?type=module&goos=%s&goarch=%s", m.Coordinates(), envMap["GOOS"], envMap["GOARCH"])
}

// IsModule determines whether dir is a Go module.
func IsModule(dir string) bool {
return util.FileExists(filepath.Join(dir, "go.mod"))
Expand Down
23 changes: 21 additions & 2 deletions internal/gomod/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ package gomod

import (
"bytes"

"os/exec"
"path/filepath"
"strings"
"testing"

"github.com/rs/zerolog"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/CycloneDX/cyclonedx-gomod/internal/gocmd"
)

func TestModule_Coordinates(t *testing.T) {
Expand Down Expand Up @@ -66,13 +70,28 @@ func TestModule_Hash(t *testing.T) {
require.Equal(t, "h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=", hash)
}

func TestModule_PackageURL(t *testing.T) {
func TestModule_BOMRef(t *testing.T) {

module := Module{
Path: "github.com/CycloneDX/cyclonedx-go",
Version: "v0.1.0",
}
assert.Equal(t, "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.1.0?type=module", module.BOMRef())
}

assert.Equal(t, "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.1.0?type=module", module.PackageURL())
func TestModule_PackageURL(t *testing.T) {
// To get value from "go env -json", cannot just use t.GetEnv() might return ""
envMap, _ = gocmd.GetEnv(zerolog.Nop())
goos := envMap["GOOS"]
goarch := envMap["GOARCH"]

module := Module{
Path: "github.com/CycloneDX/cyclonedx-go",
Version: "v0.1.0",
}
assert.Equal(t, "linux", goos)
assert.Equal(t, "amd64", goarch)
assert.Equal(t, "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.1.0?type=module&goos="+goos+"&goarch="+goarch, module.PackageURL())
}

func TestIsModule(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion internal/sbom/convert/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func ToComponent(logger zerolog.Logger, module gomod.Module, options ...Option)
Msg("converting module to component")

component := cdx.Component{
BOMRef: module.PackageURL(),
BOMRef: module.BOMRef(),
Type: cdx.ComponentTypeLibrary,
Name: module.Path,
Version: module.Version,
Expand Down
12 changes: 9 additions & 3 deletions internal/sbom/convert/module/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/CycloneDX/cyclonedx-gomod/internal/gocmd"
"github.com/CycloneDX/cyclonedx-gomod/internal/gomod"
)

Expand Down Expand Up @@ -179,6 +180,11 @@ func TestWithTestScope(t *testing.T) {
}

func TestToComponent(t *testing.T) {
// To get value from "go env -json", cannot just use t.GetEnv() might return ""
envMap, _ := gocmd.GetEnv(zerolog.Nop())
goos := envMap["GOOS"]
goarch := envMap["GOARCH"]

t.Run("Success", func(t *testing.T) {
module := gomod.Module{
Path: "path",
Expand All @@ -193,7 +199,7 @@ func TestToComponent(t *testing.T) {
require.Equal(t, cdx.ComponentTypeLibrary, component.Type)
require.Equal(t, "path", component.Name)
require.Equal(t, "version", component.Version)
require.Equal(t, "pkg:golang/path@version?type=module", component.PackageURL)
require.Equal(t, "pkg:golang/path@version?type=module&goos="+goos+"&goarch="+goarch, component.PackageURL)
require.Equal(t, cdx.ScopeRequired, component.Scope)
})

Expand All @@ -212,7 +218,7 @@ func TestToComponent(t *testing.T) {
require.Equal(t, cdx.ComponentTypeLibrary, component.Type)
require.Equal(t, "path", component.Name)
require.Equal(t, "version", component.Version)
require.Equal(t, "pkg:golang/path@version?type=module", component.PackageURL)
require.Equal(t, "pkg:golang/path@version?type=module&goos="+goos+"&goarch="+goarch, component.PackageURL)
require.Equal(t, cdx.ScopeOptional, component.Scope)
})

Expand All @@ -234,7 +240,7 @@ func TestToComponent(t *testing.T) {
require.Equal(t, cdx.ComponentTypeLibrary, component.Type)
require.Equal(t, "pathReplace", component.Name)
require.Equal(t, "versionReplace", component.Version)
require.Equal(t, "pkg:golang/pathReplace@versionReplace?type=module", component.PackageURL)
require.Equal(t, "pkg:golang/pathReplace@versionReplace?type=module&goos="+goos+"&goarch="+goarch, component.PackageURL)
require.Equal(t, cdx.ScopeRequired, component.Scope)
})

Expand Down
6 changes: 3 additions & 3 deletions internal/sbom/sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ func BuildDependencyGraph(modules []gomod.Module) []cdx.Dependency {
if module.Replace != nil {
module = *module.Replace
}
cdxDependant := cdx.Dependency{Ref: module.PackageURL()}
cdxDependant := cdx.Dependency{Ref: module.BOMRef()}

if module.Dependencies != nil {
cdxDependencies := make([]string, len(module.Dependencies))
for i := range module.Dependencies {
if module.Dependencies[i].Replace != nil {
cdxDependencies[i] = module.Dependencies[i].Replace.PackageURL()
cdxDependencies[i] = module.Dependencies[i].Replace.BOMRef()
} else {
cdxDependencies[i] = module.Dependencies[i].PackageURL()
cdxDependencies[i] = module.Dependencies[i].BOMRef()
}
}
if len(cdxDependencies) > 0 {
Expand Down
23 changes: 12 additions & 11 deletions internal/testutil/testutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,23 @@ func RequireMatchingPropertyToBeRedacted(t *testing.T, properties []cdx.Property
// If files are expected, their correlating components will be removed and replaced by an empty slice.
func RequireStdlibComponentToBeRedacted(t *testing.T, bom *cdx.BOM, expectPackages, expectFiles bool) {
var (
version string
oldPURL string
newPURL string
version string
oldBOMRef string
newBOMRef string
newPURL string
)

for i, component := range *bom.Components {
if component.Name == "std" {
require.Regexp(t, `^go1\.`, component.Version)

version = component.Version
oldPURL = component.PackageURL
oldBOMRef = component.BOMRef
newBOMRef = strings.ReplaceAll((*bom.Components)[i].BOMRef, version, Redacted)
newPURL = strings.ReplaceAll((*bom.Components)[i].PackageURL, version, Redacted)

(*bom.Components)[i].Version = Redacted
(*bom.Components)[i].BOMRef = newPURL
(*bom.Components)[i].BOMRef = newBOMRef
(*bom.Components)[i].PackageURL = newPURL

// Redact all packages and files, as they may differ from one go version to another.
Expand All @@ -110,21 +112,20 @@ func RequireStdlibComponentToBeRedacted(t *testing.T, bom *cdx.BOM, expectPackag
} else if expectPackages {
t.Fatalf("stdlib is missing packages")
}

break
}
}
if newPURL == "" {
if newPURL == "" && newBOMRef == "" {
t.Fatalf("stdlib component not found")
}

for i, dependency := range *bom.Dependencies {
if dependency.Ref == oldPURL { // Dependant
(*bom.Dependencies)[i].Ref = newPURL
if dependency.Ref == oldBOMRef { // Dependant
(*bom.Dependencies)[i].Ref = newBOMRef
} else if dependency.Dependencies != nil { // Dependencies
for j, dependency2 := range *(*bom.Dependencies)[i].Dependencies {
if dependency2 == oldPURL {
(*(*bom.Dependencies)[i].Dependencies)[j] = newPURL
if dependency2 == oldBOMRef {
(*(*bom.Dependencies)[i].Dependencies)[j] = newBOMRef
}
}
}
Expand Down
19 changes: 12 additions & 7 deletions pkg/generate/app/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,19 +232,24 @@ func (g generator) includeAppPathInMainComponentPURL(bom *cdx.BOM) error {
oldPURL := bom.Metadata.Component.PackageURL
newPURL := oldPURL + "#" + filepath.ToSlash(mainDirRel)

oldBOMRef := bom.Metadata.Component.BOMRef
newBOMRef := oldBOMRef + "#" + filepath.ToSlash(mainDirRel)

g.logger.Debug().
Str("old", oldPURL).
Str("new", newPURL).
Str("oldpurl", oldPURL).
Str("newpurl", newPURL).
Str("oldbomref", oldBOMRef).
Str("newbomref", newBOMRef).
Msg("updating purl of main component")

// Update PURL of main component
bom.Metadata.Component.BOMRef = newPURL
// Update BOMRef and PURL of main component
bom.Metadata.Component.BOMRef = newBOMRef
bom.Metadata.Component.PackageURL = newPURL

// Update PURL in dependency graph
// Update PURL in dependency graph (without GOOS and GOARCH)
for i, dep := range *bom.Dependencies {
if dep.Ref == oldPURL {
(*bom.Dependencies)[i].Ref = newPURL
if dep.Ref == oldBOMRef {
(*bom.Dependencies)[i].Ref = newBOMRef
break
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<component bom-ref="pkg:golang/testmod-simple@v0.0.0-20210716183230-c7ea7c975ab8?type=module" type="application">
<name>testmod-simple</name>
<version>v0.0.0-20210716183230-c7ea7c975ab8</version>
<purl>pkg:golang/testmod-simple@v0.0.0-20210716183230-c7ea7c975ab8?type=module</purl>
<purl>pkg:golang/testmod-simple@v0.0.0-20210716183230-c7ea7c975ab8?type=module&amp;goos=linux&amp;goarch=amd64</purl>
<properties>
<property name="cdx:gomod:build:env:CGO_ENABLED">REDACTED</property>
<property name="cdx:gomod:build:env:GOARCH">REDACTED</property>
Expand All @@ -21,7 +21,7 @@
<hashes>
<hash alg="SHA-256">a8962d5e72515a6a5eee6ff75e5ca1aec2eb11446a1d1336931ce8c57ab2503b</hash>
</hashes>
<purl>pkg:golang/github.com/google/uuid@v1.2.0?type=module</purl>
<purl>pkg:golang/github.com/google/uuid@v1.2.0?type=module&amp;goos=linux&amp;goarch=amd64</purl>
<externalReferences>
<reference type="vcs">
<url>https://github.com/google/uuid</url>
Expand All @@ -39,7 +39,7 @@
<name>std</name>
<version>REDACTED</version>
<scope>required</scope>
<purl>pkg:golang/std@REDACTED?type=module</purl>
<purl>pkg:golang/std@REDACTED?type=module&amp;goos=linux&amp;goarch=amd64</purl>
</component>
</components>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<component bom-ref="pkg:golang/testmod-simple@v0.0.0-20210901192510-dc2d14d2351d?type=module#cmd/purl" type="application">
<name>testmod-simple</name>
<version>v0.0.0-20210901192510-dc2d14d2351d</version>
<purl>pkg:golang/testmod-simple@v0.0.0-20210901192510-dc2d14d2351d?type=module#cmd/purl</purl>
<purl>pkg:golang/testmod-simple@v0.0.0-20210901192510-dc2d14d2351d?type=module&amp;goos=linux&amp;goarch=amd64#cmd/purl</purl>
<properties>
<property name="cdx:gomod:build:env:CGO_ENABLED">REDACTED</property>
<property name="cdx:gomod:build:env:GOARCH">REDACTED</property>
Expand All @@ -21,7 +21,7 @@
<hashes>
<hash alg="SHA-256">79f58173df0efdd059460d69c36c620f3a2f9e532309af4d3e77da88176e87c2</hash>
</hashes>
<purl>pkg:golang/github.com/package-url/packageurl-go@v0.1.0?type=module</purl>
<purl>pkg:golang/github.com/package-url/packageurl-go@v0.1.0?type=module&amp;goos=linux&amp;goarch=amd64</purl>
<externalReferences>
<reference type="vcs">
<url>https://github.com/package-url/packageurl-go</url>
Expand All @@ -32,7 +32,7 @@
<name>std</name>
<version>REDACTED</version>
<scope>required</scope>
<purl>pkg:golang/std@REDACTED?type=module</purl>
<purl>pkg:golang/std@REDACTED?type=module&amp;goos=linux&amp;goarch=amd64</purl>
</component>
</components>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<component bom-ref="pkg:golang/testmod-simple@v0.0.0-20210901192510-dc2d14d2351d?type=module#cmd/uuid" type="application">
<name>testmod-simple</name>
<version>v0.0.0-20210901192510-dc2d14d2351d</version>
<purl>pkg:golang/testmod-simple@v0.0.0-20210901192510-dc2d14d2351d?type=module#cmd/uuid</purl>
<purl>pkg:golang/testmod-simple@v0.0.0-20210901192510-dc2d14d2351d?type=module&amp;goos=linux&amp;goarch=amd64#cmd/uuid</purl>
<properties>
<property name="cdx:gomod:build:env:CGO_ENABLED">REDACTED</property>
<property name="cdx:gomod:build:env:GOARCH">REDACTED</property>
Expand All @@ -21,7 +21,7 @@
<hashes>
<hash alg="SHA-256">a8962d5e72515a6a5eee6ff75e5ca1aec2eb11446a1d1336931ce8c57ab2503b</hash>
</hashes>
<purl>pkg:golang/github.com/google/uuid@v1.2.0?type=module</purl>
<purl>pkg:golang/github.com/google/uuid@v1.2.0?type=module&amp;goos=linux&amp;goarch=amd64</purl>
<externalReferences>
<reference type="vcs">
<url>https://github.com/google/uuid</url>
Expand All @@ -39,7 +39,7 @@
<name>std</name>
<version>REDACTED</version>
<scope>required</scope>
<purl>pkg:golang/std@REDACTED?type=module</purl>
<purl>pkg:golang/std@REDACTED?type=module&amp;goos=linux&amp;goarch=amd64</purl>
</component>
</components>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<component bom-ref="pkg:golang/testmod-vendored@v0.0.0-20210716185931-5c9f3d791930?type=module" type="application">
<name>testmod-vendored</name>
<version>v0.0.0-20210716185931-5c9f3d791930</version>
<purl>pkg:golang/testmod-vendored@v0.0.0-20210716185931-5c9f3d791930?type=module</purl>
<purl>pkg:golang/testmod-vendored@v0.0.0-20210716185931-5c9f3d791930?type=module&amp;goos=linux&amp;goarch=amd64</purl>
<properties>
<property name="cdx:gomod:build:env:CGO_ENABLED">REDACTED</property>
<property name="cdx:gomod:build:env:GOARCH">REDACTED</property>
Expand All @@ -18,7 +18,7 @@
<name>github.com/google/uuid</name>
<version>v1.2.0</version>
<scope>required</scope>
<purl>pkg:golang/github.com/google/uuid@v1.2.0?type=module</purl>
<purl>pkg:golang/github.com/google/uuid@v1.2.0?type=module&amp;goos=linux&amp;goarch=amd64</purl>
<externalReferences>
<reference type="vcs">
<url>https://github.com/google/uuid</url>
Expand All @@ -36,7 +36,7 @@
<name>std</name>
<version>REDACTED</version>
<scope>required</scope>
<purl>pkg:golang/std@REDACTED?type=module</purl>
<purl>pkg:golang/std@REDACTED?type=module&amp;goos=linux&amp;goarch=amd64</purl>
</component>
</components>
<dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<component bom-ref="pkg:golang/testmod-vendored@v0.0.0-20210716185931-5c9f3d791930?type=module" type="application">
<name>testmod-vendored</name>
<version>v0.0.0-20210716185931-5c9f3d791930</version>
<purl>pkg:golang/testmod-vendored@v0.0.0-20210716185931-5c9f3d791930?type=module</purl>
<purl>pkg:golang/testmod-vendored@v0.0.0-20210716185931-5c9f3d791930?type=module&amp;goos=linux&amp;goarch=amd64</purl>
<properties>
<property name="cdx:gomod:build:env:CGO_ENABLED">REDACTED</property>
<property name="cdx:gomod:build:env:GOARCH">REDACTED</property>
Expand Down Expand Up @@ -39,7 +39,7 @@
<name>github.com/google/uuid</name>
<version>v1.2.0</version>
<scope>required</scope>
<purl>pkg:golang/github.com/google/uuid@v1.2.0?type=module</purl>
<purl>pkg:golang/github.com/google/uuid@v1.2.0?type=module&amp;goos=linux&amp;goarch=amd64</purl>
<externalReferences>
<reference type="vcs">
<url>https://github.com/google/uuid</url>
Expand Down Expand Up @@ -210,7 +210,7 @@
<name>std</name>
<version>REDACTED</version>
<scope>required</scope>
<purl>pkg:golang/std@REDACTED?type=module</purl>
<purl>pkg:golang/std@REDACTED?type=module&amp;goos=linux&amp;goarch=amd64</purl>
<components></components>
</component>
</components>
Expand Down

0 comments on commit 86d7a92

Please sign in to comment.