mirror of
https://github.com/anchore/syft.git
synced 2025-11-19 17:33:18 +01:00
chore: ensure syft binary is up-to-date when running CLI tests locally
Signed-off-by: Keith Zantow <kzantow@gmail.com>
This commit is contained in:
parent
a90cff1cd2
commit
fea371e36f
@ -13,8 +13,11 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/anchore/stereoscope/pkg/imagetest"
|
"github.com/anchore/stereoscope/pkg/imagetest"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -271,7 +274,137 @@ func getSyftBinaryLocation(t testing.TB) string {
|
|||||||
// SYFT_BINARY_LOCATION is the absolute path to the snapshot binary
|
// SYFT_BINARY_LOCATION is the absolute path to the snapshot binary
|
||||||
return os.Getenv("SYFT_BINARY_LOCATION")
|
return os.Getenv("SYFT_BINARY_LOCATION")
|
||||||
}
|
}
|
||||||
return getSyftBinaryLocationByOS(t, runtime.GOOS)
|
bin := getSyftBinaryLocationByOS(t, runtime.GOOS)
|
||||||
|
|
||||||
|
// only run on valid bin target, when not running in CI
|
||||||
|
if bin != "" && os.Getenv("CI") == "" {
|
||||||
|
buildSyft(t, bin)
|
||||||
|
// regardless if we have a successful build, don't attempt to keep building
|
||||||
|
_ = os.Setenv("SYFT_BINARY_LOCATION", bin)
|
||||||
|
}
|
||||||
|
|
||||||
|
return bin
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSyft(t testing.TB, outfile string) {
|
||||||
|
dir := repoRoot(t)
|
||||||
|
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
var stdout, stderr string
|
||||||
|
var err error
|
||||||
|
switch "go" {
|
||||||
|
case "go":
|
||||||
|
stdout, stderr, err = buildSyftWithGo(dir, outfile)
|
||||||
|
case "goreleaser":
|
||||||
|
stdout, stderr, err = buildSyftWithGoreleaser(dir)
|
||||||
|
case "make":
|
||||||
|
stdout, stderr, err = buildSyftWithMake(dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
took := time.Now().Sub(start).Round(time.Millisecond)
|
||||||
|
if err == nil {
|
||||||
|
if len(stderr) == 0 {
|
||||||
|
t.Logf("binary is up to date: %s in %v", outfile, took)
|
||||||
|
} else {
|
||||||
|
t.Logf("built binary: %s in %v\naffected paths:\n%s", outfile, took, stderr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Logf("unable to build binary: %s %v\nSTDOUT:\n%s\nSTDERR:\n%s", outfile, err, stdout, stderr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func goreleaserYamlContents(dir string) string {
|
||||||
|
b, _ := os.ReadFile(path.Join(dir, ".goreleaser.yaml"))
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSyftWithGo(dir string, outfile string) (string, string, error) {
|
||||||
|
d := yaml.NewDecoder(strings.NewReader(goreleaserYamlContents(dir)))
|
||||||
|
type releaser struct {
|
||||||
|
Builds []struct {
|
||||||
|
ID string `yaml:"id"`
|
||||||
|
LDFlags string `yaml:"ldflags"`
|
||||||
|
} `yaml:"builds"`
|
||||||
|
}
|
||||||
|
r := releaser{}
|
||||||
|
_ = d.Decode(&r)
|
||||||
|
ldflags := ""
|
||||||
|
for _, b := range r.Builds {
|
||||||
|
if b.ID == "linux-build" {
|
||||||
|
ldflags = executeTemplate(b.LDFlags, struct {
|
||||||
|
Version string
|
||||||
|
Commit string
|
||||||
|
Date string
|
||||||
|
Summary string
|
||||||
|
}{
|
||||||
|
Version: "VERSION",
|
||||||
|
Commit: "COMMIT",
|
||||||
|
Date: "DATE",
|
||||||
|
Summary: "SUMMARY",
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command("go",
|
||||||
|
"build",
|
||||||
|
"-v",
|
||||||
|
"-o", outfile,
|
||||||
|
"-trimpath",
|
||||||
|
"-ldflags", ldflags,
|
||||||
|
"./cmd/syft",
|
||||||
|
)
|
||||||
|
|
||||||
|
cmd.Dir = dir
|
||||||
|
stdout, stderr, err := runCommand(cmd, map[string]string{
|
||||||
|
"CGO_ENABLED": "0",
|
||||||
|
})
|
||||||
|
return stdout, stderr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSyftWithMake(dir string) (string, string, error) {
|
||||||
|
cmd := exec.Command("make", "snapshot")
|
||||||
|
cmd.Dir = dir
|
||||||
|
stdout, stderr, err := runCommand(cmd, map[string]string{})
|
||||||
|
if strings.Contains(stderr, "error=docker build failed") {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
return stdout, stderr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildSyftWithGoreleaser(dir string) (string, string, error) {
|
||||||
|
tmpDir := path.Join(dir, ".tmp")
|
||||||
|
|
||||||
|
goreleaserYaml := goreleaserYamlContents(dir)
|
||||||
|
|
||||||
|
// # create a config with the dist dir overridden
|
||||||
|
tmpGoreleaserYamlFile := path.Join(tmpDir, "goreleaser.yaml")
|
||||||
|
_ = os.WriteFile(tmpGoreleaserYamlFile, []byte("dist: snapshot\n"+goreleaserYaml), os.ModePerm)
|
||||||
|
|
||||||
|
cmd := exec.Command(path.Join(tmpDir, "goreleaser"),
|
||||||
|
"build",
|
||||||
|
"--snapshot",
|
||||||
|
"--single-target",
|
||||||
|
"--clean",
|
||||||
|
"--config", tmpGoreleaserYamlFile,
|
||||||
|
)
|
||||||
|
cmd.Dir = dir
|
||||||
|
stdout, stderr, err := runCommand(cmd, map[string]string{})
|
||||||
|
return stdout, stderr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func executeTemplate(tpl string, data any) string {
|
||||||
|
t, err := template.New("tpl").Parse(tpl)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("ERROR: %v", err)
|
||||||
|
}
|
||||||
|
out := &bytes.Buffer{}
|
||||||
|
err = t.Execute(out, data)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Sprintf("ERROR: %v", err)
|
||||||
|
}
|
||||||
|
return out.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSyftBinaryLocationByOS(t testing.TB, goOS string) string {
|
func getSyftBinaryLocationByOS(t testing.TB, goOS string) string {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user