Skip to content

Commit 702814f

Browse files
committed
feat: add parlay as tool during enrichments
Closes #82.
1 parent 2f3d685 commit 702814f

File tree

10 files changed

+186
-20
lines changed

10 files changed

+186
-20
lines changed

.goreleaser.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ builds:
2222
ldflags:
2323
- "-s"
2424
- "-w"
25-
- "-X github.com/snyk/parlay/internal/commands.version={{.Version}}"
25+
- "-X github.com/snyk/parlay/internal/utils.version={{.Version}}"
2626

2727
archives:
2828
- format: tar.gz

internal/commands/default.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,7 @@ import (
1111
"github.com/snyk/parlay/internal/commands/ecosystems"
1212
"github.com/snyk/parlay/internal/commands/scorecard"
1313
"github.com/snyk/parlay/internal/commands/snyk"
14-
)
15-
16-
// These values are set at build time
17-
var (
18-
version = ""
14+
"github.com/snyk/parlay/internal/utils"
1915
)
2016

2117
func NewDefaultCommand() *cobra.Command {
@@ -26,7 +22,7 @@ func NewDefaultCommand() *cobra.Command {
2622
Use: "parlay",
2723
Short: "Enrich an SBOM with context from third party services",
2824
SilenceUsage: true,
29-
Version: GetVersion(),
25+
Version: utils.GetVersion(),
3026
DisableFlagsInUseLine: true,
3127
Run: func(cmd *cobra.Command, args []string) {
3228
if err := cmd.Help(); err != nil {
@@ -55,7 +51,3 @@ func NewDefaultCommand() *cobra.Command {
5551

5652
return &cmd
5753
}
58-
59-
func GetVersion() string {
60-
return version
61-
}

internal/commands/ecosystems/enrich.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ import (
1212
)
1313

1414
func NewEnrichCommand(logger *zerolog.Logger) *cobra.Command {
15+
var omitWatermark bool
16+
1517
cmd := cobra.Command{
16-
Use: "enrich <sbom>",
17-
Short: "Enrich an SBOM with ecosyste.ms data",
18-
Args: cobra.ExactArgs(1),
18+
Use: "enrich <sbom>",
19+
Short: "Enrich an SBOM with ecosyste.ms data",
20+
Args: cobra.ExactArgs(1),
21+
Version: utils.GetVersion(),
1922
Run: func(cmd *cobra.Command, args []string) {
2023
b, err := utils.GetUserInput(args[0], os.Stdin)
2124
if err != nil {
@@ -29,10 +32,17 @@ func NewEnrichCommand(logger *zerolog.Logger) *cobra.Command {
2932

3033
ecosystems.EnrichSBOM(doc, logger)
3134

35+
if !omitWatermark {
36+
sbom.AddParlayWatermark(doc, cmd.Version)
37+
}
38+
3239
if err := doc.Encode(os.Stdout); err != nil {
3340
logger.Fatal().Err(err).Msg("Failed to encode new SBOM")
3441
}
3542
},
3643
}
44+
45+
cmd.Flags().BoolVar(&omitWatermark, "omit-watermark", false, "omit parlay watermark")
46+
3747
return &cmd
3848
}

internal/commands/scorecard/enrich.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ import (
1212
)
1313

1414
func NewEnrichCommand(logger *zerolog.Logger) *cobra.Command {
15+
var omitWatermark bool
16+
1517
cmd := cobra.Command{
16-
Use: "enrich <sbom>",
17-
Short: "Enrich an SBOM with OpenSSF Scorecard data",
18-
Args: cobra.ExactArgs(1),
18+
Use: "enrich <sbom>",
19+
Short: "Enrich an SBOM with OpenSSF Scorecard data",
20+
Args: cobra.ExactArgs(1),
21+
Version: utils.GetVersion(),
1922
Run: func(cmd *cobra.Command, args []string) {
2023
b, err := utils.GetUserInput(args[0], os.Stdin)
2124
if err != nil {
@@ -29,10 +32,17 @@ func NewEnrichCommand(logger *zerolog.Logger) *cobra.Command {
2932

3033
scorecard.EnrichSBOM(doc)
3134

35+
if !omitWatermark {
36+
sbom.AddParlayWatermark(doc, cmd.Version)
37+
}
38+
3239
if err := doc.Encode(os.Stdout); err != nil {
3340
logger.Fatal().Err(err).Msg("Failed to encode new SBOM")
3441
}
3542
},
3643
}
44+
45+
cmd.Flags().BoolVar(&omitWatermark, "omit-watermark", false, "omit parlay watermark")
46+
3747
return &cmd
3848
}

internal/commands/snyk/enrich.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ import (
1212
)
1313

1414
func NewEnrichCommand(logger *zerolog.Logger) *cobra.Command {
15+
var omitWatermark bool
16+
1517
cmd := cobra.Command{
16-
Use: "enrich <sbom>",
17-
Short: "Enrich an SBOM with Snyk data",
18-
Args: cobra.ExactArgs(1),
18+
Use: "enrich <sbom>",
19+
Short: "Enrich an SBOM with Snyk data",
20+
Args: cobra.ExactArgs(1),
21+
Version: utils.GetVersion(),
1922
Run: func(cmd *cobra.Command, args []string) {
2023
cfg := config()
2124
svc := snyk.NewService(cfg, logger)
@@ -32,10 +35,17 @@ func NewEnrichCommand(logger *zerolog.Logger) *cobra.Command {
3235

3336
svc.EnrichSBOM(doc)
3437

38+
if !omitWatermark {
39+
sbom.AddParlayWatermark(doc, cmd.Version)
40+
}
41+
3542
if err := doc.Encode(os.Stdout); err != nil {
3643
logger.Fatal().Err(err).Msg("Failed to encode new SBOM")
3744
}
3845
},
3946
}
47+
48+
cmd.Flags().BoolVar(&omitWatermark, "omit-watermark", false, "omit parlay watermark")
49+
4050
return &cmd
4151
}

internal/utils/version.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package utils
2+
3+
// This value gets set at build time
4+
var version string
5+
6+
func GetVersion() string {
7+
return version
8+
}

lib/sbom/cyclonedx.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,36 @@ func encodeCycloneDX(bom *cdx.BOM, f cdx.BOMFileFormat) encoderFn {
5353
return cdx.NewBOMEncoder(w, f).Encode(bom)
5454
}
5555
}
56+
57+
func addCDXTool(bom *cdx.BOM, name, version string) {
58+
if bom.Metadata == nil {
59+
bom.Metadata = &cdx.Metadata{}
60+
}
61+
62+
if bom.Metadata.Tools == nil {
63+
bom.Metadata.Tools = &cdx.ToolsChoice{}
64+
}
65+
66+
// Handle possibly existing, legacy "Tools" entry
67+
if bom.Metadata.Tools.Tools != nil {
68+
//nolint:staticcheck // Intentionally using a deprecated type in this case.
69+
*bom.Metadata.Tools.Tools = append(*bom.Metadata.Tools.Tools, cdx.Tool{
70+
Vendor: "Snyk",
71+
Name: name,
72+
})
73+
return
74+
}
75+
76+
if bom.Metadata.Tools.Components == nil {
77+
bom.Metadata.Tools.Components = &[]cdx.Component{}
78+
}
79+
80+
*bom.Metadata.Tools.Components = append(
81+
*bom.Metadata.Tools.Components,
82+
cdx.Component{
83+
Type: cdx.ComponentTypeApplication,
84+
Name: name,
85+
Version: version,
86+
Publisher: "Snyk",
87+
PackageURL: "pkg:github/snyk/parlay"})
88+
}

lib/sbom/spdx.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,13 @@ func encodeSPDX2_3JSON(bom *spdx.Document) encoderFn {
3333
return spdx_json.Write(bom, w)
3434
}
3535
}
36+
37+
func addSPDXTool(bom *spdx.Document, name, _ string) {
38+
if bom.CreationInfo == nil {
39+
bom.CreationInfo = &spdx.CreationInfo{}
40+
}
41+
42+
bom.CreationInfo.Creators = append(
43+
bom.CreationInfo.Creators,
44+
spdx.Creator{Creator: name, CreatorType: "Tool"})
45+
}

lib/sbom/watermark.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* © 2024 Snyk Limited All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package sbom
18+
19+
import (
20+
cdx "github.com/CycloneDX/cyclonedx-go"
21+
"github.com/spdx/tools-golang/spdx"
22+
)
23+
24+
func AddParlayWatermark(doc *SBOMDocument, version string) {
25+
switch bom := doc.BOM.(type) {
26+
case *cdx.BOM:
27+
addCDXTool(bom, "parlay", version)
28+
case *spdx.Document:
29+
addSPDXTool(bom, "parlay", version)
30+
}
31+
}

lib/sbom/watermark_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* © 2024 Snyk Limited All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package sbom
18+
19+
import (
20+
"testing"
21+
22+
cdx "github.com/CycloneDX/cyclonedx-go"
23+
"github.com/spdx/tools-golang/spdx"
24+
"github.com/stretchr/testify/assert"
25+
"github.com/stretchr/testify/require"
26+
)
27+
28+
func TestAddParlayWatermark_CycloneDX(t *testing.T) {
29+
doc, err := DecodeSBOMDocument([]byte(`{
30+
"bomFormat": "CycloneDX",
31+
"specVersion": "1.6"
32+
}`))
33+
require.NoError(t, err)
34+
35+
AddParlayWatermark(doc, "0.0.0")
36+
37+
bom, ok := doc.BOM.(*cdx.BOM)
38+
require.True(t, ok)
39+
40+
require.NotNil(t, bom.Metadata.Tools.Components)
41+
require.Len(t, *bom.Metadata.Tools.Components, 1)
42+
tool := (*bom.Metadata.Tools.Components)[0]
43+
assert.Equal(t, "application", string(tool.Type))
44+
assert.Equal(t, "parlay", tool.Name)
45+
assert.Equal(t, "0.0.0", tool.Version)
46+
assert.Equal(t, "Snyk", tool.Publisher)
47+
}
48+
49+
func TestAddParlayWatermark_SPDX(t *testing.T) {
50+
doc, err := DecodeSBOMDocument([]byte(`{
51+
"spdxVersion": "SPDX-2.3",
52+
"SPDXID": "SPDXRef-DOCUMENT"
53+
}`))
54+
require.NoError(t, err)
55+
56+
AddParlayWatermark(doc, "0.0.0")
57+
58+
bom, ok := doc.BOM.(*spdx.Document)
59+
require.True(t, ok)
60+
61+
assert.Contains(t, bom.CreationInfo.Creators, spdx.Creator{Creator: "parlay", CreatorType: "Tool"})
62+
}

0 commit comments

Comments
 (0)