mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-06 03:13:48 +02:00
874d698564
here's an idea: `goreleaser healthcheck` It'll check if the needed dependencies (docker, git, etc) are available in the path... this way users can preemptively run it before releasing or to debug issues. What do you think? Here's how it looks like: <img width="1007" alt="CleanShot 2023-03-02 at 23 24 26@2x" src="https://user-images.githubusercontent.com/245435/222615682-d9cd0733-d900-43d1-9166-23b2be589b3a.png"> --------- Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
763 lines
19 KiB
Go
763 lines
19 KiB
Go
package sbom
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/goreleaser/goreleaser/internal/artifact"
|
|
"github.com/goreleaser/goreleaser/internal/testctx"
|
|
"github.com/goreleaser/goreleaser/internal/testlib"
|
|
"github.com/goreleaser/goreleaser/pkg/config"
|
|
"github.com/goreleaser/goreleaser/pkg/context"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestDescription(t *testing.T) {
|
|
require.NotEmpty(t, Pipe{}.String())
|
|
}
|
|
|
|
func TestSBOMCatalogDefault(t *testing.T) {
|
|
defaultArgs := []string{"$artifact", "--file", "$document", "--output", "spdx-json"}
|
|
defaultSboms := []string{
|
|
"{{ .ArtifactName }}.sbom",
|
|
}
|
|
defaultCmd := "syft"
|
|
tests := []struct {
|
|
configs []config.SBOM
|
|
artifact string
|
|
cmd string
|
|
sboms []string
|
|
args []string
|
|
env []string
|
|
err bool
|
|
}{
|
|
{
|
|
configs: []config.SBOM{
|
|
{
|
|
// empty
|
|
},
|
|
},
|
|
artifact: "archive",
|
|
cmd: defaultCmd,
|
|
sboms: defaultSboms,
|
|
args: defaultArgs,
|
|
env: []string{
|
|
"SYFT_FILE_METADATA_CATALOGER_ENABLED=true",
|
|
},
|
|
},
|
|
{
|
|
configs: []config.SBOM{
|
|
{
|
|
Artifacts: "package",
|
|
},
|
|
},
|
|
artifact: "package",
|
|
cmd: defaultCmd,
|
|
sboms: defaultSboms,
|
|
args: defaultArgs,
|
|
},
|
|
{
|
|
configs: []config.SBOM{
|
|
{
|
|
Artifacts: "archive",
|
|
},
|
|
},
|
|
artifact: "archive",
|
|
cmd: defaultCmd,
|
|
sboms: defaultSboms,
|
|
args: defaultArgs,
|
|
env: []string{
|
|
"SYFT_FILE_METADATA_CATALOGER_ENABLED=true",
|
|
},
|
|
},
|
|
{
|
|
configs: []config.SBOM{
|
|
{
|
|
Artifacts: "archive",
|
|
Env: []string{
|
|
"something=something-else",
|
|
},
|
|
},
|
|
},
|
|
artifact: "archive",
|
|
cmd: defaultCmd,
|
|
sboms: defaultSboms,
|
|
args: defaultArgs,
|
|
env: []string{
|
|
"something=something-else",
|
|
},
|
|
},
|
|
{
|
|
configs: []config.SBOM{
|
|
{
|
|
Artifacts: "any",
|
|
},
|
|
},
|
|
artifact: "any",
|
|
cmd: defaultCmd,
|
|
sboms: []string{},
|
|
args: defaultArgs,
|
|
},
|
|
{
|
|
configs: []config.SBOM{
|
|
{
|
|
Artifacts: "binary",
|
|
},
|
|
},
|
|
artifact: "binary",
|
|
cmd: defaultCmd,
|
|
sboms: []string{"{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}.sbom"},
|
|
args: defaultArgs,
|
|
},
|
|
{
|
|
configs: []config.SBOM{
|
|
{
|
|
Artifacts: "source",
|
|
},
|
|
},
|
|
artifact: "source",
|
|
cmd: defaultCmd,
|
|
sboms: defaultSboms,
|
|
args: defaultArgs,
|
|
env: []string{
|
|
"SYFT_FILE_METADATA_CATALOGER_ENABLED=true",
|
|
},
|
|
},
|
|
{
|
|
// multiple documents are not allowed when artifacts != "any"
|
|
configs: []config.SBOM{
|
|
{
|
|
Artifacts: "binary",
|
|
Documents: []string{
|
|
"doc1",
|
|
"doc2",
|
|
},
|
|
},
|
|
},
|
|
err: true,
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(fmt.Sprintf("artifact=%q", test.configs[0].Artifacts), func(t *testing.T) {
|
|
testlib.CheckPath(t, "syft")
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
SBOMs: test.configs,
|
|
})
|
|
err := Pipe{}.Default(ctx)
|
|
if test.err {
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
require.Equal(t, ctx.Config.SBOMs[0].Cmd, test.cmd)
|
|
require.Equal(t, ctx.Config.SBOMs[0].Documents, test.sboms)
|
|
require.Equal(t, ctx.Config.SBOMs[0].Args, test.args)
|
|
require.Equal(t, ctx.Config.SBOMs[0].Env, test.env)
|
|
require.Equal(t, ctx.Config.SBOMs[0].Artifacts, test.artifact)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSBOMCatalogInvalidArtifacts(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{{Artifacts: "foo"}},
|
|
})
|
|
err := Pipe{}.Run(ctx)
|
|
require.EqualError(t, err, "invalid list of artifacts to catalog: foo")
|
|
}
|
|
|
|
func TestSeveralSBOMsWithTheSameID(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
ID: "a",
|
|
},
|
|
{
|
|
ID: "a",
|
|
},
|
|
},
|
|
})
|
|
require.EqualError(t, Pipe{}.Default(ctx), "found 2 sboms with the ID 'a', please fix your config")
|
|
}
|
|
|
|
func TestSkipCataloging(t *testing.T) {
|
|
t.Run("skip", func(t *testing.T) {
|
|
require.True(t, Pipe{}.Skip(testctx.New()))
|
|
})
|
|
|
|
t.Run("skip SBOM cataloging", func(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
Artifacts: "all",
|
|
},
|
|
},
|
|
})
|
|
ctx.SkipSBOMCataloging = true
|
|
require.True(t, Pipe{}.Skip(ctx))
|
|
})
|
|
|
|
t.Run("dont skip", func(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
Artifacts: "all",
|
|
},
|
|
},
|
|
})
|
|
require.False(t, Pipe{}.Skip(ctx))
|
|
})
|
|
}
|
|
|
|
func TestSBOMCatalogArtifacts(t *testing.T) {
|
|
tests := []struct {
|
|
desc string
|
|
ctx *context.Context
|
|
sbomPaths []string
|
|
sbomNames []string
|
|
expectedErrMsg string
|
|
}{
|
|
{
|
|
desc: "catalog errors",
|
|
expectedErrMsg: "cataloging artifacts: exit failed",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
Artifacts: "binary",
|
|
Cmd: "exit",
|
|
Args: []string{"1"},
|
|
},
|
|
},
|
|
}),
|
|
},
|
|
{
|
|
desc: "invalid args template",
|
|
expectedErrMsg: `cataloging artifacts failed: arg "${FOO}-{{ .foo }{{}}{": invalid template: template: tmpl:1: unexpected "}" in operand`,
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
Artifacts: "binary",
|
|
Cmd: "exit",
|
|
Args: []string{"${FOO}-{{ .foo }{{}}{"},
|
|
},
|
|
},
|
|
Env: []string{
|
|
"FOO=BAR",
|
|
},
|
|
}),
|
|
},
|
|
{
|
|
desc: "catalog source archives",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{Artifacts: "source"},
|
|
},
|
|
}),
|
|
sbomPaths: []string{"artifact5.tar.gz.sbom"},
|
|
sbomNames: []string{"artifact5.tar.gz.sbom"},
|
|
},
|
|
{
|
|
desc: "catalog archives",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{Artifacts: "archive"},
|
|
},
|
|
}),
|
|
sbomPaths: []string{"artifact1.sbom", "artifact2.sbom"},
|
|
sbomNames: []string{"artifact1.sbom", "artifact2.sbom"},
|
|
},
|
|
{
|
|
desc: "catalog linux packages",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{Artifacts: "package"},
|
|
},
|
|
}),
|
|
sbomPaths: []string{"package1.deb.sbom"},
|
|
sbomNames: []string{"package1.deb.sbom"},
|
|
},
|
|
{
|
|
desc: "catalog binaries",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{Artifacts: "binary"},
|
|
},
|
|
}),
|
|
sbomPaths: []string{
|
|
"artifact3-name_1.2.2_linux_amd64.sbom",
|
|
"artifact4-name_1.2.2_linux_amd64.sbom",
|
|
},
|
|
sbomNames: []string{
|
|
"artifact3-name_1.2.2_linux_amd64.sbom",
|
|
"artifact4-name_1.2.2_linux_amd64.sbom",
|
|
},
|
|
},
|
|
{
|
|
desc: "manual cataloging",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
Artifacts: "any",
|
|
Args: []string{
|
|
"--file",
|
|
"$document0",
|
|
"--output",
|
|
"spdx-json",
|
|
"artifact5.tar.gz",
|
|
},
|
|
Documents: []string{
|
|
"final.sbom",
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
sbomPaths: []string{"final.sbom"},
|
|
sbomNames: []string{"final.sbom"},
|
|
},
|
|
{
|
|
desc: "multiple SBOM configs",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
Env: []string{
|
|
"SBOM_SUFFIX=s2-ish",
|
|
},
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
ID: "s1",
|
|
Artifacts: "binary",
|
|
},
|
|
{
|
|
ID: "s2",
|
|
Artifacts: "archive",
|
|
Documents: []string{"{{ .ArtifactName }}.{{ .Env.SBOM_SUFFIX }}.sbom"},
|
|
},
|
|
},
|
|
}),
|
|
sbomPaths: []string{
|
|
"artifact1.s2-ish.sbom",
|
|
"artifact2.s2-ish.sbom",
|
|
"artifact3-name_1.2.2_linux_amd64.sbom",
|
|
"artifact4-name_1.2.2_linux_amd64.sbom",
|
|
},
|
|
sbomNames: []string{
|
|
"artifact1.s2-ish.sbom",
|
|
"artifact2.s2-ish.sbom",
|
|
"artifact3-name_1.2.2_linux_amd64.sbom",
|
|
"artifact4-name_1.2.2_linux_amd64.sbom",
|
|
},
|
|
},
|
|
{
|
|
desc: "catalog artifacts with filtered by ID",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
Artifacts: "binary",
|
|
IDs: []string{"foo"},
|
|
},
|
|
},
|
|
}),
|
|
sbomPaths: []string{
|
|
"artifact3-name_1.2.2_linux_amd64.sbom",
|
|
},
|
|
sbomNames: []string{
|
|
"artifact3-name_1.2.2_linux_amd64.sbom",
|
|
},
|
|
},
|
|
{
|
|
desc: "catalog binary artifacts with env in arguments",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
Artifacts: "binary",
|
|
Args: []string{
|
|
"--file",
|
|
"$document",
|
|
"--output",
|
|
"spdx-json",
|
|
"$artifact",
|
|
},
|
|
Documents: []string{
|
|
"{{ .ArtifactName }}.{{ .Env.TEST_USER }}.sbom",
|
|
},
|
|
},
|
|
},
|
|
Env: []string{
|
|
"TEST_USER=test-user-name",
|
|
},
|
|
}),
|
|
sbomPaths: []string{
|
|
"artifact3-name.test-user-name.sbom",
|
|
"artifact4.test-user-name.sbom",
|
|
},
|
|
sbomNames: []string{
|
|
"artifact3-name.test-user-name.sbom",
|
|
"artifact4.test-user-name.sbom",
|
|
},
|
|
},
|
|
{
|
|
desc: "cataloging 'any' artifacts fails",
|
|
ctx: testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{
|
|
Artifacts: "any",
|
|
Cmd: "false",
|
|
},
|
|
},
|
|
}),
|
|
expectedErrMsg: "cataloging artifacts: false failed: exit status 1: ",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
testSBOMCataloging(t, test.ctx, test.sbomPaths, test.sbomNames, test.expectedErrMsg)
|
|
})
|
|
}
|
|
}
|
|
|
|
func testSBOMCataloging(tb testing.TB, ctx *context.Context, sbomPaths, sbomNames []string, expectedErrMsg string) {
|
|
tb.Helper()
|
|
testlib.CheckPath(tb, "syft")
|
|
tmpdir := tb.TempDir()
|
|
|
|
ctx.Config.Dist = tmpdir
|
|
ctx.Version = "1.2.2"
|
|
|
|
// create some fake artifacts
|
|
artifacts := []string{"artifact1", "artifact2", "artifact3", "package1.deb"}
|
|
require.NoError(tb, os.Mkdir(filepath.Join(tmpdir, "linux_amd64"), os.ModePerm))
|
|
for _, f := range artifacts {
|
|
file := filepath.Join(tmpdir, f)
|
|
require.NoError(tb, os.WriteFile(file, []byte("foo"), 0o644))
|
|
}
|
|
require.NoError(tb, os.WriteFile(filepath.Join(tmpdir, "linux_amd64", "artifact4"), []byte("foo"), 0o644))
|
|
artifacts = append(artifacts, "linux_amd64/artifact4")
|
|
require.NoError(tb, os.WriteFile(filepath.Join(tmpdir, "artifact5.tar.gz"), []byte("foo"), 0o644))
|
|
artifacts = append(artifacts, "artifact5.tar.gz")
|
|
ctx.Artifacts.Add(&artifact.Artifact{
|
|
Name: "artifact1",
|
|
Path: filepath.Join(tmpdir, "artifact1"),
|
|
Type: artifact.UploadableArchive,
|
|
Extra: map[string]interface{}{
|
|
artifact.ExtraID: "foo",
|
|
},
|
|
})
|
|
ctx.Artifacts.Add(&artifact.Artifact{
|
|
Name: "artifact2",
|
|
Path: filepath.Join(tmpdir, "artifact2"),
|
|
Type: artifact.UploadableArchive,
|
|
Extra: map[string]interface{}{
|
|
artifact.ExtraID: "foo3",
|
|
},
|
|
})
|
|
ctx.Artifacts.Add(&artifact.Artifact{
|
|
Name: "artifact3-name",
|
|
Path: filepath.Join(tmpdir, "artifact3"),
|
|
Goos: "linux",
|
|
Goarch: "amd64",
|
|
Type: artifact.UploadableBinary,
|
|
Extra: map[string]interface{}{
|
|
artifact.ExtraID: "foo",
|
|
artifact.ExtraBinary: "artifact3-name",
|
|
},
|
|
})
|
|
ctx.Artifacts.Add(&artifact.Artifact{
|
|
Name: "artifact4",
|
|
Path: filepath.Join(tmpdir, "linux_amd64", "artifact4"),
|
|
Goos: "linux",
|
|
Goarch: "amd64",
|
|
Type: artifact.Binary,
|
|
Extra: map[string]interface{}{
|
|
artifact.ExtraID: "foo3",
|
|
artifact.ExtraBinary: "artifact4-name",
|
|
},
|
|
})
|
|
ctx.Artifacts.Add(&artifact.Artifact{
|
|
Name: "artifact5.tar.gz",
|
|
Path: filepath.Join(tmpdir, "artifact5.tar.gz"),
|
|
Type: artifact.UploadableSourceArchive,
|
|
})
|
|
ctx.Artifacts.Add(&artifact.Artifact{
|
|
Name: "package1.deb",
|
|
Path: filepath.Join(tmpdir, "package1.deb"),
|
|
Type: artifact.LinuxPackage,
|
|
Extra: map[string]interface{}{
|
|
artifact.ExtraID: "foo",
|
|
},
|
|
})
|
|
|
|
// configure the pipeline
|
|
require.NoError(tb, Pipe{}.Default(ctx))
|
|
|
|
// run the pipeline
|
|
if expectedErrMsg != "" {
|
|
err := Pipe{}.Run(ctx)
|
|
require.Error(tb, err)
|
|
require.Contains(tb, err.Error(), expectedErrMsg)
|
|
return
|
|
}
|
|
|
|
require.NoError(tb, Pipe{}.Run(ctx))
|
|
|
|
// ensure all artifacts have an ID
|
|
for _, arti := range ctx.Artifacts.Filter(artifact.ByType(artifact.SBOM)).List() {
|
|
require.NotEmptyf(tb, arti.ID(), ".Extra.ID on %s", arti.Path)
|
|
}
|
|
|
|
// verify that only the artifacts and the sboms are in the dist dir
|
|
gotFiles := []string{}
|
|
|
|
require.NoError(tb, filepath.Walk(tmpdir,
|
|
func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if info.IsDir() {
|
|
return nil
|
|
}
|
|
relPath, err := filepath.Rel(tmpdir, path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
gotFiles = append(gotFiles, relPath)
|
|
return nil
|
|
}),
|
|
)
|
|
|
|
wantFiles := append(artifacts, sbomPaths...)
|
|
sort.Strings(wantFiles)
|
|
require.ElementsMatch(tb, wantFiles, gotFiles, "SBOM paths differ")
|
|
|
|
var sbomArtifacts []string
|
|
for _, sig := range ctx.Artifacts.Filter(artifact.ByType(artifact.SBOM)).List() {
|
|
sbomArtifacts = append(sbomArtifacts, sig.Name)
|
|
}
|
|
|
|
require.ElementsMatch(tb, sbomArtifacts, sbomNames, "SBOM names differ")
|
|
}
|
|
|
|
func Test_subprocessDistPath(t *testing.T) {
|
|
cwd, err := os.Getwd()
|
|
require.NoError(t, err)
|
|
|
|
tests := []struct {
|
|
name string
|
|
distDir string
|
|
pathRelativeToCwd string
|
|
expects string
|
|
}{
|
|
{
|
|
name: "relative dist with anchor",
|
|
distDir: "./dist",
|
|
pathRelativeToCwd: "dist/my.sbom",
|
|
expects: "my.sbom",
|
|
},
|
|
{
|
|
name: "relative dist without anchor",
|
|
distDir: "dist",
|
|
pathRelativeToCwd: "dist/my.sbom",
|
|
expects: "my.sbom",
|
|
},
|
|
{
|
|
name: "relative dist with nested resource",
|
|
distDir: "dist",
|
|
pathRelativeToCwd: "dist/something/my.sbom",
|
|
expects: "something/my.sbom",
|
|
},
|
|
{
|
|
name: "absolute dist with nested resource",
|
|
distDir: filepath.Join(cwd, "dist/"),
|
|
pathRelativeToCwd: "dist/something/my.sbom",
|
|
expects: "something/my.sbom",
|
|
},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
actual, err := subprocessDistPath(test.distDir, test.pathRelativeToCwd)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, test.expects, actual)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_templateNames(t *testing.T) {
|
|
art := artifact.Artifact{
|
|
Name: "name-it",
|
|
Path: "to/a/place",
|
|
Goos: "darwin",
|
|
Goarch: "amd64",
|
|
Type: artifact.Binary,
|
|
Extra: map[string]interface{}{
|
|
artifact.ExtraID: "id-it",
|
|
"Binary": "binary-name",
|
|
},
|
|
}
|
|
|
|
wd, err := os.Getwd()
|
|
require.NoError(t, err)
|
|
|
|
tests := []struct {
|
|
name string
|
|
dist string
|
|
version string
|
|
cfg config.SBOM
|
|
artifact artifact.Artifact
|
|
expectedValues map[string]string
|
|
expectedPaths []string
|
|
}{
|
|
{
|
|
name: "default configuration",
|
|
artifact: art,
|
|
cfg: config.SBOM{},
|
|
dist: "/somewhere/to/dist",
|
|
expectedPaths: []string{
|
|
"/somewhere/to/dist/name-it.sbom",
|
|
},
|
|
expectedValues: map[string]string{
|
|
"artifact": "to/a/place",
|
|
"artifactID": "id-it",
|
|
"document": "/somewhere/to/dist/name-it.sbom",
|
|
"document0": "/somewhere/to/dist/name-it.sbom",
|
|
},
|
|
},
|
|
{
|
|
name: "default configuration + relative dist",
|
|
artifact: art,
|
|
cfg: config.SBOM{},
|
|
dist: "somewhere/to/dist",
|
|
expectedPaths: []string{
|
|
filepath.Join(wd, "somewhere/to/dist/name-it.sbom"),
|
|
},
|
|
expectedValues: map[string]string{
|
|
"artifact": "to/a/place", // note: this is always relative to ${dist}
|
|
"artifactID": "id-it",
|
|
"document": filepath.Join(wd, "somewhere/to/dist/name-it.sbom"),
|
|
"document0": filepath.Join(wd, "somewhere/to/dist/name-it.sbom"),
|
|
},
|
|
},
|
|
{
|
|
name: "custom document using $artifact",
|
|
// note: this configuration is probably a misconfiguration since it is placing SBOMs within each bin
|
|
// directory, however, it will behave as correctly as possible.
|
|
artifact: art,
|
|
cfg: config.SBOM{
|
|
Documents: []string{
|
|
// note: the artifact name is probably an incorrect value here since it can't express all attributes
|
|
// of the binary (os, arch, etc), so builds with multiple architectures will create SBOMs with the
|
|
// same name.
|
|
"${artifact}.cdx.sbom",
|
|
},
|
|
},
|
|
dist: "somewhere/to/dist",
|
|
expectedPaths: []string{
|
|
filepath.Join(wd, "somewhere/to/dist/to/a/place.cdx.sbom"),
|
|
},
|
|
expectedValues: map[string]string{
|
|
"artifact": "to/a/place",
|
|
"artifactID": "id-it",
|
|
"document": filepath.Join(wd, "somewhere/to/dist/to/a/place.cdx.sbom"),
|
|
"document0": filepath.Join(wd, "somewhere/to/dist/to/a/place.cdx.sbom"),
|
|
},
|
|
},
|
|
{
|
|
name: "custom document using build vars",
|
|
artifact: art,
|
|
cfg: config.SBOM{
|
|
Documents: []string{
|
|
"{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}.cdx.sbom",
|
|
},
|
|
},
|
|
version: "1.0.0",
|
|
dist: "somewhere/to/dist",
|
|
expectedPaths: []string{
|
|
filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom"),
|
|
},
|
|
expectedValues: map[string]string{
|
|
"artifact": "to/a/place",
|
|
"artifactID": "id-it",
|
|
"document": filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom"),
|
|
"document0": filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom"),
|
|
},
|
|
},
|
|
{
|
|
name: "env vars with go templated options",
|
|
artifact: art,
|
|
cfg: config.SBOM{
|
|
Documents: []string{
|
|
"{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}.cdx.sbom",
|
|
},
|
|
Env: []string{
|
|
"with-env-var=value",
|
|
"custom-os={{ .Os }}-unique",
|
|
"custom-arch={{ .Arch }}-unique",
|
|
},
|
|
},
|
|
version: "1.0.0",
|
|
dist: "somewhere/to/dist",
|
|
expectedPaths: []string{
|
|
filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom"),
|
|
},
|
|
expectedValues: map[string]string{
|
|
"artifact": "to/a/place",
|
|
"artifactID": "id-it",
|
|
"with-env-var": "value",
|
|
"custom-os": "darwin-unique",
|
|
"custom-arch": "amd64-unique",
|
|
"document": filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom"),
|
|
"document0": filepath.Join(wd, "somewhere/to/dist/binary-name_1.0.0_darwin_amd64.cdx.sbom"),
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
Dist: tt.dist,
|
|
}, testctx.WithVersion(tt.version))
|
|
|
|
cfg := tt.cfg
|
|
require.NoError(t, setConfigDefaults(&cfg))
|
|
|
|
var inputArgs []string
|
|
var expectedArgs []string
|
|
for key, value := range tt.expectedValues {
|
|
inputArgs = append(inputArgs, fmt.Sprintf("${%s}", key))
|
|
expectedArgs = append(expectedArgs, value)
|
|
}
|
|
cfg.Args = inputArgs
|
|
|
|
actualArgs, actualEnvs, actualPaths, err := applyTemplate(ctx, cfg, &tt.artifact)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, tt.expectedPaths, actualPaths, "paths differ")
|
|
|
|
assert.Equal(t, expectedArgs, actualArgs, "arguments differ")
|
|
|
|
actualEnv := make(map[string]string)
|
|
for _, str := range actualEnvs {
|
|
k, v, ok := strings.Cut(str, "=")
|
|
require.True(t, ok)
|
|
actualEnv[k] = v
|
|
}
|
|
|
|
for k, v := range tt.expectedValues {
|
|
assert.Equal(t, v, actualEnv[k])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDependencies(t *testing.T) {
|
|
ctx := testctx.NewWithCfg(config.Project{
|
|
SBOMs: []config.SBOM{
|
|
{Cmd: "syft"},
|
|
{Cmd: "foobar"},
|
|
},
|
|
})
|
|
require.Equal(t, []string{"syft", "foobar"}, Pipe{}.Dependencies(ctx))
|
|
}
|