anchore/grype
Patterns and conventions
The recurring shapes you will see across the Grype codebase.
File and package layout
- One concept per package. Most packages export 5–20 symbols and live in a single directory.
- Tests sit next to the code. Snapshot files (
__snapshots__/) are committed. - Mocks live in a sibling
mock/package (e.g.grype/vulnerability/mock/). - Test data lives in
testdata/directories within the package. - Internal helpers go under
internal/directories — not exported across the module boundary.
Configuration with clio + fangs
CLI options follow the anchore/clio + anchore/fangs pattern:
- Each subcommand defines a
*Optionsstruct (e.g.cmd/grype/cli/options/grype.go::Grype). - Struct tags drive both YAML config keys and CLI flags.
DefaultGrype(id)returns a fully-populated default options struct.- The option struct exposes converters like
ToClientConfig()andToCuratorConfig()to translate to internal types.
Add a new flag by extending the relevant options struct, wiring its mapstructure:"..." tag, and adding a default in the Default* constructor.
Error handling
- Wrap with
fmt.Errorf("...: %w", err). Sentinel errors live ingrype/grypeerr/(ErrAboveSeverityThreshold,ErrDBUpgradeAvailable). - The CLI translates sentinels to numeric exit codes in
cmd/grype/cli/cli.go::SetupConfig::WithMapExitCode. - Matchers must never panic.
vulnerability_matcher.go::callMatcherSafelyrecovers panics intomatch.NewFatalError. - Use
errors.Join(...)to aggregate per-matcher errors so the user sees them all.
Matcher contract
Implement match.Matcher:
type Matcher interface {
PackageTypes() []syftPkg.Type
Type() MatcherType
Match(vp vulnerability.Provider, p pkg.Package) ([]Match, []IgnoreFilter, error)
}Conventions:
- One matcher per ecosystem under
grype/matcher/<ecosystem>/. - Expose a
MatcherConfigstruct and aNew<Name>Matcher(cfg)constructor; embed inmatcher.Config. - Use the shared search helpers in
grype/matcher/internal/(CPE search, distro search, language search). - Return
IgnoreFilters for matches that should be downgraded by other matchers (e.g. indirect matches that should be replaced by direct ones).
Vulnerability provider abstraction
Always go through vulnerability.Provider (grype/vulnerability/provider.go):
type Provider interface {
PackageSearchNames(grypePkg.Package) []string
FindVulnerabilities(criteria ...Criteria) ([]Vulnerability, error)
MetadataProvider
io.Closer
}Build queries with grype/search/criteria.go builders rather than poking the GORM DB directly. Optional capabilities (EOLChecker, StoreMetadataProvider) are detected via type assertion.
Bus events for progress
Long-running operations publish to the partybus.Bus (set by internal/bus/):
bus.Publish(partybus.Event{
Type: event.VulnerabilityScanningStarted,
Value: reader,
})Event types are declared in grype/event/. The TUI subscribes and renders progress; the CI handler swallows them.
Logging
log.WithFields("package", displayPackage(p)).Trace("...")Conventions:
WithFieldsbuilds a structured logger; prefer it overlog.Printf.- Use
log.Tracef/Debugffor hot paths;log.Infofor once-per-scan messages. - Sensitive values must be added to the
redact.Store(internal/redact/) before they touch a log.
JSON output
The JSON presenter is the source of truth for the public schema. Schema generation happens in cmd/grype/cli/commands/internal/jsonschema/ and is checked by task check-json-schema-drift. Bumps require updating both the model and the schema.
Naming
- Packages: lowercase, no underscores (
vulnmatcher,presenter,matcher). - Files: lowercase with underscores when separating words (
vulnerability_matcher.go,db_search_vuln.go). - Type names: PascalCase. Exported only when used across packages.
- Test functions:
Test_<Subject>_<Behavior>for unit tests; integration tests follow the same pattern withit_*files.
Linting
.golangci.yaml configures golangci-lint. Notable enabled linters:
funlen— long-function check (withnolint:funlenoverrides where intentional).staticcheck— including for deprecated APIs (MetadataProvideris the most-overridden case).gosimports— replacesgoimportswith anchore-local sorting.
The task lint target runs both gofmt -l -s and golangci-lint. PRs must pass.
Deprecation policy
Deprecated symbols are marked with the // Deprecated: ... comment so staticcheck flags them. A few notable still-used-internally deprecations:
vulnerability.MetadataProviderpresenter.GetPresentergrype/db/v5/(entire schema) for runtime use
These will be removed in v1.0.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.