fixes the wrapped taskfile-tasks (#5013)

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman 2026-06-24 11:22:16 -04:00 committed by GitHub
parent fe42bcec38
commit abf6d78dfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 53 additions and 116 deletions

View File

@ -2,13 +2,11 @@ module github.com/anchore/syft/.make
go 1.25.8 go 1.25.8
require ( require github.com/anchore/go-make v0.7.0
github.com/anchore/go-make v0.7.0
github.com/goccy/go-yaml v1.19.2
)
require ( require (
github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect github.com/bmatcuk/doublestar/v4 v4.10.0 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
golang.org/x/mod v0.37.0 // indirect golang.org/x/mod v0.37.0 // indirect
golang.org/x/sys v0.46.0 // indirect golang.org/x/sys v0.46.0 // indirect
) )

View File

@ -1,28 +1,19 @@
package main package main
import ( import (
"fmt"
"os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"github.com/goccy/go-yaml"
. "github.com/anchore/go-make" . "github.com/anchore/go-make"
"github.com/anchore/go-make/file" "github.com/anchore/go-make/file"
"github.com/anchore/go-make/git"
"github.com/anchore/go-make/lang" "github.com/anchore/go-make/lang"
"github.com/anchore/go-make/run" "github.com/anchore/go-make/run"
"github.com/anchore/go-make/tasks/golint" "github.com/anchore/go-make/tasks/golint"
"github.com/anchore/go-make/tasks/goreleaser" "github.com/anchore/go-make/tasks/goreleaser"
"github.com/anchore/go-make/tasks/gotask"
"github.com/anchore/go-make/tasks/gotest" "github.com/anchore/go-make/tasks/gotest"
) )
// taskfileDescriptions maps Taskfile.yaml task names to their `desc:` field.
// Loaded at package init so wrap() can use Taskfile.yaml as the single source
// of truth for wrapped-task descriptions.
var taskfileDescriptions = mustReadTaskfileDescriptions()
func main() { func main() {
Makefile( Makefile(
// shared anchore tasks // shared anchore tasks
@ -89,110 +80,58 @@ func main() {
Dependencies: Deps("static-analysis", "test", "install-test"), Dependencies: Deps("static-analysis", "test", "install-test"),
}, },
// --- everything below is implemented in Taskfile.yaml and surfaced here // --- everything else is implemented in Taskfile.yaml. gotask.Tasks()
// via wrap(). Descriptions come from Taskfile.yaml (single source of truth). // discovers every (non-internal) Taskfile task — including the namespaced
// `generate:cpe-index:*` tasks from the included task.d file — and surfaces
// them as first-class go-make tasks (with their canonical names and `desc:`)
// that forward to `task <name>`. Descriptions live in Taskfile.yaml as the
// single source of truth; no per-task wrapping needed here.
gotask.Tasks(),
// static analysis extras // gotask.Tasks() discovers canonical task names only, not Taskfile aliases,
wrap("check-json-schema-drift").RunOn("static-analysis"), // so re-expose `refresh-fixtures`'s `fixtures` alias for manual use.
wrap("check-capability-drift"), Task{
wrap("check-binary-fixture-size").RunOn("static-analysis"), Name: "fixtures",
Description: "Clear and fetch all test fixture cache (alias of refresh-fixtures)",
Dependencies: Deps("refresh-fixtures"),
},
// test extras // gotask.Tasks() can't attach RunsOn labels, so wire the syft-specific
wrap("validate-cyclonedx-schema").RunOn("test"), // Taskfile tasks into go-make's native phases here. These thin hooks have
wrap("test-utils").RunOn("test"), // no body and no description (hidden from `make help`); they only pull the
wrap("check-docker-cache").RunOn("test"), // discovered tasks in when the labeled phase runs.
wrap("snapshot-smoke-test"), Task{
Name: "static-analysis:syft",
// update commands RunsOn: lang.List("static-analysis"),
wrap("update-format-golden-files"), Dependencies: Deps("check-json-schema-drift", "check-binary-fixture-size"),
},
// fixture cache plumbing (heavy ORAS logic, lives in Taskfile). Task{
// refresh-fixtures hooks into "unit" so `make unit` triggers the Name: "test:syft",
// stale-cache detection + download just like `task unit` did on main RunsOn: lang.List("test"),
// (its `deps: [tmpdir, fixtures]` is what kept the fixture cache fresh). Dependencies: Deps("validate-cyclonedx-schema", "test-utils", "check-docker-cache"),
wrap("fingerprints"), },
wrap("refresh-fixtures").RunOn("unit"), // refresh-fixtures hooks into "unit" so `make unit` triggers the stale-cache
wrap("fixtures"), // detection + download just like `task unit` did on main (its
wrap("build-fixtures"), // `deps: [tmpdir, fixtures]` is what kept the fixture cache fresh).
wrap("download-test-fixture-cache"), Task{
wrap("upload-test-fixture-cache"), Name: "unit:syft",
wrap("show-test-image-cache"), RunsOn: lang.List("unit"),
Dependencies: Deps("refresh-fixtures"),
// install-script tests (delegates to test/install/Makefile) },
wrap("install-test"), Task{
wrap("install-test-cache-save"), Name: "clean:syft",
wrap("install-test-cache-load"), RunsOn: lang.List("clean"),
wrap("install-test-ci-mac"), Dependencies: Deps(
"clean-snapshot",
// compare tests "clean-docker-cache",
wrap("generate-compare-file"), "clean-oras-cache",
wrap("compare-mac"), "clean-cache",
wrap("compare-linux"), "clean-test-observations",
wrap("compare-test-deb-package-install"), ),
wrap("compare-test-rpm-package-install"), },
// code/data generation (umbrella + per-target; each lives in Taskfile)
wrap("generate"),
wrap("generate-json-schema"),
wrap("generate-license-list"),
wrap("generate-cpe-dictionary-index"),
wrap("generate-capabilities"),
// cleanup (each hooks into go-make's built-in `clean` label)
wrap("clean-snapshot").RunOn("clean"),
wrap("clean-docker-cache").RunOn("clean"),
wrap("clean-oras-cache").RunOn("clean"),
wrap("clean-cache").RunOn("clean"),
wrap("clean-test-observations").RunOn("clean"),
) )
} }
// wrap creates a go-make Task that delegates execution to `task <name>`. The
// task's description is pulled from Taskfile.yaml's `desc:` field — descriptions
// for wrapped tasks must always live in Taskfile.yaml, never here.
func wrap(name string) Task {
desc, ok := taskfileDescriptions[name]
if !ok || desc == "" {
// loud-fail at startup so missing descs can't sneak through review.
panic(fmt.Sprintf("Taskfile.yaml task %q is missing a `desc:` field; please add one", name))
}
return Task{
Name: name,
Description: desc,
Run: func() { Run("task " + name) },
}
}
// mustReadTaskfileDescriptions parses Taskfile.yaml at the repo root and returns
// a map of task name -> desc. Runs at package init time so wrap() can use it.
func mustReadTaskfileDescriptions() map[string]string {
root := git.Root()
if root == "" {
return nil
}
path := filepath.Join(root, "Taskfile.yaml")
data, err := os.ReadFile(path) //nolint:gosec // G304: path resolved from git.Root()
if err != nil {
return nil
}
var tf struct {
Tasks map[string]struct {
Desc string `yaml:"desc"`
Aliases []string `yaml:"aliases"`
} `yaml:"tasks"`
}
lang.Throw(yaml.Unmarshal(data, &tf))
out := make(map[string]string, len(tf.Tasks))
for name, t := range tf.Tasks {
out[name] = t.Desc
// aliases inherit the canonical task's description so wrap() can find them.
for _, alias := range t.Aliases {
out[alias] = t.Desc
}
}
return out
}
// snapshotBinPath replicates the SNAPSHOT_BIN computation from the prior Taskfile: // snapshotBinPath replicates the SNAPSHOT_BIN computation from the prior Taskfile:
// <repoRoot>/snapshot/<os>-build_<os>_<arch>/syft, where arch maps amd64->amd64_v1 // <repoRoot>/snapshot/<os>-build_<os>_<arch>/syft, where arch maps amd64->amd64_v1
// and arm64->arm64_v8.0 to match goreleaser's per-target output directory naming. // and arm64->arm64_v8.0 to match goreleaser's per-target output directory naming.

View File

@ -2,9 +2,9 @@ version: "3"
# NOTE: most generic tasks (static-analysis, format, lint, unit, snapshot, release, # NOTE: most generic tasks (static-analysis, format, lint, unit, snapshot, release,
# changelog, ci-release, etc.) are now provided natively by anchore/go-make and # changelog, ci-release, etc.) are now provided natively by anchore/go-make and
# defined in .make/main.go. This file holds the syft-specific tasks that go-make # defined in .make/main.go. This file holds the syft-specific tasks, which go-make
# wraps via `wrap("<name>")` calls — keep descriptions (`desc:`) populated so they # auto-discovers via gotask.Tasks() and surfaces as `make <name>` — keep
# show up in `make help`. # descriptions (`desc:`) populated so they show up in `make help`.
includes: includes:
generate:cpe-index: ./task.d/generate/cpe-index.yaml generate:cpe-index: ./task.d/generate/cpe-index.yaml