Full Code of anchore/grype for AI

main dee8de483dfb cached
1026 files
4.6 MB
1.3M tokens
4164 symbols
1 requests
Download .txt
Showing preview only (5,058K chars total). Download the full file or copy to clipboard to get everything.
Repository: anchore/grype
Branch: main
Commit: dee8de483dfb
Files: 1026
Total size: 4.6 MB

Directory structure:
gitextract_p7zkpam3/

├── .binny.yaml
├── .bouncer.yaml
├── .chronicle.yaml
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   ├── feature_request.md
│   │   └── match_issue.md
│   ├── actions/
│   │   └── bootstrap/
│   │       └── action.yaml
│   ├── dependabot.yaml
│   ├── scripts/
│   │   ├── check-syft-version-is-release.sh
│   │   ├── ci-check.sh
│   │   ├── coverage.py
│   │   ├── db-schema-drift-check.sh
│   │   ├── go-mod-tidy-check.sh
│   │   ├── json-schema-drift-check.sh
│   │   └── trigger-release.sh
│   ├── workflows/
│   │   ├── codeql-analysis.yml
│   │   ├── dependabot-automation.yaml
│   │   ├── oss-project-board-add.yaml
│   │   ├── release.yaml
│   │   ├── remove-awaiting-response-label.yaml
│   │   ├── scorecards.yml
│   │   ├── update-anchore-dependencies.yml
│   │   ├── update-bootstrap-tools.yml
│   │   ├── update-generated-code.yml
│   │   ├── update-quality-gate-db.yml
│   │   ├── validate-github-actions.yaml
│   │   └── validations.yaml
│   └── zizmor.yml
├── .gitignore
├── .gitmodules
├── .golangci.yaml
├── .goreleaser.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.debug
├── Dockerfile.nonroot
├── LICENSE
├── Makefile
├── README.md
├── RELEASE.md
├── SECURITY.md
├── Taskfile.yaml
├── artifacthub-repo.yml
├── cmd/
│   └── grype/
│       ├── cli/
│       │   ├── cli.go
│       │   ├── cli_test.go
│       │   ├── commands/
│       │   │   ├── completion.go
│       │   │   ├── db.go
│       │   │   ├── db_check.go
│       │   │   ├── db_check_test.go
│       │   │   ├── db_delete.go
│       │   │   ├── db_import.go
│       │   │   ├── db_list.go
│       │   │   ├── db_list_test.go
│       │   │   ├── db_providers.go
│       │   │   ├── db_providers_test.go
│       │   │   ├── db_search.go
│       │   │   ├── db_search_test.go
│       │   │   ├── db_search_vuln.go
│       │   │   ├── db_search_vuln_test.go
│       │   │   ├── db_status.go
│       │   │   ├── db_status_test.go
│       │   │   ├── db_update.go
│       │   │   ├── explain.go
│       │   │   ├── internal/
│       │   │   │   ├── dbsearch/
│       │   │   │   │   ├── affected_packages.go
│       │   │   │   │   ├── affected_packages_test.go
│       │   │   │   │   ├── common.go
│       │   │   │   │   ├── matches.go
│       │   │   │   │   ├── matches_test.go
│       │   │   │   │   ├── versions.go
│       │   │   │   │   ├── vulnerabilities.go
│       │   │   │   │   ├── vulnerabilities_test.go
│       │   │   │   │   └── vulnerability_decorations.go
│       │   │   │   └── jsonschema/
│       │   │   │       └── main.go
│       │   │   ├── root.go
│       │   │   ├── root_test.go
│       │   │   ├── testdata/
│       │   │   │   └── provider-metadata.json
│       │   │   ├── update.go
│       │   │   ├── update_test.go
│       │   │   ├── util.go
│       │   │   └── util_test.go
│       │   ├── options/
│       │   │   ├── alerts.go
│       │   │   ├── alerts_test.go
│       │   │   ├── database.go
│       │   │   ├── database_command.go
│       │   │   ├── database_search_bounds.go
│       │   │   ├── database_search_format.go
│       │   │   ├── database_search_os.go
│       │   │   ├── database_search_os_test.go
│       │   │   ├── database_search_packages.go
│       │   │   ├── database_search_packages_test.go
│       │   │   ├── database_search_vulnerabilities.go
│       │   │   ├── database_search_vulnerabilities_test.go
│       │   │   ├── datasources.go
│       │   │   ├── experimental.go
│       │   │   ├── fix_channels.go
│       │   │   ├── grype.go
│       │   │   ├── grype_test.go
│       │   │   ├── match.go
│       │   │   ├── match_test.go
│       │   │   ├── registry.go
│       │   │   ├── registry_test.go
│       │   │   ├── search.go
│       │   │   ├── secret.go
│       │   │   └── sort_by.go
│       │   └── ui/
│       │       ├── __snapshots__/
│       │       │   ├── handle_database_diff_started_test.snap
│       │       │   ├── handle_update_vulnerability_database_test.snap
│       │       │   └── handle_vulnerability_scanning_started_test.snap
│       │       ├── handle_database_diff_started.go
│       │       ├── handle_database_diff_started_test.go
│       │       ├── handle_update_vulnerability_database.go
│       │       ├── handle_update_vulnerability_database_test.go
│       │       ├── handle_vulnerability_scanning_started.go
│       │       ├── handle_vulnerability_scanning_started_test.go
│       │       ├── handler.go
│       │       ├── new_task_progress.go
│       │       └── util_test.go
│       ├── internal/
│       │   ├── constants.go
│       │   └── ui/
│       │       ├── __snapshots__/
│       │       │   └── post_ui_event_writer_test.snap
│       │       ├── no_ui.go
│       │       ├── post_ui_event_writer.go
│       │       ├── post_ui_event_writer_test.go
│       │       └── ui.go
│       └── main.go
├── go.mod
├── go.sum
├── grype/
│   ├── cpe/
│   │   ├── cpe.go
│   │   └── cpe_test.go
│   ├── db/
│   │   ├── build.go
│   │   ├── data/
│   │   │   ├── entry.go
│   │   │   ├── processor.go
│   │   │   ├── severity.go
│   │   │   ├── severity_test.go
│   │   │   ├── transformers.go
│   │   │   └── writer.go
│   │   ├── default_schema_version.go
│   │   ├── generate.go
│   │   ├── internal/
│   │   │   ├── codename/
│   │   │   │   ├── codename.go
│   │   │   │   ├── codename_test.go
│   │   │   │   ├── codenames_generated.go
│   │   │   │   └── generate/
│   │   │   │       └── main.go
│   │   │   ├── gormadapter/
│   │   │   │   ├── logger.go
│   │   │   │   ├── open.go
│   │   │   │   └── open_test.go
│   │   │   ├── provider/
│   │   │   │   └── unmarshal/
│   │   │   │       ├── annotated_openvex_vulnerability.go
│   │   │   │       ├── eol.go
│   │   │   │       ├── epss.go
│   │   │   │       ├── errors.go
│   │   │   │       ├── github_advisory.go
│   │   │   │       ├── items_envelope.go
│   │   │   │       ├── known_exploited_vulnerability.go
│   │   │   │       ├── match_exclusion.go
│   │   │   │       ├── msrc_vulnerability.go
│   │   │   │       ├── nvd/
│   │   │   │       │   ├── cve.go
│   │   │   │       │   ├── cve_test.go
│   │   │   │       │   ├── cvss20/
│   │   │   │       │   │   └── cvss20.go
│   │   │   │       │   ├── cvss30/
│   │   │   │       │   │   └── cvss30.go
│   │   │   │       │   ├── cvss31/
│   │   │   │       │   │   └── cvss31.go
│   │   │   │       │   └── cvss40/
│   │   │   │       │       └── cvss40.go
│   │   │   │       ├── nvd_vulnerability.go
│   │   │   │       ├── openvex_vulnerability.go
│   │   │   │       ├── os_vulnerability.go
│   │   │   │       ├── os_vulnerability_test.go
│   │   │   │       ├── osv_vulnerability.go
│   │   │   │       └── single_or_multi.go
│   │   │   ├── sqlite/
│   │   │   │   ├── nullable_types.go
│   │   │   │   └── nullable_types_test.go
│   │   │   ├── tarutil/
│   │   │   │   ├── file_entry.go
│   │   │   │   ├── file_entry_test.go
│   │   │   │   ├── populate.go
│   │   │   │   ├── populate_test.go
│   │   │   │   ├── reader_entry.go
│   │   │   │   ├── reader_entry_test.go
│   │   │   │   ├── tar.go
│   │   │   │   ├── writer.go
│   │   │   │   └── writer_test.go
│   │   │   ├── testutil/
│   │   │   │   └── utils.go
│   │   │   └── versionutil/
│   │   │       ├── clean_fixed_in_version.go
│   │   │       ├── constraint.go
│   │   │       └── constraint_test.go
│   │   ├── package.go
│   │   ├── package_legacy.go
│   │   ├── processors/
│   │   │   ├── annotated_openvex_processor.go
│   │   │   ├── eol_processor.go
│   │   │   ├── eol_processor_test.go
│   │   │   ├── epss_processor.go
│   │   │   ├── epss_processor_test.go
│   │   │   ├── github_processor.go
│   │   │   ├── github_processor_test.go
│   │   │   ├── kev_processor.go
│   │   │   ├── kev_processor_test.go
│   │   │   ├── match_exclusion_processor.go
│   │   │   ├── match_exclusion_processor_test.go
│   │   │   ├── msrc_processor.go
│   │   │   ├── msrc_processor_test.go
│   │   │   ├── nvd_processor.go
│   │   │   ├── nvd_processor_test.go
│   │   │   ├── openvex_processor.go
│   │   │   ├── openvex_processor_test.go
│   │   │   ├── os_processor.go
│   │   │   ├── os_processor_test.go
│   │   │   ├── osv_processor.go
│   │   │   ├── osv_processor_test.go
│   │   │   ├── testdata/
│   │   │   │   ├── eol-with-empty.json
│   │   │   │   ├── eol.json
│   │   │   │   ├── epss.json
│   │   │   │   ├── exclusions.json
│   │   │   │   ├── github.json
│   │   │   │   ├── kev.json
│   │   │   │   ├── msrc.json
│   │   │   │   ├── nvd.json
│   │   │   │   ├── openvex.json
│   │   │   │   ├── oracle.json
│   │   │   │   ├── os.json
│   │   │   │   └── osv.json
│   │   │   ├── version.go
│   │   │   └── version_test.go
│   │   ├── provider/
│   │   │   ├── entry/
│   │   │   │   ├── file.go
│   │   │   │   ├── opener.go
│   │   │   │   └── sqlite.go
│   │   │   ├── file.go
│   │   │   ├── model.go
│   │   │   ├── model_test.go
│   │   │   ├── provider.go
│   │   │   ├── state.go
│   │   │   ├── state_test.go
│   │   │   └── workspace.go
│   │   ├── v5/
│   │   │   ├── advisory.go
│   │   │   ├── build/
│   │   │   │   ├── processors.go
│   │   │   │   ├── transformers/
│   │   │   │   │   ├── entry.go
│   │   │   │   │   ├── github/
│   │   │   │   │   │   ├── testdata/
│   │   │   │   │   │   │   ├── github-github-npm-0.json
│   │   │   │   │   │   │   ├── github-github-python-0.json
│   │   │   │   │   │   │   ├── github-github-python-1.json
│   │   │   │   │   │   │   ├── github-withdrawn.json
│   │   │   │   │   │   │   └── multiple-fixed-in-names.json
│   │   │   │   │   │   ├── transform.go
│   │   │   │   │   │   └── transform_test.go
│   │   │   │   │   ├── matchexclusions/
│   │   │   │   │   │   └── transform.go
│   │   │   │   │   ├── msrc/
│   │   │   │   │   │   ├── testdata/
│   │   │   │   │   │   │   └── microsoft-msrc-0.json
│   │   │   │   │   │   ├── transform.go
│   │   │   │   │   │   └── transform_test.go
│   │   │   │   │   ├── nvd/
│   │   │   │   │   │   ├── testdata/
│   │   │   │   │   │   │   ├── CVE-2023-45283-platform-cpe-first.json
│   │   │   │   │   │   │   ├── CVE-2023-45283-platform-cpe-last.json
│   │   │   │   │   │   │   ├── compound-pkg.json
│   │   │   │   │   │   │   ├── cve-2020-10729.json
│   │   │   │   │   │   │   ├── cve-2022-0543.json
│   │   │   │   │   │   │   ├── invalid_cpe.json
│   │   │   │   │   │   │   ├── multiple-platforms-with-application-cpe.json
│   │   │   │   │   │   │   ├── platform-cpe.json
│   │   │   │   │   │   │   ├── single-package-multi-distro.json
│   │   │   │   │   │   │   ├── unmarshal-test.json
│   │   │   │   │   │   │   └── version-range.json
│   │   │   │   │   │   ├── transform.go
│   │   │   │   │   │   ├── transform_test.go
│   │   │   │   │   │   ├── unique_pkg.go
│   │   │   │   │   │   ├── unique_pkg_test.go
│   │   │   │   │   │   └── unique_pkg_tracker.go
│   │   │   │   │   ├── os/
│   │   │   │   │   │   ├── testdata/
│   │   │   │   │   │   │   ├── alpine-3.9.json
│   │   │   │   │   │   │   ├── amazon-multiple-kernel-advisories.json
│   │   │   │   │   │   │   ├── amzn.json
│   │   │   │   │   │   │   ├── azure-linux-3.json
│   │   │   │   │   │   │   ├── debian-8-multiple-entries-for-same-package.json
│   │   │   │   │   │   │   ├── debian-8.json
│   │   │   │   │   │   │   ├── mariner-20.json
│   │   │   │   │   │   │   ├── mariner-range.json
│   │   │   │   │   │   │   ├── ol-8-modules.json
│   │   │   │   │   │   │   ├── ol-8.json
│   │   │   │   │   │   │   ├── photon-4.0.json
│   │   │   │   │   │   │   ├── rhel-8-eus.json
│   │   │   │   │   │   │   ├── rhel-8-modules.json
│   │   │   │   │   │   │   ├── rhel-8.json
│   │   │   │   │   │   │   └── unmarshal-test.json
│   │   │   │   │   │   ├── transform.go
│   │   │   │   │   │   └── transform_test.go
│   │   │   │   │   └── vulnerability_metadata.go
│   │   │   │   ├── writer.go
│   │   │   │   └── writer_test.go
│   │   │   ├── cvss.go
│   │   │   ├── diff.go
│   │   │   ├── differ/
│   │   │   │   ├── differ.go
│   │   │   │   ├── differ_test.go
│   │   │   │   └── testdata/
│   │   │   │       ├── dbs/
│   │   │   │       │   ├── base/
│   │   │   │       │   │   └── 5/
│   │   │   │       │   │       └── metadata.json
│   │   │   │       │   └── target/
│   │   │   │       │       └── 5/
│   │   │   │       │           └── metadata.json
│   │   │   │       └── snapshot/
│   │   │   │           ├── TestPresent_Json.golden
│   │   │   │           └── TestPresent_Table.golden
│   │   │   ├── distribution/
│   │   │   │   ├── curator.go
│   │   │   │   ├── curator_test.go
│   │   │   │   ├── listing.go
│   │   │   │   ├── listing_entry.go
│   │   │   │   ├── listing_test.go
│   │   │   │   ├── metadata.go
│   │   │   │   ├── metadata_test.go
│   │   │   │   ├── status.go
│   │   │   │   └── testdata/
│   │   │   │       ├── curator-validate/
│   │   │   │       │   ├── bad-checksum/
│   │   │   │       │   │   └── metadata.json
│   │   │   │       │   └── good-checksum/
│   │   │   │       │       └── metadata.json
│   │   │   │       ├── listing-sorted.json
│   │   │   │       ├── listing-unsorted.json
│   │   │   │       ├── listing.json
│   │   │   │       ├── metadata-edt-timezone/
│   │   │   │       │   └── metadata.json
│   │   │   │       ├── metadata-gocase/
│   │   │   │       │   └── metadata.json
│   │   │   │       └── tls/
│   │   │   │           ├── .gitignore
│   │   │   │           ├── Makefile
│   │   │   │           ├── README.md
│   │   │   │           ├── generate-x509-cert-pair.sh
│   │   │   │           ├── listing.py
│   │   │   │           └── serve.py
│   │   │   ├── fix.go
│   │   │   ├── id.go
│   │   │   ├── match_exclusion_provider.go
│   │   │   ├── namespace/
│   │   │   │   ├── cpe/
│   │   │   │   │   ├── namespace.go
│   │   │   │   │   └── namespace_test.go
│   │   │   │   ├── distro/
│   │   │   │   │   ├── namespace.go
│   │   │   │   │   └── namespace_test.go
│   │   │   │   ├── from_string.go
│   │   │   │   ├── from_string_test.go
│   │   │   │   ├── language/
│   │   │   │   │   ├── namespace.go
│   │   │   │   │   └── namespace_test.go
│   │   │   │   └── namespace.go
│   │   │   ├── pkg/
│   │   │   │   ├── qualifier/
│   │   │   │   │   ├── from_json.go
│   │   │   │   │   ├── platformcpe/
│   │   │   │   │   │   └── qualifier.go
│   │   │   │   │   ├── qualifier.go
│   │   │   │   │   └── rpmmodularity/
│   │   │   │   │       └── qualifier.go
│   │   │   │   └── resolver/
│   │   │   │       ├── java/
│   │   │   │       │   ├── resolver.go
│   │   │   │       │   └── resolver_test.go
│   │   │   │       ├── python/
│   │   │   │       │   ├── resolver.go
│   │   │   │       │   └── resolver_test.go
│   │   │   │       ├── resolver.go
│   │   │   │       ├── resolver_test.go
│   │   │   │       └── stock/
│   │   │   │           ├── resolver.go
│   │   │   │           └── resolver_test.go
│   │   │   ├── provider_store.go
│   │   │   ├── schema_version.go
│   │   │   ├── store/
│   │   │   │   ├── diff.go
│   │   │   │   ├── diff_test.go
│   │   │   │   ├── model/
│   │   │   │   │   ├── id.go
│   │   │   │   │   ├── vulnerability.go
│   │   │   │   │   ├── vulnerability_match_exclusion.go
│   │   │   │   │   ├── vulnerability_match_exclusion_test.go
│   │   │   │   │   ├── vulnerability_metadata.go
│   │   │   │   │   └── vulnerability_test.go
│   │   │   │   ├── store.go
│   │   │   │   └── store_test.go
│   │   │   ├── store.go
│   │   │   ├── vulnerability.go
│   │   │   ├── vulnerability_match_exclusion.go
│   │   │   ├── vulnerability_match_exclusion_store.go
│   │   │   ├── vulnerability_metadata.go
│   │   │   ├── vulnerability_metadata_store.go
│   │   │   └── vulnerability_store.go
│   │   └── v6/
│   │       ├── affected_cpe_store.go
│   │       ├── affected_cpe_store_test.go
│   │       ├── affected_package_store.go
│   │       ├── affected_package_store_test.go
│   │       ├── blob_store.go
│   │       ├── blob_store_test.go
│   │       ├── blobs.go
│   │       ├── blobs_test.go
│   │       ├── build/
│   │       │   ├── archive.go
│   │       │   ├── processors.go
│   │       │   ├── transformers/
│   │       │   │   ├── entry.go
│   │       │   │   ├── eol/
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── epss/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   └── go-case.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── github/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   ├── GHSA-2wgc-48g2-cj5w.json
│   │       │   │   │   │   ├── GHSA-3x74-v64j-qc3f.json
│   │       │   │   │   │   ├── GHSA-92cp-5422-2mw7.json
│   │       │   │   │   │   ├── GHSA-qc55-vm3j-74gp.json
│   │       │   │   │   │   ├── github-github-npm-0.json
│   │       │   │   │   │   ├── github-github-python-0.json
│   │       │   │   │   │   ├── github-withdrawn.json
│   │       │   │   │   │   └── multiple-fixed-in-names.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── internal/
│   │       │   │   │   ├── sort.go
│   │       │   │   │   ├── time.go
│   │       │   │   │   └── time_test.go
│   │       │   │   ├── kev/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   └── go-case.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── msrc/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   └── microsoft-msrc-0.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── nvd/
│   │       │   │   │   ├── affected_range.go
│   │       │   │   │   ├── affected_range_test.go
│   │       │   │   │   ├── node.go
│   │       │   │   │   ├── node_test.go
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   ├── CVE-2004-0377.json
│   │       │   │   │   │   ├── CVE-2008-3442.json
│   │       │   │   │   │   ├── CVE-2023-45283-platform-cpe-first.json
│   │       │   │   │   │   ├── CVE-2023-45283-platform-cpe-last.json
│   │       │   │   │   │   ├── compound-pkg.json
│   │       │   │   │   │   ├── cve-2020-10729.json
│   │       │   │   │   │   ├── cve-2021-1566.json
│   │       │   │   │   │   ├── cve-2022-0543.json
│   │       │   │   │   │   ├── cve-2024-26663-standalone-os.json
│   │       │   │   │   │   ├── fix-version.json
│   │       │   │   │   │   ├── fix-wrong-version.json
│   │       │   │   │   │   ├── invalid_cpe.json
│   │       │   │   │   │   ├── jvm-packages.json
│   │       │   │   │   │   ├── multiple-platforms-with-application-cpe.json
│   │       │   │   │   │   ├── platform-cpe.json
│   │       │   │   │   │   ├── single-package-multi-distro.json
│   │       │   │   │   │   └── version-range.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── openvex/
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── os/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   ├── alpine-3.9.json
│   │       │   │   │   │   ├── amazon-multiple-kernel-advisories.json
│   │       │   │   │   │   ├── amzn.json
│   │       │   │   │   │   ├── azure-linux-3.json
│   │       │   │   │   │   ├── debian-8-multiple-entries-for-same-package.json
│   │       │   │   │   │   ├── debian-8.json
│   │       │   │   │   │   ├── fedora-39.json
│   │       │   │   │   │   ├── mariner-20.json
│   │       │   │   │   │   ├── mariner-range.json
│   │       │   │   │   │   ├── ol-8-modules.json
│   │       │   │   │   │   ├── ol-8.json
│   │       │   │   │   │   ├── rhel-8-modules.json
│   │       │   │   │   │   └── rhel-8.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── osv/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   ├── ALSA-2025-7467.json
│   │       │   │   │   │   ├── BIT-apache-2020-11984.json
│   │       │   │   │   │   └── BIT-node-2020-8201.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   └── references.go
│   │       │   ├── writer.go
│   │       │   └── writer_test.go
│   │       ├── cache.go
│   │       ├── cache_test.go
│   │       ├── cpe_store.go
│   │       ├── data.go
│   │       ├── db.go
│   │       ├── db_metadata_store.go
│   │       ├── db_metadata_store_test.go
│   │       ├── description.go
│   │       ├── description_test.go
│   │       ├── distribution/
│   │       │   ├── client.go
│   │       │   ├── client_test.go
│   │       │   ├── latest.go
│   │       │   ├── latest_test.go
│   │       │   └── status.go
│   │       ├── enumerations.go
│   │       ├── enumerations_test.go
│   │       ├── fillers.go
│   │       ├── import_metadata.go
│   │       ├── import_metadata_test.go
│   │       ├── installation/
│   │       │   ├── curator.go
│   │       │   └── curator_test.go
│   │       ├── log_dropped.go
│   │       ├── models.go
│   │       ├── models_test.go
│   │       ├── name/
│   │       │   ├── java.go
│   │       │   ├── java_test.go
│   │       │   ├── python.go
│   │       │   ├── python_test.go
│   │       │   └── resolver.go
│   │       ├── operating_system_store.go
│   │       ├── operating_system_store_test.go
│   │       ├── package_store.go
│   │       ├── provider_store.go
│   │       ├── provider_store_test.go
│   │       ├── refs.go
│   │       ├── schema/
│   │       │   └── main.go
│   │       ├── search_query.go
│   │       ├── search_query_test.go
│   │       ├── severity.go
│   │       ├── severity_test.go
│   │       ├── store.go
│   │       ├── store_test.go
│   │       ├── unaffected_cpe_store.go
│   │       ├── unaffected_cpe_store_test.go
│   │       ├── unaffected_package_store.go
│   │       ├── unaffected_package_store_test.go
│   │       ├── vulnerability.go
│   │       ├── vulnerability_decorator_store.go
│   │       ├── vulnerability_decorator_store_test.go
│   │       ├── vulnerability_provider.go
│   │       ├── vulnerability_provider_mocks_test.go
│   │       ├── vulnerability_provider_test.go
│   │       ├── vulnerability_store.go
│   │       ├── vulnerability_store_test.go
│   │       └── vulnerability_test.go
│   ├── deprecated.go
│   ├── distro/
│   │   ├── distro.go
│   │   ├── distro_test.go
│   │   ├── fix_channel.go
│   │   ├── fix_channel_test.go
│   │   ├── testdata/
│   │   │   ├── bad-id
│   │   │   ├── bad-redhat-release
│   │   │   ├── bad-system-release-cpe
│   │   │   ├── centos-8
│   │   │   ├── debian-8
│   │   │   ├── os/
│   │   │   │   ├── almalinux/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── alpine/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── alpine-edge/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── amazon/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── arch/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── azurelinux/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── busybox/
│   │   │   │   │   └── bin/
│   │   │   │   │       └── busybox
│   │   │   │   ├── centos/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── centos5/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── redhat-release
│   │   │   │   ├── centos6/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── system-release-cpe
│   │   │   │   ├── chainguard/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── custom/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── debian/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── debian-sid/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── echo/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── empty/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── fedora/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── gentoo/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── mariner/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── minimos/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── opensuse-leap/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── oraclelinux/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── photon/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── postmarketos/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── postmarketos-edge/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── raspbian/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── redhat/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── rockylinux/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── scientific/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── scientific6/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── redhat-release
│   │   │   │   ├── secureos/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── sles/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── ubuntu/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   └── wolfi/
│   │   │   │       └── etc/
│   │   │   │           └── os-release
│   │   │   ├── partial-fields/
│   │   │   │   ├── missing-id/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── missing-version/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   └── unknown-id/
│   │   │   │       └── usr/
│   │   │   │           └── lib/
│   │   │   │               └── os-release
│   │   │   ├── rhel-8
│   │   │   ├── ubuntu-20.04
│   │   │   └── unprintable
│   │   ├── type.go
│   │   └── type_test.go
│   ├── event/
│   │   ├── event.go
│   │   ├── monitor/
│   │   │   ├── db_diff.go
│   │   │   └── matching.go
│   │   └── parsers/
│   │       └── parsers.go
│   ├── grypeerr/
│   │   ├── errors.go
│   │   └── expected_error.go
│   ├── internal/
│   │   ├── generate.go
│   │   └── packagemetadata/
│   │       ├── discover_type_names.go
│   │       ├── generate/
│   │       │   └── main.go
│   │       ├── generated.go
│   │       ├── names.go
│   │       └── names_test.go
│   ├── lib.go
│   ├── load_vulnerability_db.go
│   ├── load_vulnerability_db_bench_test.go
│   ├── match/
│   │   ├── details.go
│   │   ├── details_test.go
│   │   ├── explicit_ignores.go
│   │   ├── explicit_ignores_test.go
│   │   ├── fingerprint.go
│   │   ├── ignore.go
│   │   ├── ignore_test.go
│   │   ├── match.go
│   │   ├── match_test.go
│   │   ├── matcher.go
│   │   ├── matcher_type.go
│   │   ├── matches.go
│   │   ├── matches_test.go
│   │   ├── provider.go
│   │   ├── results.go
│   │   ├── sort.go
│   │   └── type.go
│   ├── matcher/
│   │   ├── apk/
│   │   │   ├── matcher.go
│   │   │   └── matcher_test.go
│   │   ├── bitnami/
│   │   │   └── matcher.go
│   │   ├── dotnet/
│   │   │   └── matcher.go
│   │   ├── dpkg/
│   │   │   ├── matcher.go
│   │   │   ├── matcher_mocks_test.go
│   │   │   └── matcher_test.go
│   │   ├── golang/
│   │   │   ├── matcher.go
│   │   │   └── matcher_test.go
│   │   ├── hex/
│   │   │   └── matcher.go
│   │   ├── internal/
│   │   │   ├── common.go
│   │   │   ├── cpe.go
│   │   │   ├── cpe_test.go
│   │   │   ├── distro.go
│   │   │   ├── distro_test.go
│   │   │   ├── eol.go
│   │   │   ├── eol_test.go
│   │   │   ├── language.go
│   │   │   ├── language_test.go
│   │   │   ├── only_non_withdrawn_vulnerabilities.go
│   │   │   ├── only_qualified_packages.go
│   │   │   ├── only_vulnerable_targets.go
│   │   │   ├── only_vulnerable_targets_test.go
│   │   │   ├── only_vulnerable_versions.go
│   │   │   ├── result/
│   │   │   │   ├── match_details_set.go
│   │   │   │   ├── provider.go
│   │   │   │   ├── results.go
│   │   │   │   └── results_test.go
│   │   │   └── utils_test.go
│   │   ├── java/
│   │   │   ├── matcher.go
│   │   │   ├── matcher_integration_test.go
│   │   │   ├── matcher_mocks_test.go
│   │   │   ├── matcher_test.go
│   │   │   ├── maven_search.go
│   │   │   └── maven_test.go
│   │   ├── javascript/
│   │   │   └── matcher.go
│   │   ├── matchers.go
│   │   ├── mock/
│   │   │   └── matcher.go
│   │   ├── msrc/
│   │   │   └── matcher.go
│   │   ├── pacman/
│   │   │   ├── matcher.go
│   │   │   └── matcher_test.go
│   │   ├── portage/
│   │   │   ├── matcher.go
│   │   │   ├── matcher_mocks_test.go
│   │   │   └── matcher_test.go
│   │   ├── python/
│   │   │   └── matcher.go
│   │   ├── rpm/
│   │   │   ├── almalinux.go
│   │   │   ├── almalinux_package_utils.go
│   │   │   ├── almalinux_package_utils_test.go
│   │   │   ├── almalinux_test.go
│   │   │   ├── matcher.go
│   │   │   ├── matcher_mocks_test.go
│   │   │   ├── matcher_test.go
│   │   │   ├── rhel_eus.go
│   │   │   └── rhel_eus_test.go
│   │   ├── ruby/
│   │   │   └── matcher.go
│   │   ├── rust/
│   │   │   └── matcher.go
│   │   └── stock/
│   │       ├── matcher.go
│   │       └── matcher_test.go
│   ├── pkg/
│   │   ├── apk_metadata.go
│   │   ├── context.go
│   │   ├── context_test.go
│   │   ├── cpe_provider.go
│   │   ├── cpe_provider_test.go
│   │   ├── file_owner.go
│   │   ├── golang_metadata.go
│   │   ├── java_metadata.go
│   │   ├── java_metadata_test.go
│   │   ├── package.go
│   │   ├── package_test.go
│   │   ├── provider.go
│   │   ├── provider_config.go
│   │   ├── provider_test.go
│   │   ├── purl_provider.go
│   │   ├── purl_provider_test.go
│   │   ├── qualifier/
│   │   │   ├── platformcpe/
│   │   │   │   ├── qualifier.go
│   │   │   │   └── qualifier_test.go
│   │   │   ├── qualifier.go
│   │   │   └── rpmmodularity/
│   │   │       ├── qualifier.go
│   │   │       └── qualifier_test.go
│   │   ├── rpm_metadata.go
│   │   ├── syft_provider.go
│   │   ├── syft_sbom_provider.go
│   │   ├── syft_sbom_provider_test.go
│   │   ├── testdata/
│   │   │   ├── alpine-tampered.att.json
│   │   │   ├── alpine-tampered.cdx.att.json
│   │   │   ├── alpine.att.json
│   │   │   ├── alpine.cdx.att.json
│   │   │   ├── another_cosign.pub
│   │   │   ├── bad-sbom.json
│   │   │   ├── cosign.pub
│   │   │   ├── cosign_broken.pub
│   │   │   ├── image-simple/
│   │   │   │   ├── Dockerfile
│   │   │   │   ├── package.json
│   │   │   │   └── target/
│   │   │   │       └── nested/
│   │   │   │           └── package.json
│   │   │   ├── invalid.json
│   │   │   ├── purl/
│   │   │   │   ├── different-os.txt
│   │   │   │   ├── empty.json
│   │   │   │   ├── homogeneous-os.txt
│   │   │   │   ├── invalid-cpe.txt
│   │   │   │   ├── invalid-purl.txt
│   │   │   │   ├── valid-purl.txt
│   │   │   │   ├── valid-rhel-9+eus.txt
│   │   │   │   └── valid-rhel-9.txt
│   │   │   ├── sbom-with-intoto-string.json
│   │   │   ├── syft-java-bad-cpes.json
│   │   │   ├── syft-multiple-ecosystems.json
│   │   │   └── syft-spring.json
│   │   ├── upstream_package.go
│   │   ├── upstream_package_test.go
│   │   ├── version_format.go
│   │   └── version_format_test.go
│   ├── presenter/
│   │   ├── cyclonedx/
│   │   │   ├── presenter.go
│   │   │   ├── presenter_test.go
│   │   │   ├── testdata/
│   │   │   │   └── snapshot/
│   │   │   │       ├── TestCycloneDxPresenterDir.golden
│   │   │   │       └── TestCycloneDxPresenterImage.golden
│   │   │   ├── vulnerability.go
│   │   │   └── vulnerability_test.go
│   │   ├── explain/
│   │   │   ├── __snapshots__/
│   │   │   │   └── explain_snapshot_test.snap
│   │   │   ├── explain.go
│   │   │   ├── explain_cve.tmpl
│   │   │   ├── explain_snapshot_test.go
│   │   │   └── testdata/
│   │   │       ├── chainguard-ruby-test.json
│   │   │       ├── ghsa-test.json
│   │   │       └── keycloak-test.json
│   │   ├── internal/
│   │   │   └── test_helpers.go
│   │   ├── json/
│   │   │   ├── presenter.go
│   │   │   ├── presenter_test.go
│   │   │   └── testdata/
│   │   │       ├── image-simple/
│   │   │       │   ├── Dockerfile
│   │   │       │   ├── file-1.txt
│   │   │       │   ├── file-2.txt
│   │   │       │   └── target/
│   │   │       │       └── really/
│   │   │       │           └── nested/
│   │   │       │               └── file-3.txt
│   │   │       └── snapshot/
│   │   │           ├── TestEmptyJsonPresenter.golden
│   │   │           ├── TestJsonDirsPresenter.golden
│   │   │           ├── TestJsonImgsPresenter.golden
│   │   │           ├── anchore-fixture-image-simple.golden
│   │   │           └── stereoscope-fixture-image-simple.golden
│   │   ├── models/
│   │   │   ├── alert.go
│   │   │   ├── alert_test.go
│   │   │   ├── cvss.go
│   │   │   ├── descriptor.go
│   │   │   ├── distribution.go
│   │   │   ├── document.go
│   │   │   ├── document_test.go
│   │   │   ├── ignore.go
│   │   │   ├── ignore_test.go
│   │   │   ├── match.go
│   │   │   ├── metadata_mock.go
│   │   │   ├── package.go
│   │   │   ├── presenter_bundle.go
│   │   │   ├── sort.go
│   │   │   ├── sort_test.go
│   │   │   ├── source.go
│   │   │   ├── source_test.go
│   │   │   ├── vulnerability.go
│   │   │   ├── vulnerability_metadata.go
│   │   │   └── vulnerability_test.go
│   │   ├── presenter.go
│   │   ├── sarif/
│   │   │   ├── presenter.go
│   │   │   ├── presenter_test.go
│   │   │   └── testdata/
│   │   │       ├── image-simple/
│   │   │       │   ├── Dockerfile
│   │   │       │   ├── file-1.txt
│   │   │       │   ├── file-2.txt
│   │   │       │   └── target/
│   │   │       │       └── really/
│   │   │       │           └── nested/
│   │   │       │               └── file-3.txt
│   │   │       └── snapshot/
│   │   │           ├── TestSarifPresenter_directory.golden
│   │   │           └── TestSarifPresenter_image.golden
│   │   ├── table/
│   │   │   ├── __snapshots__/
│   │   │   │   └── presenter_test.snap
│   │   │   ├── presenter.go
│   │   │   ├── presenter_test.go
│   │   │   └── testdata/
│   │   │       └── snapshot/
│   │   │           └── TestTablePresenter_Color.golden
│   │   └── template/
│   │       ├── presenter.go
│   │       ├── presenter_test.go
│   │       └── testdata/
│   │           ├── snapshot/
│   │           │   └── TestPresenter_Present.golden
│   │           ├── test.template
│   │           ├── test.template.sprig.date
│   │           └── test.valid.template
│   ├── search/
│   │   ├── cpe.go
│   │   ├── cpe_test.go
│   │   ├── criteria.go
│   │   ├── criteria_test.go
│   │   ├── distro.go
│   │   ├── distro_test.go
│   │   ├── ecosystem.go
│   │   ├── ecosystem_test.go
│   │   ├── func.go
│   │   ├── func_test.go
│   │   ├── id.go
│   │   ├── id_test.go
│   │   ├── package_name.go
│   │   ├── package_name_test.go
│   │   ├── unaffected.go
│   │   ├── version_constraint.go
│   │   └── version_constraint_test.go
│   ├── version/
│   │   ├── apk_version.go
│   │   ├── apk_version_test.go
│   │   ├── bitnami_version.go
│   │   ├── bitnami_version_test.go
│   │   ├── combined_constraint.go
│   │   ├── combined_constraint_test.go
│   │   ├── comparator.go
│   │   ├── constraint.go
│   │   ├── deb_version.go
│   │   ├── deb_version_test.go
│   │   ├── deprecated.go
│   │   ├── error.go
│   │   ├── format.go
│   │   ├── format_test.go
│   │   ├── fuzzy_constraint.go
│   │   ├── fuzzy_constraint_test.go
│   │   ├── fuzzy_version.go
│   │   ├── fuzzy_version_test.go
│   │   ├── gem_version.go
│   │   ├── gem_version_test.go
│   │   ├── generic_constraint.go
│   │   ├── generic_constraint_test.go
│   │   ├── golang_version.go
│   │   ├── golang_version_test.go
│   │   ├── helper_test.go
│   │   ├── jvm_version.go
│   │   ├── jvm_version_test.go
│   │   ├── kb_constraint.go
│   │   ├── kb_constraint_test.go
│   │   ├── kb_version.go
│   │   ├── kb_version_test.go
│   │   ├── maven_version.go
│   │   ├── maven_version_test.go
│   │   ├── operator.go
│   │   ├── pacman_version.go
│   │   ├── pacman_version_test.go
│   │   ├── pep440_version.go
│   │   ├── pep440_version_test.go
│   │   ├── portage_version.go
│   │   ├── portage_version_test.go
│   │   ├── range.go
│   │   ├── range_expression.go
│   │   ├── range_expression_test.go
│   │   ├── range_test.go
│   │   ├── rpm_version.go
│   │   ├── rpm_version_test.go
│   │   ├── semantic_version.go
│   │   ├── semantic_version_test.go
│   │   ├── set.go
│   │   ├── set_test.go
│   │   ├── version.go
│   │   └── version_test.go
│   ├── vex/
│   │   ├── csaf/
│   │   │   ├── csaf.go
│   │   │   ├── csaf_test.go
│   │   │   ├── implementation.go
│   │   │   ├── implementation_test.go
│   │   │   └── status.go
│   │   ├── openvex/
│   │   │   ├── implementation.go
│   │   │   └── implementation_test.go
│   │   ├── processor.go
│   │   ├── processor_test.go
│   │   ├── status/
│   │   │   └── status.go
│   │   └── testdata/
│   │       └── vex-docs/
│   │           ├── csaf-demo1.json
│   │           ├── csaf-demo2.json
│   │           ├── openvex-debian.json
│   │           ├── openvex-demo1.json
│   │           ├── openvex-demo2.json
│   │           ├── openvex-image-no-subcomponents.json
│   │           └── openvex-package-product.json
│   ├── vulnerability/
│   │   ├── advisory.go
│   │   ├── fix.go
│   │   ├── metadata.go
│   │   ├── metadata_test.go
│   │   ├── mock/
│   │   │   └── vulnerability_provider.go
│   │   ├── provider.go
│   │   ├── severity.go
│   │   └── vulnerability.go
│   ├── vulnerability_matcher.go
│   └── vulnerability_matcher_test.go
├── install.sh
├── internal/
│   ├── bus/
│   │   ├── bus.go
│   │   └── helpers.go
│   ├── cvss/
│   │   ├── metrics.go
│   │   └── metrics_test.go
│   ├── dbtest/
│   │   ├── default_vulnerabilities.go
│   │   ├── server.go
│   │   └── server_test.go
│   ├── file/
│   │   ├── copy.go
│   │   ├── exists.go
│   │   ├── getter.go
│   │   ├── getter_test.go
│   │   ├── hasher.go
│   │   ├── hasher_test.go
│   │   ├── tar_xz_decompressor.go
│   │   ├── tar_xz_decompressor_test.go
│   │   ├── xz_decompressor.go
│   │   └── xz_decompressor_test.go
│   ├── format/
│   │   ├── format.go
│   │   ├── format_test.go
│   │   ├── presenter.go
│   │   ├── writer.go
│   │   └── writer_test.go
│   ├── input.go
│   ├── log/
│   │   ├── errors.go
│   │   └── log.go
│   ├── redact/
│   │   └── redact.go
│   ├── regex_helpers.go
│   ├── regex_helpers_test.go
│   ├── schemaver/
│   │   ├── schema_ver.go
│   │   └── schema_ver_test.go
│   ├── stringutil/
│   │   ├── color.go
│   │   ├── parse.go
│   │   ├── string_helpers.go
│   │   ├── string_helpers_test.go
│   │   ├── stringset.go
│   │   └── tprint.go
│   └── testutils/
│       └── golden_file.go
├── llms.txt
├── schema/
│   └── grype/
│       ├── db/
│       │   ├── README.md
│       │   ├── blob/
│       │   │   └── json/
│       │   │       ├── schema-6.1.1.json
│       │   │       ├── schema-6.1.2.json
│       │   │       ├── schema-6.1.3.json
│       │   │       ├── schema-6.1.4.json
│       │   │       └── schema-latest.json
│       │   └── sql/
│       │       ├── schema-6.1.1.sql
│       │       ├── schema-6.1.2.sql
│       │       ├── schema-6.1.3.sql
│       │       ├── schema-6.1.4.sql
│       │       └── schema-latest.sql
│       ├── db-search/
│       │   └── json/
│       │       ├── README.md
│       │       ├── schema-1.0.0.json
│       │       ├── schema-1.0.1.json
│       │       ├── schema-1.0.2.json
│       │       ├── schema-1.0.3.json
│       │       ├── schema-1.1.0.json
│       │       ├── schema-1.1.1.json
│       │       ├── schema-1.1.2.json
│       │       ├── schema-1.1.3.json
│       │       └── schema-latest.json
│       └── db-search-vuln/
│           └── json/
│               ├── README.md
│               ├── schema-1.0.0.json
│               ├── schema-1.0.1.json
│               ├── schema-1.0.3.json
│               ├── schema-1.0.4.json
│               ├── schema-1.0.5.json
│               └── schema-latest.json
├── templates/
│   ├── README.md
│   ├── csv.tmpl
│   ├── html.tmpl
│   ├── junit.tmpl
│   ├── markdown.tmpl
│   └── table.tmpl
└── test/
    ├── cli/
    │   ├── cmd_test.go
    │   ├── config_test.go
    │   ├── db_providers_test.go
    │   ├── db_validations_test.go
    │   ├── registry_auth_test.go
    │   ├── sbom_input_test.go
    │   ├── subprocess_test.go
    │   ├── testdata/
    │   │   ├── Makefile
    │   │   ├── another_cosign.pub
    │   │   ├── configs/
    │   │   │   ├── dir1/
    │   │   │   │   └── .grype.yaml
    │   │   │   ├── dir2/
    │   │   │   │   └── .grype.yaml
    │   │   │   └── dir3/
    │   │   │       └── .grype.yaml
    │   │   ├── cosign.pub
    │   │   ├── cosign_broken.pub
    │   │   ├── empty.json
    │   │   ├── image-bare/
    │   │   │   ├── Dockerfile
    │   │   │   └── file-1.txt
    │   │   ├── image-java-subprocess/
    │   │   │   ├── Dockerfile
    │   │   │   └── app.java
    │   │   ├── image-node-subprocess/
    │   │   │   ├── Dockerfile
    │   │   │   └── app.js
    │   │   ├── sbom-grype-source.json
    │   │   ├── sbom-ubuntu-20.04--pruned.json
    │   │   └── test-ignore-reason/
    │   │       ├── config-with-ignore.yaml
    │   │       ├── sbom.json
    │   │       └── template-with-ignore-reasons
    │   ├── trait_assertions_test.go
    │   ├── utils_test.go
    │   └── version_cmd_test.go
    ├── grype-test-config.yaml
    ├── ignore-att-signature.yaml
    ├── install/
    │   ├── .dockerignore
    │   ├── .gitignore
    │   ├── 0_checksums_test.sh
    │   ├── 1_download_snapshot_asset_test.sh
    │   ├── 2_download_release_asset_test.sh
    │   ├── 3_install_asset_test.sh
    │   ├── 4_prep_signature_verification_test.sh
    │   ├── Makefile
    │   ├── environments/
    │   │   ├── Dockerfile-alpine-3.6
    │   │   ├── Dockerfile-busybox-1.36
    │   │   └── Dockerfile-ubuntu-20.04
    │   ├── github_test.sh
    │   ├── test_harness.sh
    │   └── testdata/
    │       ├── assets/
    │       │   ├── invalid/
    │       │   │   ├── .gitignore
    │       │   │   └── checksums.txt
    │       │   └── valid/
    │       │       ├── .gitignore
    │       │       └── checksums.txt
    │       ├── github-api-grype-v0.32.0-release.json
    │       ├── grype_0.32.0-SNAPSHOT-d461f63_checksums.txt
    │       └── grype_0.32.0_checksums.txt
    ├── integration/
    │   ├── compare_sbom_input_vs_lib_test.go
    │   ├── db_mock_test.go
    │   ├── match_by_image_test.go
    │   ├── match_by_sbom_document_test.go
    │   ├── testdata/
    │   │   ├── .gitignore
    │   │   ├── Makefile
    │   │   ├── image-alpine-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── etc/
    │   │   │   │   └── os-release
    │   │   │   └── lib/
    │   │   │       └── apk/
    │   │   │           └── db/
    │   │   │               └── installed
    │   │   ├── image-arch-match-coverage/
    │   │   │   └── Dockerfile
    │   │   ├── image-centos-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── etc/
    │   │   │   │   └── os-release
    │   │   │   └── var/
    │   │   │       └── lib/
    │   │   │           └── rpm/
    │   │   │               ├── Packages
    │   │   │               └── generate-fixture.sh
    │   │   ├── image-debian-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── dotnet/
    │   │   │   │   └── TestLibrary.deps.json
    │   │   │   ├── golang/
    │   │   │   │   ├── go.mod
    │   │   │   │   ├── go.sum
    │   │   │   │   └── main.go
    │   │   │   ├── haskell/
    │   │   │   │   ├── cabal.project.freeze
    │   │   │   │   └── stack.yaml
    │   │   │   ├── java/
    │   │   │   │   └── generate-fixtures.md
    │   │   │   ├── javascript/
    │   │   │   │   └── pkg-json/
    │   │   │   │       └── package.json
    │   │   │   ├── python/
    │   │   │   │   └── dist-info/
    │   │   │   │       ├── METADATA
    │   │   │   │       └── top_level.txt
    │   │   │   ├── ruby/
    │   │   │   │   └── specifications/
    │   │   │   │       └── bundler.gemspec
    │   │   │   ├── usr/
    │   │   │   │   └── lib/
    │   │   │   │       └── os-release
    │   │   │   └── var/
    │   │   │       └── lib/
    │   │   │           └── dpkg/
    │   │   │               └── status
    │   │   ├── image-jvm-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   └── opt/
    │   │   │       └── java/
    │   │   │           └── openjdk/
    │   │   │               └── release
    │   │   ├── image-portage-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── etc/
    │   │   │   │   └── os-release
    │   │   │   └── var/
    │   │   │       └── db/
    │   │   │           ├── pkg/
    │   │   │           │   └── app-containers/
    │   │   │           │       └── skopeo-1.5.1/
    │   │   │           │           ├── CONTENTS
    │   │   │           │           ├── LICENSE
    │   │   │           │           └── SIZE
    │   │   │           └── repos/
    │   │   │               └── gentoo/
    │   │   │                   └── skel.ebuild
    │   │   ├── image-rust-auditable-match-coverage/
    │   │   │   └── Dockerfile
    │   │   ├── image-sles-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── etc/
    │   │   │   │   └── os-release
    │   │   │   └── var/
    │   │   │       └── lib/
    │   │   │           └── rpm/
    │   │   │               ├── Packages
    │   │   │               └── generate-fixture.sh
    │   │   ├── sbom/
    │   │   │   ├── syft-sbom-with-kb-packages.json
    │   │   │   └── syft-sbom-with-unknown-packages.json
    │   │   ├── skopeo-policy.json
    │   │   ├── snapshot/
    │   │   │   └── TestDatabaseDiff.golden
    │   │   └── vex/
    │   │       ├── csaf/
    │   │       │   ├── affected.csaf.json
    │   │       │   └── under_investigation.csaf.json
    │   │       └── openvex/
    │   │           ├── affected.openvex.json
    │   │           └── under_investigation.openvex.json
    │   └── utils_test.go
    ├── quality/
    │   ├── .gitignore
    │   ├── .grype.yaml
    │   ├── .python-version
    │   ├── .yardstick.yaml
    │   ├── Makefile
    │   ├── README.md
    │   ├── requirements.txt
    │   └── test-db
    └── validate-grype-db-schema.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .binny.yaml
================================================
tools:
  # we want to use a pinned version of binny to manage the toolchain (so binny manages itself!)
  - name: binny
    version:
      want: v0.12.0
    method: github-release
    with:
      repo: anchore/binny

  # used to produce SBOMs during release
  - name: syft
    version:
      want: latest
    method: github-release
    with:
      repo: anchore/syft

  # used to sign mac binaries at release
  - name: quill
    version:
      want: v0.7.1
    method: github-release
    with:
      repo: anchore/quill

  # used for linting
  - name: golangci-lint
    version:
      want: v2.11.3
    method: github-release
    with:
      repo: golangci/golangci-lint

  # used for showing the changelog at release
  - name: glow
    version:
      want: v2.1.1
    method: github-release
    with:
      repo: charmbracelet/glow

  # used for signing the checksums file at release
  - name: cosign
    version:
      want: v3.0.5
    method: github-release
    with:
      repo: sigstore/cosign

  # used to release all artifacts
  - name: goreleaser
    version:
      want: v2.14.3
    method: github-release
    with:
      repo: goreleaser/goreleaser

  # used for organizing imports during static analysis
  - name: gosimports
    version:
      want: v0.3.8
    method: github-release
    with:
      repo: rinchsan/gosimports

  # used at release to generate the changelog
  - name: chronicle
    version:
      want: v0.8.0
    method: github-release
    with:
      repo: anchore/chronicle

  # used during static analysis for license compliance
  - name: bouncer
    version:
      want: v0.4.0
    method: github-release
    with:
      repo: wagoodman/go-bouncer

  # used for running all local and CI tasks
  - name: task
    version:
      want: v3.49.1
    method: github-release
    with:
      repo: go-task/task

  # used for triggering a release
  - name: gh
    version:
      want: v2.88.1
    method: github-release
    with:
      repo: cli/cli

  # used for integration tests
  - name: skopeo
    version:
      want: v1.22.0
    method: go-install
    with:
      module: github.com/containers/skopeo
      entrypoint: cmd/skopeo
      args:
        - "-tags"
        - containers_image_openpgp
      env:
        - CGO_ENABLED=0
        - GO_DYN_FLAGS=""


================================================
FILE: .bouncer.yaml
================================================
permit:
  - BSD.*
  - CC0.*
  - MIT.*
  - Apache.*
  - MPL.*
  - ISC
  - WTFPL

ignore-packages:
  # packageurl-go is released under the MIT license located in the root of the repo at /mit.LICENSE
  - github.com/anchore/packageurl-go

  # github.com/gocsaf/csaf is released under the Apache License, version 2.0 (Apache-2.0)
  # https://github.com/gocsaf/csaf/blob/main/LICENSE-Apache-2.0.txt
  - github.com/gocsaf/csaf/v3/csaf
  - github.com/gocsaf/csaf/v3/internal/misc
  - github.com/gocsaf/csaf/v3/util

  # tools-golang is released under the Apache License, version 2.0 (Apache-2.0)
  # https://github.com/spdx/tools-golang/blob/main/LICENSE.code
  - github.com/spdx/tools-golang

  # crypto/internal/boring is released under the openSSL license as a part of the Golang Standard Libary
  - crypto/internal/boring

  # from: https://github.com/xi2/xz/blob/master/LICENSE
  # All these files have been put into the public domain.
  # You can do whatever you want with these files.
  - github.com/xi2/xz

  # from: https://github.com/owenrumney/go-sarif/blob/main/LICENSE
  # This is released into the public domain using the "Unlicense license"
  - github.com/owenrumney/go-sarif

  # github.com/sorairolake/lzip-go is released under the Apache License, version 2.0 (Apache-2.0)
  # https://github.com/sorairolake/lzip-go/blob/develop/LICENSE-APACHE
  - github.com/sorairolake/lzip-go

  # from: https://gitlab.com/cznic/sqlite/-/blob/v1.66.3/LICENSE
  # This is a BSD-3-Clause license
  - modernc.org/libc
  - modernc.org/libc/errno
  - modernc.org/libc/fcntl
  - modernc.org/libc/fts
  - modernc.org/libc/grp
  - modernc.org/libc/langinfo
  - modernc.org/libc/limits
  - modernc.org/libc/netdb
  - modernc.org/libc/netinet/in
  - modernc.org/libc/poll
  - modernc.org/libc/pthread
  - modernc.org/libc/pwd
  - modernc.org/libc/signal
  - modernc.org/libc/stdio
  - modernc.org/libc/stdlib
  - modernc.org/libc/sys/socket
  - modernc.org/libc/sys/stat
  - modernc.org/libc/sys/types
  - modernc.org/libc/termios
  - modernc.org/libc/time
  - modernc.org/libc/unistd
  - modernc.org/libc/utime
  - modernc.org/libc/uuid/uuid
  - modernc.org/libc/wctype
  - modernc.org/mathutil
  - modernc.org/memory



================================================
FILE: .chronicle.yaml
================================================
enforce-v0: true # don't make breaking-change label bump major version before 1.0.
title: ""


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''

---

**What happened**:

**What you expected to happen**:

**How to reproduce it (as minimally and precisely as possible)**:

<!--
If possible, please include a link to an artifact grype can scan, instructions to make
one, or upload it on this issue. Some suggestions:

1. Link to Dockerhub, GitHub, GitLab, maven central, quay.io, etc to a public
   artifact we can try scanning
2. A Dockerfile that we can build and scan
3. A simple script that creates a directory exhibiting the issue, for example a
   list of `npm install` commands

Please also include the grype command and any configuration used.
-->
**Anything else we need to know?**:

**Environment**:
- Output of `grype version`:
- OS (e.g: `cat /etc/os-release` or similar):


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
contact_links:

  - name: Join our Discourse community 💬
    # link to our community Discourse site
    url: https://anchore.com/discourse
    about: 'Come chat with us! Ask for help, join our software development efforts, or just give us feedback!'


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''

---

**What would you like to be added**:

**Why is this needed**:

**Additional context**:
<!-- Add any other context or screenshots about the feature request here. -->


================================================
FILE: .github/ISSUE_TEMPLATE/match_issue.md
================================================
---
name: Vulnerability Match Issue
about: Report an issue with vulnerability matching
title: ''
labels: [ bug, false-positive ]
assignees: ''
---

**Vulnerability ID**:
<!-- CVE, GHSA, etc. -->

**Package URL or steps to reproduce**:
<!--
Running `grype <PackageURL>` should show the matching issue. If it does, please provide
the full Package URL, e.g.: pkg:apk/alpine/alpine-baselayout@3.7.0-r0?arch=x86_64&distro=alpine-3.22.2
make sure to include all parameters, including the distro, where applicable.

If the issue can't be reproduced with a Package URL, please link to a public artifact
grype can scan or provide other instructions to reproduce.
Some suggestions:
1. Link to Dockerhub, GitHub, GitLab, maven central, quay.io, etc to a public
   artifact we can try scanning
2. A Dockerfile that we can build and scan
3. A simple script that creates a directory exhibiting the issue, for example a
   list of `npm install` commands

Please also include the grype command and any configuration used.
-->

**Anything else we need to know?**:
<!-- Add additional information here:
Some suggestions:
1. Links to the GHSA or CVE page(s)
2. Explanation why a vulnerability is or isn't applicable
-->

**Environment**:
- Output of `grype version`:
- OS (e.g: `cat /etc/os-release` or similar):


================================================
FILE: .github/actions/bootstrap/action.yaml
================================================
name: "Bootstrap"
description: "Bootstrap all tools and dependencies"
inputs:
  go-version:
    description: "Go version to install"
    required: true
    default: "1.25.x"
  python-version:
    description: "Python version to install"
    required: true
    default: "3.11"
  go-dependencies:
    description: "Download go dependencies"
    required: true
    default: "true"
  cache-key-prefix:
    description: "Prefix all cache keys with this value"
    required: true
    default: "1ac8281053"
  compute-fingerprints:
    description: "Compute test fixture fingerprints"
    required: true
    default: "true"
  tools:
    description: "whether to install tools"
    default: "true"
  bootstrap-apt-packages:
    description: "Space delimited list of tools to install via apt"
    default: "libxml2-utils"

runs:
  using: "composite"
  steps:
    # note: go mod and build is automatically cached on default with v4+
    - uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
      if: inputs.go-version != ''
      with:
        go-version: ${{ inputs.go-version }}
        check-latest: true

    - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
      with:
        python-version: ${{ inputs.python-version }}

    - name: Restore tool cache
      id: tool-cache
      uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
      if: inputs.tools == 'true'
      with:
        path: ${{ github.workspace }}/.tool
        key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('.binny.yaml') }}

    - name: Install project tools
      if: inputs.tools == 'true'
      shell: bash
      run: |
        make tools
        .tool/binny list
        .tool/binny check

    - name: Install go dependencies
      if: inputs.go-dependencies == 'true'
      shell: bash
      run: make ci-bootstrap-go

    - name: Install apt packages
      if: inputs.bootstrap-apt-packages != ''
      shell: bash
      run: |
        read -ra PACKAGES <<< "$BOOTSTRAP_APT_PACKAGES"
        DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y "${PACKAGES[@]}"
      env:
        BOOTSTRAP_APT_PACKAGES: ${{ inputs.bootstrap-apt-packages }}

    - name: Create all cache fingerprints
      if: inputs.compute-fingerprints == 'true'
      shell: bash
      run: make fingerprints


================================================
FILE: .github/dependabot.yaml
================================================
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: daily
    cooldown:
      default-days: 7

  - package-ecosystem: "github-actions"
    directory: "/.github/actions/bootstrap"
    schedule:
      interval: "daily"
    open-pull-requests-limit: 10
    labels:
      - "dependencies"
    cooldown:
      default-days: 7

  - package-ecosystem: "gomod"
    directory: "/"
    schedule:
      interval: daily
    cooldown:
      default-days: 7


================================================
FILE: .github/scripts/check-syft-version-is-release.sh
================================================
#!/usr/bin/env bash
set -e

version=$(grep -E "github.com/anchore/syft" go.mod | awk '{print $NF}')

# ensure that the version is a release version (not a commit hash)
# a release in this case means that the go tooling resolved the version to a tag
# this does not guarantee that the tag has a github release associated with it
if [[ ! $version =~ ^v[0-9]+\.[0-9]+\.[0-9]?$ ]]; then
    echo "syft version in go.mod is not a release version: $version"
    echo "please update the version in go.mod to a release version and try again"
    exit 1
else
    echo "syft version in go.mod is a release version: $version"
fi


================================================
FILE: .github/scripts/ci-check.sh
================================================
#!/usr/bin/env bash

red=$(tput setaf 1)
bold=$(tput bold)
normal=$(tput sgr0)

# assert we are running in CI (or die!)
if [[ -z "$CI" ]]; then
    echo "${bold}${red}This step should ONLY be run in CI. Exiting...${normal}"
    exit 1
fi



================================================
FILE: .github/scripts/coverage.py
================================================
#!/usr/bin/env python3
import subprocess
import sys
import shlex


class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'


if len(sys.argv) < 3:
    print("Usage: coverage.py [threshold] [go-coverage-report]")
    sys.exit(1)


threshold = float(sys.argv[1])
report = sys.argv[2]


args = shlex.split(f"go tool cover -func {report}")
p = subprocess.run(args, capture_output=True, text=True)

percent_coverage = float(p.stdout.splitlines()[-1].split()[-1].replace("%", ""))
print(f"{bcolors.BOLD}Coverage: {percent_coverage}%{bcolors.ENDC}")

if percent_coverage < threshold:
    print(f"{bcolors.BOLD}{bcolors.FAIL}Coverage below threshold of {threshold}%{bcolors.ENDC}")
    sys.exit(1)


================================================
FILE: .github/scripts/db-schema-drift-check.sh
================================================
#!/usr/bin/env bash
set -u

if [ "$(git status --porcelain | wc -l)" -ne "0" ]; then
  echo "  🔴 there are uncommitted changes, please commit them before running this check"
  exit 1
fi

if ! make generate-db-schema; then
  echo "Generating database blob schemas failed"
  exit 1
fi

if [ "$(git status --porcelain | wc -l)" -ne "0" ]; then
  echo "  🔴 database blob schemas have uncommitted changes"
  echo "  Run 'task generate-db-schema' and commit the changes"
  echo ""
  git status --porcelain
  echo ""
  git diff schema/grype/db/
  exit 1
fi

echo "✅ Database blob schemas are up to date"


================================================
FILE: .github/scripts/go-mod-tidy-check.sh
================================================
#!/usr/bin/env bash
set -eu

ORIGINAL_STATE_DIR=$(mktemp -d "TEMP-original-state-XXXXXXXXX")
TIDY_STATE_DIR=$(mktemp -d "TEMP-tidy-state-XXXXXXXXX")

trap "cp -p ${ORIGINAL_STATE_DIR}/* ./ && git update-index -q --refresh && rm -fR ${ORIGINAL_STATE_DIR} ${TIDY_STATE_DIR}" EXIT

# capturing original state of files...
cp go.mod go.sum "${ORIGINAL_STATE_DIR}"

# capturing state of go.mod and go.sum after running go mod tidy...
go mod tidy
cp go.mod go.sum "${TIDY_STATE_DIR}"

set +e

# detect difference between the git HEAD state and the go mod tidy state
DIFF_MOD=$(diff -u "${ORIGINAL_STATE_DIR}/go.mod" "${TIDY_STATE_DIR}/go.mod")
DIFF_SUM=$(diff -u "${ORIGINAL_STATE_DIR}/go.sum" "${TIDY_STATE_DIR}/go.sum")

if [[ -n "${DIFF_MOD}" || -n "${DIFF_SUM}" ]]; then
    echo "go.mod diff:"
    echo "${DIFF_MOD}"
    echo "go.sum diff:"
    echo "${DIFF_SUM}"
    echo ""
    printf "FAILED! go.mod and/or go.sum are NOT tidy; please run 'go mod tidy'.\n\n"
    exit 1
fi


================================================
FILE: .github/scripts/json-schema-drift-check.sh
================================================
#!/usr/bin/env bash
set -u

if [ "$(git status --porcelain | wc -l)" -ne "0" ]; then
  echo "  🔴 there are uncommitted changes, please commit them before running this check"
  exit 1
fi

if ! make generate-json-schema; then
  echo "Generating json schema failed"
  exit 1
fi

if [ "$(git status --porcelain | wc -l)" -ne "0" ]; then
  echo "  🔴 there are uncommitted changes, please commit them before running this check"
  exit 1
fi


================================================
FILE: .github/scripts/trigger-release.sh
================================================
#!/usr/bin/env bash
set -eu

bold=$(tput bold)
normal=$(tput sgr0)

GH_CLI=.tool/gh

if ! [ -x "$(command -v $GH_CLI)" ]; then
    echo "The GitHub CLI could not be found. run: make bootstrap"
    exit 1
fi

# we want to stop the release as early as possible if the version is not a release version
./.github/scripts/check-syft-version-is-release.sh

$GH_CLI auth status

# set the default repo in cases where multiple remotes are defined
$GH_CLI repo set-default anchore/grype

export GITHUB_TOKEN="${GITHUB_TOKEN-"$($GH_CLI auth token)"}"

# we need all of the git state to determine the next version. Since tagging is done by
# the release pipeline it is possible to not have all of the tags from previous releases.
git fetch --tags

# populates the CHANGELOG.md and VERSION files
echo "${bold}Generating changelog...${normal}"
make changelog 2> /dev/null

NEXT_VERSION=$(cat VERSION)

if [[ "$NEXT_VERSION" == "" ||  "${NEXT_VERSION}" == "(Unreleased)" ]]; then
    echo "Could not determine the next version to release. Exiting..."
    exit 1
fi

while true; do
    read -p "${bold}Do you want to trigger a release for version '${NEXT_VERSION}'?${normal} [y/n] " yn
    case $yn in
        [Yy]* ) echo; break;;
        [Nn]* ) echo; echo "Cancelling release..."; exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

echo "${bold}Kicking off release for ${NEXT_VERSION}${normal}..."
echo
$GH_CLI workflow run release.yaml -f version=${NEXT_VERSION}

echo
echo "${bold}Waiting for release to start...${normal}"
sleep 10

set +e

echo "${bold}Head to the release workflow to monitor the release:${normal} $($GH_CLI run list --workflow=release.yaml --limit=1 --json url --jq '.[].url')"
id=$($GH_CLI run list --workflow=release.yaml --limit=1 --json databaseId --jq '.[].databaseId')
$GH_CLI run watch $id --exit-status || (echo ; echo "${bold}Logs of failed step:${normal}" && GH_PAGER="" $GH_CLI run view $id --log-failed)


================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: CodeQL Security Scan

on:
  workflow_dispatch:
  push:
    paths:
     - '**'
     - '!**.md'
     - '!LICENSE'
     - '!test/**'
    branches: [ main ]

  schedule:
    - cron: '0 14 * * 4'

jobs:
  CodeQL:
    uses: anchore/workflows/.github/workflows/codeql-go.yaml@main
    with:
      entrypoint: "./cmd/${{ github.event.repository.name }}"
    permissions:
      security-events: write
      contents: read


================================================
FILE: .github/workflows/dependabot-automation.yaml
================================================
name: Dependabot Automation
on:
  pull_request:

permissions:
  pull-requests: write

jobs:
  run:
    uses: anchore/workflows/.github/workflows/dependabot-automation.yaml@main


================================================
FILE: .github/workflows/oss-project-board-add.yaml
================================================
name: Add to OSS board

permissions:
  contents: read

on:
  issues:
    types:
      - opened
      - reopened
      - transferred
      - labeled

jobs:

  run:
    uses: "anchore/workflows/.github/workflows/oss-project-board-add.yaml@main"
    secrets:
      token: ${{ secrets.OSS_PROJECT_GH_TOKEN }}


================================================
FILE: .github/workflows/release.yaml
================================================
name: "Release"
on:
  workflow_dispatch:
    inputs:
      version:
        description: tag the latest commit on main with the given version (prefixed with v)
        required: true
      skip_quality_gate:
        description: skip quality gate and proceed directly to releasing (for emergency releases)
        type: boolean
        default: false

permissions:
  contents: read

jobs:
  quality-gate:
    if: ${{ !inputs.skip_quality_gate }}
    environment: release
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Check if running on main
        if: github.ref != 'refs/heads/main'
        # we are using the following flag when running `cosign blob-verify` for checksum signature verification:
        #   --certificate-identity-regexp "https://github.com/anchore/.github/workflows/release.yaml@refs/heads/main"
        # if we are not on the main branch, the signature will not be verifiable since the suffix requires the main branch
        # at the time of when the OIDC token was issued on the Github Actions runner.
        run: echo "This can only be run on the main branch otherwise releases produced will not be verifiable with cosign" && exit 1

      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Check if pinned syft is a release version
        run: .github/scripts/check-syft-version-is-release.sh

      - name: Check if tag already exists
        # note: this will fail if the tag already exists
        run: |
          [[ "$VERSION" == v* ]] || (echo "version '$VERSION' does not have a 'v' prefix" && exit 1)
          git tag "$VERSION"
        env:
          VERSION: ${{ github.event.inputs.version }}

      - name: Check static analysis results
        uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
        id: static-analysis
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          # This check name is defined as the github action job name (in .github/workflows/testing.yaml)
          checkName: "Static analysis"
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Check unit test results
        uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
        id: unit
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          # This check name is defined as the github action job name (in .github/workflows/testing.yaml)
          checkName: "Unit tests"
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Check integration test results
        uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
        id: integration
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          # This check name is defined as the github action job name (in .github/workflows/testing.yaml)
          checkName: "Integration tests"
          timeoutSeconds: 1200 # 20 minutes, it sometimes takes that long
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Check integration test results
        uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
        id: quality_tests
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          # This check name is defined as the github action job name (in .github/workflows/testing.yaml)
          checkName: "Quality tests"
          timeoutSeconds: 1200 # 20 minutes, it sometimes takes that long
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Check acceptance test results (linux)
        uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
        id: acceptance-linux
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          # This check name is defined as the github action job name (in .github/workflows/testing.yaml)
          checkName: "Acceptance tests (Linux)"
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Check acceptance test results (mac)
        uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
        id: acceptance-mac
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          # This check name is defined as the github action job name (in .github/workflows/testing.yaml)
          checkName: "Acceptance tests (Mac)"
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Check cli test results (linux)
        uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
        id: cli-linux
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          # This check name is defined as the github action job name (in .github/workflows/testing.yaml)
          checkName: "CLI tests (Linux)"
          ref: ${{ github.event.pull_request.head.sha || github.sha }}

      - name: Quality gate
        if: steps.static-analysis.outputs.conclusion != 'success' || steps.unit.outputs.conclusion != 'success' || steps.integration.outputs.conclusion != 'success' || steps.quality_tests.outputs.conclusion != 'success' || steps.cli-linux.outputs.conclusion != 'success' || steps.acceptance-linux.outputs.conclusion != 'success' || steps.acceptance-mac.outputs.conclusion != 'success'
        env:
          STATIC_ANALYSIS_STATUS: ${{ steps.static-analysis.conclusion }}
          UNIT_TEST_STATUS: ${{ steps.unit.outputs.conclusion }}
          INTEGRATION_TEST_STATUS: ${{ steps.integration.outputs.conclusion }}
          QUALITY_TEST_STATUS: ${{ steps.quality_tests.outputs.conclusion }}
          ACCEPTANCE_LINUX_STATUS: ${{ steps.acceptance-linux.outputs.conclusion }}
          ACCEPTANCE_MAC_STATUS: ${{ steps.acceptance-mac.outputs.conclusion }}
          CLI_LINUX_STATUS: ${{ steps.cli-linux.outputs.conclusion }}
        run: |
          echo "Static Analysis Status: $STATIC_ANALYSIS_STATUS"
          echo "Unit Test Status: $UNIT_TEST_STATUS"
          echo "Integration Test Status: $INTEGRATION_TEST_STATUS"
          echo "Quality Test Status: $QUALITY_TEST_STATUS"
          echo "Acceptance Test (Linux) Status: $ACCEPTANCE_LINUX_STATUS"
          echo "Acceptance Test (Mac) Status: $ACCEPTANCE_MAC_STATUS"
          echo "CLI Test (Linux) Status: $CLI_LINUX_STATUS"
          false

  # only release core assets within the "release" job. Any other assets not already under the purview of the
  # goreleaser configuration should be added as separate jobs to allow for debugging separately from the release workflow
  # as well as not accidentally be re-run as a step multiple times (as could be done within the release workflow) as
  # not all actions are guaranteed to be idempotent.
  release:
    needs: [quality-gate]
    if: ${{ always() && (needs.quality-gate.result == 'success' || inputs.skip_quality_gate) }}
    runs-on: ubuntu-24.04
    permissions:
      contents: write
      packages: write
      id-token: write
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          fetch-depth: 0
          persist-credentials: true

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          # use the same cache we used for building snapshots
          build-cache-key-prefix: "snapshot"

      - name: Login to Docker Hub
        uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2  #v4.0.0
        with:
          username: ${{ secrets.ANCHOREOSSWRITE_DH_USERNAME }}
          password: ${{ secrets.ANCHOREOSSWRITE_DH_PAT }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2  #v4.0.0
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Tag release
        run: |
          git config user.name "anchoreci"
          git config user.email "anchoreci@users.noreply.github.com"
          git tag -a "$VERSION" -m "Release $VERSION"
          git push origin --tags
        env:
          VERSION: ${{ github.event.inputs.version }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Build & publish release artifacts
        run: make ci-release
        env:
          # for mac signing and notarization...
          QUILL_SIGN_P12: ${{ secrets.ANCHORE_APPLE_DEVELOPER_ID_CERT_CHAIN }}
          QUILL_SIGN_PASSWORD: ${{ secrets.ANCHORE_APPLE_DEVELOPER_ID_CERT_PASS }}
          QUILL_NOTARY_ISSUER: ${{ secrets.APPLE_NOTARY_ISSUER }}
          QUILL_NOTARY_KEY_ID: ${{ secrets.APPLE_NOTARY_KEY_ID }}
          QUILL_NOTARY_KEY: ${{ secrets.APPLE_NOTARY_KEY }}
          # for creating the release (requires write access to packages and content)
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          # for updating brew formula in anchore/homebrew-syft
          GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }}

      - uses: anchore/sbom-action@57aae528053a48a3f6235f2d9461b05fbcb7366d # v0.23.1
        continue-on-error: true
        with:
          artifact-name: sbom.spdx.json

      - name: Notify Slack of new release
        uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a #v2.1.1
        continue-on-error: true
        with:
          webhook: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
          webhook-type: incoming-webhook
          payload: |
            text: "A new Grype release has been published: https://github.com/anchore/grype/releases/tag/${{ github.event.inputs.version }}"
            blocks:
              - type: section
                text:
                  type: mrkdwn
                  text: |
                    *A new Grype release has been published* :rocket:
                    • Release: <https://github.com/anchore/grype/releases/tag/${{ github.event.inputs.version }}|${{ github.event.inputs.version }}>
                    • Repo: `${{ github.repository }}`
                    • Workflow: `${{ github.workflow }}`
                    • Event: `${{ github.event_name }}`
        if: ${{ success() }}

  release-install-script:
    needs: [release]
    if: ${{ needs.release.result == 'success' }}
    uses: "anchore/workflows/.github/workflows/release-install-script.yaml@main"
    with:
      tag: ${{ github.event.inputs.version }}
    secrets:
      # needed for r2...
      R2_INSTALL_ACCESS_KEY_ID: ${{ secrets.OSS_R2_INSTALL_ACCESS_KEY_ID }}
      R2_INSTALL_SECRET_ACCESS_KEY: ${{ secrets.OSS_R2_INSTALL_SECRET_ACCESS_KEY }}
      R2_ENDPOINT: ${{ secrets.TOOLBOX_CLOUDFLARE_R2_ENDPOINT }}
      # needed for s3...
      S3_INSTALL_AWS_ACCESS_KEY_ID: ${{ secrets.TOOLBOX_AWS_ACCESS_KEY_ID }}
      S3_INSTALL_AWS_SECRET_ACCESS_KEY: ${{ secrets.TOOLBOX_AWS_SECRET_ACCESS_KEY }}

================================================
FILE: .github/workflows/remove-awaiting-response-label.yaml
================================================
name: "Manage Awaiting Response Label"

on:
  issue_comment:
    types: [created]

jobs:
  run:
    permissions:
      issues: write
      pull-requests: write
    uses: "anchore/workflows/.github/workflows/remove-awaiting-response-label.yaml@main"
    secrets:
      token: ${{ secrets.OSS_PROJECT_GH_TOKEN }}


================================================
FILE: .github/workflows/scorecards.yml
================================================
name: Scorecards supply-chain security
on:
  # Only the default branch is supported.
  branch_protection_rule:
  push:
    branches: [ "main" ]

# Declare default permissions as read only.
permissions: read-all

jobs:
  analysis:
    name: Scorecards analysis
    runs-on: ubuntu-latest
    permissions:
      # Needed to upload the results to code-scanning dashboard.
      security-events: write
      # Used to receive a badge.
      id-token: write

    steps:
      - name: "Checkout code"
        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: "Run analysis"
        uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
        with:
          results_file: results.sarif
          results_format: sarif

          # Publish the results for public repositories to enable scorecard badges. For more details, see
          # https://github.com/ossf/scorecard-action#publishing-results.
          # For private repositories, `publish_results` will automatically be set to `false`, regardless
          # of the value entered here.
          publish_results: true

      # Upload the results to GitHub's code scanning dashboard.
      - name: "Upload to code-scanning"
        uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
        with:
          sarif_file: results.sarif


================================================
FILE: .github/workflows/update-anchore-dependencies.yml
================================================
name: PR to update Anchore dependencies
on:
  workflow_dispatch:
    inputs:
      repos:
        description: "List of dependencies to update"
        required: true
        type: string

permissions:
  contents: read

jobs:
  update:
    runs-on: ubuntu-latest
    if: github.repository_owner == 'anchore' # only run for main repo (not forks)
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          tools: false
          bootstrap-apt-packages: ""

      - name: Update dependencies
        id: update
        uses: anchore/workflows/.github/actions/update-go-dependencies@main
        with:
          repos: ${{ github.event.inputs.repos }}

      - uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
        id: generate-token
        with:
          app_id: ${{ secrets.TOKEN_APP_ID }}
          private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}

      - uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 #v8.0.0
        with:
          signoff: true
          delete-branch: true
          draft: ${{ steps.update.outputs.draft }}
          # do not change this branch, as other workflows depend on it
          branch: auto/integration
          labels: dependencies,pre-release
          commit-message: "chore(deps): update anchore dependencies"
          title: "chore(deps): update anchore dependencies"
          body: ${{ steps.update.outputs.summary }}
          token: ${{ steps.generate-token.outputs.token }}


================================================
FILE: .github/workflows/update-bootstrap-tools.yml
================================================
name: PR for latest versions of tools
on:
  schedule:
    - cron: "0 8 * * *" # 3 AM EST

  workflow_dispatch:

permissions:
  contents: read

jobs:
  update-bootstrap-tools:
    runs-on: ubuntu-latest
    if: github.repository == 'anchore/grype' # only run for main repo
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          bootstrap-apt-packages: ""
          compute-fingerprints: "false"
          go-dependencies: false

      - name: "Update tool versions"
        id: latest-versions
        run: |
          make update-tools
          make list-tools

          export NO_COLOR=1
          delimiter="$(openssl rand -hex 8)"

          {
            echo "status<<${delimiter}"
            make list-tool-updates
            echo "${delimiter}"
          } >> $GITHUB_OUTPUT

          {
            echo "### Tool version status"
            echo "\`\`\`"
            make list-tool-updates
            echo "\`\`\`"
          } >> $GITHUB_STEP_SUMMARY

      - uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
        id: generate-token
        with:
          app_id: ${{ secrets.TOKEN_APP_ID }}
          private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}

      - uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 #v8.0.0
        with:
          signoff: true
          delete-branch: true
          branch: auto/latest-tools
          labels: dependencies
          commit-message: 'chore(deps): update tools to latest versions'
          title: 'chore(deps): update tools to latest versions'
          body: |
            ```
            ${{ steps.latest-versions.outputs.status }}
            ```
            This is an auto-generated pull request to update all of the tools to the latest versions.
          token: ${{ steps.generate-token.outputs.token }}


================================================
FILE: .github/workflows/update-generated-code.yml
================================================
name: PR to update OS codename generated code
on:
  schedule:
    - cron: "0 1 * * 1" # every Monday at 1 AM UTC

  workflow_dispatch:

permissions:
  contents: read

env:
  SLACK_NOTIFICATIONS: true

jobs:
  run-code-gen:
    name: "Run code generation"
    runs-on: ubuntu-latest
    if: github.repository == 'anchore/grype' # only run for main repo
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          bootstrap-apt-packages: ""
          compute-fingerprints: "false"
          go-dependencies: true

      - name: "Generate codename data"
        run: |
          make generate-codename-data

      - uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
        id: generate-token
        with:
          app_id: ${{ secrets.TOKEN_APP_ID }}
          private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}

      - uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 #v8.1.0
        with:
          signoff: true
          delete-branch: true
          branch: auto/latest-codename-data
          labels: dependencies
          commit-message: "chore(deps): update OS codename generated code"
          title: "chore(deps): update OS codename generated code"
          body: |
            Update OS codename data from endoflife.date
          token: ${{ steps.generate-token.outputs.token }}

      - name: Notify Slack on failure
        uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a #v2.1.1
        if: ${{ failure() && env.SLACK_NOTIFICATIONS == 'true' }}
        with:
          webhook: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
          webhook-type: incoming-webhook
          payload: |
            text: "Grype OS codename code generation failed"
            blocks:
              - type: section
                text:
                  type: mrkdwn
                  text: |
                    *Grype OS codename code generation failed*
                    • Workflow: `${{ github.workflow }}`
                    • Event: `${{ github.event_name }}`
                    • Job Status: `${{ job.status }}`
                    • <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run>


================================================
FILE: .github/workflows/update-quality-gate-db.yml
================================================
name: PR for upgrading quality gate test DB
on:
  schedule:
    - cron: "0 16 1 * *" # first day of each month @ 11 AM EST

  workflow_dispatch:

permissions:
  contents: read

jobs:
  update-test-db-url:
    runs-on: ubuntu-latest
    if: github.repository == 'anchore/grype' # only run for main repo
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: "Update quality DB"
        run: |
          make update-quality-gate-db

      - uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
        id: generate-token
        with:
          app_id: ${{ secrets.TOKEN_APP_ID }}
          private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}

      - uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 #v8.0.0
        with:
          signoff: true
          delete-branch: true
          branch: auto/update-quality-test-db
          labels: test, changelog-ignore
          commit-message: 'test: update quality gate db to latest version'
          title: 'test: update quality gate db to latest version'
          body: |
            This is an auto-generated pull request to update the quality gate db to latest version
          token: ${{ steps.generate-token.outputs.token }}


================================================
FILE: .github/workflows/validate-github-actions.yaml
================================================
name: "Validate GitHub Actions"

on:
  pull_request:
    paths:
      - '.github/workflows/**'
      - '.github/actions/**'
  push:
    branches:
      - main
    paths:
      - '.github/workflows/**'
      - '.github/actions/**'

permissions:
  contents: read

jobs:
  zizmor:
    name: "Lint"
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write  # for uploading SARIF results
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: "Run zizmor"
        uses: zizmorcore/zizmor-action@0dce2577a4760a2749d8cfb7a84b7d5585ebcb7d # v0.5.0
        with:
          config: .github/zizmor.yml
          # Disable SARIF upload so the step is a simple pass/fail gate
          advanced-security: false
          inputs: .github


================================================
FILE: .github/workflows/validations.yaml
================================================
name: "Validations"

on:
  workflow_dispatch:
  pull_request:
  push:
    branches:
      - main

permissions:
  contents: read

jobs:
  Static-Analysis:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Static analysis"
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap

      - name: Run static analysis
        run: make static-analysis

  Unit-Test:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Unit tests"
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
      
      - name: Run unit tests
        run: make unit

  Quality-Test:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Quality tests"
    runs-on: ubuntu-22.04-4core-16gb
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          submodules: true
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap

      - name: Run quality tests
        run: make quality
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Archive the provider state
        if: ${{ failure() }}
        run: tar -czvf qg-capture-state.tar.gz -C test/quality --exclude tools --exclude labels .yardstick.yaml .yardstick

      - name: Upload the provider state archive
        if: ${{ failure() }}
        uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
        with:
          name: qg-capture-state
          path: qg-capture-state.tar.gz

      - name: Show instructions to debug
        if: ${{ failure() }}
        run: |
          ARCHIVE_BASENAME=qg-capture-state
          ARCHIVE_NAME=$ARCHIVE_BASENAME.zip

          cat << EOF >> $GITHUB_STEP_SUMMARY
          ## Troubleshooting failed run

          Download the artifact from this workflow run: \`$ARCHIVE_NAME\`

          Then run the following commands to debug:
          \`\`\`bash
          # copy the archive to the tests/quality directory
          cd test/quality
          unzip $ARCHIVE_NAME && tar -xzf $ARCHIVE_BASENAME.tar.gz
          \`\`\`

          Now you can debug the with yardstick:
          \`\`\`bash
          poetry shell
          yardstick result list
          yardstick label explore
          \`\`\`
          EOF


  Integration-Test:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Integration tests"
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap

      - name: Restore integration test cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
        with:
          path: ${{ github.workspace }}/test/integration/testdata/cache
          key: ${{ runner.os }}-integration-test-cache-${{ hashFiles('test/integration/testdata/cache.fingerprint') }}

      - name: Run integration tests
        run: make integration

  Build-Snapshot-Artifacts:
    name: "Build snapshot artifacts"
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap
        with:
          # why have another build cache key? We don't want unit/integration/etc test build caches to replace
          # the snapshot build cache, which includes builds for all OSs and architectures. As long as this key is
          # unique from the build-cache-key-prefix in other CI jobs, we should be fine.
          #
          # note: ideally this value should match what is used in release (just to help with build times).
          build-cache-key-prefix: "snapshot"
          bootstrap-apt-packages: ""

      - name: Build snapshot artifacts
        run: make snapshot

      # why not use actions/upload-artifact? It is very slow (3 minutes to upload ~600MB of data, vs 10 seconds with this approach).
      # see https://github.com/actions/upload-artifact/issues/199 for more info
      - name: Upload snapshot artifacts
        uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
        with:
          path: snapshot
          key: snapshot-build-${{ github.run_id }}

  Upload-Snapshot-Artifacts:
    name: "Upload snapshot artifacts"
    needs: [Build-Snapshot-Artifacts]
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Download snapshot build
        uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
        with:
          path: snapshot
          key: snapshot-build-${{ github.run_id }}

      - run: npm install @actions/artifact@2.2.2

      - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd #v8.0.0
        with:
          script: |
            const { readdirSync } = require('fs')
            const { DefaultArtifactClient } = require('@actions/artifact')
            const artifact = new DefaultArtifactClient()
            const ls = d => readdirSync(d, { withFileTypes: true })
            const baseDir = "./snapshot"
            const dirs = ls(baseDir).filter(f => f.isDirectory()).map(f => f.name)
            const uploads = []
            for (const dir of dirs) {
              // uploadArtifact returns Promise<{id, size}>
              uploads.push(artifact.uploadArtifact(
                // name of the archive:
                `${dir}`,
                // array of all files to include:
                ls(`${baseDir}/${dir}`).map(f => `${baseDir}/${dir}/${f.name}`),
                // base directory to trim from entries:
                `${baseDir}/${dir}`,
                { retentionDays: 30 }
              ))
            }
            // wait for all uploads to finish
            Promise.all(uploads)

  Acceptance-Linux:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Acceptance tests (Linux)"
    needs: [Build-Snapshot-Artifacts]
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Download snapshot build
        uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
        with:
          path: snapshot
          key: snapshot-build-${{ github.run_id }}

      - name: Restore install.sh test image cache
        id: install-test-image-cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
        with:
          path: ${{ github.workspace }}/test/install/cache
          key: ${{ runner.os }}-install-test-image-cache-${{ hashFiles('test/install/cache.fingerprint') }}

      - name: Load test image cache
        if: steps.install-test-image-cache.outputs.cache-hit == 'true'
        run: make install-test-cache-load

      - name: Run install.sh tests (Linux)
        run: make install-test

      - name: (cache-miss) Create test image cache
        if: steps.install-test-image-cache.outputs.cache-hit != 'true'
        run: make install-test-cache-save

  Acceptance-Mac:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "Acceptance tests (Mac)"
    needs: [Build-Snapshot-Artifacts]
    runs-on: macos-latest
    steps:
      - name: Install Cosign
        uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 #v4.1.0

      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Download snapshot build
        uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
        with:
          path: snapshot
          key: snapshot-build-${{ github.run_id }}

      - name: Restore docker image cache for compare testing
        id: mac-compare-testing-cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
        with:
          path: image.tar
          key: ${{ runner.os }}-${{ hashFiles('test/compare/mac.sh') }}

      - name: Run install.sh tests (Mac)
        run: make install-test-ci-mac


  Cli-Linux:
    # Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
    name: "CLI tests (Linux)"
    needs: [Build-Snapshot-Artifacts]
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Bootstrap environment
        uses: ./.github/actions/bootstrap

      - name: Restore CLI test-fixture cache
        uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
        with:
          path: ${{ github.workspace }}/test/cli/testdata/cache
          key: ${{ runner.os }}-cli-test-cache-${{ hashFiles('test/cli/testdata/cache.fingerprint') }}

      - name: Download snapshot build
        uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
        with:
          path: snapshot
          key: snapshot-build-${{ github.run_id }}

      - name: Run CLI Tests (Linux)
        run: make cli
        env:
          GRYPE_SNAPSHOT_PREBUILT: "true"
          GRYPE_BINARY_LOCATION: ${{ github.workspace }}/snapshot/linux-build_linux_amd64_v1/grype

  Cleanup-Cache:
    name: "Cleanup snapshot cache"
    if: github.event.pull_request.head.repo.full_name == github.repository
    runs-on: ubuntu-24.04
    permissions:
      actions: write
    needs:
      - Acceptance-Linux
      - Acceptance-Mac
      - Cli-Linux
      - Upload-Snapshot-Artifacts
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
        with:
          persist-credentials: false

      - name: Delete snapshot cache
        run: gh cache delete "snapshot-build-${{ github.run_id }}" || echo "Cache deletion failed or cache not found - continuing"
        env:
          GH_TOKEN: ${{ github.token }}


================================================
FILE: .github/zizmor.yml
================================================
rules:
  unpinned-uses:
    config:
      policies:
        # anchore/workflows is an internal repository; using @main is acceptable
        anchore/*: any


================================================
FILE: .gitignore
================================================
# AI
.claude
CLAUDE.MD

# local development tailoring
go.work
go.work.sum
.tool-versions
.jj/
mise.toml
specs/
*.xxh64

# AI and LLM related files
CLAUDE.md
.claude

# app configuration
/.grype.yaml

# tool and bin directories
.tmp/
bin/
/bin
/.bin
/build
/dist
/snapshot
/.tool
/.task

# changelog generation
/CHANGELOG.md
/VERSION

# IDE configuration
.vscode/
.idea/
.server/
.history/

# test related
*.fingerprint
/test/results
coverage.txt
*.log
.server

# grype-db related
/metadata.json
/listing.json
*.db
*.db-journal
!**/testdata/**/*.db
!**/testdata/**/bin/
!**/testdata/**/*.jar

# probable archives
.images
*.tar
*.jar
*.war
*.ear
*.jpi
*.hpi
*.zip
*.iml

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, build with `go test -c`
*.test

# OS files
.DS_Store

*.profile

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
/grype/grype
main

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out


================================================
FILE: .gitmodules
================================================
[submodule "test/quality/vulnerability-match-labels"]
	path = test/quality/vulnerability-match-labels
	url = https://github.com/anchore/vulnerability-match-labels.git
	branch = main


================================================
FILE: .golangci.yaml
================================================
version: "2"
linters:
    # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
  default: none
  enable:
    - asciicheck
    - bodyclose
    - copyloopvar
    - dogsled
    - dupl
    - errcheck
    - funlen
    - gocognit
    - goconst
    - gocritic
    - gocyclo
    - goprintffuncname
    - gosec
    - govet
    - ineffassign
    - misspell
    - nakedret
    - revive
    - staticcheck
    - unconvert
    - unparam
    - unused
    - whitespace
  settings:
    funlen:
      lines: 70
      statements: 50
  exclusions:
    generated: lax
    presets:
      - comments
      - common-false-positives
      - legacy
      - std-error-handling
    rules:
      # we have multiple packages in grype that might overlap with the stblib; their names reflect their purpose
      - linters:
          - revive
        text: "var-naming: avoid package names that conflict"

    paths:
      - third_party$
      - builtin$
      - examples$

# do not enable...
#    - deadcode          # The owner seems to have abandoned the linter. Replaced by "unused".
#    - depguard          # we need to setup a configuration for this
#    - goprintffuncname  # does not catch all cases and there are exceptions
#    - nakedret          # does not catch all cases and should not fail a build
#    - gochecknoglobals
#    - gochecknoinits    # this is too aggressive
#    - rowserrcheck disabled per generics https://github.com/golangci/golangci-lint/issues/2649
#    - godot
#    - godox
#    - goerr113
#    - goimports   # we're using gosimports now instead to account for extra whitespaces (see https://github.com/golang/go/issues/20818)
#    - golint      # deprecated
#    - gomnd       # this is too aggressive
#    - interfacer  # this is a good idea, but is no longer supported and is prone to false positives
#    - lll         # without a way to specify per-line exception cases, this is not usable
#    - maligned    # this is an excellent linter, but tricky to optimize and we are not sensitive to memory layout optimizations
#    - nestif
#    - nolintlint   # as of go1.19 this conflicts with the behavior of gofmt, which is a deal-breaker (lint-fix will still fail when running lint)
#    - prealloc     # following this rule isn't consistently a good idea, as it sometimes forces unnecessary allocations that result in less idiomatic code
#    - rowserrcheck # not in a repo with sql, so this is not useful
#    - scopelint    # deprecated
#    - structcheck  # The owner seems to have abandoned the linter. Replaced by "unused".
#    - testpackage
#    - varcheck     # The owner seems to have abandoned the linter. Replaced by "unused".
#    - wsl          # this doens't have an auto-fixer yet and is pretty noisy (https://github.com/bombsimon/wsl/issues/90)

issues:
  max-same-issues: 25
  uniq-by-line: false

# TODO: enable this when we have coverage on docstring comments
#  # The list of ids of default excludes to include or disable.
#  include:
#    - EXC0002 # disable excluding of issues about comments from golint

formatters:
  enable:
    - gofmt
    - goimports
  exclusions:
    generated: lax
    paths:
      - third_party$
      - builtin$
      - examples$


================================================
FILE: .goreleaser.yaml
================================================
version: 2

release:
  prerelease: auto
  draft: false

env:
  # required to support multi architecture docker builds
  - DOCKER_CLI_EXPERIMENTAL=enabled
  - CGO_ENABLED=0

builds:
  - id: linux-build
    dir: ./cmd/grype
    binary: grype
    goos:
      - linux
    goarch:
      - amd64
      - arm64
      - ppc64le
      - s390x
    # set the modified timestamp on the output binary to the git timestamp to ensure a reproducible build
    mod_timestamp: &build-timestamp '{{ .CommitTimestamp }}'
    ldflags: &build-ldflags |
      -w
      -s
      -extldflags '-static'
      -X main.version={{.Version}}
      -X main.gitCommit={{.Commit}}
      -X main.buildDate={{.Date}}
      -X main.gitDescription={{.Summary}}

  - id: darwin-build
    dir: ./cmd/grype
    binary: grype
    goos:
      - darwin
    goarch:
      - amd64
      - arm64
    mod_timestamp: *build-timestamp
    ldflags: *build-ldflags
    hooks:
      post:
        - cmd: .tool/quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv
          env:
            - QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log

  - id: windows-build
    dir: ./cmd/grype
    binary: grype
    goos:
      - windows
    goarch:
      - amd64
    mod_timestamp: *build-timestamp
    ldflags: *build-ldflags

archives:
  - id: linux-archives
    ids:
      - linux-build

  - id: darwin-archives
    ids:
      - darwin-build

  - id: windows-archives
    formats: [zip]
    ids:
      - windows-build

nfpms:
  - license: "Apache 2.0"
    maintainer: "Anchore, Inc"
    homepage: &website "https://github.com/anchore/grype"
    description: &description "A vulnerability scanner for container images and filesystems"
    formats:
      - rpm
      - deb

homebrew_casks:
  - repository:
      owner: anchore
      name: homebrew-grype
      token: "{{.Env.GITHUB_BREW_TOKEN}}"
    ids:
      - darwin-archives
      - linux-archives
    homepage: *website
    description: *description
    license: "Apache License 2.0"
    conflicts:
      # claim that the previous grype formula (in the root of homebrew-grype) conflicts with the new cask
      # see https://goreleaser.com/deprecations/#brews for more information
      - formula: grype

dockers:
  # production images...
  - image_templates:
      - anchore/grype:{{.Tag}}-amd64
      - ghcr.io/anchore/grype:{{.Tag}}-amd64
    goarch: amd64
    dockerfile: Dockerfile
    use: buildx
    build_flag_templates:
      - "--platform=linux/amd64"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  - image_templates:
      - anchore/grype:{{.Tag}}-arm64v8
      - ghcr.io/anchore/grype:{{.Tag}}-arm64v8
    goarch: arm64
    dockerfile: Dockerfile
    use: buildx
    build_flag_templates:
      - "--platform=linux/arm64/v8"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  - image_templates:
      - anchore/grype:{{.Tag}}-ppc64le
      - ghcr.io/anchore/grype:{{.Tag}}-ppc64le
    goarch: ppc64le
    dockerfile: Dockerfile
    use: buildx
    build_flag_templates:
      - "--platform=linux/ppc64le"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  - image_templates:
      - anchore/grype:{{.Tag}}-s390x
      - ghcr.io/anchore/grype:{{.Tag}}-s390x
    goarch: s390x
    dockerfile: Dockerfile
    use: buildx
    build_flag_templates:
      - "--platform=linux/s390x"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  # nonroot images...
  - image_templates:
      - anchore/grype:{{.Tag}}-nonroot-amd64
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-amd64
    goarch: amd64
    dockerfile: Dockerfile.nonroot
    use: buildx
    build_flag_templates:
      - "--platform=linux/amd64"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  - image_templates:
      - anchore/grype:{{.Tag}}-nonroot-arm64v8
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-arm64v8
    goarch: arm64
    dockerfile: Dockerfile.nonroot
    use: buildx
    build_flag_templates:
      - "--platform=linux/arm64/v8"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  - image_templates:
      - anchore/grype:{{.Tag}}-nonroot-ppc64le
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-ppc64le
    goarch: ppc64le
    dockerfile: Dockerfile.nonroot
    use: buildx
    build_flag_templates:
      - "--platform=linux/ppc64le"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  - image_templates:
      - anchore/grype:{{.Tag}}-nonroot-s390x
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-s390x
    goarch: s390x
    dockerfile: Dockerfile.nonroot
    use: buildx
    build_flag_templates:
      - "--platform=linux/s390x"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  # debug images...
  - image_templates:
      - anchore/grype:{{.Tag}}-debug-amd64
      - ghcr.io/anchore/grype:{{.Tag}}-debug-amd64
    goarch: amd64
    dockerfile: Dockerfile.debug
    use: buildx
    build_flag_templates:
      - "--platform=linux/amd64"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  - image_templates:
      - anchore/grype:{{.Tag}}-debug-arm64v8
      - ghcr.io/anchore/grype:{{.Tag}}-debug-arm64v8
    goarch: arm64
    dockerfile: Dockerfile.debug
    use: buildx
    build_flag_templates:
      - "--platform=linux/arm64/v8"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  - image_templates:
      - anchore/grype:{{.Tag}}-debug-ppc64le
      - ghcr.io/anchore/grype:{{.Tag}}-debug-ppc64le
    goarch: ppc64le
    dockerfile: Dockerfile.debug
    use: buildx
    build_flag_templates:
      - "--platform=linux/ppc64le"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

  - image_templates:
      - anchore/grype:{{.Tag}}-debug-s390x
      - ghcr.io/anchore/grype:{{.Tag}}-debug-s390x
    goarch: s390x
    dockerfile: Dockerfile.debug
    use: buildx
    build_flag_templates:
      - "--platform=linux/s390x"
      - "--provenance=false"
      - "--build-arg=BUILD_DATE={{.Date}}"
      - "--build-arg=BUILD_VERSION={{.Version}}"
      - "--build-arg=VCS_REF={{.FullCommit}}"
      - "--build-arg=VCS_URL={{.GitURL}}"

docker_manifests:
  - name_template: anchore/grype:latest
    image_templates:
      - anchore/grype:{{.Tag}}-amd64
      - anchore/grype:{{.Tag}}-arm64v8
      - anchore/grype:{{.Tag}}-ppc64le
      - anchore/grype:{{.Tag}}-s390x

  - name_template: ghcr.io/anchore/grype:latest
    image_templates:
      - ghcr.io/anchore/grype:{{.Tag}}-amd64
      - ghcr.io/anchore/grype:{{.Tag}}-arm64v8
      - ghcr.io/anchore/grype:{{.Tag}}-ppc64le
      - ghcr.io/anchore/grype:{{.Tag}}-s390x

  - name_template: anchore/grype:{{.Tag}}
    image_templates:
      - anchore/grype:{{.Tag}}-amd64
      - anchore/grype:{{.Tag}}-arm64v8
      - anchore/grype:{{.Tag}}-ppc64le
      - anchore/grype:{{.Tag}}-s390x

  - name_template: ghcr.io/anchore/grype:{{.Tag}}
    image_templates:
      - ghcr.io/anchore/grype:{{.Tag}}-amd64
      - ghcr.io/anchore/grype:{{.Tag}}-arm64v8
      - ghcr.io/anchore/grype:{{.Tag}}-ppc64le
      - ghcr.io/anchore/grype:{{.Tag}}-s390x

  # nonroot images...
  - name_template: anchore/grype:nonroot
    image_templates:
      - anchore/grype:{{.Tag}}-nonroot-amd64
      - anchore/grype:{{.Tag}}-nonroot-arm64v8
      - anchore/grype:{{.Tag}}-nonroot-ppc64le
      - anchore/grype:{{.Tag}}-nonroot-s390x

  - name_template: ghcr.io/anchore/grype:nonroot
    image_templates:
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-amd64
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-arm64v8
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-ppc64le
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-s390x

  - name_template: anchore/grype:{{.Tag}}-nonroot
    image_templates:
      - anchore/grype:{{.Tag}}-nonroot-amd64
      - anchore/grype:{{.Tag}}-nonroot-arm64v8
      - anchore/grype:{{.Tag}}-nonroot-ppc64le
      - anchore/grype:{{.Tag}}-nonroot-s390x

  - name_template: ghcr.io/anchore/grype:{{.Tag}}-nonroot
    image_templates:
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-amd64
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-arm64v8
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-ppc64le
      - ghcr.io/anchore/grype:{{.Tag}}-nonroot-s390x

  # debug images...
  - name_template: anchore/grype:debug
    image_templates:
      - anchore/grype:{{.Tag}}-debug-amd64
      - anchore/grype:{{.Tag}}-debug-arm64v8
      - anchore/grype:{{.Tag}}-debug-ppc64le
      - anchore/grype:{{.Tag}}-debug-s390x

  - name_template: ghcr.io/anchore/grype:debug
    image_templates:
      - ghcr.io/anchore/grype:{{.Tag}}-debug-amd64
      - ghcr.io/anchore/grype:{{.Tag}}-debug-arm64v8
      - ghcr.io/anchore/grype:{{.Tag}}-debug-ppc64le
      - ghcr.io/anchore/grype:{{.Tag}}-debug-s390x

  - name_template: anchore/grype:{{.Tag}}-debug
    image_templates:
      - anchore/grype:{{.Tag}}-debug-amd64
      - anchore/grype:{{.Tag}}-debug-arm64v8
      - anchore/grype:{{.Tag}}-debug-ppc64le
      - anchore/grype:{{.Tag}}-debug-s390x

  - name_template: ghcr.io/anchore/grype:{{.Tag}}-debug
    image_templates:
      - ghcr.io/anchore/grype:{{.Tag}}-debug-amd64
      - ghcr.io/anchore/grype:{{.Tag}}-debug-arm64v8
      - ghcr.io/anchore/grype:{{.Tag}}-debug-ppc64le
      - ghcr.io/anchore/grype:{{.Tag}}-debug-s390x

signs:
  - cmd: .tool/cosign
    signature: "${artifact}.sig"
    certificate: "${artifact}.pem"
    args:
      - "sign-blob"
      - "--use-signing-config=false"
      - "--oidc-issuer=https://token.actions.githubusercontent.com"
      - "--output-certificate=${certificate}"
      - "--output-signature=${signature}"
      - "${artifact}"
      - "--yes"
    artifacts: checksum


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct

All contributors for any Anchore project must follow the [Contributor Covenant Code of Conduct](https://oss.anchore.com/docs/contributing/code-of-conduct/).

**TLDR:** Be kind, be respectful, and assume good intentions. We're all here to build great software together.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

Thank you for your interest in contributing to Grype!

Please see the [contribution guide](https://oss.anchore.com/docs/contributing/grype/) for development requirements and helpful tips to get started developing in the repo. For a deeper dive, please see the [architecture docs for grype](https://oss.anchore.com/docs/architecture/grype/) and the sister project [grype-db](https://oss.anchore.com/docs/architecture/grype-db/).

**Have a question or need help?** Check out our [issues and discussions guide](https://oss.anchore.com/docs/contributing/issues-and-discussions/) to find the right place to start a conversation.

**Ready to submit code?** Our [pull request guide](https://oss.anchore.com/docs/contributing/pull-requests/) covers everything from title conventions to the review process. Don't forget that ***all commits require a [sign-off](https://oss.anchore.com/docs/contributing/sign-off/)***.

**Found a security issue?** Please do **not** open a public issue. Instead, see our [security policy](https://oss.anchore.com/docs/contributing/security/) for how to report vulnerabilities responsibly.

**Want to help improve the docs?** Check out the [anchore/oss-docs](https://github.com/anchore/oss-docs) repository.


================================================
FILE: Dockerfile
================================================
FROM gcr.io/distroless/static-debian12:latest AS build

FROM scratch
# needed for version check HTTPS request
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt

# create the /tmp dir, which is needed for image content cache
WORKDIR /tmp

COPY grype /

ARG BUILD_DATE
ARG BUILD_VERSION
ARG VCS_REF
ARG VCS_URL

LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.title="grype"
LABEL org.opencontainers.image.description="A vulnerability scanner for container images and filesystems"
LABEL org.opencontainers.image.source=$VCS_URL
LABEL org.opencontainers.image.revision=$VCS_REF
LABEL org.opencontainers.image.vendor="Anchore, Inc."
LABEL org.opencontainers.image.version=$BUILD_VERSION
LABEL org.opencontainers.image.licenses="Apache-2.0"
LABEL io.artifacthub.package.readme-url="https://raw.githubusercontent.com/anchore/grype/main/README.md"
LABEL io.artifacthub.package.logo-url="https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png"
LABEL io.artifacthub.package.license="Apache-2.0"

ENTRYPOINT ["/grype"]


================================================
FILE: Dockerfile.debug
================================================
FROM gcr.io/distroless/static-debian12:debug-nonroot

# create the /tmp dir, which is needed for image content cache
WORKDIR /tmp

COPY grype /

ARG BUILD_DATE
ARG BUILD_VERSION
ARG VCS_REF
ARG VCS_URL

LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.title="grype"
LABEL org.opencontainers.image.description="A vulnerability scanner for container images and filesystems"
LABEL org.opencontainers.image.source=$VCS_URL
LABEL org.opencontainers.image.revision=$VCS_REF
LABEL org.opencontainers.image.vendor="Anchore, Inc."
LABEL org.opencontainers.image.version=$BUILD_VERSION
LABEL org.opencontainers.image.licenses="Apache-2.0"
LABEL io.artifacthub.package.readme-url="https://raw.githubusercontent.com/anchore/grype/main/README.md"
LABEL io.artifacthub.package.logo-url="https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png"
LABEL io.artifacthub.package.license="Apache-2.0"

ENTRYPOINT ["/grype"]


================================================
FILE: Dockerfile.nonroot
================================================
FROM gcr.io/distroless/static-debian12:nonroot

# create the /tmp dir, which is needed for image content cache
WORKDIR /tmp

COPY grype /

ARG BUILD_DATE
ARG BUILD_VERSION
ARG VCS_REF
ARG VCS_URL

LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.title="grype"
LABEL org.opencontainers.image.description="A vulnerability scanner for container images and filesystems"
LABEL org.opencontainers.image.source=$VCS_URL
LABEL org.opencontainers.image.revision=$VCS_REF
LABEL org.opencontainers.image.vendor="Anchore, Inc."
LABEL org.opencontainers.image.version=$BUILD_VERSION
LABEL org.opencontainers.image.licenses="Apache-2.0"
LABEL io.artifacthub.package.readme-url="https://raw.githubusercontent.com/anchore/grype/main/README.md"
LABEL io.artifacthub.package.logo-url="https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png"
LABEL io.artifacthub.package.license="Apache-2.0"

ENTRYPOINT ["/grype"]


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: Makefile
================================================
TOOL_DIR = .tool
BINNY = $(TOOL_DIR)/binny
TASK = $(TOOL_DIR)/task

.DEFAULT_GOAL := make-default

## Bootstrapping targets #################################

# note: we need to assume that binny and task have not already been installed
$(BINNY):
	@mkdir -p $(TOOL_DIR)
	@curl -sSfL https://get.anchore.io/binny | sh -s -- -b $(TOOL_DIR)

# note: we need to assume that binny and task have not already been installed
.PHONY: task
$(TASK) task: $(BINNY)
	@$(BINNY) install task -q

.PHONY: ci-bootstrap-go
ci-bootstrap-go:
	go mod download

# this is a bootstrapping catch-all, where if the target doesn't exist, we'll ensure the tools are installed and then try again
%:
	make $(TASK)
	$(TASK) $@

## Shim targets #################################

.PHONY: make-default
make-default: $(TASK)
	@# run the default task in the taskfile
	@$(TASK)

# for those of us that can't seem to kick the habit of typing `make ...` lets wrap the superior `task` tool
TASKS := $(shell bash -c "test -f $(TASK) && NO_COLOR=1 $(TASK) -l | grep '^\* ' | cut -d' ' -f2 | tr -d ':' | tr '\n' ' '" ) $(shell bash -c "test -f $(TASK) && NO_COLOR=1 $(TASK) -l | grep 'aliases:' | cut -d ':' -f 3 | tr '\n' ' ' | tr -d ','")

.PHONY: $(TASKS)
$(TASKS): $(TASK)
	@$(TASK) $@

help: $(TASK)
	@$(TASK) -l


================================================
FILE: README.md
================================================
<p align="center">
    <img alt="Grype logo" src="https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png" width="234">
</p>

# Grype

**A vulnerability scanner for container images and filesystems.**

<p align="center">
    &nbsp;<a href="https://github.com/anchore/grype/actions?query=workflow%3A%22Static+Analysis+%2B+Unit+%2B+Integration%22"><img src="https://github.com/anchore/grype/workflows/Static%20Analysis%20+%20Unit%20+%20Integration/badge.svg" alt="Static Analysis + Unit + Integration"></a>&nbsp;
    &nbsp;<a href="https://github.com/anchore/grype/actions/workflows/validations.yaml"><img src="https://github.com/anchore/grype/workflows/Validations/badge.svg" alt="Validations"></a>&nbsp;
    &nbsp;<a href="https://goreportcard.com/report/github.com/anchore/grype"><img src="https://goreportcard.com/badge/github.com/anchore/grype" alt="Go Report Card"></a>&nbsp;
    &nbsp;<a href="https://github.com/anchore/grype/releases/latest"><img src="https://img.shields.io/github/release/anchore/grype.svg" alt="GitHub release"></a>&nbsp;
    &nbsp;<a href="https://github.com/anchore/grype"><img src="https://img.shields.io/github/go-mod/go-version/anchore/grype.svg" alt="GitHub go.mod Go version"></a>&nbsp;
    &nbsp;<a href="https://github.com/anchore/grype/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache-2.0"></a>&nbsp;
    &nbsp;<a href="https://anchore.com/discourse"><img src="https://img.shields.io/badge/Discourse-Join-blue?logo=discourse" alt="Join our Discourse"></a>&nbsp;
    &nbsp;<a rel="me" href="https://fosstodon.org/@grype"><img src="https://img.shields.io/badge/Mastodon-Follow-blue?logoColor=white&logo=mastodon" alt="Follow on Mastodon"></a>&nbsp;
</p>

![grype-demo](https://user-images.githubusercontent.com/590471/90276236-9868f300-de31-11ea-8068-4268b6b68529.gif)

## Features

- Scan **container images**, **filesystems**, and **SBOMs** for known vulnerabilities (see the docs for a full list of [supported scan targets](https://oss.anchore.com/docs/guides/vulnerability/scan-targets/))
- Supports major OS package ecosystems (Alpine, Debian, Ubuntu, RHEL, Oracle Linux, Amazon Linux, and [more](https://oss.anchore.com/docs/capabilities/all-os/))
- Supports language-specific packages (Ruby, Java, JavaScript, Python, .NET, Go, PHP, Rust, and [more](https://oss.anchore.com/docs/capabilities/all-packages/))
- Supports Docker, OCI, and [Singularity](https://github.com/sylabs/singularity) image formats
- Threat & risk prioritization with **EPSS**, **KEV**, and **risk scoring** (see [interpreting the results docs](https://oss.anchore.com/docs/guides/vulnerability/interpreting-results/))
- [OpenVEX](https://github.com/openvex) support for filtering and augmenting scan results

> [!TIP]
> New to Grype? Check out the [Getting Started guide](https://oss.anchore.com/docs/guides/vulnerability/getting-started/) for a walkthrough!

## Installation

The quickest way to get up and going:
```bash
curl -sSfL https://get.anchore.io/grype | sudo sh -s -- -b /usr/local/bin
```

> [!TIP]
> See [Installation docs](https://oss.anchore.com/docs/installation/grype/) for more ways to get Grype, including Homebrew, Docker, Chocolatey, MacPorts, and more!

## The basics

Scan a container image or directory for vulnerabilities:

```bash
# container image
grype alpine:latest

# directory
grype ./my-project
```

Scan an SBOM for even faster vulnerability detection:

```bash
# scan a Syft SBOM
grype sbom:./sbom.json

# pipe an SBOM into Grype
cat ./sbom.json | grype
```

> [!TIP]
> Check out the [Getting Started guide](https://oss.anchore.com/docs/guides/vulnerability/getting-started/) to explore all of the capabilities and features.
>
> Want to know all of the ins-and-outs of Grype? Check out the [CLI docs](https://oss.anchore.com/docs/reference/grype/cli/) and [configuration docs](https://oss.anchore.com/docs/reference/grype/configuration/).

## Contributing

We encourage users to help make these tools better by [submitting issues](https://github.com/anchore/grype/issues) when you find a bug or want a new feature.
Check out our [contributing overview](https://oss.anchore.com/docs/contributing/) and [developer-specific documentation](https://oss.anchore.com/docs/contributing/grype/) if you are interested in providing code contributions.

<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/">
  Grype development is sponsored by <a href="https://anchore.com/">Anchore</a>, and is released under the <a href="https://github.com/anchore/grype?tab=Apache-2.0-1-ov-file">Apache-2.0 License</a>.
  The <a property="dct:title" rel="cc:attributionURL" href="https://anchore.com/wp-content/uploads/2024/11/grype-logo.svg">Grype logo</a> by <a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://anchore.com/">Anchore</a> is licensed under <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY 4.0<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt=""></a>
</p>

For commercial support options with Syft or Grype, please [contact Anchore](https://get.anchore.com/contact/).

## Come talk to us!

The Grype Team holds regular community meetings online. All are welcome to join to bring topics for discussion.
- Check the [calendar](https://calendar.google.com/calendar/u/0/r?cid=Y182OTM4dGt0MjRtajI0NnNzOThiaGtnM29qNEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t) for the next meeting date.
- Add items to the [agenda](https://docs.google.com/document/d/1ZtSAa6fj2a6KRWviTn3WoJm09edvrNUp4Iz_dOjjyY8/edit?usp=sharing) (join [this group](https://groups.google.com/g/anchore-oss-community) for write access to the [agenda](https://docs.google.com/document/d/1ZtSAa6fj2a6KRWviTn3WoJm09edvrNUp4Iz_dOjjyY8/edit?usp=sharing))
- See you there!


================================================
FILE: RELEASE.md
================================================
# Release

A release of grype comprises:
- a new semver git tag from the current tip of the main branch
- a new [github release](https://github.com/anchore/grype/releases) with a changelog and archived binary assets
- docker images published to `ghcr.io` and `dockerhub`, including multi architecture images + manifest
- [`anchore/homebrew-grype`](https://github.com/anchore/homebrew-grype) tap updated to point to assets in the latest github release

Ideally releasing should be done often with small increments when possible. Unless a
breaking change is blocking the release, or no fixes/features have been merged, a good
target release cadence is between every 1 or 2 weeks.


## Creating a release

This release process itself should be as automated as possible, and has only a few steps:

1. **Trigger a new release with `make release`**. At this point you'll see a preview
   changelog in the terminal. If you're happy with the changelog, press `y` to continue, otherwise
   you can abort and adjust the labels on the PRs and issues to be included in the release and
   re-run the release trigger command.

1. A release admin must approve the release on the GitHub Actions [release pipeline](https://github.com/anchore/grype/actions/workflows/release.yaml) run page.
   Once approved, the release pipeline will generate all assets and publish a GitHub Release.


## Retracting a release

If a release is found to be problematic, it can be retracted with the following steps:

- Deleting the GitHub Release
- Untag the docker images in the `ghcr.io` and `docker.io` registries
- Revert the brew formula in [`anchore/homebrew-grype`](https://github.com/anchore/homebrew-grype) to point to the previous release
- Add a new `retract` entry in the go.mod for the versioned release

**Note**: do not delete release tags from the git repository since there may already be references to the release
in the go proxy, which will cause confusion when trying to reuse the tag later (the H1 hash will not match and there
will be a warning when users try to pull the new release).



================================================
FILE: SECURITY.md
================================================
# Security Policy

## Supported Versions

Security updates are applied only to the most recent release, try to always be up to date.

## Reporting a Vulnerability

To report a security issue, please email
[security@anchore.com](mailto:security@anchore.com)
with a description of the issue, the steps you took to create the issue,
affected versions, and, if known, mitigations for the issue.

All support will be made on a best effort basis, so please indicate the "urgency level" of the vulnerability as Critical, High, Medium or Low.

For more details, see our [security policy documentation](https://oss.anchore.com/docs/contributing/security/).


================================================
FILE: Taskfile.yaml
================================================
version: "3"
vars:
  OWNER: anchore
  PROJECT: grype

  # static file dirs
  TOOL_DIR: .tool
  TMP_DIR: .tmp

  # used for changelog generation
  CHANGELOG: CHANGELOG.md
  NEXT_VERSION: VERSION

  # used for snapshot builds
  OS:
    sh: uname -s | tr '[:upper:]' '[:lower:]'
  ARCH:
    sh: |
      [ "$(uname -m)" = "x86_64" ] && echo "amd64_v1" || echo $(uname -m)
  PROJECT_ROOT:
    sh: echo $PWD
  # note: the snapshot dir must be a relative path starting with ./
  SNAPSHOT_DIR: ./snapshot
  SNAPSHOT_BIN: "{{ .PROJECT_ROOT }}/{{ .SNAPSHOT_DIR }}/{{ .OS }}-build_{{ .OS }}_{{ .ARCH }}/{{ .PROJECT }}"
  SNAPSHOT_CMD: "{{ .TOOL_DIR }}/goreleaser release --config {{ .TMP_DIR }}/goreleaser.yaml --clean --snapshot --skip=publish --skip=sign"
  BUILD_CMD:    "{{ .TOOL_DIR }}/goreleaser build   --config {{ .TMP_DIR }}/goreleaser.yaml --clean --snapshot --single-target"
  RELEASE_CMD:  "{{ .TOOL_DIR }}/goreleaser release --clean --release-notes {{ .CHANGELOG }}"
  VERSION:
    sh: git describe --dirty --always --tags

  # used for install and acceptance testing
  COMPARE_DIR: ./test/compare
  COMPARE_TEST_IMAGE: centos:8.2.2004

env:
  SYFT_CHECK_FOR_APP_UPDATE: false
  GRYPE_CHECK_FOR_APP_UPDATE: false

tasks:

  ## High-level tasks #################################

  # note: the default task should not run levels of test, only build the project.
  default:
    desc: Build the project
    cmds:
      - task: build

  validate:
    desc: Run all validation tasks
    aliases:
      - pr-validations
      - validations
    cmds:
      - task: static-analysis
      - task: test
      - task: install-test

  static-analysis:
    desc: Run all static analysis tasks
    cmds:
      - task: check-go-mod-tidy
      - task: check-licenses
      - task: lint
      - task: check-json-schema-drift
      - task: check-db-schema-drift
# TODO: while developing v6, we need to disable this check (since v5 and v6 are imported in the same codebase)
#      - task: validate-grype-db-schema

  test:
    desc: Run all levels of test
    cmds:
      - task: unit
      - task: integration
      - task: cli

  ## Bootstrap tasks #################################

  binny:
    internal: true
    # desc: Get the binny tool
    generates:
      - "{{ .TOOL_DIR }}/binny"
    status:
      - "test -f {{ .TOOL_DIR }}/binny"
    cmd: "curl -sSfL https://get.anchore.io/binny | sh -s -- -b .tool"
    silent: true

  tools:
    desc: Install all tools needed for CI and local development
    deps: [binny]
    aliases:
      - bootstrap
    generates:
      - ".binny.yaml"
      - "{{ .TOOL_DIR }}/*"
    status:
      - "{{ .TOOL_DIR }}/binny check -v"
    cmd: "{{ .TOOL_DIR }}/binny install -v"
    silent: true

  update-tools:
    desc: Update pinned versions of all tools to their latest available versions
    deps: [binny]
    generates:
      - ".binny.yaml"
      - "{{ .TOOL_DIR }}/*"
    cmd: "{{ .TOOL_DIR }}/binny update -v"
    silent: true

  update-quality-gate-db:
    desc: Update pinned version of quality gate database
    cmds:
      - cmd: "go run cmd/grype/main.go db list -o json | jq -r '\"https://grype.anchore.io/databases/v6/\" + .[0].path' > test/quality/test-db"
        silent: true

  list-tools:
    desc: List all tools needed for CI and local development
    deps: [binny]
    cmd: "{{ .TOOL_DIR }}/binny list"
    silent: true

  list-tool-updates:
    desc: List all tools that are not up to date relative to the binny config
    deps: [binny]
    cmd: "{{ .TOOL_DIR }}/binny list --updates"
    silent: true

  tmpdir:
    silent: true
    generates:
      - "{{ .TMP_DIR }}"
    cmd: "mkdir -p {{ .TMP_DIR }}"

  ## Static analysis tasks #################################

  format:
    desc: Auto-format all source code
    deps: [tools]
    cmds:
      - gofmt -w -s .
      - "{{ .TOOL_DIR }}/gosimports -local github.com/anchore -w ."
      - go mod tidy

  lint-fix:
    desc: Auto-format all source code + run golangci lint fixers
    deps: [tools]
    cmds:
      - task: format
      - "{{ .TOOL_DIR }}/golangci-lint run --tests=false --fix"

  lint:
    desc: Run gofmt + golangci lint checks
    vars:
      BAD_FMT_FILES:
        sh: gofmt -l -s .
      BAD_FILE_NAMES:
        sh: "find . | grep -e ':' | grep -v -e 'test/quality/.yardstick' -e 'test/quality/vulnerability-match-labels' || true"
    deps: [tools]
    cmds:
      # ensure there are no go fmt differences
      - cmd: 'test -z "{{ .BAD_FMT_FILES }}" || (echo "files with gofmt issues: [{{ .BAD_FMT_FILES }}]"; exit 1)'
        silent: true
      # ensure there are no files with ":" in it (a known back case in the go ecosystem)
      - cmd: 'test -z "{{ .BAD_FILE_NAMES }}" || (echo "files with bad names: [{{ .BAD_FILE_NAMES }}]"; exit 1)'
        silent: true
      # run linting
      - "{{ .TOOL_DIR }}/golangci-lint run --tests=false"

  check-licenses:
    # desc: Ensure transitive dependencies are compliant with the current license policy
    deps: [tools]
    cmd: "{{ .TOOL_DIR }}/bouncer check ./..."

  check-go-mod-tidy:
    # desc: Ensure go.mod and go.sum are up to date
    cmds:
      - cmd: .github/scripts/go-mod-tidy-check.sh && echo "go.mod and go.sum are tidy!"
        silent: true

  check-json-schema-drift:
    desc: Ensure there is no drift between the JSON schema and the code
    cmds:
      - .github/scripts/json-schema-drift-check.sh

  check-db-schema-drift:
    desc: Ensure there is no drift between the database blob schemas and the code
    cmds:
      - .github/scripts/db-schema-drift-check.sh

  validate-grype-db-schema:
    desc: Ensure the codebase is only referencing a single grype-db schema version (multiple is not allowed)
    cmds:
      - python test/validate-grype-db-schema.py


  ## Testing tasks #################################

  unit:
    desc: Run unit tests
    deps:
      - tmpdir
    vars:
      TEST_PKGS:
        sh: "go list ./... | grep -v {{ .OWNER }}/{{ .PROJECT }}/test | grep -v {{ .OWNER }}/{{ .PROJECT }}/internal/test | tr '\n' ' '"

      # unit test coverage threshold (in % coverage)
      COVERAGE_THRESHOLD: 47
    cmds:
      - "go test -coverprofile {{ .TMP_DIR }}/unit-coverage-details.txt {{ .TEST_PKGS }}"
      - cmd: ".github/scripts/coverage.py {{ .COVERAGE_THRESHOLD }} {{ .TMP_DIR }}/unit-coverage-details.txt"
        silent: true

  integration:
    desc: Run integration tests
    cmds:
      - "go test -v ./test/integration"
      # update database outside race detector, since doing so with
      # race detector on is very slow
      - "go run cmd/{{ .PROJECT }}/main.go db update"
      # exercise most of the CLI with the data race detector enabled
      - "go run -race cmd/{{ .PROJECT }}/main.go alpine:latest"

  _ensure-snapshot:
    # Ensure the snapshot binary is available, building only if needed.
    # In CI, set GRYPE_SNAPSHOT_PREBUILT=true to skip the rebuild when the binary was restored from cache.
    # Locally, this falls through to the snapshot task which uses checksum-based staleness detection
    # so that code changes always produce a fresh binary.
    internal: true
    status:
      - test -n "$GRYPE_SNAPSHOT_PREBUILT" -a -f "{{ .SNAPSHOT_BIN }}"
    cmds:
      - task: snapshot

  cli:
    desc: Run CLI tests
    deps: [tools, _ensure-snapshot]
    sources:
      - "{{ .SNAPSHOT_BIN }}"
      - ./test/cli/**
      - ./**/*.go
    cmds:
      - cmd: "echo 'testing binary: {{ .SNAPSHOT_BIN }}'"
        silent: true

      - cmd: "test -f {{ .SNAPSHOT_BIN }} || (find {{ .SNAPSHOT_DIR }} && echo '\nno snapshot found' && false)"
        silent: true

      - "go test -count=1 -timeout=15m -v ./test/cli"

  quality:
    desc: Run quality tests
    cmds:
      - "cd test/quality && make"


  ## Test-fixture-related targets #################################

  fingerprints:
    desc: Generate test fixture fingerprints
    generates:
      - test/integration/testdata/cache.fingerprint
      - test/install/cache.fingerprint
      - test/cli/testdata/cache.fingerprint
    cmds:
      # for IMAGE integration test fixtures
      - "cd test/integration/testdata && make cache.fingerprint"
      # for INSTALL integration test fixtures
      - "cd test/install && make cache.fingerprint"
      # for CLI test fixtures
      - "cd test/cli/testdata && make cache.fingerprint"

  show-test-image-cache:
    silent: true
    cmds:
      - "echo '\nDocker daemon cache:'"
      - "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}:{{`{{.Tag}}`}}' | grep stereoscope-fixture- | sort"
      - "echo '\nTar cache:'"
      - 'find . -type f -wholename "**/testdata/snapshot/*" | sort'


  ## install.sh testing targets #################################

  install-test:
    cmds:
      - "cd test/install && make"

  install-test-cache-save:
    cmds:
      - "cd test/install && make save"

  install-test-cache-load:
    cmds:
      - "cd test/install && make load"

  install-test-ci-mac:
    cmds:
      - "cd test/install && make ci-test-mac"

  generate-compare-file:
    cmd: "go run ./cmd/{{ .PROJECT }} {{ .COMPARE_TEST_IMAGE }} -o json > {{ .COMPARE_DIR }}/testdata/acceptance-{{ .COMPARE_TEST_IMAGE }}.json"

  compare-mac:
    deps: [tmpdir]
    cmd: |
      {{ .COMPARE_DIR }}/mac.sh \
        {{ .SNAPSHOT_DIR }} \
        {{ .COMPARE_DIR }} \
        {{ .COMPARE_TEST_IMAGE }} \
        {{ .TMP_DIR }}

  compare-linux:
    cmds:
      - task: compare-test-deb-package-install
      - task: compare-test-rpm-package-install

  compare-test-deb-package-install:
    deps: [tmpdir]
    cmd: |
      {{ .COMPARE_DIR }}/deb.sh \
        {{ .SNAPSHOT_DIR }} \
        {{ .COMPARE_DIR }} \
        {{ .COMPARE_TEST_IMAGE }} \
        {{ .TMP_DIR }}

  compare-test-rpm-package-install:
    deps: [tmpdir]
    cmd: |
      {{ .COMPARE_DIR }}/rpm.sh \
        {{ .SNAPSHOT_DIR }} \
        {{ .COMPARE_DIR }} \
        {{ .COMPARE_TEST_IMAGE }} \
        {{ .TMP_DIR }}


  ## Code and data generation targets #################################

  generate:
    desc: Run code and data generation tasks
    cmds:
      - task: generate-json-schema
      - task: generate-db-schema
      - task: generate-codename-data

  generate-json-schema:
    desc: Generate a new JSON schema
    cmds:
      # re-generate package metadata
      - "cd grype/internal && go generate"
      # generate the JSON schema for the CLI output
      - "cd cmd/grype/cli/commands/internal/jsonschema && go run ."

  generate-db-schema:
    desc: Generate database blob JSON schemas
    cmds:
      # generate the JSON schema for database blob types
      - "cd grype/db/v6/schema && go run ."

  generate-codename-data:
    desc: Generate OS codename lookup data
    cmds:
      - "go generate ./grype/db"
      - task: format


  ## Build-related targets #################################

  build:
    desc: Build the project
    deps: [tools, tmpdir]
    generates:
      - "{{ .PROJECT }}"
    cmds:
      - silent: true
        cmd: |
          echo "dist: {{ .SNAPSHOT_DIR }}" > {{ .TMP_DIR }}/goreleaser.yaml
          cat .goreleaser.yaml >> {{ .TMP_DIR }}/goreleaser.yaml

      - "{{ .BUILD_CMD }}"

  snapshot:
    desc: Create a snapshot release
    aliases:
      - build
    deps: [tools, tmpdir]
    sources:
      - cmd/**/*.go
      - "{{ .PROJECT }}/**/*.go"
      - internal/**/*.go
    method: checksum
    generates:
      - "{{ .SNAPSHOT_BIN }}"
    cmds:
      - silent: true
        cmd: |
          echo "dist: {{ .SNAPSHOT_DIR }}" > {{ .TMP_DIR }}/goreleaser.yaml
          cat .goreleaser.yaml >> {{ .TMP_DIR }}/goreleaser.yaml

      - "{{ .SNAPSHOT_CMD }}"

  changelog:
    desc: Generate a changelog
    deps: [tools]
    generates:
      - "{{ .CHANGELOG }}"
      - "{{ .NEXT_VERSION }}"
    cmds:
      - "{{ .TOOL_DIR }}/chronicle -vv -n --version-file {{ .NEXT_VERSION }} > {{ .CHANGELOG }}"
      - "{{ .TOOL_DIR }}/glow -w 0 {{ .CHANGELOG }}"


  ## Release targets #################################

  release:
    desc: Create a release
    interactive: true
    deps: [tools]
    cmds:
      - cmd: .github/scripts/trigger-release.sh
        silent: true


  ## CI-only targets #################################

  ci-check:
    # desc: "[CI only] Are you in CI?"
    cmds:
      - cmd: .github/scripts/ci-check.sh
        silent: true

  ci-release:
    # desc: "[CI only] Create a release"
    deps: [tools]
    cmds:
      - task: ci-check
      - "{{ .TOOL_DIR }}/chronicle -vvv > CHANGELOG.md"
      - cmd: "cat CHANGELOG.md"
        silent: true
      - "{{ .RELEASE_CMD }}"

  ci-validate-test-config:
    # desc: "[CI only] Ensure the update URL is not overridden (not pointing to staging)"
    silent: true
    cmd: |
      bash -c '\
        grep -q "update-url" test/grype-test-config.yaml; \
        if [ $? -eq 0 ]; then \
          echo "Found \"update-url\" in CLI testing config. Cannot release if previous CLI testing did not use production (default) values"; \
        else
          echo "Test configuration valid"
        fi'


  ## Cleanup targets #################################

  clean-snapshot:
    desc: Remove any snapshot builds
    cmds:
      - "rm -rf {{ .SNAPSHOT_DIR }}"
      - "rm -rf {{ .TMP_DIR }}/goreleaser.yaml"

  clean-cache:
    desc: Remove all docker cache and local image tar cache
    cmds:
      - 'find . -type f -wholename "**/testdata/cache/stereoscope-fixture-*.tar" -delete'
      - "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}' | grep stereoscope-fixture- | awk '{print $$1}' | uniq | xargs -r docker rmi --force"


================================================
FILE: artifacthub-repo.yml
================================================
# See documentation here: https://github.com/artifacthub/hub/blob/v1.6.0/docs/metadata/artifacthub-repo.yml
repositoryID: 8ff93ef9-2a75-40b6-945e-514e936fe9bb
owners:
  - name: wagoodman
    email: wagoodman@gmail.com


================================================
FILE: cmd/grype/cli/cli.go
================================================
package cli

import (
	"errors"
	"os"
	"runtime/debug"
	"strings"

	"github.com/charmbracelet/lipgloss"
	"github.com/muesli/termenv"
	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/commands"
	grypeHandler "github.com/anchore/grype/cmd/grype/cli/ui"
	"github.com/anchore/grype/cmd/grype/internal/ui"
	v6 "github.com/anchore/grype/grype/db/v6"
	"github.com/anchore/grype/grype/grypeerr"
	"github.com/anchore/grype/internal/bus"
	"github.com/anchore/grype/internal/log"
	"github.com/anchore/grype/internal/redact"
	"github.com/anchore/stereoscope"
	syftHandler "github.com/anchore/syft/cmd/syft/cli/ui"
	"github.com/anchore/syft/syft"
)

func Application(id clio.Identification) clio.Application {
	app, _ := create(id)
	return app
}

func Command(id clio.Identification) *cobra.Command {
	_, cmd := create(id)
	return cmd
}

func SetupConfig(id clio.Identification) *clio.SetupConfig {
	return clio.NewSetupConfig(id).
		WithGlobalConfigFlag().   // add persistent -c <path> for reading an application config from
		WithGlobalLoggingFlags(). // add persistent -v and -q flags tied to the logging config
		WithConfigInRootHelp().   // --help on the root command renders the full application config in the help text
		WithUIConstructor(
			// select a UI based on the logging configuration and state of stdin (if stdin is a tty)
			func(cfg clio.Config) (*clio.UICollection, error) {
				// remove CI var from consideration when determining if we should use the UI
				lipgloss.SetDefaultRenderer(lipgloss.NewRenderer(os.Stdout, termenv.WithEnvironment(environWithoutCI{})))

				// setup the UIs
				noUI := ui.None(cfg.Log.Quiet)
				if !cfg.Log.AllowUI(os.Stdin) || cfg.Log.Quiet {
					return clio.NewUICollection(noUI), nil
				}

				return clio.NewUICollection(
					ui.New(cfg.Log.Quiet,
						grypeHandler.New(grypeHandler.DefaultHandlerConfig()),
						syftHandler.New(syftHandler.DefaultHandlerConfig()),
					),
					noUI,
				), nil
			},
		).
		WithInitializers(
			func(state *clio.State) error {
				// clio is setting up and providing the bus, redact store, and logger to the application. Once loaded,
				// we can hoist them into the internal packages for global use.
				stereoscope.SetBus(state.Bus)
				syft.SetBus(state.Bus)
				bus.Set(state.Bus)

				redact.Set(state.RedactStore)

				log.Set(state.Logger)
				syft.SetLogger(state.Logger.Nested("from", "syft"))
				stereoscope.SetLogger(state.Logger.Nested("from", "stereoscope"))

				return nil
			},
		).
		WithPostRuns(func(_ *clio.State, _ error) {
			stereoscope.Cleanup() //nolint:staticcheck
		}).
		WithMapExitCode(func(err error) int {
			// return exit code 2 to indicate when a vulnerability severity is discovered
			// that is equal or above the given --fail-on severity value.
			if errors.Is(err, grypeerr.ErrAboveSeverityThreshold) {
				return 2
			}
			// return exit code 100 to indicate a DB upgrade is available (cmd: db check).
			if errors.Is(err, grypeerr.ErrDBUpgradeAvailable) {
				return 100
			}
			return 1
		})
}

func create(id clio.Identification) (clio.Application, *cobra.Command) {
	clioCfg := SetupConfig(id)

	app := clio.New(*clioCfg)

	rootCmd := commands.Root(app)

	// add sub-commands
	rootCmd.AddCommand(
		commands.DB(app),
		commands.Completion(app),
		commands.Explain(app),
		clio.VersionCommand(id, syftVersion, dbVersion),
		clio.ConfigCommand(app, nil),
	)

	return app, rootCmd
}

func syftVersion() (string, any) {
	buildInfo, ok := debug.ReadBuildInfo()
	if !ok {
		log.Debug("unable to find the buildinfo section of the binary (syft version is unknown)")
		return "", ""
	}

	for _, d := range buildInfo.Deps {
		if d.Path == "github.com/anchore/syft" {
			return "Syft Version", d.Version
		}
	}

	log.Debug("unable to find 'github.com/anchore/syft' from the buildinfo section of the binary")
	return "", ""
}

func dbVersion() (string, any) {
	return "Supported DB Schema", v6.ModelVersion
}

type environWithoutCI struct {
}

func (e environWithoutCI) Environ() []string {
	var out []string
	for _, s := range os.Environ() {
		if strings.HasPrefix(s, "CI=") {
			continue
		}
		out = append(out, s)
	}
	return out
}

func (e environWithoutCI) Getenv(s string) string {
	if s == "CI" {
		return ""
	}
	return os.Getenv(s)
}


================================================
FILE: cmd/grype/cli/cli_test.go
================================================
package cli

import (
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/anchore/clio"
)

func Test_Command(t *testing.T) {
	root := Command(clio.Identification{
		Name:    "test-name",
		Version: "test-version",
	})

	require.Equal(t, root.Name(), "test-name")
	require.NotEmpty(t, root.Commands())
}


================================================
FILE: cmd/grype/cli/commands/completion.go
================================================
package commands

import (
	"context"
	"os"
	"strings"

	"github.com/docker/docker/api/types/filters"
	"github.com/docker/docker/api/types/image"
	"github.com/docker/docker/client"
	"github.com/spf13/cobra"

	"github.com/anchore/clio"
)

// Completion returns a command to provide completion to various terminal shells
func Completion(app clio.Application) *cobra.Command {
	return &cobra.Command{
		Use:   "completion [bash|zsh|fish]",
		Short: "Generate a shell completion for Grype (listing local docker images)",
		Long: `To load completions (docker image list):

Bash:

$ source <(grype completion bash)

# To load completions for each session, execute once:
Linux:
  $ grype completion bash > /etc/bash_completion.d/grype
MacOS:
  $ grype completion bash > /usr/local/etc/bash_completion.d/grype

Zsh:

# If shell completion is not already enabled in your environment you will need
# to enable it.  You can execute the following once:

$ echo "autoload -U compinit; compinit" >> ~/.zshrc

# To load completions for each session, execute once:
$ grype completion zsh > "${fpath[1]}/_grype"

# You will need to start a new shell for this setup to take effect.

Fish:

$ grype completion fish | source

# To load completions for each session, execute once:
$ grype completion fish > ~/.config/fish/completions/grype.fish
`,
		DisableFlagsInUseLine: true,
		ValidArgs:             []string{"bash", "fish", "zsh"},
		PreRunE:               disableUI(app),
		Args:                  cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
		RunE: func(cmd *cobra.Command, args []string) error {
			var err error
			switch args[0] {
			case "zsh":
				err = cmd.Root().GenZshCompletion(os.Stdout)
			case "bash":
				err = cmd.Root().GenBashCompletion(os.Stdout)
			case "fish":
				err = cmd.Root().GenFishCompletion(os.Stdout, true)
			}
			return err
		},
	}
}

func listLocalDockerImages(prefix string) ([]string, error) {
	var repoTags = make([]string, 0)
	ctx := context.Background()
	cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
	if err != nil {
		return repoTags, err
	}

	// Only want to return tagged images
	imageListArgs := filters.NewArgs()
	imageListArgs.Add("dangling", "false")
	images, err := cli.ImageList(ctx, image.ListOptions{All: false, Filters: imageListArgs})
	if err != nil {
		return repoTags, err
	}

	for _, image := range images {
		// image may have multiple tags
		for _, tag := range image.RepoTags {
			if strings.HasPrefix(tag, prefix) {
				repoTags = append(repoTags, tag)
			}
		}
	}
	return repoTags, nil
}

func dockerImageValidArgsFunction(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) {
	// Since we use ValidArgsFunction, Cobra will call this AFTER having parsed all flags and arguments provided
	dockerImageRepoTags, err := listLocalDockerImages(toComplete)
	if err != nil {
		// Indicates that an error occurred and completions should be ignored
		return []string{"completion failed"}, cobra.ShellCompDirectiveError
	}
	if len(dockerImageRepoTags) == 0 {
		return []string{"no docker images found"}, cobra.ShellCompDirectiveError
	}
	// ShellCompDirectiveDefault indicates that the shell will perform its default behavior after completions have
	// been provided (without implying other possible directives)
	return dockerImageRepoTags, cobra.ShellCompDirectiveDefault
}


================================================
FILE: cmd/grype/cli/commands/db.go
================================================
package commands

import (
	"github.com/spf13/cobra"

	"github.com/anchore/clio"
)

const (
	jsonOutputFormat  = "json"
	tableOutputFormat = "table"
	textOutputFormat  = "text"
)

func DB(app clio.Application) *cobra.Command {
	db := &cobra.Command{
		Use:   "db",
		Short: "vulnerability database operations",
	}

	db.AddCommand(
		DBCheck(app),
		DBDelete(app),
		DBImport(app),
		DBList(app),
		DBStatus(app),
		DBUpdate(app),
		DBSearch(app),
		DBProviders(app),
	)

	return db
}


================================================
FILE: cmd/grype/cli/commands/db_check.go
================================================
package commands

import (
	"encoding/json"
	"fmt"
	"io"
	"os"

	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/options"
	db "github.com/anchore/grype/grype/db/v6"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/grype/grypeerr"
	"github.com/anchore/grype/internal/log"
)

type dbCheckOptions struct {
	Output                  string `yaml:"output" json:"output" mapstructure:"output"`
	options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}

var _ clio.FlagAdder = (*dbCheckOptions)(nil)

func (d *dbCheckOptions) AddFlags(flags clio.FlagSet) {
	flags.StringVarP(&d.Output, "output", "o", "format to display results (available=[text, json])")
}

func DBCheck(app clio.Application) *cobra.Command {
	opts := &dbCheckOptions{
		Output:          textOutputFormat,
		DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
	}

	cmd := &cobra.Command{
		Use:   "check",
		Short: "Check to see if there is a database update available",
		PreRunE: func(cmd *cobra.Command, args []string) error {
			// DB commands should not opt into the low-pass check filter
			opts.DB.MaxUpdateCheckFrequency = 0
			return disableUI(app)(cmd, args)
		},
		Args: cobra.ExactArgs(0),
		RunE: func(_ *cobra.Command, _ []string) error {
			return runDBCheck(*opts)
		},
	}

	// prevent from being shown in the grype config
	type configWrapper struct {
		Hidden                   *dbCheckOptions `json:"-" yaml:"-" mapstructure:"-"`
		*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
	}

	return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}

func runDBCheck(opts dbCheckOptions) error {
	client, err := distribution.NewClient(opts.ToClientConfig())
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}

	cfg := opts.ToCuratorConfig()

	current, err := db.ReadDescription(cfg.DBFilePath())
	if err != nil {
		log.WithFields("error", err).Debug("unable to read current database metadata")
		current = nil
	}

	archive, err := client.IsUpdateAvailable(current)
	if err != nil {
		return fmt.Errorf("unable to check for vulnerability database update: %w", err)
	}

	updateAvailable := archive != nil

	if err := presentNewDBCheck(opts.Output, os.Stdout, updateAvailable, current, archive); err != nil {
		return err
	}

	if updateAvailable {
		return grypeerr.ErrDBUpgradeAvailable
	}
	return nil
}

type dbCheckJSON struct {
	CurrentDB       *db.Description       `json:"currentDB"`
	CandidateDB     *distribution.Archive `json:"candidateDB"`
	UpdateAvailable bool                  `json:"updateAvailable"`
}

func presentNewDBCheck(format string, writer io.Writer, updateAvailable bool, current *db.Description, candidate *distribution.Archive) error {
	switch format {
	case textOutputFormat:
		if current != nil {
			fmt.Fprintf(writer, "Installed DB version %s was built on %s\n", current.SchemaVersion, current.Built.String())
		} else {
			fmt.Fprintln(writer, "No installed DB version found")
		}

		if !updateAvailable {
			fmt.Fprintln(writer, "No update available")
			return nil
		}

		fmt.Fprintf(writer, "Updated DB version %s was built on %s\n", candidate.SchemaVersion, candidate.Built.String())
		fmt.Fprintln(writer, "You can run 'grype db update' to update to the latest db")
	case jsonOutputFormat:
		data := dbCheckJSON{
			CurrentDB:       current,
			CandidateDB:     candidate,
			UpdateAvailable: updateAvailable,
		}

		enc := json.NewEncoder(writer)
		enc.SetEscapeHTML(false)
		enc.SetIndent("", " ")
		if err := enc.Encode(&data); err != nil {
			return fmt.Errorf("failed to db listing information: %+v", err)
		}
	default:
		return fmt.Errorf("unsupported output format: %s", format)
	}
	return nil
}


================================================
FILE: cmd/grype/cli/commands/db_check_test.go
================================================
package commands

import (
	"bytes"
	"strings"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	db "github.com/anchore/grype/grype/db/v6"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/internal/schemaver"
)

func TestPresentNewDBCheck(t *testing.T) {
	currentDB := &db.Description{
		SchemaVersion: schemaver.New(6, 0, 0),
		Built:         db.Time{Time: time.Date(2023, 11, 25, 12, 0, 0, 0, time.UTC)},
	}

	candidateDB := &distribution.Archive{
		Description: db.Description{
			SchemaVersion: schemaver.New(6, 0, 1),
			Built:         db.Time{Time: time.Date(2023, 11, 26, 12, 0, 0, 0, time.UTC)},
		},
		Path:     "vulnerability-db_6.0.1_2023-11-26T12:00:00Z_6238463.tar.gz",
		Checksum: "sha256:1234561234567890345674561234567890345678",
	}
	tests := []struct {
		name            string
		format          string
		updateAvailable bool
		current         *db.Description
		candidate       *distribution.Archive
		expectedText    string
		expectErr       require.ErrorAssertionFunc
	}{
		{
			name:            "text format with update available",
			format:          textOutputFormat,
			updateAvailable: true,
			current:         currentDB,
			candidate:       candidateDB,
			expectedText: `
Installed DB version v6.0.0 was built on 2023-11-25T12:00:00Z
Updated DB version v6.0.1 was built on 2023-11-26T12:00:00Z
You can run 'grype db update' to update to the latest db
`,
		},
		{
			name:            "text format without update available",
			format:          textOutputFormat,
			updateAvailable: false,
			current:         currentDB,
			candidate:       nil,
			expectedText: `
Installed DB version v6.0.0 was built on 2023-11-25T12:00:00Z
No update available
`,
		},
		{
			name:            "json format with update available",
			format:          jsonOutputFormat,
			updateAvailable: true,
			current:         currentDB,
			candidate:       candidateDB,
			expectedText: `
{
 "currentDB": {
  "schemaVersion": "v6.0.0",
  "built": "2023-11-25T12:00:00Z"
 },
 "candidateDB": {
  "schemaVersion": "v6.0.1",
  "built": "2023-11-26T12:00:00Z",
  "path": "vulnerability-db_6.0.1_2023-11-26T12:00:00Z_6238463.tar.gz",
  "checksum": "sha256:1234561234567890345674561234567890345678"
 },
 "updateAvailable": true
}
`,
		},
		{
			name:            "json format without update available",
			format:          jsonOutputFormat,
			updateAvailable: false,
			current:         currentDB,
			candidate:       nil,
			expectedText: `
{
 "currentDB": {
  "schemaVersion": "v6.0.0",
  "built": "2023-11-25T12:00:00Z"
 },
 "candidateDB": null,
 "updateAvailable": false
}
`,
		},
		{
			name:      "unsupported format",
			format:    "xml",
			expectErr: requireErrorContains("unsupported output format: xml"),
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.expectErr == nil {
				tt.expectErr = require.NoError
			}
			buf := &bytes.Buffer{}
			err := presentNewDBCheck(tt.format, buf, tt.updateAvailable, tt.current, tt.candidate)

			tt.expectErr(t, err)
			if err != nil {
				return
			}

			assert.Equal(t, strings.TrimSpace(tt.expectedText), strings.TrimSpace(buf.String()))
		})
	}
}

func requireErrorContains(expected string) require.ErrorAssertionFunc {
	return func(t require.TestingT, err error, msgAndArgs ...interface{}) {
		require.Error(t, err)
		assert.Contains(t, err.Error(), expected)
	}
}


================================================
FILE: cmd/grype/cli/commands/db_delete.go
================================================
package commands

import (
	"fmt"

	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/options"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/grype/db/v6/installation"
)

func DBDelete(app clio.Application) *cobra.Command {
	opts := options.DefaultDatabaseCommand(app.ID())

	cmd := &cobra.Command{
		Use:     "delete",
		Short:   "Delete the vulnerability database",
		Args:    cobra.ExactArgs(0),
		PreRunE: disableUI(app),
		RunE: func(_ *cobra.Command, _ []string) error {
			return runDBDelete(*opts)
		},
	}

	// prevent from being shown in the grype config
	type configWrapper struct {
		*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
	}

	return app.SetupCommand(cmd, &configWrapper{opts})
}

func runDBDelete(opts options.DatabaseCommand) error {
	client, err := distribution.NewClient(opts.ToClientConfig())
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}
	c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
	if err != nil {
		return fmt.Errorf("unable to create curator: %w", err)
	}

	if err := c.Delete(); err != nil {
		return fmt.Errorf("unable to delete vulnerability database: %+v", err)
	}

	return stderrPrintLnf("Vulnerability database deleted")
}


================================================
FILE: cmd/grype/cli/commands/db_import.go
================================================
package commands

import (
	"fmt"

	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/options"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/grype/db/v6/installation"
	"github.com/anchore/grype/internal/log"
)

func DBImport(app clio.Application) *cobra.Command {
	opts := options.DefaultDatabaseCommand(app.ID())

	cmd := &cobra.Command{
		Use:   "import FILE | URL",
		Short: "Import a vulnerability database or archive from a local file or URL",
		Long:  fmt.Sprintf("import a vulnerability database archive from a local FILE or URL.\nDB archives can be obtained from %q (or running `db list`). If the URL has a `checksum` query parameter with a fully qualified digest (e.g. 'sha256:abc728...') then the archive/DB will be verified against this value.", opts.DB.UpdateURL),
		Args:  cobra.ExactArgs(1),
		RunE: func(_ *cobra.Command, args []string) error {
			return runDBImport(*opts, args[0])
		},
	}

	// prevent from being shown in the grype config
	type configWrapper struct {
		*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
	}

	return app.SetupCommand(cmd, &configWrapper{opts})
}

func runDBImport(opts options.DatabaseCommand, reference string) error {
	// TODO: tui update? better logging?
	client, err := distribution.NewClient(opts.ToClientConfig())
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}
	c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
	if err != nil {
		return fmt.Errorf("unable to create curator: %w", err)
	}

	log.WithFields("reference", reference).Infof("importing vulnerability database archive")
	if err := c.Import(reference); err != nil {
		return fmt.Errorf("unable to import vulnerability database: %w", err)
	}

	s := c.Status()
	log.WithFields("built", s.Built.String(), "status", renderStoreValidation(s)).Info("vulnerability database imported")
	return nil
}


================================================
FILE: cmd/grype/cli/commands/db_list.go
================================================
package commands

import (
	"encoding/json"
	"fmt"
	"io"
	"net/url"
	"os"

	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/options"
	"github.com/anchore/grype/grype/db/v6/distribution"
)

type dbListOptions struct {
	Output                  string `yaml:"output" json:"output" mapstructure:"output"`
	options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}

var _ clio.FlagAdder = (*dbListOptions)(nil)

func (d *dbListOptions) AddFlags(flags clio.FlagSet) {
	flags.StringVarP(&d.Output, "output", "o", "format to display results (available=[text, raw, json])")
}

func DBList(app clio.Application) *cobra.Command {
	opts := &dbListOptions{
		Output:          textOutputFormat,
		DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
	}

	cmd := &cobra.Command{
		Use:     "list",
		Short:   "List all DBs available according to the listing URL",
		PreRunE: disableUI(app),
		Args:    cobra.ExactArgs(0),
		RunE: func(_ *cobra.Command, _ []string) error {
			return runDBList(*opts)
		},
	}

	// prevent from being shown in the grype config
	type configWrapper struct {
		Hidden                   *dbListOptions `json:"-" yaml:"-" mapstructure:"-"`
		*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
	}

	return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}

func runDBList(opts dbListOptions) error {
	c, err := distribution.NewClient(opts.ToClientConfig())
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}

	latest, err := c.Latest()
	if err != nil {
		return fmt.Errorf("unable to get database listing: %w", err)
	}

	u, err := c.ResolveArchiveURL(latest.Archive)
	if err != nil {
		return fmt.Errorf("unable to resolve database URL: %w", err)
	}

	return presentDBList(opts.Output, u, opts.DB.UpdateURL, os.Stdout, latest)
}

func presentDBList(format string, archiveURL, listingURL string, writer io.Writer, latest *distribution.LatestDocument) error {
	if latest == nil {
		return fmt.Errorf("no database listing found")
	}

	// remove query params
	archiveURLObj, err := url.Parse(archiveURL)
	if err != nil {
		return fmt.Errorf("unable to parse db URL %q: %w", archiveURL, err)
	}

	archiveURLObj.RawQuery = ""

	if listingURL == distribution.DefaultConfig().LatestURL {
		// append on the schema
		listingURL = fmt.Sprintf("%s/v%v/%s", listingURL, latest.SchemaVersion.Model, distribution.LatestFileName)
	}

	switch format {
	case textOutputFormat:
		fmt.Fprintf(writer, "Status:   %s\n", latest.Status)
		fmt.Fprintf(writer, "Schema:   %s\n", latest.SchemaVersion.String())
		fmt.Fprintf(writer, "Built:    %s\n", latest.Built.String())
		fmt.Fprintf(writer, "Listing:  %s\n", listingURL)
		fmt.Fprintf(writer, "DB URL:   %s\n", archiveURLObj.String())
		fmt.Fprintf(writer, "Checksum: %s\n", latest.Checksum)
	case jsonOutputFormat, "raw":
		enc := json.NewEncoder(writer)
		enc.SetEscapeHTML(false)
		enc.SetIndent("", " ")
		// why make an array? We are reserving the right to list additional entries in the future without the
		// need to change from an object to an array at that point in time. This will be useful if we implement
		// the history.json functionality for grabbing historical database listings.
		if err := enc.Encode([]any{latest}); err != nil {
			return fmt.Errorf("failed to db listing information: %+v", err)
		}
	default:
		return fmt.Errorf("unsupported output format: %s", format)
	}
	return nil
}


================================================
FILE: cmd/grype/cli/commands/db_list_test.go
================================================
package commands

import (
	"bytes"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/options"
	db "github.com/anchore/grype/grype/db/v6"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/internal/schemaver"
)

func Test_ListingUserAgent(t *testing.T) {

	t.Run("new", func(t *testing.T) {
		listingFile := "/latest.json"

		got := ""

		// setup mock
		handler := http.NewServeMux()
		handler.HandleFunc(listingFile, func(w http.ResponseWriter, r *http.Request) {
			got = r.Header.Get("User-Agent")
			w.WriteHeader(http.StatusOK)
			_ = json.NewEncoder(w).Encode(&distribution.LatestDocument{
				Status: "active",
				Archive: distribution.Archive{
					Description: db.Description{
						SchemaVersion: schemaver.New(6, 0, 0),
						Built:         db.Time{Time: time.Now()},
					},
					Path:     "vulnerability-db_v6.0.0.tar.gz",
					Checksum: "sha256:dummychecksum",
				},
			})
		})
		mockSrv := httptest.NewServer(handler)
		defer mockSrv.Close()

		dbOptions := *options.DefaultDatabaseCommand(clio.Identification{
			Name:    "new-app",
			Version: "v4.0.0",
		})
		dbOptions.DB.RequireUpdateCheck = true
		dbOptions.DB.UpdateURL = mockSrv.URL + listingFile

		err := runDBList(dbListOptions{
			Output:          textOutputFormat,
			DatabaseCommand: dbOptions,
		})
		require.NoError(t, err)

		if got != "new-app v4.0.0" {
			t.Errorf("expected User-Agent header to match, got: %v", got)
		}
	})

}

func TestPresentDBList(t *testing.T) {
	latestDoc := &distribution.LatestDocument{
		Status: "active",
		Archive: distribution.Archive{
			Description: db.Description{
				SchemaVersion: schemaver.New(6, 0, 0),
				Built:         db.Time{Time: time.Date(2024, 11, 27, 14, 43, 17, 0, time.UTC)},
			},
			Path:     "vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst",
			Checksum: "sha256:16bcb6551c748056f752f299fcdb4fa50fe61589d086be3889e670261ff21ca4",
		},
	}

	tests := []struct {
		name         string
		format       string
		baseURL      string
		archiveURL   string
		latest       *distribution.LatestDocument
		expectedText string
		expectedErr  require.ErrorAssertionFunc
	}{
		{
			name:       "valid text format",
			format:     textOutputFormat,
			latest:     latestDoc,
			baseURL:    "http://localhost:8000/latest.json",
			archiveURL: "http://localhost:8000/vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst",
			expectedText: `Status:   active
Schema:   v6.0.0
Built:    2024-11-27T14:43:17Z
Listing:  http://localhost:8000/latest.json
DB URL:   http://localhost:8000/vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst
Checksum: sha256:16bcb6551c748056f752f299fcdb4fa50fe61589d086be3889e670261ff21ca4
`,
			expectedErr: require.NoError,
		},
		{
			name:       "complete default values",
			format:     textOutputFormat,
			latest:     latestDoc,
			baseURL:    "https://grype.anchore.io/databases",
			archiveURL: "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst",
			expectedText: `Status:   active
Schema:   v6.0.0
Built:    2024-11-27T14:43:17Z
Listing:  https://grype.anchore.io/databases/v6/latest.json
DB URL:   https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst
Checksum: sha256:16bcb6551c748056f752f299fcdb4fa50fe61589d086be3889e670261ff21ca4
`,
			expectedErr: require.NoError,
		},
		{
			name:   "valid JSON format",
			format: jsonOutputFormat,
			latest: latestDoc,
			expectedText: `[
 {
  "status": "active",
  "schemaVersion": "v6.0.0",
  "built": "2024-11-27T14:43:17Z",
  "path": "vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst",
  "checksum": "sha256:16bcb6551c748056f752f299fcdb4fa50fe61589d086be3889e670261ff21ca4"
 }
]
`,
			expectedErr: require.NoError,
		},
		{
			name:        "nil latest document",
			format:      textOutputFormat,
			latest:      nil,
			expectedErr: requireErrorContains("no database listing found"),
		},
		{
			name:        "unsupported format",
			format:      "unsupported",
			latest:      latestDoc,
			expectedErr: requireErrorContains("unsupported output format"),
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			writer := &bytes.Buffer{}

			err := presentDBList(tt.format, tt.archiveURL, tt.baseURL, writer, tt.latest)
			if tt.expectedErr == nil {
				tt.expectedErr = require.NoError
			}
			tt.expectedErr(t, err)

			if err != nil {
				return
			}

			require.Equal(t, strings.TrimSpace(tt.expectedText), strings.TrimSpace(writer.String()))
		})
	}
}


================================================
FILE: cmd/grype/cli/commands/db_providers.go
================================================
package commands

import (
	"encoding/json"
	"fmt"
	"io"
	"strings"
	"time"

	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/options"
	v6 "github.com/anchore/grype/grype/db/v6"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/grype/db/v6/installation"
	"github.com/anchore/grype/internal/bus"
)

type dbProvidersOptions struct {
	Output                  string `yaml:"output" json:"output"`
	options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}

var _ clio.FlagAdder = (*dbProvidersOptions)(nil)

func (d *dbProvidersOptions) AddFlags(flags clio.FlagSet) {
	flags.StringVarP(&d.Output, "output", "o", "format to display results (available=[table, json])")
}

func DBProviders(app clio.Application) *cobra.Command {
	opts := &dbProvidersOptions{
		Output:          tableOutputFormat,
		DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
	}

	cmd := &cobra.Command{
		Use:   "providers",
		Short: "List vulnerability providers that are in the database",
		Args:  cobra.ExactArgs(0),
		RunE: func(_ *cobra.Command, _ []string) error {
			return runDBProviders(opts)
		},
	}

	// prevent from being shown in the grype config
	type configWrapper struct {
		Hidden                   *dbProvidersOptions `json:"-" yaml:"-" mapstructure:"-"`
		*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
	}

	return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}

func runDBProviders(opts *dbProvidersOptions) error {
	client, err := distribution.NewClient(opts.ToClientConfig())
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}
	c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
	if err != nil {
		return fmt.Errorf("unable to create curator: %w", err)
	}

	reader, err := c.Reader()
	if err != nil {
		return fmt.Errorf("unable to get providers: %w", err)
	}

	providerModels, err := reader.AllProviders()
	if err != nil {
		return fmt.Errorf("unable to get providers: %w", err)
	}

	sb := &strings.Builder{}

	switch opts.Output {
	case tableOutputFormat, textOutputFormat:
		err = displayDBProvidersTable(toProviders(providerModels), sb)
		if err != nil {
			return err
		}
	case jsonOutputFormat:
		err = displayDBProvidersJSON(toProviders(providerModels), sb)
		if err != nil {
			return err
		}
	default:
		return fmt.Errorf("unsupported output format: %s", opts.Output)
	}
	bus.Report(sb.String())

	return nil
}

type provider struct {
	Name         string     `json:"name"`
	Version      string     `json:"version"`
	Processor    string     `json:"processor"`
	DateCaptured *time.Time `json:"dateCaptured"`
	InputDigest  string     `json:"inputDigest"`
}

func toProviders(providers []v6.Provider) []provider {
	var res []provider
	for _, p := range providers {
		res = append(res, provider{
			Name:         p.ID,
			Version:      p.Version,
			Processor:    p.Processor,
			DateCaptured: p.DateCaptured,
			InputDigest:  p.InputDigest,
		})
	}
	return res
}

func displayDBProvidersTable(providers []provider, output io.Writer) error {
	rows := [][]string{}
	for _, p := range providers {
		rows = append(rows, []string{p.Name, p.Version, p.Processor, p.DateCaptured.String(), p.InputDigest})
	}

	table := newTable(output, []string{"Name", "Version", "Processor", "Date Captured", "Input Digest"})

	if err := table.Bulk(rows); err != nil {
		return fmt.Errorf("failed to add table rows: %w", err)
	}
	return table.Render()
}

func displayDBProvidersJSON(providers []provider, output io.Writer) error {
	encoder := json.NewEncoder(output)
	encoder.SetEscapeHTML(false)
	encoder.SetIndent("", " ")
	err := encoder.Encode(providers)
	if err != nil {
		return fmt.Errorf("cannot display json: %w", err)
	}
	return nil
}


================================================
FILE: cmd/grype/cli/commands/db_providers_test.go
================================================
package commands

import (
	"bytes"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
)

func TestDisplayDBProvidersTable(t *testing.T) {
	providers := []provider{
		{
			Name:         "provider1",
			Version:      "1.0.0",
			Processor:    "vunnel@3.2",
			DateCaptured: timeRef(time.Date(2024, 11, 25, 14, 30, 0, 0, time.UTC)),
			InputDigest:  "xxh64:1234567834567",
		},
		{
			Name:         "provider2",
			Version:      "2.0.0",
			Processor:    "vunnel@3.2",
			DateCaptured: timeRef(time.Date(2024, 11, 26, 10, 15, 0, 0, time.UTC)),
			InputDigest:  "xxh64:9876543212345",
		},
	}

	expectedOutput := `NAME       VERSION  PROCESSOR   DATE CAPTURED                  INPUT DIGEST         
provider1  1.0.0    vunnel@3.2  2024-11-25 14:30:00 +0000 UTC  xxh64:1234567834567  
provider2  2.0.0    vunnel@3.2  2024-11-26 10:15:00 +0000 UTC  xxh64:9876543212345  
`

	var output bytes.Buffer
	require.NoError(t, displayDBProvidersTable(providers, &output))

	require.Equal(t, expectedOutput, output.String())
}

func TestDisplayDBProvidersJSON(t *testing.T) {
	providers := []provider{
		{
			Name:         "provider1",
			Version:      "1.0.0",
			Processor:    "vunnel@3.2",
			DateCaptured: timeRef(time.Date(2024, 11, 25, 14, 30, 0, 0, time.UTC)),
			InputDigest:  "xxh64:1234567834567",
		},
		{
			Name:         "provider2",
			Version:      "2.0.0",
			Processor:    "vunnel@3.2",
			DateCaptured: timeRef(time.Date(2024, 11, 26, 10, 15, 0, 0, time.UTC)),
			InputDigest:  "xxh64:9876543212345",
		},
	}

	expectedJSON := `[
 {
  "name": "provider1",
  "version": "1.0.0",
  "processor": "vunnel@3.2",
  "dateCaptured": "2024-11-25T14:30:00Z",
  "inputDigest": "xxh64:1234567834567"
 },
 {
  "name": "provider2",
  "version": "2.0.0",
  "processor": "vunnel@3.2",
  "dateCaptured": "2024-11-26T10:15:00Z",
  "inputDigest": "xxh64:9876543212345"
 }
]
`

	var output bytes.Buffer
	err := displayDBProvidersJSON(providers, &output)
	require.NoError(t, err)

	require.JSONEq(t, expectedJSON, output.String())
}

func timeRef(t time.Time) *time.Time {
	return &t
}


================================================
FILE: cmd/grype/cli/commands/db_search.go
================================================
package commands

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"regexp"
	"sort"
	"strings"

	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/commands/internal/dbsearch"
	"github.com/anchore/grype/cmd/grype/cli/options"
	v6 "github.com/anchore/grype/grype/db/v6"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/grype/db/v6/installation"
	"github.com/anchore/grype/internal/bus"
	"github.com/anchore/grype/internal/log"
)

type dbSearchMatchOptions struct {
	Format        options.DBSearchFormat          `yaml:",inline" mapstructure:",squash"`
	Vulnerability options.DBSearchVulnerabilities `yaml:",inline" mapstructure:",squash"`
	Package       options.DBSearchPackages        `yaml:",inline" mapstructure:",squash"`
	OS            options.DBSearchOSs             `yaml:",inline" mapstructure:",squash"`
	Bounds        options.DBSearchBounds          `yaml:",inline" mapstructure:",squash"`

	options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}

var alasPattern = regexp.MustCompile(`^alas[\w]*-\d+-\d+$`)

func (o *dbSearchMatchOptions) applyArgs(args []string) error {
	for _, arg := range args {
		lowerArg := strings.ToLower(arg)
		switch {
		case hasAnyPrefix(lowerArg, "cpe:", "purl:"):
			// this is explicitly a package...
			log.WithFields("value", arg).Trace("assuming arg is a package specifier")
			o.Package.Packages = append(o.Package.Packages, arg)
		case hasAnyPrefix(lowerArg, "cve-", "ghsa-", "elsa-", "rhsa-") || alasPattern.MatchString(lowerArg):
			// this is a vulnerability...
			log.WithFields("value", arg).Trace("assuming arg is a vulnerability ID")
			o.Vulnerability.VulnerabilityIDs = append(o.Vulnerability.VulnerabilityIDs, arg)
		default:
			// assume this is a package name
			log.WithFields("value", arg).Trace("assuming arg is a package name")
			o.Package.Packages = append(o.Package.Packages, arg)
		}
	}

	if err := o.Vulnerability.PostLoad(); err != nil {
		return err
	}

	if err := o.Package.PostLoad(); err != nil {
		return err
	}

	return nil
}

func hasAnyPrefix(s string, prefixes ...string) bool {
	for _, prefix := range prefixes {
		if strings.HasPrefix(s, prefix) {
			return true
		}
	}
	return false
}

func DBSearch(app clio.Application) *cobra.Command {
	opts := &dbSearchMatchOptions{
		Format: options.DefaultDBSearchFormat(),
		Vulnerability: options.DBSearchVulnerabilities{
			UseVulnIDFlag: true,
		},
		Bounds:          options.DefaultDBSearchBounds(),
		DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
	}

	cmd := &cobra.Command{
		Use:   "search",
		Short: "Search the DB for vulnerabilities or affected packages",
		Example: `
  Search for affected packages by vulnerability ID:

    $ grype db search --vuln ELSA-2023-12205

  Search for affected packages by package name:

    $ grype db search --pkg log4j

  Search for affected packages by package name, filtering down to a specific vulnerability:

    $ grype db search --pkg log4j --vuln CVE-2021-44228

  Search for affected packages by PURL (note: version is not considered):

    $ grype db search --pkg 'pkg:rpm/redhat/openssl' # or: '--ecosystem rpm --pkg openssl

  Search for affected packages by CPE (note: version/update is not considered):

    $ grype db search --pkg 'cpe:2.3:a:jetty:jetty_http_server:*:*:*:*:*:*:*:*'
    $ grype db search --pkg 'cpe:/a:jetty:jetty_http_server'`,
		PreRunE: disableUI(app),
		RunE: func(cmd *cobra.Command, args []string) (err error) {
			if len(args) > 0 {
				// try to stay backwards compatible with v5 search command (which takes args)
				if err := opts.applyArgs(args); err != nil {
					return err
				}
			}
			err = runDBSearchMatches(*opts)
			if err != nil {
				if errors.Is(err, dbsearch.ErrNoSearchCriteria) {
					_ = cmd.Usage()
				}
				return err
			}
			return nil
		},
	}

	cmd.AddCommand(
		DBSearchVulnerabilities(app),
	)

	// prevent from being shown in the grype config
	type configWrapper struct {
		Hidden                   *dbSearchMatchOptions `json:"-" yaml:"-" mapstructure:"-"`
		*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
	}

	return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}

func runDBSearchMatches(opts dbSearchMatchOptions) error {
	client, err := distribution.NewClient(opts.ToClientConfig())
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}

	curator, err := installation.NewCurator(opts.ToCuratorConfig(), client)
	if err != nil {
		return fmt.Errorf("unable to create curator: %w", err)
	}

	reader, err := curator.Reader()
	if err != nil {
		return fmt.Errorf("unable to get providers: %w", err)
	}

	if err := validateProvidersFilter(reader, opts.Vulnerability.Providers); err != nil {
		return err
	}

	rows, queryErr := dbsearch.FindMatches(reader, dbsearch.AffectedPackagesOptions{
		Vulnerability:         opts.Vulnerability.Specs,
		Package:               opts.Package.PkgSpecs,
		CPE:                   opts.Package.CPESpecs,
		OS:                    opts.OS.Specs,
		AllowBroadCPEMatching: opts.Package.AllowBroadCPEMatching,
		RecordLimit:           opts.Bounds.RecordLimit,
		FixedStates:           opts.Vulnerability.FixedState,
	})
	if queryErr != nil {
		if !errors.Is(queryErr, v6.ErrLimitReached) {
			return queryErr
		}
	}

	sb := &strings.Builder{}
	err = presentDBSearchMatches(opts.Format.Output, rows, sb)
	rep := sb.String()
	if rep != "" {
		bus.Report(rep)
	}
	if err != nil {
		return fmt.Errorf("unable to present search results: %w", err)
	}

	return queryErr
}

func presentDBSearchMatches(outputFormat string, structuredRows dbsearch.Matches, output io.Writer) error {
	switch outputFormat {
	case tableOutputFormat:
		if len(structuredRows) == 0 {
			bus.Notify("No results found")
			return nil
		}
		rows := renderDBSearchPackagesTableRows(structuredRows.Flatten())

		table := newTable(output, []string{"Vulnerability", "Package", "Ecosystem", "Namespace", "Version Constraint"})

		if err := table.Bulk(rows); err != nil {
			return fmt.Errorf("failed to add table rows: %+v", err)
		}
		return table.Render()
	case jsonOutputFormat:
		if structuredRows == nil {
			// always allocate the top level collection
			structuredRows = dbsearch.Matches{}
		}
		enc := json.NewEncoder(output)
		enc.SetEscapeHTML(false)
		enc.SetIndent("", " ")
		if err := enc.Encode(structuredRows); err != nil {
			return fmt.Errorf("failed to encode diff information: %+v", err)
		}
	default:
		return fmt.Errorf("unsupported output format: %s", outputFormat)
	}
	return nil
}

func renderDBSearchPackagesTableRows(structuredRows []dbsearch.AffectedPackage) [][]string {
	var rows [][]string
	for _, rr := range structuredRows {
		var pkgOrCPE, ecosystem string
		if rr.Package != nil {
			pkgOrCPE = rr.Package.Name
			ecosystem = rr.Package.Ecosystem
		} else if rr.CPE != nil {
			pkgOrCPE = rr.CPE.String()
			ecosystem = rr.CPE.TargetSoftware
		}

		var ranges []string
		for _, ra := range rr.Detail.Ranges {
			ranges = append(ranges, ra.Version.Constraint)
		}
		rangeStr := strings.Join(ranges, " || ")
		rows = append(rows, []string{rr.Vulnerability.ID, pkgOrCPE, ecosystem, mimicV5Namespace(rr), rangeStr})
	}

	// sort rows by each column
	sort.Slice(rows, func(i, j int) bool {
		for k := range rows[i] {
			if rows[i][k] != rows[j][k] {
				return rows[i][k] < rows[j][k]
			}
		}
		return false
	})

	return rows
}

func mimicV5Namespace(row dbsearch.AffectedPackage) string {
	namespace := v6.MimicV5Namespace(&row.Vulnerability.Model, row.Model)

	if row.Model != nil && row.Model.OperatingSystem != nil && row.Model.OperatingSystem.Channel != "" {
		return namespace + ":" + row.Model.OperatingSystem.Channel
	}

	return namespace
}


================================================
FILE: cmd/grype/cli/commands/db_search_test.go
================================================
package commands

import (
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
	"github.com/stretchr/testify/require"

	"github.com/anchore/grype/cmd/grype/cli/commands/internal/dbsearch"
	"github.com/anchore/grype/cmd/grype/cli/options"
	v6 "github.com/anchore/grype/grype/db/v6"
)

func TestDBSearchMatchOptionsApplyArgs(t *testing.T) {
	testCases := []struct {
		name               string
		args               []string
		expectedPackages   []string
		expectedVulnIDs    []string
		expectedErrMessage string
	}{
		{
			name:             "empty arguments",
			args:             []string{},
			expectedPackages: []string{},
			expectedVulnIDs:  []string{},
		},
		{
			name: "valid cpe",
			args: []string{"cpe:2.3:a:vendor:product:1.0:*:*:*:*:*:*:*"},
			expectedPackages: []string{
				"cpe:2.3:a:vendor:product:1.0:*:*:*:*:*:*:*",
			},
			expectedVulnIDs: []string{},
		},
		{
			name: "valid purl",
			args: []string{"pkg:npm/package-name@1.0.0"},
			expectedPackages: []string{
				"pkg:npm/package-name@1.0.0",
			},
			expectedVulnIDs: []string{},
		},
		{
			name:             "valid vulnerability IDs",
			args:             []string{"CVE-2023-0001", "GHSA-1234", "ALAS-2023-1234"},
			expectedPackages: []string{},
			expectedVulnIDs: []string{
				"CVE-2023-0001",
				"GHSA-1234",
				"ALAS-2023-1234",
			},
		},
		{
			name: "mixed package and vulns",
			args: []string{"cpe:2.3:a:vendor:product:1.0:*:*:*:*:*:*:*", "CVE-2023-0001"},
			expectedPackages: []string{
				"cpe:2.3:a:vendor:product:1.0:*:*:*:*:*:*:*",
			},
			expectedVulnIDs: []string{
				"CVE-2023-0001",
			},
		},
		{
			name: "plain package name",
			args: []string{"package-name"},
			expectedPackages: []string{
				"package-name",
			},
			expectedVulnIDs: []string{},
		},
		{
			name: "invalid PostLoad error for Package",
			args: []string{"pkg:npm/package-name@1.0.0", "cpe:invalid"},
			expectedPackages: []string{
				"pkg:npm/package-name@1.0.0",
			},
			expectedErrMessage: "invalid CPE",
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			opts := &dbSearchMatchOptions{
				Vulnerability: options.DBSearchVulnerabilities{},
				Package:       options.DBSearchPackages{},
			}

			err := opts.applyArgs(tc.args)

			if tc.expectedErrMessage != "" {
				require.Error(t, err)
				require.Contains(t, err.Error(), tc.expectedErrMessage)
				return
			}

			require.NoError(t, err)
			if d := cmp.Diff(tc.expectedPackages, opts.Package.Packages, cmpopts.EquateEmpty()); d != "" {
				t.Errorf("unexpected package specifiers: %s", d)
			}
			if d := cmp.Diff(tc.expectedVulnIDs, opts.Vulnerability.VulnerabilityIDs, cmpopts.EquateEmpty()); d != "" {
				t.Errorf("unexpected vulnerability specifiers: %s", d)
			}
		})
	}
}

func TestMimicV5Namespace(t *testing.T) {
	tests := []struct {
		name      string
		osName    string
		osChannel string
		expected  string
	}{
		{
			name:      "distro namespace without channel",
			osName:    "redhat",
			osChannel: "",
			expected:  "redhat:distro:redhat:8",
		},
		{
			name:      "distro namespace with channel",
			osName:    "redhat",
			osChannel: "eus",
			expected:  "redhat:distro:redhat:8:eus",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			row := dbsearch.AffectedPackage{
				Vulnerability: dbsearch.VulnerabilityInfo{
					Model: v6.VulnerabilityHandle{
						Provider: &v6.Provider{ID: "rhel"},
					},
				},
				AffectedPackageInfo: dbsearch.AffectedPackageInfo{
					Model: &v6.AffectedPackageHandle{
						OperatingSystem: &v6.OperatingSystem{
							Name:         tt.osName,
							MajorVersion: "8",
							MinorVersion: "6",
							Channel:      tt.osChannel,
						},
						Package: &v6.Package{
							Name:      "test-package",
							Ecosystem: "rpm",
						},
					},
				},
			}

			result := mimicV5Namespace(row)
			require.Equal(t, tt.expected, result)
		})
	}
}


================================================
FILE: cmd/grype/cli/commands/db_search_vuln.go
================================================
package commands

import (
	"encoding/json"
	"fmt"
	"io"
	"sort"
	"strings"
	"time"

	"github.com/hashicorp/go-multierror"
	"github.com/scylladb/go-set/strset"
	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/commands/internal/dbsearch"
	"github.com/anchore/grype/cmd/grype/cli/options"
	v6 "github.com/anchore/grype/grype/db/v6"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/grype/db/v6/installation"
	"github.com/anchore/grype/internal/bus"
)

type dbSearchVulnerabilityOptions struct {
	Format        options.DBSearchFormat          `yaml:",inline" mapstructure:",squash"`
	Vulnerability options.DBSearchVulnerabilities `yaml:",inline" mapstructure:",squash"`
	Bounds        options.DBSearchBounds          `yaml:",inline" mapstructure:",squash"`

	options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}

func DBSearchVulnerabilities(app clio.Application) *cobra.Command {
	opts := &dbSearchVulnerabilityOptions{
		Format: options.DefaultDBSearchFormat(),
		Vulnerability: options.DBSearchVulnerabilities{
			UseVulnIDFlag: false, // we input this through the args
		},
		Bounds:          options.DefaultDBSearchBounds(),
		DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
	}

	cmd := &cobra.Command{
		Use:     "vuln ID...",
		Aliases: []string{"vulnerability", "vulnerabilities", "vulns"},
		Short:   "Search for vulnerabilities within the DB (supports DB schema v6+ only)",
		Args: func(_ *cobra.Command, args []string) error {
			if len(args) == 0 {
				return fmt.Errorf("must specify at least one vulnerability ID")
			}
			opts.Vulnerability.VulnerabilityIDs = args
			return nil
		},
		RunE: func(_ *cobra.Command, _ []string) (err error) {
			return runDBSearchVulnerabilities(*opts)
		},
	}

	// prevent from being shown in the grype config
	type configWrapper struct {
		Hidden                   *dbSearchVulnerabilityOptions `json:"-" yaml:"-" mapstructure:"-"`
		*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
	}

	return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}

func runDBSearchVulnerabilities(opts dbSearchVulnerabilityOptions) error {
	client, err := distribution.NewClient(opts.ToClientConfig())
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}

	c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
	if err != nil {
		return fmt.Errorf("unable to create curator: %w", err)
	}

	reader, err := c.Reader()
	if err != nil {
		return fmt.Errorf("unable to get providers: %w", err)
	}

	if err := validateProvidersFilter(reader, opts.Vulnerability.Providers); err != nil {
		return err
	}

	rows, err := dbsearch.FindVulnerabilities(reader, dbsearch.VulnerabilitiesOptions{
		Vulnerability: opts.Vulnerability.Specs,
		RecordLimit:   opts.Bounds.RecordLimit,
	})
	if err != nil {
		return err
	}

	sb := &strings.Builder{}
	err = presentDBSearchVulnerabilities(opts.Format.Output, rows, sb)
	rep := sb.String()
	if rep != "" {
		bus.Report(rep)
	}

	return err
}

func validateProvidersFilter(reader v6.Reader, providers []string) error {
	if len(providers) == 0 {
		return nil
	}
	availableProviders, err := reader.AllProviders()
	if err != nil {
		return fmt.Errorf("unable to get providers: %w", err)
	}
	activeProviders := strset.New()
	for _, p := range availableProviders {
		activeProviders.Add(p.ID)
	}

	provSet := strset.New(providers...)

	diff := strset.Difference(provSet, activeProviders)
	diffList := diff.List()
	sort.Strings(diffList)
	var errs error
	for _, p := range diffList {
		errs = multierror.Append(errs, fmt.Errorf("provider not found: %q", p))
	}

	return errs
}

func presentDBSearchVulnerabilities(outputFormat string, structuredRows []dbsearch.Vulnerability, output io.Writer) error {
	switch outputFormat {
	case tableOutputFormat:
		if len(structuredRows) == 0 {
			bus.Notify("No results found")
			return nil
		}

		rows := renderDBSearchVulnerabilitiesTableRows(structuredRows)

		table := newTable(output, []string{"ID", "Provider", "Published", "Severity", "Reference"})

		if err := table.Bulk(rows); err != nil {
			return fmt.Errorf("failed to add table rows: %+v", err)
		}
		return table.Render()
	case jsonOutputFormat:
		if structuredRows == nil {
			// always allocate the top level collection
			structuredRows = []dbsearch.Vulnerability{}
		}
		enc := json.NewEncoder(output)
		enc.SetEscapeHTML(false)
		enc.SetIndent("", " ")
		if err := enc.Encode(structuredRows); err != nil {
			return fmt.Errorf("failed to encode diff information: %+v", err)
		}
	default:
		return fmt.Errorf("unsupported output format: %s", outputFormat)
	}
	return nil
}

func renderDBSearchVulnerabilitiesTableRows(structuredRows []dbsearch.Vulnerability) [][]string {
	type row struct {
		Vuln                    string
		ProviderWithoutVersions string
		PublishedDate           string
		Severity                string
		Reference               string
	}

	versionsByRow := make(map[row][]string)
	for _, rr := range structuredRows {
		r := row{
			Vuln:                    rr.ID,
			ProviderWithoutVersions: rr.Provider,
			PublishedDate:           getDate(rr.PublishedDate),
			Severity:                rr.Severity,
			Reference:               getPrimaryReference(rr.References),
		}
		versionsByRow[r] = append(versionsByRow[r], getOSVersions(rr.OperatingSystems)...)
	}

	var rows [][]string
	for r, versions := range versionsByRow {
		prov := r.ProviderWithoutVersions
		if len(versions) > 0 {
			sort.Strings(versions)
			prov = fmt.Sprintf("%s (%s)", r.ProviderWithoutVersions, strings.Join(versions, ", "))
		}
		rows = append(rows, []string{r.Vuln, prov, r.PublishedDate, r.Severity, r.Reference})
	}

	// sort rows by each column
	sort.Slice(rows, func(i, j int) bool {
		for k := range rows[i] {
			if rows[i][k] != rows[j][k] {
				return rows[i][k] < rows[j][k]
			}
		}
		return false
	})

	return rows
}

func getOSVersions(oss []dbsearch.OperatingSystem) []string {
	var versions []string
	for _, os := range oss {
		versions = append(versions, os.Version)
	}
	return versions
}

func getPrimaryReference(refs []v6.Reference) string {
	if len(refs) > 0 {
		return refs[0].URL
	}

	return ""
}

func getDate(t *time.Time) string {
	if t != nil && !t.IsZero() {
		return t.Format("2006-01-02")
	}
	return ""
}


================================================
FILE: cmd/grype/cli/commands/db_search_vuln_test.go
================================================
package commands

import (
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"github.com/anchore/grype/cmd/grype/cli/commands/internal/dbsearch"
	v6 "github.com/anchore/grype/grype/db/v6"
)

func TestGetOSVersions(t *testing.T) {
	tests := []struct {
		name     string
		input    []dbsearch.OperatingSystem
		expected []string
	}{
		{
			name:     "empty list",
			input:    []dbsearch.OperatingSystem{},
			expected: nil,
		},
		{
			name: "single os",
			input: []dbsearch.OperatingSystem{
				{
					Name:    "debian",
					Version: "11",
				},
			},
			expected: []string{"11"},
		},
		{
			name: "multiple os",
			input: []dbsearch.OperatingSystem{
				{
					Name:    "ubuntu",
					Version: "16.04",
				},
				{
					Name:    "ubuntu",
					Version: "22.04",
				},
				{
					Name:    "ubuntu",
					Version: "24.04",
				},
			},
			expected: []string{"16.04", "22.04", "24.04"},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			actual := getOSVersions(tt.input)
			require.Equal(t, tt.expected, actual)
		})
	}
}

func TestGetPrimaryReference(t *testing.T) {
	tests := []struct {
		name     string
		input    []v6.Reference
		expected string
	}{
		{
			name:     "empty list",
			input:    []v6.Reference{},
			expected: "",
		},
		{
			name: "single reference",
			input: []v6.Reference{
				{
					URL:  "https://example.com/vuln/123",
					Tags: []string{"primary"},
				},
			},
			expected: "https://example.com/vuln/123",
		},
		{
			name: "multiple references",
			input: []v6.Reference{
				{
					URL:  "https://example.com/vuln/123",
					Tags: []string{"primary"},
				},
				{
					URL:  "https://example.com/advisory/123",
					Tags: []string{"secondary"},
				},
			},
			expected: "https://example.com/vuln/123",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			actual := getPrimaryReference(tt.input)
			require.Equal(t, tt.expected, actual)
		})
	}
}

func TestGetDate(t *testing.T) {
	tests := []struct {
		name     string
		input    *time.Time
		expected string
	}{
		{
			name:     "nil time",
			input:    nil,
			expected: "",
		},
		{
			name:     "zero time",
			input:    &time.Time{},
			expected: "",
		},
		{
			name:     "valid time",
			input:    timePtr(time.Date(2023, 5, 15, 0, 0, 0, 0, time.UTC)),
			expected: "2023-05-15",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			actual := getDate(tt.input)
			require.Equal(t, tt.expected, actual)
		})
	}
}

func timePtr(t time.Time) *time.Time {
	return &t
}


================================================
FILE: cmd/grype/cli/commands/db_status.go
================================================
package commands

import (
	"encoding/json"
	"fmt"
	"io"
	"os"
	"time"

	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/options"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/grype/db/v6/installation"
	"github.com/anchore/grype/grype/vulnerability"
)

type dbStatusOptions struct {
	Output                  string `yaml:"output" json:"output" mapstructure:"output"`
	options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}

var _ clio.FlagAdder = (*dbStatusOptions)(nil)

func (d *dbStatusOptions) AddFlags(flags clio.FlagSet) {
	flags.StringVarP(&d.Output, "output", "o", "format to display results (available=[text, json])")
}

func DBStatus(app clio.Application) *cobra.Command {
	opts := &dbStatusOptions{
		Output:          textOutputFormat,
		DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
	}

	cmd := &cobra.Command{
		Use:     "status",
		Short:   "Display database status and metadata",
		Args:    cobra.ExactArgs(0),
		PreRunE: disableUI(app),
		RunE: func(_ *cobra.Command, _ []string) error {
			return runDBStatus(*opts)
		},
	}

	// prevent from being shown in the grype config
	type configWrapper struct {
		Hidden                   *dbStatusOptions `json:"-" yaml:"-" mapstructure:"-"`
		*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
	}

	return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}

func runDBStatus(opts dbStatusOptions) error {
	client, err := distribution.NewClient(opts.ToClientConfig())
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}
	c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}

	status := c.Status()

	if err := presentDBStatus(opts.Output, os.Stdout, status); err != nil {
		return fmt.Errorf("failed to present db status information: %+v", err)
	}

	return status.Error
}

func presentDBStatus(format string, writer io.Writer, status vulnerability.ProviderStatus) error {
	switch format {
	case textOutputFormat:
		fmt.Fprintln(writer, "Path:     ", status.Path)
		fmt.Fprintln(writer, "Schema:   ", status.SchemaVersion)
		fmt.Fprintln(writer, "Built:    ", status.Built.Format(time.RFC3339))
		if status.From != "" {
			fmt.Fprintln(writer, "From:     ", status.From)
		}
		fmt.Fprintln(writer, "Status:   ", renderStoreValidation(status))
	case jsonOutputFormat:
		enc := json.NewEncoder(writer)
		enc.SetEscapeHTML(false)
		enc.SetIndent("", " ")
		if err := enc.Encode(&status); err != nil {
			return fmt.Errorf("failed to db status information: %+v", err)
		}
	default:
		return fmt.Errorf("unsupported output format: %s", format)
	}

	return nil
}

func renderStoreValidation(status vulnerability.ProviderStatus) string {
	if status.Error != nil {
		return "invalid"
	}
	return "valid"
}


================================================
FILE: cmd/grype/cli/commands/db_status_test.go
================================================
package commands

import (
	"bytes"
	"errors"
	"strings"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/anchore/grype/grype/vulnerability"
)

func TestPresentDBStatus(t *testing.T) {
	validStatus := vulnerability.ProviderStatus{
		Path:          "/Users/test/Library/Caches/grype/db/6/vulnerability.db",
		From:          "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8",
		SchemaVersion: "6.0.0",
		Built:         time.Date(2024, 11, 27, 14, 43, 17, 0, time.UTC),
		Error:         nil,
	}

	invalidStatus := vulnerability.ProviderStatus{
		Path:          "/Users/test/Library/Caches/grype/db/6/vulnerability.db",
		From:          "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8",
		SchemaVersion: "6.0.0",
		Built:         time.Date(2024, 11, 27, 14, 43, 17, 0, time.UTC),
		Error:         errors.New("checksum mismatch"),
	}

	tests := []struct {
		name         string
		format       string
		status       vulnerability.ProviderStatus
		expectedText string
		expectedErr  require.ErrorAssertionFunc
	}{
		{
			name:   "valid status, text format",
			format: textOutputFormat,
			status: validStatus,
			expectedText: `Path:      /Users/test/Library/Caches/grype/db/6/vulnerability.db
Schema:    6.0.0
Built:     2024-11-27T14:43:17Z
From:      https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8
Status:    valid
`,
			expectedErr: require.NoError,
		},
		{
			name:   "invalid status, text format",
			format: textOutputFormat,
			status: invalidStatus,
			expectedText: `Path:      /Users/test/Library/Caches/grype/db/6/vulnerability.db
Schema:    6.0.0
Built:     2024-11-27T14:43:17Z
From:      https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8
Status:    invalid
`,
			expectedErr: require.NoError,
		},
		{
			name:   "valid status, JSON format",
			format: jsonOutputFormat,
			status: validStatus,
			expectedText: `{
 "schemaVersion": "6.0.0",
 "from": "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8",
 "built": "2024-11-27T14:43:17Z",
 "path": "/Users/test/Library/Caches/grype/db/6/vulnerability.db",
 "valid": true
}
`,
			expectedErr: require.NoError,
		},
		{
			name:   "invalid status, JSON format",
			format: jsonOutputFormat,
			status: invalidStatus,
			expectedText: `{
 "schemaVersion": "6.0.0",
 "from": "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8",
 "built": "2024-11-27T14:43:17Z",
 "path": "/Users/test/Library/Caches/grype/db/6/vulnerability.db",
 "valid": false,
 "error": "checksum mismatch"
}
`,
			expectedErr: require.NoError,
		},
		{
			name:        "unsupported format",
			format:      "unsupported",
			status:      validStatus,
			expectedErr: requireErrorContains("unsupported output format"),
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if tt.expectedErr == nil {
				tt.expectedErr = require.NoError
			}
			writer := &bytes.Buffer{}

			err := presentDBStatus(tt.format, writer, tt.status)
			tt.expectedErr(t, err)
			if err != nil {
				return
			}

			assert.Equal(t, strings.TrimSpace(tt.expectedText), strings.TrimSpace(writer.String()))
		})
	}
}


================================================
FILE: cmd/grype/cli/commands/db_update.go
================================================
package commands

import (
	"fmt"

	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/cmd/grype/cli/options"
	"github.com/anchore/grype/grype/db/v6/distribution"
	"github.com/anchore/grype/grype/db/v6/installation"
	"github.com/anchore/grype/internal/bus"
	"github.com/anchore/grype/internal/log"
)

func DBUpdate(app clio.Application) *cobra.Command {
	opts := options.DefaultDatabaseCommand(app.ID())

	cmd := &cobra.Command{
		Use:   "update",
		Short: "Download and install the latest vulnerability database",
		Args:  cobra.ExactArgs(0),
		PreRunE: func(_ *cobra.Command, _ []string) error {
			// DB commands should not opt into the low-pass check filter
			opts.DB.MaxUpdateCheckFrequency = 0
			return nil
		},
		RunE: func(_ *cobra.Command, _ []string) error {
			return runDBUpdate(*opts)
		},
	}

	// prevent from being shown in the grype config
	type configWrapper struct {
		*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
	}

	return app.SetupCommand(cmd, &configWrapper{opts})
}

func runDBUpdate(opts options.DatabaseCommand) error {
	cfg := opts.ToClientConfig()
	// we need to have this set to true to force the update call to try to update
	// regardless of what the user provided in order for update checks to fail
	if !cfg.RequireUpdateCheck {
		log.Warn("overriding db update check")
		cfg.RequireUpdateCheck = true
	}
	client, err := distribution.NewClient(cfg)
	if err != nil {
		return fmt.Errorf("unable to create distribution client: %w", err)
	}
	c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
	if err != nil {
		return fmt.Errorf("unable to create curator: %w", err)
	}

	updated, err := c.Update()
	if err != nil {
		return fmt.Errorf("unable to update vulnerability database: %w", err)
	}

	result := "No vulnerability database update available\n"
	if updated {
		result = "Vulnerability database updated to latest version!\n"
	}

	log.Debugf("completed db update check with result: %s", result)

	bus.Report(result)

	return nil
}


================================================
FILE: cmd/grype/cli/commands/explain.go
================================================
package commands

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/spf13/cobra"

	"github.com/anchore/clio"
	"github.com/anchore/grype/grype/presenter/explain"
	"github.com/anchore/grype/grype/presenter/models"
	"github.com/anchore/grype/internal"
	"github.com/anchore/grype/internal/log"
)

type explainOptions struct {
	CVEIDs []string `yaml:"cve-ids" json:"cve-ids" mapstructure:"cve-ids"`
}

var _ clio.FlagAdder = (*explainOptions)(nil)

func (d *explainOptions) AddFlags(flags clio.FlagSet) {
	flags.StringArrayVarP(&d.CVEIDs, "id", "", "CVE IDs to explain")
}

func Explain(app clio.Application) *cobra.Command {
	opts := &explainOptions{}

	cmd := &cobra.Command{
		Use:     "explain --id [VULNERABILITY ID]",
		Short:   "Ask grype to explain a set of findings",
		PreRunE: disableUI(app),
		RunE: func(_ *cobra.Command, _ []string) error {
			log.Warn("grype explain is a prototype feature and is subject to change")
			isStdinPipeOrRedirect, err := internal.IsStdinPipeOrRedirect()
			if err != nil {
				log.Warnf("unable to determine if there is piped input: %+v", err)
				isStdinPipeOrRedirect = false
			}
			if isStdinPipeOrRedirect {
				// TODO: eventually detect different types of input; for now assume grype json
				var parseResult models.Document
				decoder := json.NewDecoder(os.Stdin)
				err := decoder.Decode(&parseResult)
				if err != nil {
					return fmt.Errorf("unable to parse piped input: %+v", err)
				}
				explainer := explain.NewVulnerabilityExplainer(os.Stdout, &parseResult)
				return explainer.ExplainByID(opts.CVEIDs)
			}
			// perform a scan, then explain requested CVEs
			// TODO: implement
			return fmt.Errorf("requires grype json on stdin, please run 'grype -o json ... | grype explain ...'")
		},
	}

	// prevent from being shown in the grype config
	type configWrapper struct {
		Opts *explainOptions `json:"-" yaml:"-" mapstructure:"-"`
	}

	return app.SetupCommand(cmd, &configWrapper{opts})
}


================================================
FILE: cmd/grype/cli/commands/internal/dbsearch/affected_packages.go
================================================
package dbsearch

import (
	"errors"
	"fmt"

	v6 "github.com/anchore/grype/grype/db/v6"
	"github.com/anchore/grype/internal/log"
	"github.com/anchore/syft/syft/cpe"
)

var ErrNoSearchCriteria = errors.New("must provide at least one of vulnerability or package to search for")

// AffectedPackage represents a package affected by a vulnerability
type AffectedPackage struct {
	// Vulnerability is the core advisory record for a single known vulnerability from a specific provider.
	Vulnerability VulnerabilityInfo `json:"vulnerability"`

	// AffectedPackageInfo is the detailed information about the affected package
	AffectedPackageInfo `json:",inline"`
}

type AffectedPackageInfo struct {
	// TODO: remove this when namespace is no longer used
	Model *v6.AffectedPackageHandle `json:"-"` // tracking package handle info is necessary for namespace lookup (note CPE handles are not tracked)

	// OS identifies the operating system release that the affected package is released for
	OS *OperatingSystem `json:"os,omitempty"`

	// Package identifies the name of the package in a specific ecosystem affected by the vulnerability
	Package *Package `json:"package,omitempty"`

	// CPE is a Common Platform Enumeration that is affected by the vulnerability
	CPE *CPE `json:"cpe,omitempty"`

	// Namespace is a holdover value from the v5 DB schema that combines provider and search methods into a single value
	//
	// Deprecated: this field will be removed in a later version of the search schema
	Namespace string `json:"namespace"`

	// Detail is the detailed information about the affected package
	Detail v6.PackageBlob `json:"detail"`
}

// Package represents a package name within a known ecosystem, such as "python" or "golang".
type Package struct {
	// Name is the name of the package within the ecosystem
	Name string `json:"name"`

	// Ecosystem is the tooling and language ecosystem that the package is released within
	Ecosystem string `json:"ecosystem"`
}

// CPE is a Common Platform Enumeration that identifies a package
type CPE v6.Cpe

func (c *CPE) MarshalJSON() ([]byte, error) {
	return []byte(fmt.Sprintf("%q", c.String())), nil
}

func (c *CPE) String() string {
	if c == nil {
		return ""
	}

	return v6.Cpe(*c).String()
}

type AffectedPackagesOptions struct {
	Vulnerability         v6.VulnerabilitySpecifiers
	Package               v6.PackageSpecifiers
	CPE                   v6.PackageSpecifiers
	OS                    v6.OSSpecifiers
	AllowBroadCPEMatching bool
	RecordLimit           int
	FixedStates           []string
}

type affectedPackageWithDecorations struct {
	v6.AffectedPackageHandle
	vulnerabilityDecorations
}

func (a *affectedPackageWithDecorations) getCVEs() []string {
	if a == nil {
		return nil
	}
	return getCVEs(a.Vulnerability)
}

type affectedCPEWithDecorations struct {
	v6.AffectedCPEHandle
	vulnerabilityDecorations
}

func (a *affectedCPEWithDecorations) getCVEs() []string {
	if a == nil {
		return nil
	}
	return getCVEs(a.Vulnerability)
}

func newAffectedPackageRows(affectedPkgs []affectedPackageWithDecorations, affectedCPEs []affectedCPEWithDecorations) (rows []AffectedPackage) {
	for i := range affectedPkgs {
		pkg := affectedPkgs[i]
		var detail v6.PackageBlob
		if pkg.BlobValue != nil {
			detail = *pkg.BlobValue
		}
		if pkg.Vulnerability == nil {
			log.Errorf("affected package record missing vulnerability: %+v", pkg)
			continue
		}

		rows = append(rows, AffectedPackage{
			Vulnerability: newVulnerabilityInfo(*pkg.Vulnerability, pkg.vulnerabilityDecorations),
			AffectedPackageInfo: AffectedPackageInfo{
				Model:     &pkg.AffectedPackageHandle,
				OS:        toOS(pkg.OperatingSystem),
				Package:   toPackage(pkg.Package),
				Namespace: v6.MimicV5Namespace(pkg.Vulnerability, &pkg.AffectedPackageHandle),
				Detail:    detail,
			},
		})
	}

	for _, ac := range affectedCPEs {
		var detail v6.PackageBlob
		if ac.BlobValue != nil {
			detail = *ac.BlobValue
		}
		if ac.Vulnerability == nil {
			log.Errorf("affected CPE record missing vulnerability: %+v", ac)
			continue
		}

		var c *CPE
		if ac.CPE != nil {
			cv := CPE(*ac.CPE)
			c = &cv
		}

		rows = append(rows, AffectedPackage{
			// tracking model information is not possible with CPE handles
			Vulnerability: newVulnerabilityInfo(*ac.Vulnerability, ac.vulnerabilityDecorations),
			AffectedPackageInfo: AffectedPackageInfo{
				CPE:       c,
				Namespace: v6.MimicV5Namespace(ac.Vulnerability, nil), // no affected package will default to NVD
				Detail:    detail,
			},
		})
	}

	return rows
}

func toPackage(pkg *v6.Package) *Package {
	if pkg == nil {
		return nil
	}
	return &Package{
		Name:      pkg.Name,
		Ecosystem: pkg.Ecosystem,
	}
}

func toOS(os *v6.OperatingSystem) *OperatingSystem {
	if os == nil {
		return nil
	}

	return &OperatingSystem{
		Name:    os.Name,
		Version: os.Version(),
	}
}

func FindAffectedPackages(reader interface {
	v6.AffectedPackageStoreReader
	v6.AffectedCPEStoreReader
	v6.VulnerabilityDecoratorStoreReader
}, criteria AffectedPackagesOptions,
) ([]AffectedPackage, error) {
	allAffectedPkgs, allAffectedCPEs, err := findAffectedPackages(reader, criteria)
	if err != nil {
		return nil, err
	}

	if len(criteria.FixedStates) > 0 {
		allAffectedPkgs = filterByFixedStateForPackages(allAffectedPkgs, criteria.FixedStates)
		allAffectedCPEs = filterByFixedStateForCPEs(allAffectedCPEs, criteria.FixedStates)
	}

	return newAffectedPackageRows(allAffectedPkgs, allAffectedCPEs), nil
}

func findAffectedPackages(reader interface { //nolint:funlen,gocognit
	v6.AffectedPackageStoreReader
	v6.AffectedCPEStoreReader
	v6.VulnerabilityDecoratorStoreReader
}, config AffectedPackagesOptions,
) ([]affectedPackageWithDecorations, []affectedCPEWithDecorations, error) {
	var allAffectedPkgs []affectedPackageWithDecorations
	var allAffectedCPEs []affectedCPEWithDecorations

	pkgSpecs := config.Package
	cpeSpecs := config.CPE
	osSpecs := config.OS
	vulnSpecs := config.Vulnerability

	if config.RecordLimit == 0 {
		log.Warn("no record limit set! For queries with large result sets this may result in performance issues")
	}

	if len(vulnSpecs) == 0 && len(pkgSpecs) == 0 && len(cpeSpecs) == 0 {
		return nil, nil, ErrNoSearchCriteria
	}

	// don't allow for searching by any package AND any CPE AND any vulnerability AND any OS. Since these searches
	// are oriented by primarily package, we only want to have ANY package/CPE when there is a vulnerability or OS specified.
	if len(vulnSpecs) > 0 || !osSpecs.IsAny() {
		if len(pkgSpecs) == 0 {
			pkgSpecs = []*v6.PackageSpecifier{v6.AnyPackageSpecified}
		}

		if len(cpeSpecs) == 0 {
			cpeSpecs = []*v6.PackageSpecifier{v6.AnyPackageSpecified}
		}
	}

	// we have multiple return points that return actual values, using a defer to decorate any given results
	// ensures that all paths are handled the same way.
	defer func() {
		for i := range allAffectedPkgs {
			decorateVulnerabilities(reader, &allAffectedPkgs[i])
		}

		for i := range allAffectedCPEs {
			decorateVulnerabilities(reader, &allAffectedCPEs[i])
		}
	}()

	for i := range pkgSpecs {
		pkgSpec := pkgSpecs[i]

		log.WithFields("vuln", vulnSpecs, "pkg", pkgSpec, "os", osSpecs).Debug("searching for affected packages")

		affectedPkgs, err := reader.GetAffectedPackages(pkgSpec, &v6.GetPackageOptions{
			PreloadOS:             true,
			PreloadPackage:        true,
			PreloadPackageCPEs:    false,
			PreloadVulnerability:  true,
			PreloadBlob:           true,
			OSs:                   osSpecs,
			Vulnerabilities:       vulnSpecs,
			AllowBroadCPEMatching: config.AllowBroadCPEMatching,
			Limit:                 config.RecordLimit,
		})

		for i := range affectedPkgs {
			allAffectedPkgs = append(allAffectedPkgs, affectedPackageWithDecorations{
				AffectedPackageHandle: affectedPkgs[i],
			})
		}

		if err != nil {
			if errors.Is(err, v6.ErrLimitReached) {
				return allAffectedPkgs, allAffectedCPEs, err
			}
			return nil, nil, fmt.Errorf("unable to get affected packages for %s: %w", vulnSpecs, err)
		}
	}

	if osSpecs.IsAny() {
		for i := range cpeSpecs {
			cpeSpec := cpeSpecs[i]
			var searchCPE *cpe.Attributes
			if cpeSpec != nil {
				searchCPE = cpeSpec.CPE
			}

			log.WithFields("vuln", vulnSpecs, "cpe", cpeSpec).Debug("searching for affected packages")

			affectedCPEs, err := reader.GetAffectedCPEs(searchCPE, &v6.GetCPEOptions{
				PreloadCPE:            true,
				PreloadVulnerability:  true,
				PreloadBlob:           true,
				Vulnerabilities:       vulnSpecs,
				AllowBroadCPEMatching: config.AllowBroadCPEMatching,
				Limit:                 config.RecordLimit,
			})

			for i := range affectedCPEs {
				allAffectedCPEs = append(allAffectedCPEs, affectedCPEWithDecorations{
					AffectedCPEHandle: affectedCPEs[i],
				})
			}

			if err != nil {
				if errors.Is(err, v6.ErrLimitReached) {
					return allAffectedPkgs, allAffectedCPEs, err
				}
				return nil, nil, fmt.Errorf("unable to get affected cpes for %s: %w", vulnSpecs, err)
			}
		}
	}

	return allAffectedPkgs, allAffectedCPEs, nil
}


================================================
FILE: cmd/grype/cli/commands/internal/dbsearch/affected_packages_test.go
================================================
package dbsearch

import (
	"bytes"
	"encoding/json"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"

	v6 "github.com/anchore/grype/grype/db/v6"
	"github.com/anchore/syft/syft/cpe"
)

func TestAffectedPackageTableRowMarshalJSON(t *testing.T) {
	row := AffectedPackage{
		Vulnerability: VulnerabilityInfo{
			VulnerabilityBlob: v6.VulnerabilityBlob{
				ID:          "CVE-1234-5678",
				Description: "Test vulnerability",
			},
			Provider:      "provider1",
			Status:        "active",
			PublishedDate: ptr(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)),
			ModifiedDate:  ptr(time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC)),
			KnownExploited: []KnownExploited{
				{
					CVE:                        "CVE-1234-5678",
					VendorProject:              "LinuxFoundation",
					Product:                    "Linux",
					DateAdded:                  "2025-02-02",
					RequiredAction:             "Yes",
					DueDate:                    "2025-02-02",
					KnownRansomwareCampaignUse: "Known",
					Notes:                      "note!",
					URLs:                       []string{"https://example.com"},
					CWEs:                       []string{"CWE-1234"},
				},
			},
			EPSS: []EPSS{
				{
					CVE:        "CVE-1234-5678",
					EPSS:       0.893,
					Percentile: 0.99,
					Date:       "2025-02-24",
				},
			},
		},
		AffectedPackageInfo: AffectedPackageInfo{
			Package:   &Package{Name: "pkg1", Ecosystem: "ecosystem1"},
			CPE:       &CPE{Part: "a", Vendor: "vendor1", Product: "product1"},
			Namespace: "namespace1",
			Detail: v6.PackageBlob{
				CVEs: []string{"CVE-1234-5678"},
				Qualifiers: &v6.PackageQualifiers{
					RpmModularity: ptr("modularity"),
					PlatformCPEs:  []string{"platform-cpe-1"},
				},
				Ranges: []v6.Range{
					{
						Version: v6.Version{
							Type:       "semver",
							Constraint: ">=1.0.0, <2.0.0",
						},
						Fix: &v6.Fix{
							Version: "1.2.0",
							State:   "fixed",
						},
					},
				},
			},
		},
	}

	buf := bytes.Buffer{}
	enc := json.NewEncoder(&buf)
	enc.SetIndent("", "  ")
	enc.SetEscapeHTML(false)
	err := enc.Encode(row)
	require.NoError(t, err)

	expectedJSON := `{
  "vulnerability": {
    "id": "CVE-1234-5678",
    "description": "Test vulnerability",
    "provider": "provider1",
    "status": "active",
    "published_date": "2023-01-01T00:00:00Z",
    "modified_date": "2023-02-01T00:00:00Z",
    "known_exploited": [
      {
        "cve": "CVE-1234-5678",
        "vendor_project": "LinuxFoundation",
        "product": "Linux",
        "date_added": "2025-02-02",
        "required_action": "Yes",
        "due_date": "2025-02-02",
        "known_ransomware_campaign_use": "Known",
        "notes": "note!",
        "urls": [
          "https://example.com"
        ],
        "cwes": [
          "CWE-1234"
        ]
      }
    ],
    "epss": [
      {
        "cve": "CVE-1234-5678",
        "epss": 0.893,
        "percentile": 0.99,
        "date": "2025-02-24"
      }
    ]
  },
  "package": {
    "name": "pkg1",
    "ecosystem": "ecosystem1"
  },
  "cpe": "cpe:2.3:a:vendor1:product1:*:*:*:*:*:*:*:*",
  "namespace": "namespace1",
  "detail": {
    "cves": [
      "CVE-1234-5678"
    ],
    "qualifiers": {
      "rpm_modularity": "modularity",
      "platform_cpes": [
        "platform-cpe-1"
      ]
    },
    "ranges": [
      {
        "version": {
          "type": "semver",
          "constraint": ">=1.0.0, <2.0.0"
        },
        "fix": {
          "version": "1.2.0",
          "state": "fixed"
        }
      }
    ]
  }
}
`

	if diff := cmp.Diff(expectedJSON, buf.String()); diff != "" {
		t.Errorf("unexpected JSON (-want +got):\n%s", diff)
	}
}

func TestNewAffectedPackageRows(t *testing.T) {
	affectedPkgs := []affectedPackageWithDecorations{
		{
			AffectedPackageHandle: v6.AffectedPackageHandle{
				Package: &v6.Package{Name: "pkg1", Ecosystem: "ecosystem1"},
				OperatingSystem: &v6.OperatingSystem{
					Name:         "Linux",
					MajorVersion: "5",
					MinorVersion: "10",
				},
				Vulnerability: &v6.VulnerabilityHandle{
					Name:          "CVE-1234-5678",
					Provider:      &v6.Provider{ID: "provider1"},
					Status:        "active",
					PublishedDate: ptr(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)),
					ModifiedDate:  ptr(time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC)),
					BlobValue: &v6.VulnerabilityBlob{
						Description: "Test vulnerability",
						Severities: []v6.Severity{
							{
								Scheme: "CVSS_V3",
								Value: CVSSSeverity{
									Vector:  "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
									Version: "3.1",
									Metrics: CvssMetrics{
										BaseScore: 9.8,
									},
								},
								Source: "nvd@nist.gov",
								Rank:   1,
							},
						},
					},
				},
				BlobValue: &v6.PackageBlob{
					CVEs: []string{"CVE-1234-5678"},
					Qualifiers: &v6.PackageQualifiers{
						RpmModularity: ptr("modularity"),
						PlatformCPEs:  []string{"platform-cpe-1"},
					},
					Ranges: []v6.Range{
						{
							Version: v6.Version{
								Type:       "semver",
								Constraint: ">=1.0.0, <2.0.0",
							},
							Fix: &v6.Fix{
								Version: "1.2.0",
								State:   "fixed",
							},
						},
					},
				},
			},
			vulnerabilityDecorations: vulnerabilityDecorations{
				KnownExploited: []KnownExploited{
					{
						CVE:                        "CVE-1234-5678",
						VendorProject:              "LinuxFoundation",
						Product:                    "Linux",
						DateAdded:                  "2025-02-02",
						RequiredAction:             "Yes",
						DueDate:                    "2025-02-02",
						KnownRansomwareCampaignUse: "Known",
						Notes:                      "note!",
						URLs:                       []string{"https://example.com"},
						CWEs:                       []string{"CWE-1234"},
					},
				},
				EPSS: []EPSS{
					{
						CVE:        "CVE-1234-5678",
						EPSS:       0.893,
						Percentile: 0.99,
						Date:       "2025-02-24",
					},
				},
			},
		},
	}

	affectedCPEs := []affectedCPEWithDecorations{
		{
			AffectedCPEHandle: v6.AffectedCPEHandle{
				CPE: &v6.Cpe{Part: "a", Vendor: "vendor1", Product: "product1"},
				Vulnerability: &v6.VulnerabilityHandle{
					Name:      "CVE-9876-5432",
					Provider:  &v6.Provider{ID: "provider2"},
					BlobValue: &v6.VulnerabilityBlob{Description: "CPE vulnerability description"},
				},
				BlobValue: &v6.PackageBlob{
					CVEs: []string{"CVE-9876-5432"},
					Ranges: []v6.Range{
						{
							Version: v6.Version{
								Type:       "rpm",
								Constraint: ">=2.0.0, <3.0.0",
							},
							Fix: &v6.Fix{
								Version: "2.5.0",
								State:   "fixed",
							},
						},
					},
				},
			},
			vulnerabilityDecorations: vulnerabilityDecorations{
				KnownExploited: []KnownExploited{
					{
						CVE:                        "CVE-9876-5432",
						VendorProject:              "vendor1",
						Product:                    "product1",
						DateAdded:                  "2025-02-03",
						RequiredAction:             "Yes",
						DueDate:                    "2025-02-03",
						KnownRansomwareCampaignUse: "Known",
						Notes:                      "note!",
						URLs:                       []string{"https://example.com"},
						CWEs:                       []string{"CWE-5678"},
					},
				},
				EPSS: []EPSS{
					{
						CVE:        "CVE-9876-5432",
						EPSS:       0.938,
						Percentile: 0.9222,
						Date:       "2025-02-25",
					},
				},
			},
		},
	}

	rows := newAffectedPackageRows(affectedPkgs, affectedCPEs)
	expected := []AffectedPackage{
		{
			Vulnerability: VulnerabilityInfo{
				VulnerabilityBlob: v6.VulnerabilityBlob{
					Description: "Test vulnerability",
					Severities: []v6.Severity{
						{
							Scheme: "CVSS_V3",
							Value: CVSSSeverity{
								Vector:  "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
								Version: "3.1",
								Metrics: CvssMetrics{
									BaseScore: 9.8,
								},
							},
							Source: "nvd@nist.gov",
							Rank:   1,
						},
					},
				},
				Severity:      "critical",
				Provider:      "provider1",
				Status:        "active",
				PublishedDate: ptr(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)),
				ModifiedDate:  ptr(time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC)),
				KnownExploited: []KnownExploited{
					{
						CVE:                        "CVE-1234-5678",
						VendorProject:              "LinuxFoundation",
						Product:                    "Linux",
						DateAdded:                  "2025-02-02",
						RequiredAction:             "Yes",
						DueDate:                    "2025-02-02",
						KnownRansomwareCampaignUse: "Known",
						Notes:                      "note!",
						URLs:                       []string{"https://example.com"},
						CWEs:                       []string{"CWE-1234"},
					},
				},
				EPSS: []EPSS{
					{
						CVE:        "CVE-1234-5678",
						EPSS:       0.893,
						Percentile: 0.99,
						Date:       "2025-02-24",
					},
				},
			},
			AffectedPackageInfo: AffectedPackageInfo{
				OS:        &OperatingSystem{Name: "Linux", Version: "5.10"},
				Package:   &Package{Name: "pkg1", Ecosystem: "ecosystem1"},
				Namespace: "provider1:distro:Linux:5.10",
				Detail: v6.PackageBlob{
					CVEs: []string{"CVE-1234-5678"},
					Qualifiers: &v6.PackageQualifiers{
						RpmModularity: ptr("modularity"),
						PlatformCPEs:  []string{"platform-cpe-1"},
					},
					Ranges: []v6.Range{
						{
							Version: v6.Version{
								Type:       "semver",
								Constraint: ">=1.0.0, <2.0.0",
							},
							Fix: &v6.Fix{
								Version: "1.2.0",
								State:   "fixed",
							},
						},
					},
				},
			},
		},
		{
			Vulnerability: VulnerabilityInfo{
				VulnerabilityBlob: v6.VulnerabilityBlob{Description: "CPE vulnerability description"},
				Severity:          "unknown",
				Provider:          "provider2",
				KnownExploited: []KnownExploited{
					{
						CVE:                        "CVE-9876-5432",
						VendorProject:              "vendor1",
						Product:                    "product1",
						DateAdded:                  "2025-02-03",
						RequiredAction:             "Yes",
						DueDate:                    "2025-02-03",
						KnownRansomwareCampaignUse: "Known",
						Notes:                      "note!",
						URLs:                       []string{"https://example.com"},
						CWEs:                       []string{"CWE-5678"},
					},
				},
				EPSS: []EPSS{
					{
						CVE:        "CVE-9876-5432",
						EPSS:       0.938,
						Percentile: 0.9222,
						Date:       "2025-02-25",
					},
				},
			},
			AffectedPackageInfo: AffectedPackageInfo{
				CPE:       &CPE{Part: "a", Vendor: "vendor1", Product: "product1"},
				Namespace: "provider2:cpe",
				Detail: v6.PackageBlob{
					CVEs: []string{"CVE-9876-5432"},
					Ranges: []v6.Range{
						{
							Version: v6.Version{
								Type:       "rpm",
								Constraint: ">=2.0.0, <3.0.0",
							},
							Fix: &v6.Fix{
								Version: "2.5.0",
								State:   "fixed",
							},
						},
					},
				},
			},
		},
	}

	if diff := cmp.Diff(expected, rows, cmpOpts()...); diff != "" {
		t.Errorf("unexpected rows (-want +got):\n%s", diff)
	}
}

func TestAffectedPackages(t *testing.T) {
	mockReader := new(affectedMockReader)

	mockReader.On("GetAffectedPackages", mock.Anything, mock.Anything).Return([]v6.AffectedPackageHandle{
		{
			Package: &v6.Package{Name: "pkg1", Ecosystem: "ecosystem1"},
			OperatingSystem: &v6.OperatingSystem{
				Name:         "Linux",
				MajorVersion: "5",
				MinorVersion: "10",
			},
			Vulnerability: &v6.VulnerabilityHandle{
				Name:          "CVE-1234-5678",
				Provider:      &v6.Provider{ID: "provider1"},
				Status:        "active",
				PublishedDate: ptr(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)),
				ModifiedDate:  ptr(time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC)),
				BlobValue:     &v6.VulnerabilityBlob{Description: "Test vulnerability"},
			},
			BlobValue: &v6.PackageBlob{
				CVEs: []string{"CVE-1234-5678"},
				Ranges: []v6.Range{
					{
						Version: v6.Version{
							Type:       "semver",
							Constraint: ">=1.0.0, <2.0.0",
						},
						Fix: &v6.Fix{
							Version: "1.2.0",
							State:   "fixed",
						},
					},
				},
			},
		},
	}, nil)

	mockReader.On("GetAffectedCPEs", mock.Anything, mock.Anything).Return([]v6.AffectedCPEHandle{
		{
			CPE: &v6.Cpe{Part: "a", Vendor: "vendor1", Product: "product1"},
			Vulnerability: &v6.VulnerabilityHandle{
				Name:      "CVE-9876-5432",
				Provider:  &v6.Provider{ID: "provider2"},
				BlobValue: &v6.VulnerabilityBlob
Download .txt
gitextract_p7zkpam3/

├── .binny.yaml
├── .bouncer.yaml
├── .chronicle.yaml
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   ├── feature_request.md
│   │   └── match_issue.md
│   ├── actions/
│   │   └── bootstrap/
│   │       └── action.yaml
│   ├── dependabot.yaml
│   ├── scripts/
│   │   ├── check-syft-version-is-release.sh
│   │   ├── ci-check.sh
│   │   ├── coverage.py
│   │   ├── db-schema-drift-check.sh
│   │   ├── go-mod-tidy-check.sh
│   │   ├── json-schema-drift-check.sh
│   │   └── trigger-release.sh
│   ├── workflows/
│   │   ├── codeql-analysis.yml
│   │   ├── dependabot-automation.yaml
│   │   ├── oss-project-board-add.yaml
│   │   ├── release.yaml
│   │   ├── remove-awaiting-response-label.yaml
│   │   ├── scorecards.yml
│   │   ├── update-anchore-dependencies.yml
│   │   ├── update-bootstrap-tools.yml
│   │   ├── update-generated-code.yml
│   │   ├── update-quality-gate-db.yml
│   │   ├── validate-github-actions.yaml
│   │   └── validations.yaml
│   └── zizmor.yml
├── .gitignore
├── .gitmodules
├── .golangci.yaml
├── .goreleaser.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.debug
├── Dockerfile.nonroot
├── LICENSE
├── Makefile
├── README.md
├── RELEASE.md
├── SECURITY.md
├── Taskfile.yaml
├── artifacthub-repo.yml
├── cmd/
│   └── grype/
│       ├── cli/
│       │   ├── cli.go
│       │   ├── cli_test.go
│       │   ├── commands/
│       │   │   ├── completion.go
│       │   │   ├── db.go
│       │   │   ├── db_check.go
│       │   │   ├── db_check_test.go
│       │   │   ├── db_delete.go
│       │   │   ├── db_import.go
│       │   │   ├── db_list.go
│       │   │   ├── db_list_test.go
│       │   │   ├── db_providers.go
│       │   │   ├── db_providers_test.go
│       │   │   ├── db_search.go
│       │   │   ├── db_search_test.go
│       │   │   ├── db_search_vuln.go
│       │   │   ├── db_search_vuln_test.go
│       │   │   ├── db_status.go
│       │   │   ├── db_status_test.go
│       │   │   ├── db_update.go
│       │   │   ├── explain.go
│       │   │   ├── internal/
│       │   │   │   ├── dbsearch/
│       │   │   │   │   ├── affected_packages.go
│       │   │   │   │   ├── affected_packages_test.go
│       │   │   │   │   ├── common.go
│       │   │   │   │   ├── matches.go
│       │   │   │   │   ├── matches_test.go
│       │   │   │   │   ├── versions.go
│       │   │   │   │   ├── vulnerabilities.go
│       │   │   │   │   ├── vulnerabilities_test.go
│       │   │   │   │   └── vulnerability_decorations.go
│       │   │   │   └── jsonschema/
│       │   │   │       └── main.go
│       │   │   ├── root.go
│       │   │   ├── root_test.go
│       │   │   ├── testdata/
│       │   │   │   └── provider-metadata.json
│       │   │   ├── update.go
│       │   │   ├── update_test.go
│       │   │   ├── util.go
│       │   │   └── util_test.go
│       │   ├── options/
│       │   │   ├── alerts.go
│       │   │   ├── alerts_test.go
│       │   │   ├── database.go
│       │   │   ├── database_command.go
│       │   │   ├── database_search_bounds.go
│       │   │   ├── database_search_format.go
│       │   │   ├── database_search_os.go
│       │   │   ├── database_search_os_test.go
│       │   │   ├── database_search_packages.go
│       │   │   ├── database_search_packages_test.go
│       │   │   ├── database_search_vulnerabilities.go
│       │   │   ├── database_search_vulnerabilities_test.go
│       │   │   ├── datasources.go
│       │   │   ├── experimental.go
│       │   │   ├── fix_channels.go
│       │   │   ├── grype.go
│       │   │   ├── grype_test.go
│       │   │   ├── match.go
│       │   │   ├── match_test.go
│       │   │   ├── registry.go
│       │   │   ├── registry_test.go
│       │   │   ├── search.go
│       │   │   ├── secret.go
│       │   │   └── sort_by.go
│       │   └── ui/
│       │       ├── __snapshots__/
│       │       │   ├── handle_database_diff_started_test.snap
│       │       │   ├── handle_update_vulnerability_database_test.snap
│       │       │   └── handle_vulnerability_scanning_started_test.snap
│       │       ├── handle_database_diff_started.go
│       │       ├── handle_database_diff_started_test.go
│       │       ├── handle_update_vulnerability_database.go
│       │       ├── handle_update_vulnerability_database_test.go
│       │       ├── handle_vulnerability_scanning_started.go
│       │       ├── handle_vulnerability_scanning_started_test.go
│       │       ├── handler.go
│       │       ├── new_task_progress.go
│       │       └── util_test.go
│       ├── internal/
│       │   ├── constants.go
│       │   └── ui/
│       │       ├── __snapshots__/
│       │       │   └── post_ui_event_writer_test.snap
│       │       ├── no_ui.go
│       │       ├── post_ui_event_writer.go
│       │       ├── post_ui_event_writer_test.go
│       │       └── ui.go
│       └── main.go
├── go.mod
├── go.sum
├── grype/
│   ├── cpe/
│   │   ├── cpe.go
│   │   └── cpe_test.go
│   ├── db/
│   │   ├── build.go
│   │   ├── data/
│   │   │   ├── entry.go
│   │   │   ├── processor.go
│   │   │   ├── severity.go
│   │   │   ├── severity_test.go
│   │   │   ├── transformers.go
│   │   │   └── writer.go
│   │   ├── default_schema_version.go
│   │   ├── generate.go
│   │   ├── internal/
│   │   │   ├── codename/
│   │   │   │   ├── codename.go
│   │   │   │   ├── codename_test.go
│   │   │   │   ├── codenames_generated.go
│   │   │   │   └── generate/
│   │   │   │       └── main.go
│   │   │   ├── gormadapter/
│   │   │   │   ├── logger.go
│   │   │   │   ├── open.go
│   │   │   │   └── open_test.go
│   │   │   ├── provider/
│   │   │   │   └── unmarshal/
│   │   │   │       ├── annotated_openvex_vulnerability.go
│   │   │   │       ├── eol.go
│   │   │   │       ├── epss.go
│   │   │   │       ├── errors.go
│   │   │   │       ├── github_advisory.go
│   │   │   │       ├── items_envelope.go
│   │   │   │       ├── known_exploited_vulnerability.go
│   │   │   │       ├── match_exclusion.go
│   │   │   │       ├── msrc_vulnerability.go
│   │   │   │       ├── nvd/
│   │   │   │       │   ├── cve.go
│   │   │   │       │   ├── cve_test.go
│   │   │   │       │   ├── cvss20/
│   │   │   │       │   │   └── cvss20.go
│   │   │   │       │   ├── cvss30/
│   │   │   │       │   │   └── cvss30.go
│   │   │   │       │   ├── cvss31/
│   │   │   │       │   │   └── cvss31.go
│   │   │   │       │   └── cvss40/
│   │   │   │       │       └── cvss40.go
│   │   │   │       ├── nvd_vulnerability.go
│   │   │   │       ├── openvex_vulnerability.go
│   │   │   │       ├── os_vulnerability.go
│   │   │   │       ├── os_vulnerability_test.go
│   │   │   │       ├── osv_vulnerability.go
│   │   │   │       └── single_or_multi.go
│   │   │   ├── sqlite/
│   │   │   │   ├── nullable_types.go
│   │   │   │   └── nullable_types_test.go
│   │   │   ├── tarutil/
│   │   │   │   ├── file_entry.go
│   │   │   │   ├── file_entry_test.go
│   │   │   │   ├── populate.go
│   │   │   │   ├── populate_test.go
│   │   │   │   ├── reader_entry.go
│   │   │   │   ├── reader_entry_test.go
│   │   │   │   ├── tar.go
│   │   │   │   ├── writer.go
│   │   │   │   └── writer_test.go
│   │   │   ├── testutil/
│   │   │   │   └── utils.go
│   │   │   └── versionutil/
│   │   │       ├── clean_fixed_in_version.go
│   │   │       ├── constraint.go
│   │   │       └── constraint_test.go
│   │   ├── package.go
│   │   ├── package_legacy.go
│   │   ├── processors/
│   │   │   ├── annotated_openvex_processor.go
│   │   │   ├── eol_processor.go
│   │   │   ├── eol_processor_test.go
│   │   │   ├── epss_processor.go
│   │   │   ├── epss_processor_test.go
│   │   │   ├── github_processor.go
│   │   │   ├── github_processor_test.go
│   │   │   ├── kev_processor.go
│   │   │   ├── kev_processor_test.go
│   │   │   ├── match_exclusion_processor.go
│   │   │   ├── match_exclusion_processor_test.go
│   │   │   ├── msrc_processor.go
│   │   │   ├── msrc_processor_test.go
│   │   │   ├── nvd_processor.go
│   │   │   ├── nvd_processor_test.go
│   │   │   ├── openvex_processor.go
│   │   │   ├── openvex_processor_test.go
│   │   │   ├── os_processor.go
│   │   │   ├── os_processor_test.go
│   │   │   ├── osv_processor.go
│   │   │   ├── osv_processor_test.go
│   │   │   ├── testdata/
│   │   │   │   ├── eol-with-empty.json
│   │   │   │   ├── eol.json
│   │   │   │   ├── epss.json
│   │   │   │   ├── exclusions.json
│   │   │   │   ├── github.json
│   │   │   │   ├── kev.json
│   │   │   │   ├── msrc.json
│   │   │   │   ├── nvd.json
│   │   │   │   ├── openvex.json
│   │   │   │   ├── oracle.json
│   │   │   │   ├── os.json
│   │   │   │   └── osv.json
│   │   │   ├── version.go
│   │   │   └── version_test.go
│   │   ├── provider/
│   │   │   ├── entry/
│   │   │   │   ├── file.go
│   │   │   │   ├── opener.go
│   │   │   │   └── sqlite.go
│   │   │   ├── file.go
│   │   │   ├── model.go
│   │   │   ├── model_test.go
│   │   │   ├── provider.go
│   │   │   ├── state.go
│   │   │   ├── state_test.go
│   │   │   └── workspace.go
│   │   ├── v5/
│   │   │   ├── advisory.go
│   │   │   ├── build/
│   │   │   │   ├── processors.go
│   │   │   │   ├── transformers/
│   │   │   │   │   ├── entry.go
│   │   │   │   │   ├── github/
│   │   │   │   │   │   ├── testdata/
│   │   │   │   │   │   │   ├── github-github-npm-0.json
│   │   │   │   │   │   │   ├── github-github-python-0.json
│   │   │   │   │   │   │   ├── github-github-python-1.json
│   │   │   │   │   │   │   ├── github-withdrawn.json
│   │   │   │   │   │   │   └── multiple-fixed-in-names.json
│   │   │   │   │   │   ├── transform.go
│   │   │   │   │   │   └── transform_test.go
│   │   │   │   │   ├── matchexclusions/
│   │   │   │   │   │   └── transform.go
│   │   │   │   │   ├── msrc/
│   │   │   │   │   │   ├── testdata/
│   │   │   │   │   │   │   └── microsoft-msrc-0.json
│   │   │   │   │   │   ├── transform.go
│   │   │   │   │   │   └── transform_test.go
│   │   │   │   │   ├── nvd/
│   │   │   │   │   │   ├── testdata/
│   │   │   │   │   │   │   ├── CVE-2023-45283-platform-cpe-first.json
│   │   │   │   │   │   │   ├── CVE-2023-45283-platform-cpe-last.json
│   │   │   │   │   │   │   ├── compound-pkg.json
│   │   │   │   │   │   │   ├── cve-2020-10729.json
│   │   │   │   │   │   │   ├── cve-2022-0543.json
│   │   │   │   │   │   │   ├── invalid_cpe.json
│   │   │   │   │   │   │   ├── multiple-platforms-with-application-cpe.json
│   │   │   │   │   │   │   ├── platform-cpe.json
│   │   │   │   │   │   │   ├── single-package-multi-distro.json
│   │   │   │   │   │   │   ├── unmarshal-test.json
│   │   │   │   │   │   │   └── version-range.json
│   │   │   │   │   │   ├── transform.go
│   │   │   │   │   │   ├── transform_test.go
│   │   │   │   │   │   ├── unique_pkg.go
│   │   │   │   │   │   ├── unique_pkg_test.go
│   │   │   │   │   │   └── unique_pkg_tracker.go
│   │   │   │   │   ├── os/
│   │   │   │   │   │   ├── testdata/
│   │   │   │   │   │   │   ├── alpine-3.9.json
│   │   │   │   │   │   │   ├── amazon-multiple-kernel-advisories.json
│   │   │   │   │   │   │   ├── amzn.json
│   │   │   │   │   │   │   ├── azure-linux-3.json
│   │   │   │   │   │   │   ├── debian-8-multiple-entries-for-same-package.json
│   │   │   │   │   │   │   ├── debian-8.json
│   │   │   │   │   │   │   ├── mariner-20.json
│   │   │   │   │   │   │   ├── mariner-range.json
│   │   │   │   │   │   │   ├── ol-8-modules.json
│   │   │   │   │   │   │   ├── ol-8.json
│   │   │   │   │   │   │   ├── photon-4.0.json
│   │   │   │   │   │   │   ├── rhel-8-eus.json
│   │   │   │   │   │   │   ├── rhel-8-modules.json
│   │   │   │   │   │   │   ├── rhel-8.json
│   │   │   │   │   │   │   └── unmarshal-test.json
│   │   │   │   │   │   ├── transform.go
│   │   │   │   │   │   └── transform_test.go
│   │   │   │   │   └── vulnerability_metadata.go
│   │   │   │   ├── writer.go
│   │   │   │   └── writer_test.go
│   │   │   ├── cvss.go
│   │   │   ├── diff.go
│   │   │   ├── differ/
│   │   │   │   ├── differ.go
│   │   │   │   ├── differ_test.go
│   │   │   │   └── testdata/
│   │   │   │       ├── dbs/
│   │   │   │       │   ├── base/
│   │   │   │       │   │   └── 5/
│   │   │   │       │   │       └── metadata.json
│   │   │   │       │   └── target/
│   │   │   │       │       └── 5/
│   │   │   │       │           └── metadata.json
│   │   │   │       └── snapshot/
│   │   │   │           ├── TestPresent_Json.golden
│   │   │   │           └── TestPresent_Table.golden
│   │   │   ├── distribution/
│   │   │   │   ├── curator.go
│   │   │   │   ├── curator_test.go
│   │   │   │   ├── listing.go
│   │   │   │   ├── listing_entry.go
│   │   │   │   ├── listing_test.go
│   │   │   │   ├── metadata.go
│   │   │   │   ├── metadata_test.go
│   │   │   │   ├── status.go
│   │   │   │   └── testdata/
│   │   │   │       ├── curator-validate/
│   │   │   │       │   ├── bad-checksum/
│   │   │   │       │   │   └── metadata.json
│   │   │   │       │   └── good-checksum/
│   │   │   │       │       └── metadata.json
│   │   │   │       ├── listing-sorted.json
│   │   │   │       ├── listing-unsorted.json
│   │   │   │       ├── listing.json
│   │   │   │       ├── metadata-edt-timezone/
│   │   │   │       │   └── metadata.json
│   │   │   │       ├── metadata-gocase/
│   │   │   │       │   └── metadata.json
│   │   │   │       └── tls/
│   │   │   │           ├── .gitignore
│   │   │   │           ├── Makefile
│   │   │   │           ├── README.md
│   │   │   │           ├── generate-x509-cert-pair.sh
│   │   │   │           ├── listing.py
│   │   │   │           └── serve.py
│   │   │   ├── fix.go
│   │   │   ├── id.go
│   │   │   ├── match_exclusion_provider.go
│   │   │   ├── namespace/
│   │   │   │   ├── cpe/
│   │   │   │   │   ├── namespace.go
│   │   │   │   │   └── namespace_test.go
│   │   │   │   ├── distro/
│   │   │   │   │   ├── namespace.go
│   │   │   │   │   └── namespace_test.go
│   │   │   │   ├── from_string.go
│   │   │   │   ├── from_string_test.go
│   │   │   │   ├── language/
│   │   │   │   │   ├── namespace.go
│   │   │   │   │   └── namespace_test.go
│   │   │   │   └── namespace.go
│   │   │   ├── pkg/
│   │   │   │   ├── qualifier/
│   │   │   │   │   ├── from_json.go
│   │   │   │   │   ├── platformcpe/
│   │   │   │   │   │   └── qualifier.go
│   │   │   │   │   ├── qualifier.go
│   │   │   │   │   └── rpmmodularity/
│   │   │   │   │       └── qualifier.go
│   │   │   │   └── resolver/
│   │   │   │       ├── java/
│   │   │   │       │   ├── resolver.go
│   │   │   │       │   └── resolver_test.go
│   │   │   │       ├── python/
│   │   │   │       │   ├── resolver.go
│   │   │   │       │   └── resolver_test.go
│   │   │   │       ├── resolver.go
│   │   │   │       ├── resolver_test.go
│   │   │   │       └── stock/
│   │   │   │           ├── resolver.go
│   │   │   │           └── resolver_test.go
│   │   │   ├── provider_store.go
│   │   │   ├── schema_version.go
│   │   │   ├── store/
│   │   │   │   ├── diff.go
│   │   │   │   ├── diff_test.go
│   │   │   │   ├── model/
│   │   │   │   │   ├── id.go
│   │   │   │   │   ├── vulnerability.go
│   │   │   │   │   ├── vulnerability_match_exclusion.go
│   │   │   │   │   ├── vulnerability_match_exclusion_test.go
│   │   │   │   │   ├── vulnerability_metadata.go
│   │   │   │   │   └── vulnerability_test.go
│   │   │   │   ├── store.go
│   │   │   │   └── store_test.go
│   │   │   ├── store.go
│   │   │   ├── vulnerability.go
│   │   │   ├── vulnerability_match_exclusion.go
│   │   │   ├── vulnerability_match_exclusion_store.go
│   │   │   ├── vulnerability_metadata.go
│   │   │   ├── vulnerability_metadata_store.go
│   │   │   └── vulnerability_store.go
│   │   └── v6/
│   │       ├── affected_cpe_store.go
│   │       ├── affected_cpe_store_test.go
│   │       ├── affected_package_store.go
│   │       ├── affected_package_store_test.go
│   │       ├── blob_store.go
│   │       ├── blob_store_test.go
│   │       ├── blobs.go
│   │       ├── blobs_test.go
│   │       ├── build/
│   │       │   ├── archive.go
│   │       │   ├── processors.go
│   │       │   ├── transformers/
│   │       │   │   ├── entry.go
│   │       │   │   ├── eol/
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── epss/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   └── go-case.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── github/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   ├── GHSA-2wgc-48g2-cj5w.json
│   │       │   │   │   │   ├── GHSA-3x74-v64j-qc3f.json
│   │       │   │   │   │   ├── GHSA-92cp-5422-2mw7.json
│   │       │   │   │   │   ├── GHSA-qc55-vm3j-74gp.json
│   │       │   │   │   │   ├── github-github-npm-0.json
│   │       │   │   │   │   ├── github-github-python-0.json
│   │       │   │   │   │   ├── github-withdrawn.json
│   │       │   │   │   │   └── multiple-fixed-in-names.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── internal/
│   │       │   │   │   ├── sort.go
│   │       │   │   │   ├── time.go
│   │       │   │   │   └── time_test.go
│   │       │   │   ├── kev/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   └── go-case.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── msrc/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   └── microsoft-msrc-0.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── nvd/
│   │       │   │   │   ├── affected_range.go
│   │       │   │   │   ├── affected_range_test.go
│   │       │   │   │   ├── node.go
│   │       │   │   │   ├── node_test.go
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   ├── CVE-2004-0377.json
│   │       │   │   │   │   ├── CVE-2008-3442.json
│   │       │   │   │   │   ├── CVE-2023-45283-platform-cpe-first.json
│   │       │   │   │   │   ├── CVE-2023-45283-platform-cpe-last.json
│   │       │   │   │   │   ├── compound-pkg.json
│   │       │   │   │   │   ├── cve-2020-10729.json
│   │       │   │   │   │   ├── cve-2021-1566.json
│   │       │   │   │   │   ├── cve-2022-0543.json
│   │       │   │   │   │   ├── cve-2024-26663-standalone-os.json
│   │       │   │   │   │   ├── fix-version.json
│   │       │   │   │   │   ├── fix-wrong-version.json
│   │       │   │   │   │   ├── invalid_cpe.json
│   │       │   │   │   │   ├── jvm-packages.json
│   │       │   │   │   │   ├── multiple-platforms-with-application-cpe.json
│   │       │   │   │   │   ├── platform-cpe.json
│   │       │   │   │   │   ├── single-package-multi-distro.json
│   │       │   │   │   │   └── version-range.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── openvex/
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── os/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   ├── alpine-3.9.json
│   │       │   │   │   │   ├── amazon-multiple-kernel-advisories.json
│   │       │   │   │   │   ├── amzn.json
│   │       │   │   │   │   ├── azure-linux-3.json
│   │       │   │   │   │   ├── debian-8-multiple-entries-for-same-package.json
│   │       │   │   │   │   ├── debian-8.json
│   │       │   │   │   │   ├── fedora-39.json
│   │       │   │   │   │   ├── mariner-20.json
│   │       │   │   │   │   ├── mariner-range.json
│   │       │   │   │   │   ├── ol-8-modules.json
│   │       │   │   │   │   ├── ol-8.json
│   │       │   │   │   │   ├── rhel-8-modules.json
│   │       │   │   │   │   └── rhel-8.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   ├── osv/
│   │       │   │   │   ├── testdata/
│   │       │   │   │   │   ├── ALSA-2025-7467.json
│   │       │   │   │   │   ├── BIT-apache-2020-11984.json
│   │       │   │   │   │   └── BIT-node-2020-8201.json
│   │       │   │   │   ├── transform.go
│   │       │   │   │   └── transform_test.go
│   │       │   │   └── references.go
│   │       │   ├── writer.go
│   │       │   └── writer_test.go
│   │       ├── cache.go
│   │       ├── cache_test.go
│   │       ├── cpe_store.go
│   │       ├── data.go
│   │       ├── db.go
│   │       ├── db_metadata_store.go
│   │       ├── db_metadata_store_test.go
│   │       ├── description.go
│   │       ├── description_test.go
│   │       ├── distribution/
│   │       │   ├── client.go
│   │       │   ├── client_test.go
│   │       │   ├── latest.go
│   │       │   ├── latest_test.go
│   │       │   └── status.go
│   │       ├── enumerations.go
│   │       ├── enumerations_test.go
│   │       ├── fillers.go
│   │       ├── import_metadata.go
│   │       ├── import_metadata_test.go
│   │       ├── installation/
│   │       │   ├── curator.go
│   │       │   └── curator_test.go
│   │       ├── log_dropped.go
│   │       ├── models.go
│   │       ├── models_test.go
│   │       ├── name/
│   │       │   ├── java.go
│   │       │   ├── java_test.go
│   │       │   ├── python.go
│   │       │   ├── python_test.go
│   │       │   └── resolver.go
│   │       ├── operating_system_store.go
│   │       ├── operating_system_store_test.go
│   │       ├── package_store.go
│   │       ├── provider_store.go
│   │       ├── provider_store_test.go
│   │       ├── refs.go
│   │       ├── schema/
│   │       │   └── main.go
│   │       ├── search_query.go
│   │       ├── search_query_test.go
│   │       ├── severity.go
│   │       ├── severity_test.go
│   │       ├── store.go
│   │       ├── store_test.go
│   │       ├── unaffected_cpe_store.go
│   │       ├── unaffected_cpe_store_test.go
│   │       ├── unaffected_package_store.go
│   │       ├── unaffected_package_store_test.go
│   │       ├── vulnerability.go
│   │       ├── vulnerability_decorator_store.go
│   │       ├── vulnerability_decorator_store_test.go
│   │       ├── vulnerability_provider.go
│   │       ├── vulnerability_provider_mocks_test.go
│   │       ├── vulnerability_provider_test.go
│   │       ├── vulnerability_store.go
│   │       ├── vulnerability_store_test.go
│   │       └── vulnerability_test.go
│   ├── deprecated.go
│   ├── distro/
│   │   ├── distro.go
│   │   ├── distro_test.go
│   │   ├── fix_channel.go
│   │   ├── fix_channel_test.go
│   │   ├── testdata/
│   │   │   ├── bad-id
│   │   │   ├── bad-redhat-release
│   │   │   ├── bad-system-release-cpe
│   │   │   ├── centos-8
│   │   │   ├── debian-8
│   │   │   ├── os/
│   │   │   │   ├── almalinux/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── alpine/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── alpine-edge/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── amazon/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── arch/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── azurelinux/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── busybox/
│   │   │   │   │   └── bin/
│   │   │   │   │       └── busybox
│   │   │   │   ├── centos/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── centos5/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── redhat-release
│   │   │   │   ├── centos6/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── system-release-cpe
│   │   │   │   ├── chainguard/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── custom/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── debian/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── debian-sid/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── echo/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── empty/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── fedora/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── gentoo/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── mariner/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── minimos/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── opensuse-leap/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── oraclelinux/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── photon/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── postmarketos/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── postmarketos-edge/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── raspbian/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── redhat/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── rockylinux/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── scientific/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── scientific6/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── redhat-release
│   │   │   │   ├── secureos/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── sles/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   ├── ubuntu/
│   │   │   │   │   └── etc/
│   │   │   │   │       └── os-release
│   │   │   │   └── wolfi/
│   │   │   │       └── etc/
│   │   │   │           └── os-release
│   │   │   ├── partial-fields/
│   │   │   │   ├── missing-id/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   ├── missing-version/
│   │   │   │   │   └── usr/
│   │   │   │   │       └── lib/
│   │   │   │   │           └── os-release
│   │   │   │   └── unknown-id/
│   │   │   │       └── usr/
│   │   │   │           └── lib/
│   │   │   │               └── os-release
│   │   │   ├── rhel-8
│   │   │   ├── ubuntu-20.04
│   │   │   └── unprintable
│   │   ├── type.go
│   │   └── type_test.go
│   ├── event/
│   │   ├── event.go
│   │   ├── monitor/
│   │   │   ├── db_diff.go
│   │   │   └── matching.go
│   │   └── parsers/
│   │       └── parsers.go
│   ├── grypeerr/
│   │   ├── errors.go
│   │   └── expected_error.go
│   ├── internal/
│   │   ├── generate.go
│   │   └── packagemetadata/
│   │       ├── discover_type_names.go
│   │       ├── generate/
│   │       │   └── main.go
│   │       ├── generated.go
│   │       ├── names.go
│   │       └── names_test.go
│   ├── lib.go
│   ├── load_vulnerability_db.go
│   ├── load_vulnerability_db_bench_test.go
│   ├── match/
│   │   ├── details.go
│   │   ├── details_test.go
│   │   ├── explicit_ignores.go
│   │   ├── explicit_ignores_test.go
│   │   ├── fingerprint.go
│   │   ├── ignore.go
│   │   ├── ignore_test.go
│   │   ├── match.go
│   │   ├── match_test.go
│   │   ├── matcher.go
│   │   ├── matcher_type.go
│   │   ├── matches.go
│   │   ├── matches_test.go
│   │   ├── provider.go
│   │   ├── results.go
│   │   ├── sort.go
│   │   └── type.go
│   ├── matcher/
│   │   ├── apk/
│   │   │   ├── matcher.go
│   │   │   └── matcher_test.go
│   │   ├── bitnami/
│   │   │   └── matcher.go
│   │   ├── dotnet/
│   │   │   └── matcher.go
│   │   ├── dpkg/
│   │   │   ├── matcher.go
│   │   │   ├── matcher_mocks_test.go
│   │   │   └── matcher_test.go
│   │   ├── golang/
│   │   │   ├── matcher.go
│   │   │   └── matcher_test.go
│   │   ├── hex/
│   │   │   └── matcher.go
│   │   ├── internal/
│   │   │   ├── common.go
│   │   │   ├── cpe.go
│   │   │   ├── cpe_test.go
│   │   │   ├── distro.go
│   │   │   ├── distro_test.go
│   │   │   ├── eol.go
│   │   │   ├── eol_test.go
│   │   │   ├── language.go
│   │   │   ├── language_test.go
│   │   │   ├── only_non_withdrawn_vulnerabilities.go
│   │   │   ├── only_qualified_packages.go
│   │   │   ├── only_vulnerable_targets.go
│   │   │   ├── only_vulnerable_targets_test.go
│   │   │   ├── only_vulnerable_versions.go
│   │   │   ├── result/
│   │   │   │   ├── match_details_set.go
│   │   │   │   ├── provider.go
│   │   │   │   ├── results.go
│   │   │   │   └── results_test.go
│   │   │   └── utils_test.go
│   │   ├── java/
│   │   │   ├── matcher.go
│   │   │   ├── matcher_integration_test.go
│   │   │   ├── matcher_mocks_test.go
│   │   │   ├── matcher_test.go
│   │   │   ├── maven_search.go
│   │   │   └── maven_test.go
│   │   ├── javascript/
│   │   │   └── matcher.go
│   │   ├── matchers.go
│   │   ├── mock/
│   │   │   └── matcher.go
│   │   ├── msrc/
│   │   │   └── matcher.go
│   │   ├── pacman/
│   │   │   ├── matcher.go
│   │   │   └── matcher_test.go
│   │   ├── portage/
│   │   │   ├── matcher.go
│   │   │   ├── matcher_mocks_test.go
│   │   │   └── matcher_test.go
│   │   ├── python/
│   │   │   └── matcher.go
│   │   ├── rpm/
│   │   │   ├── almalinux.go
│   │   │   ├── almalinux_package_utils.go
│   │   │   ├── almalinux_package_utils_test.go
│   │   │   ├── almalinux_test.go
│   │   │   ├── matcher.go
│   │   │   ├── matcher_mocks_test.go
│   │   │   ├── matcher_test.go
│   │   │   ├── rhel_eus.go
│   │   │   └── rhel_eus_test.go
│   │   ├── ruby/
│   │   │   └── matcher.go
│   │   ├── rust/
│   │   │   └── matcher.go
│   │   └── stock/
│   │       ├── matcher.go
│   │       └── matcher_test.go
│   ├── pkg/
│   │   ├── apk_metadata.go
│   │   ├── context.go
│   │   ├── context_test.go
│   │   ├── cpe_provider.go
│   │   ├── cpe_provider_test.go
│   │   ├── file_owner.go
│   │   ├── golang_metadata.go
│   │   ├── java_metadata.go
│   │   ├── java_metadata_test.go
│   │   ├── package.go
│   │   ├── package_test.go
│   │   ├── provider.go
│   │   ├── provider_config.go
│   │   ├── provider_test.go
│   │   ├── purl_provider.go
│   │   ├── purl_provider_test.go
│   │   ├── qualifier/
│   │   │   ├── platformcpe/
│   │   │   │   ├── qualifier.go
│   │   │   │   └── qualifier_test.go
│   │   │   ├── qualifier.go
│   │   │   └── rpmmodularity/
│   │   │       ├── qualifier.go
│   │   │       └── qualifier_test.go
│   │   ├── rpm_metadata.go
│   │   ├── syft_provider.go
│   │   ├── syft_sbom_provider.go
│   │   ├── syft_sbom_provider_test.go
│   │   ├── testdata/
│   │   │   ├── alpine-tampered.att.json
│   │   │   ├── alpine-tampered.cdx.att.json
│   │   │   ├── alpine.att.json
│   │   │   ├── alpine.cdx.att.json
│   │   │   ├── another_cosign.pub
│   │   │   ├── bad-sbom.json
│   │   │   ├── cosign.pub
│   │   │   ├── cosign_broken.pub
│   │   │   ├── image-simple/
│   │   │   │   ├── Dockerfile
│   │   │   │   ├── package.json
│   │   │   │   └── target/
│   │   │   │       └── nested/
│   │   │   │           └── package.json
│   │   │   ├── invalid.json
│   │   │   ├── purl/
│   │   │   │   ├── different-os.txt
│   │   │   │   ├── empty.json
│   │   │   │   ├── homogeneous-os.txt
│   │   │   │   ├── invalid-cpe.txt
│   │   │   │   ├── invalid-purl.txt
│   │   │   │   ├── valid-purl.txt
│   │   │   │   ├── valid-rhel-9+eus.txt
│   │   │   │   └── valid-rhel-9.txt
│   │   │   ├── sbom-with-intoto-string.json
│   │   │   ├── syft-java-bad-cpes.json
│   │   │   ├── syft-multiple-ecosystems.json
│   │   │   └── syft-spring.json
│   │   ├── upstream_package.go
│   │   ├── upstream_package_test.go
│   │   ├── version_format.go
│   │   └── version_format_test.go
│   ├── presenter/
│   │   ├── cyclonedx/
│   │   │   ├── presenter.go
│   │   │   ├── presenter_test.go
│   │   │   ├── testdata/
│   │   │   │   └── snapshot/
│   │   │   │       ├── TestCycloneDxPresenterDir.golden
│   │   │   │       └── TestCycloneDxPresenterImage.golden
│   │   │   ├── vulnerability.go
│   │   │   └── vulnerability_test.go
│   │   ├── explain/
│   │   │   ├── __snapshots__/
│   │   │   │   └── explain_snapshot_test.snap
│   │   │   ├── explain.go
│   │   │   ├── explain_cve.tmpl
│   │   │   ├── explain_snapshot_test.go
│   │   │   └── testdata/
│   │   │       ├── chainguard-ruby-test.json
│   │   │       ├── ghsa-test.json
│   │   │       └── keycloak-test.json
│   │   ├── internal/
│   │   │   └── test_helpers.go
│   │   ├── json/
│   │   │   ├── presenter.go
│   │   │   ├── presenter_test.go
│   │   │   └── testdata/
│   │   │       ├── image-simple/
│   │   │       │   ├── Dockerfile
│   │   │       │   ├── file-1.txt
│   │   │       │   ├── file-2.txt
│   │   │       │   └── target/
│   │   │       │       └── really/
│   │   │       │           └── nested/
│   │   │       │               └── file-3.txt
│   │   │       └── snapshot/
│   │   │           ├── TestEmptyJsonPresenter.golden
│   │   │           ├── TestJsonDirsPresenter.golden
│   │   │           ├── TestJsonImgsPresenter.golden
│   │   │           ├── anchore-fixture-image-simple.golden
│   │   │           └── stereoscope-fixture-image-simple.golden
│   │   ├── models/
│   │   │   ├── alert.go
│   │   │   ├── alert_test.go
│   │   │   ├── cvss.go
│   │   │   ├── descriptor.go
│   │   │   ├── distribution.go
│   │   │   ├── document.go
│   │   │   ├── document_test.go
│   │   │   ├── ignore.go
│   │   │   ├── ignore_test.go
│   │   │   ├── match.go
│   │   │   ├── metadata_mock.go
│   │   │   ├── package.go
│   │   │   ├── presenter_bundle.go
│   │   │   ├── sort.go
│   │   │   ├── sort_test.go
│   │   │   ├── source.go
│   │   │   ├── source_test.go
│   │   │   ├── vulnerability.go
│   │   │   ├── vulnerability_metadata.go
│   │   │   └── vulnerability_test.go
│   │   ├── presenter.go
│   │   ├── sarif/
│   │   │   ├── presenter.go
│   │   │   ├── presenter_test.go
│   │   │   └── testdata/
│   │   │       ├── image-simple/
│   │   │       │   ├── Dockerfile
│   │   │       │   ├── file-1.txt
│   │   │       │   ├── file-2.txt
│   │   │       │   └── target/
│   │   │       │       └── really/
│   │   │       │           └── nested/
│   │   │       │               └── file-3.txt
│   │   │       └── snapshot/
│   │   │           ├── TestSarifPresenter_directory.golden
│   │   │           └── TestSarifPresenter_image.golden
│   │   ├── table/
│   │   │   ├── __snapshots__/
│   │   │   │   └── presenter_test.snap
│   │   │   ├── presenter.go
│   │   │   ├── presenter_test.go
│   │   │   └── testdata/
│   │   │       └── snapshot/
│   │   │           └── TestTablePresenter_Color.golden
│   │   └── template/
│   │       ├── presenter.go
│   │       ├── presenter_test.go
│   │       └── testdata/
│   │           ├── snapshot/
│   │           │   └── TestPresenter_Present.golden
│   │           ├── test.template
│   │           ├── test.template.sprig.date
│   │           └── test.valid.template
│   ├── search/
│   │   ├── cpe.go
│   │   ├── cpe_test.go
│   │   ├── criteria.go
│   │   ├── criteria_test.go
│   │   ├── distro.go
│   │   ├── distro_test.go
│   │   ├── ecosystem.go
│   │   ├── ecosystem_test.go
│   │   ├── func.go
│   │   ├── func_test.go
│   │   ├── id.go
│   │   ├── id_test.go
│   │   ├── package_name.go
│   │   ├── package_name_test.go
│   │   ├── unaffected.go
│   │   ├── version_constraint.go
│   │   └── version_constraint_test.go
│   ├── version/
│   │   ├── apk_version.go
│   │   ├── apk_version_test.go
│   │   ├── bitnami_version.go
│   │   ├── bitnami_version_test.go
│   │   ├── combined_constraint.go
│   │   ├── combined_constraint_test.go
│   │   ├── comparator.go
│   │   ├── constraint.go
│   │   ├── deb_version.go
│   │   ├── deb_version_test.go
│   │   ├── deprecated.go
│   │   ├── error.go
│   │   ├── format.go
│   │   ├── format_test.go
│   │   ├── fuzzy_constraint.go
│   │   ├── fuzzy_constraint_test.go
│   │   ├── fuzzy_version.go
│   │   ├── fuzzy_version_test.go
│   │   ├── gem_version.go
│   │   ├── gem_version_test.go
│   │   ├── generic_constraint.go
│   │   ├── generic_constraint_test.go
│   │   ├── golang_version.go
│   │   ├── golang_version_test.go
│   │   ├── helper_test.go
│   │   ├── jvm_version.go
│   │   ├── jvm_version_test.go
│   │   ├── kb_constraint.go
│   │   ├── kb_constraint_test.go
│   │   ├── kb_version.go
│   │   ├── kb_version_test.go
│   │   ├── maven_version.go
│   │   ├── maven_version_test.go
│   │   ├── operator.go
│   │   ├── pacman_version.go
│   │   ├── pacman_version_test.go
│   │   ├── pep440_version.go
│   │   ├── pep440_version_test.go
│   │   ├── portage_version.go
│   │   ├── portage_version_test.go
│   │   ├── range.go
│   │   ├── range_expression.go
│   │   ├── range_expression_test.go
│   │   ├── range_test.go
│   │   ├── rpm_version.go
│   │   ├── rpm_version_test.go
│   │   ├── semantic_version.go
│   │   ├── semantic_version_test.go
│   │   ├── set.go
│   │   ├── set_test.go
│   │   ├── version.go
│   │   └── version_test.go
│   ├── vex/
│   │   ├── csaf/
│   │   │   ├── csaf.go
│   │   │   ├── csaf_test.go
│   │   │   ├── implementation.go
│   │   │   ├── implementation_test.go
│   │   │   └── status.go
│   │   ├── openvex/
│   │   │   ├── implementation.go
│   │   │   └── implementation_test.go
│   │   ├── processor.go
│   │   ├── processor_test.go
│   │   ├── status/
│   │   │   └── status.go
│   │   └── testdata/
│   │       └── vex-docs/
│   │           ├── csaf-demo1.json
│   │           ├── csaf-demo2.json
│   │           ├── openvex-debian.json
│   │           ├── openvex-demo1.json
│   │           ├── openvex-demo2.json
│   │           ├── openvex-image-no-subcomponents.json
│   │           └── openvex-package-product.json
│   ├── vulnerability/
│   │   ├── advisory.go
│   │   ├── fix.go
│   │   ├── metadata.go
│   │   ├── metadata_test.go
│   │   ├── mock/
│   │   │   └── vulnerability_provider.go
│   │   ├── provider.go
│   │   ├── severity.go
│   │   └── vulnerability.go
│   ├── vulnerability_matcher.go
│   └── vulnerability_matcher_test.go
├── install.sh
├── internal/
│   ├── bus/
│   │   ├── bus.go
│   │   └── helpers.go
│   ├── cvss/
│   │   ├── metrics.go
│   │   └── metrics_test.go
│   ├── dbtest/
│   │   ├── default_vulnerabilities.go
│   │   ├── server.go
│   │   └── server_test.go
│   ├── file/
│   │   ├── copy.go
│   │   ├── exists.go
│   │   ├── getter.go
│   │   ├── getter_test.go
│   │   ├── hasher.go
│   │   ├── hasher_test.go
│   │   ├── tar_xz_decompressor.go
│   │   ├── tar_xz_decompressor_test.go
│   │   ├── xz_decompressor.go
│   │   └── xz_decompressor_test.go
│   ├── format/
│   │   ├── format.go
│   │   ├── format_test.go
│   │   ├── presenter.go
│   │   ├── writer.go
│   │   └── writer_test.go
│   ├── input.go
│   ├── log/
│   │   ├── errors.go
│   │   └── log.go
│   ├── redact/
│   │   └── redact.go
│   ├── regex_helpers.go
│   ├── regex_helpers_test.go
│   ├── schemaver/
│   │   ├── schema_ver.go
│   │   └── schema_ver_test.go
│   ├── stringutil/
│   │   ├── color.go
│   │   ├── parse.go
│   │   ├── string_helpers.go
│   │   ├── string_helpers_test.go
│   │   ├── stringset.go
│   │   └── tprint.go
│   └── testutils/
│       └── golden_file.go
├── llms.txt
├── schema/
│   └── grype/
│       ├── db/
│       │   ├── README.md
│       │   ├── blob/
│       │   │   └── json/
│       │   │       ├── schema-6.1.1.json
│       │   │       ├── schema-6.1.2.json
│       │   │       ├── schema-6.1.3.json
│       │   │       ├── schema-6.1.4.json
│       │   │       └── schema-latest.json
│       │   └── sql/
│       │       ├── schema-6.1.1.sql
│       │       ├── schema-6.1.2.sql
│       │       ├── schema-6.1.3.sql
│       │       ├── schema-6.1.4.sql
│       │       └── schema-latest.sql
│       ├── db-search/
│       │   └── json/
│       │       ├── README.md
│       │       ├── schema-1.0.0.json
│       │       ├── schema-1.0.1.json
│       │       ├── schema-1.0.2.json
│       │       ├── schema-1.0.3.json
│       │       ├── schema-1.1.0.json
│       │       ├── schema-1.1.1.json
│       │       ├── schema-1.1.2.json
│       │       ├── schema-1.1.3.json
│       │       └── schema-latest.json
│       └── db-search-vuln/
│           └── json/
│               ├── README.md
│               ├── schema-1.0.0.json
│               ├── schema-1.0.1.json
│               ├── schema-1.0.3.json
│               ├── schema-1.0.4.json
│               ├── schema-1.0.5.json
│               └── schema-latest.json
├── templates/
│   ├── README.md
│   ├── csv.tmpl
│   ├── html.tmpl
│   ├── junit.tmpl
│   ├── markdown.tmpl
│   └── table.tmpl
└── test/
    ├── cli/
    │   ├── cmd_test.go
    │   ├── config_test.go
    │   ├── db_providers_test.go
    │   ├── db_validations_test.go
    │   ├── registry_auth_test.go
    │   ├── sbom_input_test.go
    │   ├── subprocess_test.go
    │   ├── testdata/
    │   │   ├── Makefile
    │   │   ├── another_cosign.pub
    │   │   ├── configs/
    │   │   │   ├── dir1/
    │   │   │   │   └── .grype.yaml
    │   │   │   ├── dir2/
    │   │   │   │   └── .grype.yaml
    │   │   │   └── dir3/
    │   │   │       └── .grype.yaml
    │   │   ├── cosign.pub
    │   │   ├── cosign_broken.pub
    │   │   ├── empty.json
    │   │   ├── image-bare/
    │   │   │   ├── Dockerfile
    │   │   │   └── file-1.txt
    │   │   ├── image-java-subprocess/
    │   │   │   ├── Dockerfile
    │   │   │   └── app.java
    │   │   ├── image-node-subprocess/
    │   │   │   ├── Dockerfile
    │   │   │   └── app.js
    │   │   ├── sbom-grype-source.json
    │   │   ├── sbom-ubuntu-20.04--pruned.json
    │   │   └── test-ignore-reason/
    │   │       ├── config-with-ignore.yaml
    │   │       ├── sbom.json
    │   │       └── template-with-ignore-reasons
    │   ├── trait_assertions_test.go
    │   ├── utils_test.go
    │   └── version_cmd_test.go
    ├── grype-test-config.yaml
    ├── ignore-att-signature.yaml
    ├── install/
    │   ├── .dockerignore
    │   ├── .gitignore
    │   ├── 0_checksums_test.sh
    │   ├── 1_download_snapshot_asset_test.sh
    │   ├── 2_download_release_asset_test.sh
    │   ├── 3_install_asset_test.sh
    │   ├── 4_prep_signature_verification_test.sh
    │   ├── Makefile
    │   ├── environments/
    │   │   ├── Dockerfile-alpine-3.6
    │   │   ├── Dockerfile-busybox-1.36
    │   │   └── Dockerfile-ubuntu-20.04
    │   ├── github_test.sh
    │   ├── test_harness.sh
    │   └── testdata/
    │       ├── assets/
    │       │   ├── invalid/
    │       │   │   ├── .gitignore
    │       │   │   └── checksums.txt
    │       │   └── valid/
    │       │       ├── .gitignore
    │       │       └── checksums.txt
    │       ├── github-api-grype-v0.32.0-release.json
    │       ├── grype_0.32.0-SNAPSHOT-d461f63_checksums.txt
    │       └── grype_0.32.0_checksums.txt
    ├── integration/
    │   ├── compare_sbom_input_vs_lib_test.go
    │   ├── db_mock_test.go
    │   ├── match_by_image_test.go
    │   ├── match_by_sbom_document_test.go
    │   ├── testdata/
    │   │   ├── .gitignore
    │   │   ├── Makefile
    │   │   ├── image-alpine-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── etc/
    │   │   │   │   └── os-release
    │   │   │   └── lib/
    │   │   │       └── apk/
    │   │   │           └── db/
    │   │   │               └── installed
    │   │   ├── image-arch-match-coverage/
    │   │   │   └── Dockerfile
    │   │   ├── image-centos-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── etc/
    │   │   │   │   └── os-release
    │   │   │   └── var/
    │   │   │       └── lib/
    │   │   │           └── rpm/
    │   │   │               ├── Packages
    │   │   │               └── generate-fixture.sh
    │   │   ├── image-debian-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── dotnet/
    │   │   │   │   └── TestLibrary.deps.json
    │   │   │   ├── golang/
    │   │   │   │   ├── go.mod
    │   │   │   │   ├── go.sum
    │   │   │   │   └── main.go
    │   │   │   ├── haskell/
    │   │   │   │   ├── cabal.project.freeze
    │   │   │   │   └── stack.yaml
    │   │   │   ├── java/
    │   │   │   │   └── generate-fixtures.md
    │   │   │   ├── javascript/
    │   │   │   │   └── pkg-json/
    │   │   │   │       └── package.json
    │   │   │   ├── python/
    │   │   │   │   └── dist-info/
    │   │   │   │       ├── METADATA
    │   │   │   │       └── top_level.txt
    │   │   │   ├── ruby/
    │   │   │   │   └── specifications/
    │   │   │   │       └── bundler.gemspec
    │   │   │   ├── usr/
    │   │   │   │   └── lib/
    │   │   │   │       └── os-release
    │   │   │   └── var/
    │   │   │       └── lib/
    │   │   │           └── dpkg/
    │   │   │               └── status
    │   │   ├── image-jvm-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   └── opt/
    │   │   │       └── java/
    │   │   │           └── openjdk/
    │   │   │               └── release
    │   │   ├── image-portage-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── etc/
    │   │   │   │   └── os-release
    │   │   │   └── var/
    │   │   │       └── db/
    │   │   │           ├── pkg/
    │   │   │           │   └── app-containers/
    │   │   │           │       └── skopeo-1.5.1/
    │   │   │           │           ├── CONTENTS
    │   │   │           │           ├── LICENSE
    │   │   │           │           └── SIZE
    │   │   │           └── repos/
    │   │   │               └── gentoo/
    │   │   │                   └── skel.ebuild
    │   │   ├── image-rust-auditable-match-coverage/
    │   │   │   └── Dockerfile
    │   │   ├── image-sles-match-coverage/
    │   │   │   ├── Dockerfile
    │   │   │   ├── etc/
    │   │   │   │   └── os-release
    │   │   │   └── var/
    │   │   │       └── lib/
    │   │   │           └── rpm/
    │   │   │               ├── Packages
    │   │   │               └── generate-fixture.sh
    │   │   ├── sbom/
    │   │   │   ├── syft-sbom-with-kb-packages.json
    │   │   │   └── syft-sbom-with-unknown-packages.json
    │   │   ├── skopeo-policy.json
    │   │   ├── snapshot/
    │   │   │   └── TestDatabaseDiff.golden
    │   │   └── vex/
    │   │       ├── csaf/
    │   │       │   ├── affected.csaf.json
    │   │       │   └── under_investigation.csaf.json
    │   │       └── openvex/
    │   │           ├── affected.openvex.json
    │   │           └── under_investigation.openvex.json
    │   └── utils_test.go
    ├── quality/
    │   ├── .gitignore
    │   ├── .grype.yaml
    │   ├── .python-version
    │   ├── .yardstick.yaml
    │   ├── Makefile
    │   ├── README.md
    │   ├── requirements.txt
    │   └── test-db
    └── validate-grype-db-schema.py
Download .txt
Showing preview only (406K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4164 symbols across 640 files)

FILE: .github/scripts/coverage.py
  class bcolors (line 7) | class bcolors:

FILE: cmd/grype/cli/cli.go
  function Application (line 27) | func Application(id clio.Identification) clio.Application {
  function Command (line 32) | func Command(id clio.Identification) *cobra.Command {
  function SetupConfig (line 37) | func SetupConfig(id clio.Identification) *clio.SetupConfig {
  function create (line 97) | func create(id clio.Identification) (clio.Application, *cobra.Command) {
  function syftVersion (line 116) | func syftVersion() (string, any) {
  function dbVersion (line 133) | func dbVersion() (string, any) {
  type environWithoutCI (line 137) | type environWithoutCI struct
    method Environ (line 140) | func (e environWithoutCI) Environ() []string {
    method Getenv (line 151) | func (e environWithoutCI) Getenv(s string) string {

FILE: cmd/grype/cli/cli_test.go
  function Test_Command (line 11) | func Test_Command(t *testing.T) {

FILE: cmd/grype/cli/commands/completion.go
  function Completion (line 17) | func Completion(app clio.Application) *cobra.Command {
  function listLocalDockerImages (line 71) | func listLocalDockerImages(prefix string) ([]string, error) {
  function dockerImageValidArgsFunction (line 98) | func dockerImageValidArgsFunction(_ *cobra.Command, _ []string, toComple...

FILE: cmd/grype/cli/commands/db.go
  constant jsonOutputFormat (line 10) | jsonOutputFormat  = "json"
  constant tableOutputFormat (line 11) | tableOutputFormat = "table"
  constant textOutputFormat (line 12) | textOutputFormat  = "text"
  function DB (line 15) | func DB(app clio.Application) *cobra.Command {

FILE: cmd/grype/cli/commands/db_check.go
  type dbCheckOptions (line 19) | type dbCheckOptions struct
    method AddFlags (line 26) | func (d *dbCheckOptions) AddFlags(flags clio.FlagSet) {
  function DBCheck (line 30) | func DBCheck(app clio.Application) *cobra.Command {
  function runDBCheck (line 59) | func runDBCheck(opts dbCheckOptions) error {
  type dbCheckJSON (line 90) | type dbCheckJSON struct
  function presentNewDBCheck (line 96) | func presentNewDBCheck(format string, writer io.Writer, updateAvailable ...

FILE: cmd/grype/cli/commands/db_check_test.go
  function TestPresentNewDBCheck (line 17) | func TestPresentNewDBCheck(t *testing.T) {
  function requireErrorContains (line 127) | func requireErrorContains(expected string) require.ErrorAssertionFunc {

FILE: cmd/grype/cli/commands/db_delete.go
  function DBDelete (line 14) | func DBDelete(app clio.Application) *cobra.Command {
  function runDBDelete (line 35) | func runDBDelete(opts options.DatabaseCommand) error {

FILE: cmd/grype/cli/commands/db_import.go
  function DBImport (line 15) | func DBImport(app clio.Application) *cobra.Command {
  function runDBImport (line 36) | func runDBImport(opts options.DatabaseCommand, reference string) error {

FILE: cmd/grype/cli/commands/db_list.go
  type dbListOptions (line 17) | type dbListOptions struct
    method AddFlags (line 24) | func (d *dbListOptions) AddFlags(flags clio.FlagSet) {
  function DBList (line 28) | func DBList(app clio.Application) *cobra.Command {
  function runDBList (line 53) | func runDBList(opts dbListOptions) error {
  function presentDBList (line 72) | func presentDBList(format string, archiveURL, listingURL string, writer ...

FILE: cmd/grype/cli/commands/db_list_test.go
  function Test_ListingUserAgent (line 21) | func Test_ListingUserAgent(t *testing.T) {
  function TestPresentDBList (line 68) | func TestPresentDBList(t *testing.T) {

FILE: cmd/grype/cli/commands/db_providers.go
  type dbProvidersOptions (line 20) | type dbProvidersOptions struct
    method AddFlags (line 27) | func (d *dbProvidersOptions) AddFlags(flags clio.FlagSet) {
  function DBProviders (line 31) | func DBProviders(app clio.Application) *cobra.Command {
  function runDBProviders (line 55) | func runDBProviders(opts *dbProvidersOptions) error {
  type provider (line 96) | type provider struct
  function toProviders (line 104) | func toProviders(providers []v6.Provider) []provider {
  function displayDBProvidersTable (line 118) | func displayDBProvidersTable(providers []provider, output io.Writer) err...
  function displayDBProvidersJSON (line 132) | func displayDBProvidersJSON(providers []provider, output io.Writer) error {

FILE: cmd/grype/cli/commands/db_providers_test.go
  function TestDisplayDBProvidersTable (line 11) | func TestDisplayDBProvidersTable(t *testing.T) {
  function TestDisplayDBProvidersJSON (line 40) | func TestDisplayDBProvidersJSON(t *testing.T) {
  function timeRef (line 83) | func timeRef(t time.Time) *time.Time {

FILE: cmd/grype/cli/commands/db_search.go
  type dbSearchMatchOptions (line 24) | type dbSearchMatchOptions struct
    method applyArgs (line 36) | func (o *dbSearchMatchOptions) applyArgs(args []string) error {
  function hasAnyPrefix (line 66) | func hasAnyPrefix(s string, prefixes ...string) bool {
  function DBSearch (line 75) | func DBSearch(app clio.Application) *cobra.Command {
  function runDBSearchMatches (line 141) | func runDBSearchMatches(opts dbSearchMatchOptions) error {
  function presentDBSearchMatches (line 189) | func presentDBSearchMatches(outputFormat string, structuredRows dbsearch...
  function renderDBSearchPackagesTableRows (line 221) | func renderDBSearchPackagesTableRows(structuredRows []dbsearch.AffectedP...
  function mimicV5Namespace (line 254) | func mimicV5Namespace(row dbsearch.AffectedPackage) string {

FILE: cmd/grype/cli/commands/db_search_test.go
  function TestDBSearchMatchOptionsApplyArgs (line 15) | func TestDBSearchMatchOptionsApplyArgs(t *testing.T) {
  function TestMimicV5Namespace (line 109) | func TestMimicV5Namespace(t *testing.T) {

FILE: cmd/grype/cli/commands/db_search_vuln.go
  type dbSearchVulnerabilityOptions (line 24) | type dbSearchVulnerabilityOptions struct
  function DBSearchVulnerabilities (line 32) | func DBSearchVulnerabilities(app clio.Application) *cobra.Command {
  function runDBSearchVulnerabilities (line 67) | func runDBSearchVulnerabilities(opts dbSearchVulnerabilityOptions) error {
  function validateProvidersFilter (line 105) | func validateProvidersFilter(reader v6.Reader, providers []string) error {
  function presentDBSearchVulnerabilities (line 131) | func presentDBSearchVulnerabilities(outputFormat string, structuredRows ...
  function renderDBSearchVulnerabilitiesTableRows (line 164) | func renderDBSearchVulnerabilitiesTableRows(structuredRows []dbsearch.Vu...
  function getOSVersions (line 208) | func getOSVersions(oss []dbsearch.OperatingSystem) []string {
  function getPrimaryReference (line 216) | func getPrimaryReference(refs []v6.Reference) string {
  function getDate (line 224) | func getDate(t *time.Time) string {

FILE: cmd/grype/cli/commands/db_search_vuln_test.go
  function TestGetOSVersions (line 13) | func TestGetOSVersions(t *testing.T) {
  function TestGetPrimaryReference (line 62) | func TestGetPrimaryReference(t *testing.T) {
  function TestGetDate (line 107) | func TestGetDate(t *testing.T) {
  function timePtr (line 138) | func timePtr(t time.Time) *time.Time {

FILE: cmd/grype/cli/commands/db_status.go
  type dbStatusOptions (line 19) | type dbStatusOptions struct
    method AddFlags (line 26) | func (d *dbStatusOptions) AddFlags(flags clio.FlagSet) {
  function DBStatus (line 30) | func DBStatus(app clio.Application) *cobra.Command {
  function runDBStatus (line 55) | func runDBStatus(opts dbStatusOptions) error {
  function presentDBStatus (line 74) | func presentDBStatus(format string, writer io.Writer, status vulnerabili...
  function renderStoreValidation (line 98) | func renderStoreValidation(status vulnerability.ProviderStatus) string {

FILE: cmd/grype/cli/commands/db_status_test.go
  function TestPresentDBStatus (line 16) | func TestPresentDBStatus(t *testing.T) {

FILE: cmd/grype/cli/commands/db_update.go
  function DBUpdate (line 16) | func DBUpdate(app clio.Application) *cobra.Command {
  function runDBUpdate (line 41) | func runDBUpdate(opts options.DatabaseCommand) error {

FILE: cmd/grype/cli/commands/explain.go
  type explainOptions (line 17) | type explainOptions struct
    method AddFlags (line 23) | func (d *explainOptions) AddFlags(flags clio.FlagSet) {
  function Explain (line 27) | func Explain(app clio.Application) *cobra.Command {

FILE: cmd/grype/cli/commands/internal/dbsearch/affected_packages.go
  type AffectedPackage (line 15) | type AffectedPackage struct
  type AffectedPackageInfo (line 23) | type AffectedPackageInfo struct
  type Package (line 46) | type Package struct
  type CPE (line 55) | type CPE
    method MarshalJSON (line 57) | func (c *CPE) MarshalJSON() ([]byte, error) {
    method String (line 61) | func (c *CPE) String() string {
  type AffectedPackagesOptions (line 69) | type AffectedPackagesOptions struct
  type affectedPackageWithDecorations (line 79) | type affectedPackageWithDecorations struct
    method getCVEs (line 84) | func (a *affectedPackageWithDecorations) getCVEs() []string {
  type affectedCPEWithDecorations (line 91) | type affectedCPEWithDecorations struct
    method getCVEs (line 96) | func (a *affectedCPEWithDecorations) getCVEs() []string {
  function newAffectedPackageRows (line 103) | func newAffectedPackageRows(affectedPkgs []affectedPackageWithDecoration...
  function toPackage (line 157) | func toPackage(pkg *v6.Package) *Package {
  function toOS (line 167) | func toOS(os *v6.OperatingSystem) *OperatingSystem {
  function FindAffectedPackages (line 178) | func FindAffectedPackages(reader interface {
  function findAffectedPackages (line 197) | func findAffectedPackages(reader interface { //nolint:funlen,gocognit

FILE: cmd/grype/cli/commands/internal/dbsearch/affected_packages_test.go
  function TestAffectedPackageTableRowMarshalJSON (line 18) | func TestAffectedPackageTableRowMarshalJSON(t *testing.T) {
  function TestNewAffectedPackageRows (line 157) | func TestNewAffectedPackageRows(t *testing.T) {
  function TestAffectedPackages (line 419) | func TestAffectedPackages(t *testing.T) {
  function TestFindAffectedPackages (line 653) | func TestFindAffectedPackages(t *testing.T) {
  type affectedMockReader (line 874) | type affectedMockReader struct
    method GetAffectedPackages (line 878) | func (m *affectedMockReader) GetAffectedPackages(pkgSpec *v6.PackageSp...
    method GetAffectedCPEs (line 883) | func (m *affectedMockReader) GetAffectedCPEs(cpeSpec *cpe.Attributes, ...
    method GetKnownExploitedVulnerabilities (line 888) | func (m *affectedMockReader) GetKnownExploitedVulnerabilities(cve stri...
    method GetEpss (line 893) | func (m *affectedMockReader) GetEpss(cve string) ([]v6.EpssHandle, err...
    method GetCWEs (line 898) | func (m *affectedMockReader) GetCWEs(cve string) ([]v6.CWEHandle, erro...
  function ptr (line 903) | func ptr[T any](t T) *T {
  function TestGetFixStateFromPackageBlob (line 907) | func TestGetFixStateFromPackageBlob(t *testing.T) {
  function TestFilterByFixedStateForPackages (line 1003) | func TestFilterByFixedStateForPackages(t *testing.T) {
  function TestFilterByFixedStateForCPEs (line 1065) | func TestFilterByFixedStateForCPEs(t *testing.T) {
  function makeAffectedPackageWithFixState (line 1119) | func makeAffectedPackageWithFixState(state v6.FixStatus) affectedPackage...
  function makeAffectedCPEWithFixState (line 1136) | func makeAffectedCPEWithFixState(state v6.FixStatus) affectedCPEWithDeco...

FILE: cmd/grype/cli/commands/internal/dbsearch/common.go
  constant fixStateFixed (line 6) | fixStateFixed    = "fixed"
  constant fixStateNotFixed (line 7) | fixStateNotFixed = "not-fixed"
  constant fixStateWontFix (line 8) | fixStateWontFix  = "wont-fix"
  constant fixStateUnknown (line 9) | fixStateUnknown  = "unknown"
  function getFixStateFromPackageBlob (line 16) | func getFixStateFromPackageBlob(blob *v6.PackageBlob) string {
  function filterByFixedStateForPackages (line 52) | func filterByFixedStateForPackages(packages []affectedPackageWithDecorat...
  function filterByFixedStateForCPEs (line 77) | func filterByFixedStateForCPEs(cpes []affectedCPEWithDecorations, fixedS...

FILE: cmd/grype/cli/commands/internal/dbsearch/matches.go
  type Matches (line 14) | type Matches
    method Flatten (line 36) | func (m Matches) Flatten() []AffectedPackage {
  type Match (line 17) | type Match struct
    method Flatten (line 25) | func (m Match) Flatten() []AffectedPackage {
  function newMatchesRows (line 44) | func newMatchesRows(affectedPkgs []affectedPackageWithDecorations, affec...
  function FindMatches (line 120) | func FindMatches(reader interface {

FILE: cmd/grype/cli/commands/internal/dbsearch/matches_test.go
  function TestGetFixStateFromBlob (line 11) | func TestGetFixStateFromBlob(t *testing.T) {
  function TestFilterByFixedState (line 125) | func TestFilterByFixedState(t *testing.T) {
  function TestFilterCPEsByFixedState (line 200) | func TestFilterCPEsByFixedState(t *testing.T) {
  function makeTestPackages (line 265) | func makeTestPackages(count int) []affectedPackageWithDecorations {
  function makePackageWithFixState (line 277) | func makePackageWithFixState(state v6.FixStatus) affectedPackageWithDeco...
  function makeTestCPEs (line 294) | func makeTestCPEs(count int) []affectedCPEWithDecorations {
  function makeCPEWithFixState (line 306) | func makeCPEWithFixState(state v6.FixStatus) affectedCPEWithDecorations {

FILE: cmd/grype/cli/commands/internal/dbsearch/versions.go
  constant MatchesSchemaVersion (line 5) | MatchesSchemaVersion = "1.1.3"
  constant VulnerabilitiesSchemaVersion (line 18) | VulnerabilitiesSchemaVersion = "1.0.5"

FILE: cmd/grype/cli/commands/internal/dbsearch/vulnerabilities.go
  type Vulnerabilities (line 16) | type Vulnerabilities
  type Vulnerability (line 19) | type Vulnerability struct
  type VulnerabilityInfo (line 29) | type VulnerabilityInfo struct
  type OperatingSystem (line 66) | type OperatingSystem struct
  type KnownExploited (line 74) | type KnownExploited struct
  type EPSS (line 87) | type EPSS struct
  type CWE (line 94) | type CWE struct
  type CVSSSeverity (line 101) | type CVSSSeverity struct
  type CvssMetrics (line 112) | type CvssMetrics struct
  type vulnerabilityAffectedPackageJoin (line 118) | type vulnerabilityAffectedPackageJoin struct
  type VulnerabilitiesOptions (line 125) | type VulnerabilitiesOptions struct
  function newVulnerabilityRows (line 130) | func newVulnerabilityRows(vaps ...vulnerabilityAffectedPackageJoin) (row...
  function newVulnerabilityInfo (line 141) | func newVulnerabilityInfo(vuln v6.VulnerabilityHandle, vc vulnerabilityD...
  function patchCVSSMetrics (line 161) | func patchCVSSMetrics(blob *v6.VulnerabilityBlob) {
  function newOperatingSystems (line 184) | func newOperatingSystems(oss []v6.OperatingSystem) (os []OperatingSystem) {
  function FindVulnerabilities (line 194) | func FindVulnerabilities(reader interface { //nolint:funlen
  function getSeverity (line 286) | func getSeverity(sevs []v6.Severity) string {

FILE: cmd/grype/cli/commands/internal/dbsearch/vulnerabilities_test.go
  function TestGetSeverity (line 17) | func TestGetSeverity(t *testing.T) {
  function TestNewVulnerabilityRows (line 104) | func TestNewVulnerabilityRows(t *testing.T) {
  function TestVulnerabilities (line 224) | func TestVulnerabilities(t *testing.T) {
  function TestFindVulnerabilities_DecorationErrors (line 354) | func TestFindVulnerabilities_DecorationErrors(t *testing.T) {
  type mockVulnReader (line 414) | type mockVulnReader struct
    method GetVulnerabilities (line 418) | func (m *mockVulnReader) GetVulnerabilities(vuln *v6.VulnerabilitySpec...
    method GetAffectedPackages (line 423) | func (m *mockVulnReader) GetAffectedPackages(pkg *v6.PackageSpecifier,...
    method GetKnownExploitedVulnerabilities (line 428) | func (m *mockVulnReader) GetKnownExploitedVulnerabilities(cve string) ...
    method GetEpss (line 433) | func (m *mockVulnReader) GetEpss(cve string) ([]v6.EpssHandle, error) {
    method GetCWEs (line 438) | func (m *mockVulnReader) GetCWEs(cve string) ([]v6.CWEHandle, error) {
  function cmpOpts (line 443) | func cmpOpts() []cmp.Option {

FILE: cmd/grype/cli/commands/internal/dbsearch/vulnerability_decorations.go
  type canonicalVulnerability (line 14) | type canonicalVulnerability interface
  type vulnerabilityDecorations (line 23) | type vulnerabilityDecorations struct
    method decorate (line 89) | func (vd *vulnerabilityDecorations) decorate(kevs []KnownExploited, ep...
  function decorateVulnerabilities (line 28) | func decorateVulnerabilities(reader v6.VulnerabilityDecoratorStoreReader...
  method getCVEs (line 49) | func (afj *vulnerabilityAffectedPackageJoin) getCVEs() []string {
  function getCVEs (line 56) | func getCVEs(v *v6.VulnerabilityHandle) []string {
  function fetchKnownExploited (line 98) | func fetchKnownExploited(reader v6.VulnerabilityDecoratorStoreReader, cv...
  function fetchEpss (line 125) | func fetchEpss(reader v6.VulnerabilityDecoratorStoreReader, cves []strin...

FILE: cmd/grype/cli/commands/internal/jsonschema/main.go
  function main (line 21) | func main() {
  function compose (line 31) | func compose(document any, component, version string, comments map[strin...
  function write (line 35) | func write(schema []byte, component, version string) {
  function encode (line 88) | func encode(schema *jsonschema.Schema) []byte {
  function build (line 102) | func build(document any, component, version string, comments map[string]...
  function parseCommentsFromPackages (line 148) | func parseCommentsFromPackages(pkgPatterns []string) map[string]map[stri...
  function parseFileComments (line 173) | func parseFileComments(node *ast.File) map[string]map[string]string {
  function cleanComment (line 227) | func cleanComment(comment string) string {
  function getJSONTag (line 237) | func getJSONTag(field *ast.Field) string {
  function schemaID (line 249) | func schemaID(component, version string) jsonschema.ID {
  function repoRoot (line 253) | func repoRoot() string {

FILE: cmd/grype/cli/commands/root.go
  function Root (line 49) | func Root(app clio.Application) *cobra.Command {
  function runGrype (line 119) | func runGrype(ctx context.Context, app clio.Application, opts *options.G...
  function warnWhenDistroHintNeeded (line 278) | func warnWhenDistroHintNeeded(pkgs []pkg.Package, context *pkg.Context) {
  function warnDistroAlerts (line 296) | func warnDistroAlerts(data *models.DistroAlertData) {
  function countPackagesByDistro (line 308) | func countPackagesByDistro(packages []pkg.Package) map[string]int {
  function dbInfo (line 320) | func dbInfo(status *vulnerability.ProviderStatus, vp vulnerability.Provi...
  function checkForAppUpdate (line 343) | func checkForAppUpdate(id clio.Identification, opts *options.Grype) {
  function getMatcherConfig (line 367) | func getMatcherConfig(opts *options.Grype) matcher.Config {
  function getMatchers (line 395) | func getMatchers(opts *options.Grype) []match.Matcher {
  function getProviderConfig (line 399) | func getProviderConfig(opts *options.Grype) pkg.ProviderConfig {
  function getFixChannels (line 429) | func getFixChannels(fixChannelOpts options.FixChannels) distro.FixChanne...
  function applyDistroHint (line 455) | func applyDistroHint(hint string) *distro.Distro {
  function validateDBLoad (line 464) | func validateDBLoad(loadErr error, status *vulnerability.ProviderStatus)...
  function validateRootArgs (line 484) | func validateRootArgs(cmd *cobra.Command, args []string) error {
  function applyVexRules (line 510) | func applyVexRules(opts *options.Grype) error {

FILE: cmd/grype/cli/commands/root_test.go
  function Test_getProviderConfig (line 35) | func Test_getProviderConfig(t *testing.T) {
  function Test_getMatcherConfig (line 88) | func Test_getMatcherConfig(t *testing.T) {
  function Test_applyVexRules (line 208) | func Test_applyVexRules(t *testing.T) {

FILE: cmd/grype/cli/commands/update.go
  function isProductionBuild (line 22) | func isProductionBuild(version string) bool {
  function isUpdateAvailable (line 29) | func isUpdateAvailable(id clio.Identification) (bool, string, error) {
  function fetchLatestApplicationVersion (line 51) | func fetchLatestApplicationVersion(id clio.Identification) (*hashiVersio...

FILE: cmd/grype/cli/commands/update_test.go
  function TestIsUpdateAvailable (line 13) | func TestIsUpdateAvailable(t *testing.T) {
  function TestFetchLatestApplicationVersion (line 131) | func TestFetchLatestApplicationVersion(t *testing.T) {
  function Test_UserAgent (line 213) | func Test_UserAgent(t *testing.T) {

FILE: cmd/grype/cli/commands/util.go
  function disableUI (line 21) | func disableUI(app clio.Application) func(*cobra.Command, []string) error {
  function stderrPrintLnf (line 34) | func stderrPrintLnf(message string, args ...interface{}) error {
  function parallel (line 45) | func parallel(funcs ...func() error) error {
  function parallelMapped (line 59) | func parallelMapped(funcs ...func() error) map[int]error {
  function appendErrors (line 79) | func appendErrors(errs error, err ...error) error {
  function newTable (line 91) | func newTable(output io.Writer, columns []string) *tablewriter.Table {

FILE: cmd/grype/cli/commands/util_test.go
  constant lotsaParallel (line 13) | lotsaParallel = 100
  function Test_lotsaLotsaParallel (line 15) | func Test_lotsaLotsaParallel(t *testing.T) {
  function Test_lotsaParallel (line 27) | func Test_lotsaParallel(t *testing.T) {
  function Test_parallel (line 35) | func Test_parallel(t *testing.T) {
  function Test_parallelMapped (line 95) | func Test_parallelMapped(t *testing.T) {

FILE: cmd/grype/cli/options/alerts.go
  type Alerts (line 6) | type Alerts struct
    method DescribeFields (line 19) | func (a *Alerts) DescribeFields(descriptions clio.FieldDescriptionSet) {
  function defaultAlerts (line 13) | func defaultAlerts() Alerts {

FILE: cmd/grype/cli/options/alerts_test.go
  function TestDefaultAlerts (line 9) | func TestDefaultAlerts(t *testing.T) {

FILE: cmd/grype/cli/options/database.go
  type Database (line 12) | type Database struct
    method DescribeFields (line 52) | func (cfg *Database) DescribeFields(descriptions clio.FieldDescription...
    method PostLoad (line 70) | func (cfg *Database) PostLoad() error {
  function DefaultDatabase (line 32) | func DefaultDatabase(id clio.Identification) Database {

FILE: cmd/grype/cli/options/database_command.go
  type DatabaseCommand (line 9) | type DatabaseCommand struct
    method ToCuratorConfig (line 26) | func (cfg DatabaseCommand) ToCuratorConfig() installation.Config {
    method ToClientConfig (line 37) | func (cfg DatabaseCommand) ToClientConfig() distribution.Config {
  function DefaultDatabaseCommand (line 15) | func DefaultDatabaseCommand(id clio.Identification) *DatabaseCommand {

FILE: cmd/grype/cli/options/database_search_bounds.go
  type DBSearchBounds (line 9) | type DBSearchBounds struct
    method AddFlags (line 19) | func (o *DBSearchBounds) AddFlags(flags clio.FlagSet) {
    method PostLoad (line 23) | func (o *DBSearchBounds) PostLoad() error {
  function DefaultDBSearchBounds (line 13) | func DefaultDBSearchBounds() DBSearchBounds {

FILE: cmd/grype/cli/options/database_search_format.go
  type DBSearchFormat (line 12) | type DBSearchFormat struct
    method AddFlags (line 24) | func (c *DBSearchFormat) AddFlags(flags clio.FlagSet) {
    method PostLoad (line 29) | func (c *DBSearchFormat) PostLoad() error {
  function DefaultDBSearchFormat (line 17) | func DefaultDBSearchFormat() DBSearchFormat {

FILE: cmd/grype/cli/options/database_search_os.go
  type DBSearchOSs (line 13) | type DBSearchOSs struct
    method AddFlags (line 18) | func (o *DBSearchOSs) AddFlags(flags clio.FlagSet) {
    method PostLoad (line 23) | func (o *DBSearchOSs) PostLoad() error {
  function parseOSString (line 42) | func parseOSString(osValue string) (*v6.OSSpecifier, error) {

FILE: cmd/grype/cli/options/database_search_os_test.go
  function TestDBSearchOSsPostLoad (line 12) | func TestDBSearchOSsPostLoad(t *testing.T) {

FILE: cmd/grype/cli/options/database_search_packages.go
  type DBSearchPackages (line 15) | type DBSearchPackages struct
    method AddFlags (line 23) | func (o *DBSearchPackages) AddFlags(flags clio.FlagSet) {
    method PostLoad (line 29) | func (o *DBSearchPackages) PostLoad() error {

FILE: cmd/grype/cli/options/database_search_packages_test.go
  function TestDBSearchPackagesPostLoad (line 13) | func TestDBSearchPackagesPostLoad(t *testing.T) {

FILE: cmd/grype/cli/options/database_search_vulnerabilities.go
  type DBSearchVulnerabilities (line 13) | type DBSearchVulnerabilities struct
    method AddFlags (line 26) | func (c *DBSearchVulnerabilities) AddFlags(flags clio.FlagSet) {
    method PostLoad (line 36) | func (c *DBSearchVulnerabilities) PostLoad() error {

FILE: cmd/grype/cli/options/database_search_vulnerabilities_test.go
  function TestDBSearchVulnerabilitiesPostLoad (line 13) | func TestDBSearchVulnerabilitiesPostLoad(t *testing.T) {
  function parseTime (line 145) | func parseTime(value string) *time.Time {

FILE: cmd/grype/cli/options/datasources.go
  constant defaultMavenBaseURL (line 11) | defaultMavenBaseURL = "https://search.maven.org/solrsearch/select"
  type externalSources (line 14) | type externalSources struct
    method ToJavaMatcherConfig (line 39) | func (cfg externalSources) ToJavaMatcherConfig() java.ExternalSearchCo...
    method DescribeFields (line 52) | func (cfg *externalSources) DescribeFields(descriptions clio.FieldDesc...
  type maven (line 23) | type maven struct
  function defaultExternalSources (line 29) | func defaultExternalSources() externalSources {

FILE: cmd/grype/cli/options/experimental.go
  type Experimental (line 9) | type Experimental struct

FILE: cmd/grype/cli/options/fix_channels.go
  type FixChannelEnabled (line 11) | type FixChannelEnabled
  type FixChannels (line 13) | type FixChannels struct
    method DescribeFields (line 57) | func (o *FixChannels) DescribeFields(descriptions clio.FieldDescriptio...
  type FixChannel (line 20) | type FixChannel struct
    method PostLoad (line 28) | func (o *FixChannel) PostLoad() error {
  function DefaultFixChannels (line 41) | func DefaultFixChannels() FixChannels {

FILE: cmd/grype/cli/options/grype.go
  type Grype (line 14) | type Grype struct
    method AddFlags (line 81) | func (o *Grype) AddFlags(flags clio.FlagSet) {
    method PostLoad (line 167) | func (o *Grype) PostLoad() error {
    method DescribeFields (line 179) | func (o *Grype) DescribeFields(descriptions clio.FieldDescriptionSet) {
    method FailOnSeverity (line 217) | func (o Grype) FailOnSeverity() *vulnerability.Severity {
  type developer (line 48) | type developer struct
  type databaseDeveloper (line 52) | type databaseDeveloper struct
  function DefaultGrype (line 62) | func DefaultGrype(id clio.Identification) *Grype {
  function flatten (line 223) | func flatten(commaSeparatedEntries []string) []string {

FILE: cmd/grype/cli/options/grype_test.go
  function Test_flatten (line 9) | func Test_flatten(t *testing.T) {

FILE: cmd/grype/cli/options/match.go
  type matchConfig (line 11) | type matchConfig struct
    method PostLoad (line 136) | func (cfg *matchConfig) PostLoad() error {
    method DescribeFields (line 164) | func (cfg *matchConfig) DescribeFields(descriptions clio.FieldDescript...
  type matcherConfig (line 31) | type matcherConfig struct
  type golangConfig (line 35) | type golangConfig struct
  type dpkgConfig (line 42) | type dpkgConfig struct
    method PostLoad (line 156) | func (cfg *dpkgConfig) PostLoad() error {
  type rpmConfig (line 67) | type rpmConfig struct
    method PostLoad (line 147) | func (cfg *rpmConfig) PostLoad() error {
  function defaultGolangConfig (line 91) | func defaultGolangConfig() golangConfig {
  function defaultRpmConfig (line 101) | func defaultRpmConfig() rpmConfig {
  function defaultDpkgConfig (line 109) | func defaultDpkgConfig() dpkgConfig {
  function defaultMatchConfig (line 117) | func defaultMatchConfig() matchConfig {

FILE: cmd/grype/cli/options/match_test.go
  function TestRpmConfig_PostLoad (line 12) | func TestRpmConfig_PostLoad(t *testing.T) {
  function TestDpkgConfig_PostLoad (line 68) | func TestDpkgConfig_PostLoad(t *testing.T) {
  function TestMatchConfig_PostLoad (line 119) | func TestMatchConfig_PostLoad(t *testing.T) {
  function TestDefaultRpmConfig (line 177) | func TestDefaultRpmConfig(t *testing.T) {
  function TestDefaultDpkgConfig (line 187) | func TestDefaultDpkgConfig(t *testing.T) {
  function TestDefaultMatchConfig (line 197) | func TestDefaultMatchConfig(t *testing.T) {

FILE: cmd/grype/cli/options/registry.go
  type RegistryCredentials (line 10) | type RegistryCredentials struct
  type registry (line 21) | type registry struct
    method PostLoad (line 33) | func (cfg *registry) PostLoad() error {
    method DescribeFields (line 59) | func (cfg *registry) DescribeFields(descriptions clio.FieldDescription...
    method ToOptions (line 80) | func (cfg *registry) ToOptions() *image.RegistryOptions {
  function hasNonEmptyCredentials (line 73) | func hasNonEmptyCredentials(username, password, token, tlsCert, tlsKey s...

FILE: cmd/grype/cli/options/registry_test.go
  function TestHasNonEmptyCredentials (line 12) | func TestHasNonEmptyCredentials(t *testing.T) {
  function Test_registry_ToOptions (line 72) | func Test_registry_ToOptions(t *testing.T) {

FILE: cmd/grype/cli/options/search.go
  type search (line 11) | type search struct
    method PostLoad (line 31) | func (cfg *search) PostLoad() error {
    method DescribeFields (line 39) | func (cfg *search) DescribeFields(descriptions clio.FieldDescriptionSe...
    method GetScope (line 47) | func (cfg search) GetScope() source.Scope {
  function defaultSearch (line 22) | func defaultSearch(scope source.Scope) search {

FILE: cmd/grype/cli/options/secret.go
  type secret (line 10) | type secret
    method PostLoad (line 18) | func (r *secret) PostLoad() error {
    method String (line 23) | func (r secret) String() string {
    method MarshalText (line 31) | func (r secret) MarshalText() ([]byte, error) {

FILE: cmd/grype/cli/options/sort_by.go
  type SortBy (line 19) | type SortBy struct
    method AddFlags (line 35) | func (o *SortBy) AddFlags(flags clio.FlagSet) {
    method PostLoad (line 42) | func (o *SortBy) PostLoad() error {
  function defaultSortBy (line 24) | func defaultSortBy() SortBy {

FILE: cmd/grype/cli/ui/handle_database_diff_started.go
  type dbDiffProgressStager (line 16) | type dbDiffProgressStager struct
    method Stage (line 20) | func (p dbDiffProgressStager) Stage() string {
    method Current (line 27) | func (p dbDiffProgressStager) Current() int64 {
    method Error (line 31) | func (p dbDiffProgressStager) Error() error {
    method Size (line 35) | func (p dbDiffProgressStager) Size() int64 {
  method handleDatabaseDiffStarted (line 39) | func (m *Handler) handleDatabaseDiffStarted(e partybus.Event) ([]tea.Mod...

FILE: cmd/grype/cli/ui/handle_database_diff_started_test.go
  function TestHandler_handleDatabaseDiffStarted (line 18) | func TestHandler_handleDatabaseDiffStarted(t *testing.T) {

FILE: cmd/grype/cli/ui/handle_update_vulnerability_database.go
  type dbDownloadProgressStager (line 16) | type dbDownloadProgressStager struct
    method Stage (line 20) | func (s dbDownloadProgressStager) Stage() string {
  method handleUpdateVulnerabilityDatabase (line 38) | func (m *Handler) handleUpdateVulnerabilityDatabase(e partybus.Event) ([...
  function safeConvertInt64ToUint64 (line 58) | func safeConvertInt64ToUint64(i int64) uint64 {

FILE: cmd/grype/cli/ui/handle_update_vulnerability_database_test.go
  function TestHandler_handleUpdateVulnerabilityDatabase (line 17) | func TestHandler_handleUpdateVulnerabilityDatabase(t *testing.T) {

FILE: cmd/grype/cli/ui/handle_vulnerability_scanning_started.go
  constant branch (line 22) | branch = "├──"
  constant end (line 23) | end    = "└──"
  type vulnerabilityProgressTree (line 28) | type vulnerabilityProgressTree struct
    method Init (line 112) | func (l vulnerabilityProgressTree) Init() tea.Cmd {
    method Update (line 129) | func (l vulnerabilityProgressTree) Update(msg tea.Msg) (tea.Model, tea...
    method View (line 155) | func (l vulnerabilityProgressTree) View() string {
    method queueNextTick (line 193) | func (l vulnerabilityProgressTree) queueNextTick() tea.Cmd {
    method handleTick (line 203) | func (l *vulnerabilityProgressTree) handleTick(msg vulnerabilityProgre...
  function newVulnerabilityProgressTree (line 47) | func newVulnerabilityProgressTree(monitor *monitor.Matching, textStyle l...
  type vulnerabilityProgressTreeTickMsg (line 60) | type vulnerabilityProgressTreeTickMsg struct
  type vulnerabilityScanningAdapter (line 66) | type vulnerabilityScanningAdapter struct
    method Current (line 70) | func (p vulnerabilityScanningAdapter) Current() int64 {
    method Error (line 74) | func (p vulnerabilityScanningAdapter) Error() error {
    method Size (line 78) | func (p vulnerabilityScanningAdapter) Size() int64 {
    method Stage (line 82) | func (p vulnerabilityScanningAdapter) Stage() string {
  method handleVulnerabilityScanningStarted (line 86) | func (m *Handler) handleVulnerabilityScanningStarted(e partybus.Event) (...

FILE: cmd/grype/cli/ui/handle_vulnerability_scanning_started_test.go
  function TestHandler_handleVulnerabilityScanningStarted (line 20) | func TestHandler_handleVulnerabilityScanningStarted(t *testing.T) {
  function getVulnerabilityMonitor (line 86) | func getVulnerabilityMonitor(completed bool) monitor.Matching {

FILE: cmd/grype/cli/ui/handler.go
  type HandlerConfig (line 20) | type HandlerConfig struct
  type Handler (line 25) | type Handler struct
    method OnMessage (line 58) | func (m *Handler) OnMessage(msg tea.Msg) {
    method Wait (line 64) | func (m *Handler) Wait() {
  function DefaultHandlerConfig (line 33) | func DefaultHandlerConfig() HandlerConfig {
  function New (line 39) | func New(cfg HandlerConfig) *Handler {

FILE: cmd/grype/cli/ui/new_task_progress.go
  method newTaskProgress (line 5) | func (m Handler) newTaskProgress(title taskprogress.Title, opts ...taskp...

FILE: cmd/grype/cli/ui/util_test.go
  function runModel (line 12) | func runModel(t testing.TB, m tea.Model, iterations int, message tea.Msg...
  function flatten (line 42) | func flatten(p tea.Msg) (msgs []tea.Msg) {
  function extractBatchMessages (line 54) | func extractBatchMessages(m tea.Msg) (ret []tea.Msg) {

FILE: cmd/grype/internal/constants.go
  constant NotProvided (line 4) | NotProvided = "[not provided]"

FILE: cmd/grype/internal/ui/no_ui.go
  type NoUI (line 14) | type NoUI struct
    method Setup (line 26) | func (n *NoUI) Setup(subscription partybus.Unsubscribable) error {
    method Handle (line 31) | func (n *NoUI) Handle(e partybus.Event) error {
    method Teardown (line 40) | func (n NoUI) Teardown(_ bool) error {
  function None (line 20) | func None(quiet bool) *NoUI {

FILE: cmd/grype/internal/ui/post_ui_event_writer.go
  type postUIEventWriter (line 17) | type postUIEventWriter struct
    method write (line 55) | func (w postUIEventWriter) write(quiet bool, events ...partybus.Event)...
  type postUIHandle (line 21) | type postUIHandle struct
  type eventWriter (line 28) | type eventWriter
  function newPostUIEventWriter (line 30) | func newPostUIEventWriter(stdout, stderr io.Writer) *postUIEventWriter {
  function writeReports (line 75) | func writeReports(writer io.Writer, events ...partybus.Event) error {
  function writeNotifications (line 97) | func writeNotifications(writer io.Writer, events ...partybus.Event) error {
  function writeAppUpdate (line 116) | func writeAppUpdate(writer io.Writer, events ...partybus.Event) error {

FILE: cmd/grype/internal/ui/post_ui_event_writer_test.go
  function Test_postUIEventWriter_write (line 15) | func Test_postUIEventWriter_write(t *testing.T) {

FILE: cmd/grype/internal/ui/ui.go
  type UI (line 27) | type UI struct
    method Setup (line 47) | func (m *UI) Setup(subscription partybus.Unsubscribable) error {
    method Handle (line 68) | func (m *UI) Handle(e partybus.Event) error {
    method Teardown (line 75) | func (m *UI) Teardown(force bool) error {
    method Init (line 115) | func (m UI) Init() tea.Cmd {
    method RespondsTo (line 119) | func (m UI) RespondsTo() []partybus.EventType {
    method Update (line 127) | func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
    method View (line 182) | func (m UI) View() string {
  function New (line 38) | func New(quiet bool, handlers ...bubbly.EventHandler) *UI {
  function runWithTimeout (line 186) | func runWithTimeout(timeout time.Duration, fn func() error) (err error) {

FILE: cmd/grype/main.go
  constant applicationName (line 12) | applicationName = "grype"
  function main (line 22) | func main() {

FILE: grype/cpe/cpe.go
  function NewSlice (line 10) | func NewSlice(cpeStrs ...string) ([]cpe.CPE, error) {
  function MatchWithoutVersion (line 24) | func MatchWithoutVersion(c cpe.CPE, candidates []cpe.CPE) []cpe.CPE {

FILE: grype/cpe/cpe_test.go
  function TestMatchWithoutVersion (line 11) | func TestMatchWithoutVersion(t *testing.T) {

FILE: grype/db/build.go
  constant DefaultBatchSize (line 25) | DefaultBatchSize = 2000
  type BuildConfig (line 27) | type BuildConfig struct
  function Build (line 39) | func Build(cfg BuildConfig) error {
  type providerResults (line 86) | type providerResults struct
  function getProcessors (line 92) | func getProcessors(cfg BuildConfig) ([]data.Processor, error) {
  function getWriter (line 103) | func getWriter(cfg BuildConfig) (data.Writer, error) {
  function build (line 120) | func build(results []providerResults, writer data.Writer, processors ......
  function hydrate (line 204) | func hydrate(cfg BuildConfig) error {
  function logDropped (line 222) | func logDropped(droppedElementsByProvider, droppedSchemaElements map[str...
  type expMovingAverage (line 242) | type expMovingAverage struct
    method Add (line 252) | func (e *expMovingAverage) Add(sample float64) {
    method Average (line 261) | func (e *expMovingAverage) Average() float64 {
  function newEMA (line 248) | func newEMA(alpha float64) *expMovingAverage {
  function recordsPerSecond (line 265) | func recordsPerSecond(idx int, lastUpdate time.Time) float64 {
  function percent (line 273) | func percent(idx, total int) float64 {
  function eta (line 280) | func eta(idx, total int, rate float64) time.Duration {

FILE: grype/db/data/entry.go
  type Entry (line 4) | type Entry struct

FILE: grype/db/data/processor.go
  type Processor (line 11) | type Processor interface

FILE: grype/db/data/severity.go
  type Severity (line 5) | type Severity
  constant SeverityUnknown (line 8) | SeverityUnknown    Severity = "Unknown"
  constant SeverityNegligible (line 9) | SeverityNegligible Severity = "Negligible"
  constant SeverityLow (line 10) | SeverityLow        Severity = "Low"
  constant SeverityMedium (line 11) | SeverityMedium     Severity = "Medium"
  constant SeverityHigh (line 12) | SeverityHigh       Severity = "High"
  constant SeverityCritical (line 13) | SeverityCritical   Severity = "Critical"
  function ParseSeverity (line 16) | func ParseSeverity(s string) Severity {

FILE: grype/db/data/severity_test.go
  function TestParseSeverity (line 9) | func TestParseSeverity(t *testing.T) {

FILE: grype/db/data/transformers.go
  type GitHubTransformer (line 14) | type GitHubTransformer
  type MSRCTransformer (line 15) | type MSRCTransformer
  type NVDTransformer (line 16) | type NVDTransformer
  type OSTransformer (line 17) | type OSTransformer
  type MatchExclusionTransformer (line 18) | type MatchExclusionTransformer
  type GitHubTransformerV2 (line 22) | type GitHubTransformerV2
  type MSRCTransformerV2 (line 23) | type MSRCTransformerV2
  type NVDTransformerV2 (line 24) | type NVDTransformerV2
  type OSTransformerV2 (line 25) | type OSTransformerV2
  type MatchExclusionTransformerV2 (line 26) | type MatchExclusionTransformerV2
  type KnownExploitedVulnerabilityTransformerV2 (line 28) | type KnownExploitedVulnerabilityTransformerV2
  type EPSSTransformerV2 (line 29) | type EPSSTransformerV2
  type OSVTransformerV2 (line 30) | type OSVTransformerV2
  type OpenVEXTransformerV2 (line 31) | type OpenVEXTransformerV2
  type AnnotatedOpenVEXTransformerV2 (line 32) | type AnnotatedOpenVEXTransformerV2
  type EOLTransformerV2 (line 33) | type EOLTransformerV2

FILE: grype/db/data/writer.go
  type Writer (line 6) | type Writer interface

FILE: grype/db/default_schema_version.go
  constant DefaultSchemaVersion (line 5) | DefaultSchemaVersion = db.ModelVersion

FILE: grype/db/internal/codename/codename.go
  function LookupOS (line 5) | func LookupOS(osName, majorVersion, minorVersion string) string {

FILE: grype/db/internal/codename/codename_test.go
  function TestLookupOSCodename (line 9) | func TestLookupOSCodename(t *testing.T) {

FILE: grype/db/internal/codename/generate/main.go
  constant outputPackage (line 15) | outputPackage = "grype/db/internal/codename"
  constant outputPath (line 16) | outputPath    = "internal/codename/codenames_generated.go"
  type Version (line 19) | type Version struct
  function main (line 24) | func main() {
  function fetchAndParse (line 70) | func fetchAndParse(url string, handler func(string) string) map[string]m...
  function lowercaseHandler (line 101) | func lowercaseHandler(codename string) string {
  function ubuntuHandler (line 105) | func ubuntuHandler(codename string) string {
  function parseVersion (line 110) | func parseVersion(version string) (string, string) {

FILE: grype/db/internal/gormadapter/logger.go
  type logAdapter (line 16) | type logAdapter struct
    method LogMode (line 23) | func (l *logAdapter) LogMode(level logger.LogLevel) logger.Interface {
    method Info (line 29) | func (l logAdapter) Info(_ context.Context, fmt string, v ...interface...
    method Warn (line 37) | func (l logAdapter) Warn(_ context.Context, fmt string, v ...interface...
    method Error (line 43) | func (l logAdapter) Error(_ context.Context, fmt string, v ...interfac...
    method Trace (line 50) | func (l logAdapter) Trace(_ context.Context, t time.Time, fn func() (s...

FILE: grype/db/internal/gormadapter/open.go
  type config (line 38) | type config struct
    method apply (line 101) | func (c *config) apply(path string, opts []Option) {
    method connectionString (line 109) | func (c config) connectionString() string {
    method prepareDB (line 153) | func (c config) prepareDB(dbObj *gorm.DB) (*gorm.DB, error) {
    method applyStatements (line 207) | func (c config) applyStatements(db *gorm.DB, statements []string) error {
    method pragmaNameValue (line 237) | func (c config) pragmaNameValue(sqlStmt string) (string, string, error) {
  type Option (line 50) | type Option
  function WithDebug (line 52) | func WithDebug(debug bool) Option {
  function WithTruncate (line 58) | func WithTruncate(truncate bool, models []any, initialData []any) Option {
  function WithStatements (line 70) | func WithStatements(statements ...string) Option {
  function WithModels (line 76) | func WithModels(models []any) Option {
  function WithWritable (line 82) | func WithWritable(write bool, models []any) Option {
  function WithLargeMemoryFootprint (line 89) | func WithLargeMemoryFootprint(largeFootprint bool) Option {
  function newConfig (line 95) | func newConfig(path string, opts []Option) config {
  function Open (line 129) | func Open(path string, options ...Option) (*gorm.DB, error) {
  function deleteDB (line 269) | func deleteDB(path string) error {

FILE: grype/db/internal/gormadapter/open_test.go
  function TestConfigApply (line 11) | func TestConfigApply(t *testing.T) {
  function TestConfigConnectionString (line 52) | func TestConfigConnectionString(t *testing.T) {
  function TestPrepareWritableDB (line 93) | func TestPrepareWritableDB(t *testing.T) {
  function TestPragmaNameValue (line 131) | func TestPragmaNameValue(t *testing.T) {

FILE: grype/db/internal/provider/unmarshal/annotated_openvex_vulnerability.go
  type AnnotatedOpenVEXVulnerability (line 9) | type AnnotatedOpenVEXVulnerability struct
  type AnnotatedOpenVEXFix (line 14) | type AnnotatedOpenVEXFix struct
  type AnnotatedOpenVEXFixAvailability (line 19) | type AnnotatedOpenVEXFixAvailability struct
  function AnnotatedOpenVEXVulnerabilityEntries (line 24) | func AnnotatedOpenVEXVulnerabilityEntries(reader io.Reader) ([]Annotated...

FILE: grype/db/internal/provider/unmarshal/eol.go
  type EndOfLifeDateRelease (line 10) | type EndOfLifeDateRelease struct
    method IsEmpty (line 82) | func (e EndOfLifeDateRelease) IsEmpty() bool {
    method ProductName (line 87) | func (e EndOfLifeDateRelease) ProductName() string {
  type EndOfLifeDateLatest (line 32) | type EndOfLifeDateLatest struct
  type EndOfLifeDateIdentifier (line 39) | type EndOfLifeDateIdentifier struct
  type EndOfLifeDateLabels (line 45) | type EndOfLifeDateLabels struct
  type EndOfLifeDateLinks (line 53) | type EndOfLifeDateLinks struct
  type EndOfLifeDateResult (line 60) | type EndOfLifeDateResult struct
  type EndOfLifeDateProduct (line 74) | type EndOfLifeDateProduct struct
  function EndOfLifeDateReleaseEntries (line 92) | func EndOfLifeDateReleaseEntries(reader io.Reader) ([]EndOfLifeDateRelea...

FILE: grype/db/internal/provider/unmarshal/epss.go
  type EPSS (line 5) | type EPSS struct
    method IsEmpty (line 12) | func (o EPSS) IsEmpty() bool {
  function EPSSEntries (line 16) | func EPSSEntries(reader io.Reader) ([]EPSS, error) {

FILE: grype/db/internal/provider/unmarshal/errors.go
  function handleJSONUnmarshalError (line 8) | func handleJSONUnmarshalError(err error) error {

FILE: grype/db/internal/provider/unmarshal/github_advisory.go
  type GitHubAdvisory (line 7) | type GitHubAdvisory struct
    method IsEmpty (line 44) | func (g GitHubAdvisory) IsEmpty() bool {
  function GitHubAdvisoryEntries (line 48) | func GitHubAdvisoryEntries(reader io.Reader) ([]GitHubAdvisory, error) {
  type GithubFixedIn (line 52) | type GithubFixedIn struct

FILE: grype/db/internal/provider/unmarshal/items_envelope.go
  type ItemsEnvelope (line 9) | type ItemsEnvelope struct
  function Envelope (line 15) | func Envelope(reader io.Reader) (*ItemsEnvelope, error) {

FILE: grype/db/internal/provider/unmarshal/known_exploited_vulnerability.go
  type KnownExploitedVulnerability (line 5) | type KnownExploitedVulnerability struct
    method IsEmpty (line 19) | func (g KnownExploitedVulnerability) IsEmpty() bool {
  function KnownExploitedVulnerabilityEntries (line 23) | func KnownExploitedVulnerabilityEntries(reader io.Reader) ([]KnownExploi...

FILE: grype/db/internal/provider/unmarshal/match_exclusion.go
  type MatchExclusion (line 7) | type MatchExclusion struct
    method IsEmpty (line 25) | func (m MatchExclusion) IsEmpty() bool {
  function MatchExclusions (line 29) | func MatchExclusions(reader io.Reader) ([]MatchExclusion, error) {

FILE: grype/db/internal/provider/unmarshal/msrc_vulnerability.go
  type MSRCVulnerability (line 8) | type MSRCVulnerability struct
    method IsEmpty (line 36) | func (o MSRCVulnerability) IsEmpty() bool {
  function MSRCVulnerabilityEntries (line 40) | func MSRCVulnerabilityEntries(reader io.Reader) ([]MSRCVulnerability, er...

FILE: grype/db/internal/provider/unmarshal/nvd/cve.go
  type Operator (line 19) | type Operator
  constant And (line 22) | And Operator = "AND"
  constant Or (line 23) | Or  Operator = "OR"
  constant englishLanguage (line 26) | englishLanguage = "en"
  type Vulnerability (line 39) | type Vulnerability struct
    method IsEmpty (line 334) | func (o Vulnerability) IsEmpty() bool {
  type CveItem (line 43) | type CveItem struct
    method Description (line 172) | func (o CveItem) Description() string {
    method CVSS (line 263) | func (o CveItem) CVSS() []CvssSummary {
  type Configuration (line 64) | type Configuration struct
  type Node (line 70) | type Node struct
  type FixInfo (line 76) | type FixInfo struct
  type CpeMatch (line 82) | type CpeMatch struct
  type LangString (line 93) | type LangString struct
  type Metrics (line 99) | type Metrics struct
  type CvssV2 (line 106) | type CvssV2 struct
  type CvssV30 (line 120) | type CvssV30 struct
  type CvssV31 (line 128) | type CvssV31 struct
  type CvssV40 (line 136) | type CvssV40 struct
  type CvssType (line 148) | type CvssType
  constant Primary (line 151) | Primary   CvssType = "Primary"
  constant Secondary (line 152) | Secondary CvssType = "Secondary"
  type Reference (line 155) | type Reference struct
  type Weakness (line 166) | type Weakness struct
  type CvssSummary (line 181) | type CvssSummary struct
    method Severity (line 192) | func (o CvssSummary) Severity() string {
    method version (line 199) | func (o CvssSummary) version() *semver.Version {
  type CvssSummaries (line 207) | type CvssSummaries
    method Len (line 209) | func (o CvssSummaries) Len() int {
    method Less (line 213) | func (o CvssSummaries) Less(i, j int) bool {
    method Swap (line 240) | func (o CvssSummaries) Swap(i, j int) {
    method Severity (line 244) | func (o CvssSummaries) Severity() string {
    method Sorted (line 254) | func (o CvssSummaries) Sorted() CvssSummaries {

FILE: grype/db/internal/provider/unmarshal/nvd/cve_test.go
  function TestCvssSummariesSorted (line 10) | func TestCvssSummariesSorted(t *testing.T) {
  function TestCvssSummaryVersion (line 176) | func TestCvssSummaryVersion(t *testing.T) {

FILE: grype/db/internal/provider/unmarshal/nvd/cvss20/cvss20.go
  type Cvss20 (line 5) | type Cvss20 struct

FILE: grype/db/internal/provider/unmarshal/nvd/cvss30/cvss30.go
  type Cvss30 (line 5) | type Cvss30 struct
  type SeverityType (line 71) | type SeverityType
  constant Critical (line 74) | Critical           SeverityType = "CRITICAL"
  constant SeverityTypeHIGH (line 75) | SeverityTypeHIGH   SeverityType = "HIGH"
  constant SeverityTypeLOW (line 76) | SeverityTypeLOW    SeverityType = "LOW"
  constant SeverityTypeMEDIUM (line 77) | SeverityTypeMEDIUM SeverityType = "MEDIUM"
  constant SeverityTypeNONE (line 78) | SeverityTypeNONE   SeverityType = "NONE"

FILE: grype/db/internal/provider/unmarshal/nvd/cvss31/cvss31.go
  type Cvss31 (line 5) | type Cvss31 struct
  type SeverityType (line 71) | type SeverityType
  constant Critical (line 74) | Critical           SeverityType = "CRITICAL"
  constant SeverityTypeHIGH (line 75) | SeverityTypeHIGH   SeverityType = "HIGH"
  constant SeverityTypeLOW (line 76) | SeverityTypeLOW    SeverityType = "LOW"
  constant SeverityTypeMEDIUM (line 77) | SeverityTypeMEDIUM SeverityType = "MEDIUM"
  constant SeverityTypeNONE (line 78) | SeverityTypeNONE   SeverityType = "NONE"

FILE: grype/db/internal/provider/unmarshal/nvd/cvss40/cvss40.go
  type Cvss40 (line 5) | type Cvss40 struct
  type SeverityType (line 44) | type SeverityType
  constant SeverityTypeCritical (line 47) | SeverityTypeCritical SeverityType = "CRITICAL"
  constant SeverityTypeHIGH (line 48) | SeverityTypeHIGH     SeverityType = "HIGH"
  constant SeverityTypeLOW (line 49) | SeverityTypeLOW      SeverityType = "LOW"
  constant SeverityTypeMEDIUM (line 50) | SeverityTypeMEDIUM   SeverityType = "MEDIUM"
  constant SeverityTypeNONE (line 51) | SeverityTypeNONE     SeverityType = "NONE"

FILE: grype/db/internal/provider/unmarshal/nvd_vulnerability.go
  function NvdVulnerabilityEntries (line 13) | func NvdVulnerabilityEntries(reader io.Reader) ([]nvd.Vulnerability, err...

FILE: grype/db/internal/provider/unmarshal/openvex_vulnerability.go
  function OpenVEXVulnerabilityEntries (line 11) | func OpenVEXVulnerabilityEntries(reader io.Reader) ([]OpenVEXVulnerabili...

FILE: grype/db/internal/provider/unmarshal/os_vulnerability.go
  type OSFixedIn (line 13) | type OSFixedIn struct
  type OSFixedIns (line 33) | type OSFixedIns
    method FilterToHighestModularity (line 84) | func (fixes OSFixedIns) FilterToHighestModularity() OSFixedIns {
  type OSVulnerability (line 35) | type OSVulnerability struct
    method IsEmpty (line 72) | func (o OSVulnerability) IsEmpty() bool {
  function OSVulnerabilityEntries (line 76) | func OSVulnerabilityEntries(reader io.Reader) ([]OSVulnerability, error) {
  function moduleNameAndVersion (line 136) | func moduleNameAndVersion(module *string) (bool, string, *version.Versio...
  function moduleVersionConstraint (line 159) | func moduleVersionConstraint(moduleVersion string) (*version.Version, *v...

FILE: grype/db/internal/provider/unmarshal/os_vulnerability_test.go
  function Test_OSFixedIns_FilterToHighestModularity (line 9) | func Test_OSFixedIns_FilterToHighestModularity(t *testing.T) {

FILE: grype/db/internal/provider/unmarshal/osv_vulnerability.go
  function OSVVulnerabilityEntries (line 11) | func OSVVulnerabilityEntries(reader io.Reader) ([]OSVVulnerability, erro...

FILE: grype/db/internal/provider/unmarshal/single_or_multi.go
  function unmarshalSingleOrMulti (line 10) | func unmarshalSingleOrMulti[T interface{}](reader io.Reader) ([]T, error) {

FILE: grype/db/internal/sqlite/nullable_types.go
  type NullString (line 8) | type NullString struct
    method ToByteSlice (line 49) | func (v NullString) ToByteSlice() []byte {
    method MarshalJSON (line 57) | func (v NullString) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 65) | func (v *NullString) UnmarshalJSON(data []byte) error {
  function NewNullString (line 12) | func NewNullString(s string, valid bool) NullString {
  function ToNullString (line 21) | func ToNullString(v any) NullString {

FILE: grype/db/internal/sqlite/nullable_types_test.go
  function TestToNullString (line 9) | func TestToNullString(t *testing.T) {

FILE: grype/db/internal/tarutil/file_entry.go
  type FileEntry (line 11) | type FileEntry struct
    method writeEntry (line 29) | func (t FileEntry) writeEntry(tw lowLevelWriter) error {
  function NewEntryFromFilePath (line 15) | func NewEntryFromFilePath(path string) Entry {
  function NewEntryFromFilePaths (line 21) | func NewEntryFromFilePaths(paths ...string) []Entry {

FILE: grype/db/internal/tarutil/file_entry_test.go
  type mockTarWriter (line 17) | type mockTarWriter struct
    method Flush (line 26) | func (m *mockTarWriter) Flush() error {
    method Close (line 31) | func (m *mockTarWriter) Close() error {
    method WriteHeader (line 36) | func (m *mockTarWriter) WriteHeader(header *tar.Header) error {
    method Write (line 42) | func (m *mockTarWriter) Write(b []byte) (int, error) {
  function TestFileEntry_writeEntry (line 46) | func TestFileEntry_writeEntry(t *testing.T) {

FILE: grype/db/internal/tarutil/populate.go
  function PopulateWithPaths (line 4) | func PopulateWithPaths(tarPath string, filePaths ...string) error {
  function PopulateWithPathsAndCompressors (line 9) | func PopulateWithPathsAndCompressors(tarPath string, compressorCommands ...

FILE: grype/db/internal/tarutil/populate_test.go
  function TestPopulateWithPaths (line 17) | func TestPopulateWithPaths(t *testing.T) {

FILE: grype/db/internal/tarutil/reader_entry.go
  type ReaderEntry (line 15) | type ReaderEntry struct
    method writeEntry (line 29) | func (t ReaderEntry) writeEntry(tw lowLevelWriter) error {
  function NewEntryFromBytes (line 21) | func NewEntryFromBytes(by []byte, filename string, fileInfo os.FileInfo)...
  type autoDeleteFile (line 37) | type autoDeleteFile struct
    method Close (line 41) | func (f *autoDeleteFile) Close() error {
  function readerWithSize (line 54) | func readerWithSize(reader io.Reader) (int64, io.ReadCloser, error) {
  function writeEntry (line 95) | func writeEntry(tw lowLevelWriter, filename string, fileInfo os.FileInfo...

FILE: grype/db/internal/tarutil/reader_entry_test.go
  type mockFileInfo (line 23) | type mockFileInfo struct
    method Name (line 32) | func (m mockFileInfo) Name() string {
    method Size (line 36) | func (m mockFileInfo) Size() int64 {
    method Mode (line 40) | func (m mockFileInfo) Mode() fs.FileMode {
    method ModTime (line 44) | func (m mockFileInfo) ModTime() time.Time {
    method IsDir (line 48) | func (m mockFileInfo) IsDir() bool {
    method Sys (line 52) | func (m mockFileInfo) Sys() any {
  function TestReaderEntry_writeEntry (line 56) | func TestReaderEntry_writeEntry(t *testing.T) {
  function Test_readerWithSize (line 148) | func Test_readerWithSize(t *testing.T) {
  function Test_autoDeleteFile (line 222) | func Test_autoDeleteFile(t *testing.T) {

FILE: grype/db/internal/tarutil/tar.go
  type Writer (line 9) | type Writer interface
  type lowLevelWriter (line 15) | type lowLevelWriter interface
  type Entry (line 22) | type Entry interface

FILE: grype/db/internal/tarutil/writer.go
  type writer (line 23) | type writer struct
    method WriteEntry (line 150) | func (w *writer) WriteEntry(entry Entry) error {
    method Close (line 154) | func (w *writer) Close() error {
  function NewWriter (line 29) | func NewWriter(archivePath string) (Writer, error) {
  function NewWriterWithCompressors (line 34) | func NewWriterWithCompressors(archivePath string, compressorCommands map...
  function newCompressorWithCommands (line 48) | func newCompressorWithCommands(archivePath string, compressorCommands ma...
  type shellCompressor (line 81) | type shellCompressor struct
    method Write (line 136) | func (sc *shellCompressor) Write(p []byte) (int, error) {
    method Close (line 140) | func (sc *shellCompressor) Close() error {
  function newShellCompressor (line 86) | func newShellCompressor(c string, archive io.Writer) (*shellCompressor, ...

FILE: grype/db/internal/tarutil/writer_test.go
  function TestNewWriter (line 17) | func TestNewWriter(t *testing.T) {

FILE: grype/db/internal/testutil/utils.go
  function CloseFile (line 8) | func CloseFile(f *os.File) {

FILE: grype/db/internal/versionutil/clean_fixed_in_version.go
  function CleanFixedInVersion (line 5) | func CleanFixedInVersion(version string) string {

FILE: grype/db/internal/versionutil/constraint.go
  function EnforceSemVerConstraint (line 18) | func EnforceSemVerConstraint(constraint string) string {
  function AndConstraints (line 26) | func AndConstraints(c ...string) string {
  function OrConstraints (line 30) | func OrConstraints(c ...string) string {
  function CleanConstraint (line 34) | func CleanConstraint(constraint string) string {

FILE: grype/db/internal/versionutil/constraint_test.go
  function TestEnforceSemVerConstraint (line 5) | func TestEnforceSemVerConstraint(t *testing.T) {

FILE: grype/db/package.go
  function Package (line 11) | func Package(dbDir, publishBaseURL, overrideArchiveExtension string, com...

FILE: grype/db/package_legacy.go
  function packageLegacyDB (line 25) | func packageLegacyDB(dbDir, publishBaseURL, overrideArchiveExtension str...
  function populateLegacyTar (line 113) | func populateLegacyTar(tarPath string, compressorCommands map[string]str...
  function secondsSinceEpoch (line 152) | func secondsSinceEpoch() int64 {

FILE: grype/db/processors/annotated_openvex_processor.go
  type annotatedOpenVEXProcessor (line 12) | type annotatedOpenVEXProcessor struct
    method Process (line 22) | func (p annotatedOpenVEXProcessor) Process(reader io.Reader, state pro...
    method IsSupported (line 42) | func (p annotatedOpenVEXProcessor) IsSupported(schemaURL string) bool {
  function NewV2AnnotatedOpenVEXProcessor (line 16) | func NewV2AnnotatedOpenVEXProcessor(transformer data.AnnotatedOpenVEXTra...

FILE: grype/db/processors/eol_processor.go
  type eolProcessor (line 13) | type eolProcessor struct
    method Process (line 23) | func (p eolProcessor) Process(reader io.Reader, state provider.State) ...
    method IsSupported (line 48) | func (p eolProcessor) IsSupported(schemaURL string) bool {
  function NewV2EOLProcessor (line 17) | func NewV2EOLProcessor(transformer data.EOLTransformerV2) data.Processor {

FILE: grype/db/processors/eol_processor_test.go
  function mockEOLProcessorTransform (line 15) | func mockEOLProcessorTransform(entry unmarshal.EndOfLifeDateRelease, sta...
  function TestEOLProcessor_Process (line 24) | func TestEOLProcessor_Process(t *testing.T) {
  function TestEOLProcessor_Process_EmptyEntry (line 51) | func TestEOLProcessor_Process_EmptyEntry(t *testing.T) {
  function TestEOLProcessor_IsSupported (line 70) | func TestEOLProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/epss_processor.go
  type epssProcessor (line 13) | type epssProcessor struct
    method Process (line 23) | func (p epssProcessor) Process(reader io.Reader, state provider.State)...
    method IsSupported (line 48) | func (p epssProcessor) IsSupported(schemaURL string) bool {
  function NewV2EPSSProcessor (line 17) | func NewV2EPSSProcessor(transformer data.EPSSTransformerV2) data.Process...

FILE: grype/db/processors/epss_processor_test.go
  function mockEPSSProcessorTransform (line 15) | func mockEPSSProcessorTransform(entry unmarshal.EPSS, state provider.Sta...
  function TestEPSSProcessor_Process (line 24) | func TestEPSSProcessor_Process(t *testing.T) {
  function TestEPSSProcessor_IsSupported (line 38) | func TestEPSSProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/github_processor.go
  type githubProcessor (line 13) | type githubProcessor struct
    method Process (line 29) | func (p githubProcessor) Process(reader io.Reader, state provider.Stat...
    method IsSupported (line 66) | func (p githubProcessor) IsSupported(schemaURL string) bool {
  function NewGitHubProcessor (line 17) | func NewGitHubProcessor(transformer data.GitHubTransformer) data.Process...
  function NewV2GitHubProcessor (line 23) | func NewV2GitHubProcessor(transformer data.GitHubTransformerV2) data.Pro...

FILE: grype/db/processors/github_processor_test.go
  function mockGithubProcessorTransform (line 16) | func mockGithubProcessorTransform(vulnerability unmarshal.GitHubAdvisory...
  function TestGitHubProcessor_Process (line 25) | func TestGitHubProcessor_Process(t *testing.T) {
  function TestGithubProcessor_IsSupported (line 39) | func TestGithubProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/kev_processor.go
  type kevProcessor (line 13) | type kevProcessor struct
    method Process (line 23) | func (p kevProcessor) Process(reader io.Reader, state provider.State) ...
    method IsSupported (line 48) | func (p kevProcessor) IsSupported(schemaURL string) bool {
  function NewV2KEVProcessor (line 17) | func NewV2KEVProcessor(transformer data.KnownExploitedVulnerabilityTrans...

FILE: grype/db/processors/kev_processor_test.go
  function mockKEVProcessorTransform (line 15) | func mockKEVProcessorTransform(vulnerability unmarshal.KnownExploitedVul...
  function TestKEVProcessor_Process (line 24) | func TestKEVProcessor_Process(t *testing.T) {
  function TestKEVProcessor_IsSupported (line 38) | func TestKEVProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/match_exclusion_processor.go
  type matchExclusionProcessor (line 13) | type matchExclusionProcessor struct
    method Process (line 23) | func (p matchExclusionProcessor) Process(reader io.Reader, _ provider....
    method IsSupported (line 48) | func (p matchExclusionProcessor) IsSupported(schemaURL string) bool {
  function NewMatchExclusionProcessor (line 17) | func NewMatchExclusionProcessor(transformer data.MatchExclusionTransform...

FILE: grype/db/processors/match_exclusion_processor_test.go
  function mockMatchExclusionProcessorTransform (line 16) | func mockMatchExclusionProcessorTransform(vulnerability unmarshal.MatchE...
  function TestMatchExclusionProcessor_Process (line 25) | func TestMatchExclusionProcessor_Process(t *testing.T) {
  function TestMatchExclusionProcessor_IsSupported (line 39) | func TestMatchExclusionProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/msrc_processor.go
  type msrcProcessor (line 14) | type msrcProcessor struct
    method Process (line 31) | func (p msrcProcessor) Process(reader io.Reader, state provider.State)...
    method IsSupported (line 68) | func (p msrcProcessor) IsSupported(schemaURL string) bool {
  function NewMSRCProcessor (line 19) | func NewMSRCProcessor(transformer data.MSRCTransformer) data.Processor {
  function NewV2MSRCProcessor (line 25) | func NewV2MSRCProcessor(transformer data.MSRCTransformerV2) data.Process...

FILE: grype/db/processors/msrc_processor_test.go
  function mockMSRCProcessorTransform (line 16) | func mockMSRCProcessorTransform(vulnerability unmarshal.MSRCVulnerabilit...
  function TestMSRCProcessor_Process (line 25) | func TestMSRCProcessor_Process(t *testing.T) {
  function TestMsrcProcessor_IsSupported (line 39) | func TestMsrcProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/nvd_processor.go
  type nvdProcessor (line 12) | type nvdProcessor struct
    method Process (line 28) | func (p nvdProcessor) Process(reader io.Reader, state provider.State) ...
    method IsSupported (line 65) | func (p nvdProcessor) IsSupported(schemaURL string) bool {
  function NewNVDProcessor (line 16) | func NewNVDProcessor(transformer data.NVDTransformer) data.Processor {
  function NewV2NVDProcessor (line 22) | func NewV2NVDProcessor(transformer data.NVDTransformerV2) data.Processor {

FILE: grype/db/processors/nvd_processor_test.go
  function mockNVDProcessorTransform (line 16) | func mockNVDProcessorTransform(vulnerability unmarshal.NVDVulnerability)...
  function TestNVDProcessor_Process (line 25) | func TestNVDProcessor_Process(t *testing.T) {
  function TestNvdProcessor_IsSupported (line 39) | func TestNvdProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/openvex_processor.go
  type openVEXProcessor (line 12) | type openVEXProcessor struct
    method Process (line 22) | func (p openVEXProcessor) Process(reader io.Reader, state provider.Sta...
    method IsSupported (line 42) | func (p openVEXProcessor) IsSupported(schemaURL string) bool {
  function NewV2OpenVEXProcessor (line 16) | func NewV2OpenVEXProcessor(transformer data.OpenVEXTransformerV2) data.P...

FILE: grype/db/processors/openvex_processor_test.go
  function mockOpenVEXProcessorTransform (line 16) | func mockOpenVEXProcessorTransform(vulnerability unmarshal.OpenVEXVulner...
  function TestV2OpenVEXProcessor_Process (line 25) | func TestV2OpenVEXProcessor_Process(t *testing.T) {
  function TestOpenVEXProcessor_IsSupported (line 39) | func TestOpenVEXProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/os_processor.go
  type osProcessor (line 13) | type osProcessor struct
    method Process (line 29) | func (p osProcessor) Process(reader io.Reader, state provider.State) (...
    method IsSupported (line 66) | func (p osProcessor) IsSupported(schemaURL string) bool {
  function NewOSProcessor (line 17) | func NewOSProcessor(transformer data.OSTransformer) data.Processor {
  function NewV2OSProcessor (line 23) | func NewV2OSProcessor(transformer data.OSTransformerV2) data.Processor {

FILE: grype/db/processors/os_processor_test.go
  function mockOSProcessorTransform (line 16) | func mockOSProcessorTransform(vulnerability unmarshal.OSVulnerability) (...
  function TestOSProcessor_Process (line 25) | func TestOSProcessor_Process(t *testing.T) {
  function TestOsProcessor_IsSupported (line 39) | func TestOsProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/osv_processor.go
  type osvProcessor (line 12) | type osvProcessor struct
    method Process (line 22) | func (p osvProcessor) Process(reader io.Reader, state provider.State) ...
    method IsSupported (line 42) | func (p osvProcessor) IsSupported(schemaURL string) bool {
  function NewV2OSVProcessor (line 16) | func NewV2OSVProcessor(transformer data.OSVTransformerV2) data.Processor {

FILE: grype/db/processors/osv_processor_test.go
  function mockOSVProcessorTransform (line 16) | func mockOSVProcessorTransform(vulnerability unmarshal.OSVVulnerability,...
  function TestV2OSVProcessor_Process (line 25) | func TestV2OSVProcessor_Process(t *testing.T) {
  function TestOSVProcessor_IsSupported (line 39) | func TestOSVProcessor_IsSupported(t *testing.T) {

FILE: grype/db/processors/version.go
  type version (line 12) | type version struct
  function parseVersion (line 18) | func parseVersion(schemaURL string) (*version, error) {
  function hasSchemaSegment (line 46) | func hasSchemaSegment(schemaURL string, segment string) bool {

FILE: grype/db/processors/version_test.go
  function TestParseVersion (line 9) | func TestParseVersion(t *testing.T) {

FILE: grype/db/provider/entry/file.go
  type fileOpener (line 8) | type fileOpener struct
    method Open (line 23) | func (e fileOpener) Open() (io.ReadCloser, error) {
    method String (line 27) | func (e fileOpener) String() string {
  function fileOpeners (line 12) | func fileOpeners(resultPaths []string) <-chan Opener {

FILE: grype/db/provider/entry/opener.go
  type Opener (line 8) | type Opener interface
  function Openers (line 13) | func Openers(store string, resultPaths []string) (<-chan Opener, int64, ...
  function Count (line 23) | func Count(store string, resultPaths []string) (int64, error) {

FILE: grype/db/provider/entry/sqlite.go
  type results (line 25) | type results struct
  type bytesOpener (line 30) | type bytesOpener struct
    method Open (line 115) | func (e bytesOpener) Open() (io.ReadCloser, error) {
    method String (line 119) | func (e bytesOpener) String() string {
  type errorOpener (line 35) | type errorOpener struct
    method Open (line 123) | func (e errorOpener) Open() (io.ReadCloser, error) {
    method String (line 127) | func (e errorOpener) String() string {
  function sqliteEntryCount (line 39) | func sqliteEntryCount(resultPaths []string) (int64, error) {
  function sqliteOpeners (line 64) | func sqliteOpeners(resultPaths []string) (<-chan Opener, int64, error) {
  function openDB (line 132) | func openDB(path string) (*gorm.DB, error) {
  function connectionString (line 152) | func connectionString(path string) (string, error) {
  type logAdapter (line 159) | type logAdapter struct
    method LogMode (line 165) | func (l logAdapter) LogMode(logger.LogLevel) logger.Interface {
    method Info (line 169) | func (l logAdapter) Info(_ context.Context, _ string, _ ...interface{}) {
    method Warn (line 173) | func (l logAdapter) Warn(_ context.Context, fmt string, v ...interface...
    method Error (line 177) | func (l logAdapter) Error(_ context.Context, fmt string, v ...interfac...
    method Trace (line 181) | func (l logAdapter) Trace(_ context.Context, _ time.Time, _ func() (_ ...
  function newLogger (line 161) | func newLogger() logger.Interface {

FILE: grype/db/provider/file.go
  type File (line 13) | type File struct
  type Files (line 19) | type Files
    method Paths (line 46) | func (i Files) Paths() []string {
  function NewFile (line 21) | func NewFile(path string) (*File, error) {
  function NewFiles (line 34) | func NewFiles(paths ...string) (Files, error) {
  function NewFilesFromDir (line 54) | func NewFilesFromDir(dir string) (Files, error) {

FILE: grype/db/provider/model.go
  function Model (line 9) | func Model(state State) *db.Provider {

FILE: grype/db/provider/model_test.go
  function TestProviderModel (line 12) | func TestProviderModel(t *testing.T) {

FILE: grype/db/provider/provider.go
  type Kind (line 7) | type Kind
  type Reader (line 9) | type Reader interface
  type Writer (line 14) | type Writer interface
  type Identifier (line 18) | type Identifier struct
  type Providers (line 23) | type Providers
    method Filter (line 25) | func (ps Providers) Filter(names ...string) Providers {
  type Collection (line 37) | type Collection struct

FILE: grype/db/provider/state.go
  type State (line 20) | type State struct
    method ResultPath (line 98) | func (sd State) ResultPath(filename string) string {
    method ResultPaths (line 102) | func (sd State) ResultPaths() []string {
    method Verify (line 110) | func (sd State) Verify(workspaceRoots ...string) error {
  type Schema (line 36) | type Schema struct
  type States (line 41) | type States
    method Names (line 134) | func (s States) Names() []string {
    method EarliestTimestamp (line 142) | func (s States) EarliestTimestamp() (time.Time, error) {
  function ReadState (line 43) | func ReadState(location string) (*State, error) {

FILE: grype/db/provider/state_test.go
  function Test_earliestTimestamp (line 11) | func Test_earliestTimestamp(t *testing.T) {
  function requireErrorContains (line 125) | func requireErrorContains(text string) require.ErrorAssertionFunc {

FILE: grype/db/provider/workspace.go
  type Workspace (line 7) | type Workspace struct
    method Path (line 26) | func (w Workspace) Path() string {
    method StatePath (line 30) | func (w Workspace) StatePath() string {
    method InputPath (line 34) | func (w Workspace) InputPath() string {
    method ResultsPath (line 38) | func (w Workspace) ResultsPath() string {
    method ReadState (line 42) | func (w Workspace) ReadState() (*State, error) {
  function NewWorkspace (line 12) | func NewWorkspace(root, name string) Workspace {
  function NewWorkspaceFromExisting (line 19) | func NewWorkspaceFromExisting(workspacePath string) Workspace {

FILE: grype/db/v5/advisory.go
  type Advisory (line 4) | type Advisory struct

FILE: grype/db/v5/build/processors.go
  type Config (line 15) | type Config struct
  type Option (line 19) | type Option
  function WithCPEParts (line 21) | func WithCPEParts(included []string) Option {
  function WithInferNVDFixVersions (line 27) | func WithInferNVDFixVersions(infer bool) Option {
  function NewConfig (line 33) | func NewConfig(options ...Option) Config {
  function Processors (line 42) | func Processors(cfg Config) []data.Processor {

FILE: grype/db/v5/build/transformers/entry.go
  function NewEntries (line 8) | func NewEntries(vs []db.Vulnerability, metadata db.VulnerabilityMetadata...

FILE: grype/db/v5/build/transformers/github/transform.go
  function buildGrypeNamespace (line 19) | func buildGrypeNamespace(group string) (namespace.Namespace, error) {
  function Transform (line 50) | func Transform(vulnerability unmarshal.GitHubAdvisory) ([]data.Entry, er...
  function getFix (line 112) | func getFix(entry unmarshal.GitHubAdvisory, idx int) db.Fix {
  function getRelatedVulnerabilities (line 132) | func getRelatedVulnerabilities(entry unmarshal.GitHubAdvisory) []db.Vuln...
  function getCvss (line 143) | func getCvss(entry unmarshal.GitHubAdvisory) (cvss []db.Cvss) {

FILE: grype/db/v5/build/transformers/github/transform_test.go
  function TestBuildGrypeNamespace (line 21) | func TestBuildGrypeNamespace(t *testing.T) {
  function TestUnmarshalGitHubEntries (line 77) | func TestUnmarshalGitHubEntries(t *testing.T) {
  function TestParseGitHubEntry (line 89) | func TestParseGitHubEntry(t *testing.T) {
  function TestDefaultVersionFormatNpmGitHubEntry (line 188) | func TestDefaultVersionFormatNpmGitHubEntry(t *testing.T) {
  function TestFilterWithdrawnEntries (line 257) | func TestFilterWithdrawnEntries(t *testing.T) {

FILE: grype/db/v5/build/transformers/matchexclusions/transform.go
  function Transform (line 9) | func Transform(matchExclusion unmarshal.MatchExclusion) ([]data.Entry, e...

FILE: grype/db/v5/build/transformers/msrc/transform.go
  function Transform (line 17) | func Transform(vulnerability unmarshal.MSRCVulnerability) ([]data.Entry,...
  function getFix (line 67) | func getFix(entry unmarshal.MSRCVulnerability) db.Fix {
  function fixedInKB (line 83) | func fixedInKB(vulnerability unmarshal.MSRCVulnerability) string {

FILE: grype/db/v5/build/transformers/msrc/transform_test.go
  function TestUnmarshalMsrcVulnerabilities (line 15) | func TestUnmarshalMsrcVulnerabilities(t *testing.T) {
  function TestParseMSRCEntry (line 26) | func TestParseMSRCEntry(t *testing.T) {

FILE: grype/db/v5/build/transformers/nvd/transform.go
  type Config (line 23) | type Config struct
  function defaultConfig (line 28) | func defaultConfig() Config {
  function Transformer (line 35) | func Transformer(cfg Config) data.NVDTransformer {
  function transform (line 44) | func transform(cfg Config, vulnerability unmarshal.NVDVulnerability) ([]...
  function getVersionFormat (line 115) | func getVersionFormat(name string, cpes []string) version.Format {
  function getFix (line 131) | func getFix(matches []nvd.CpeMatch, inferNVDFixVersions bool) db.Fix {
  function getCvss (line 185) | func getCvss(cvss ...nvd.CvssSummary) []db.Cvss {

FILE: grype/db/v5/build/transformers/nvd/transform_test.go
  function TestUnmarshalNVDVulnerabilitiesEntries (line 21) | func TestUnmarshalNVDVulnerabilitiesEntries(t *testing.T) {
  function TestParseAllNVDVulnerabilityEntries (line 31) | func TestParseAllNVDVulnerabilityEntries(t *testing.T) {
  function TestGetVersionFormat (line 753) | func TestGetVersionFormat(t *testing.T) {
  function TestGetFix (line 812) | func TestGetFix(t *testing.T) {

FILE: grype/db/v5/build/transformers/nvd/unique_pkg.go
  constant ANY (line 15) | ANY = "*"
  constant NA (line 16) | NA  = "-"
  type pkgCandidate (line 19) | type pkgCandidate struct
    method String (line 26) | func (p pkgCandidate) String() string {
  function newPkgCandidate (line 34) | func newPkgCandidate(tCfg Config, match nvd.CpeMatch, platformCPE string...
  function findUniquePkgs (line 59) | func findUniquePkgs(tCfg Config, cfgs ...nvd.Configuration) uniquePkgTra...
  function platformPackageCandidates (line 67) | func platformPackageCandidates(tCfg Config, set uniquePkgTracker, c nvd....
  function anyHardwareCPEPresent (line 127) | func anyHardwareCPEPresent(n nvd.Node) bool {
  function allCPEsVulnerable (line 137) | func allCPEsVulnerable(node nvd.Node) bool {
  function noCPEsVulnerable (line 146) | func noCPEsVulnerable(node nvd.Node) bool {
  function _findUniquePkgs (line 155) | func _findUniquePkgs(tCfg Config, set uniquePkgTracker, c nvd.Configurat...
  function buildConstraints (line 181) | func buildConstraints(matches []nvd.CpeMatch) string {
  function buildConstraint (line 190) | func buildConstraint(match nvd.CpeMatch) string {
  function removeDuplicateConstraints (line 223) | func removeDuplicateConstraints(constraints []string) []string {

FILE: grype/db/v5/build/transformers/nvd/unique_pkg_test.go
  function newUniquePkgTrackerFromSlice (line 15) | func newUniquePkgTrackerFromSlice(candidates []pkgCandidate) uniquePkgTr...
  function TestFindUniquePkgs (line 23) | func TestFindUniquePkgs(t *testing.T) {
  function strRef (line 450) | func strRef(s string) *string {
  function TestBuildConstraints (line 454) | func TestBuildConstraints(t *testing.T) {
  function Test_UniquePackageTrackerHandlesOnlyPlatformDiff (line 553) | func Test_UniquePackageTrackerHandlesOnlyPlatformDiff(t *testing.T) {
  function TestPlatformPackageCandidates (line 604) | func TestPlatformPackageCandidates(t *testing.T) {
  function opRef (line 744) | func opRef(op nvd.Operator) *nvd.Operator {
  function boolRef (line 748) | func boolRef(b bool) *bool {
  function mustNewPackage (line 752) | func mustNewPackage(t *testing.T, match nvd.CpeMatch, platformCPE string...

FILE: grype/db/v5/build/transformers/nvd/unique_pkg_tracker.go
  type uniquePkgTracker (line 9) | type uniquePkgTracker
    method Diff (line 15) | func (s uniquePkgTracker) Diff(other uniquePkgTracker) (missing []pkgC...
    method Matches (line 31) | func (s uniquePkgTracker) Matches(i pkgCandidate) []nvd.CpeMatch {
    method Add (line 35) | func (s uniquePkgTracker) Add(i pkgCandidate, match nvd.CpeMatch) {
    method Remove (line 42) | func (s uniquePkgTracker) Remove(i pkgCandidate) {
    method Contains (line 46) | func (s uniquePkgTracker) Contains(i pkgCandidate) bool {
    method All (line 51) | func (s uniquePkgTracker) All() []pkgCandidate {
  function newUniquePkgTracker (line 11) | func newUniquePkgTracker() uniquePkgTracker {

FILE: grype/db/v5/build/transformers/os/transform.go
  function buildGrypeNamespace (line 18) | func buildGrypeNamespace(group string) (namespace.Namespace, error) {
  function buildPackageQualifiers (line 67) | func buildPackageQualifiers(fixedInEntry unmarshal.OSFixedIn) (qualifier...
  function Transform (line 83) | func Transform(vulnerability unmarshal.OSVulnerability) ([]data.Entry, e...
  function getLinks (line 133) | func getLinks(entry unmarshal.OSVulnerability) []string {
  function getCvss (line 146) | func getCvss(entry unmarshal.OSVulnerability) (cvss []db.Cvss) {
  function getAdvisories (line 165) | func getAdvisories(entry unmarshal.OSVulnerability, idx int) (advisories...
  function getFix (line 177) | func getFix(entry unmarshal.OSVulnerability, idx int) db.Fix {
  function getRelatedVulnerabilities (line 199) | func getRelatedVulnerabilities(entry unmarshal.OSVulnerability) (vulns [...
  function deriveConstraintFromFix (line 218) | func deriveConstraintFromFix(fixVersion, vulnerabilityID string) string {
  function enforceConstraint (line 239) | func enforceConstraint(fixedVersion, vulnerableRange, format, vulnerabil...

FILE: grype/db/v5/build/transformers/os/transform_test.go
  function TestUnmarshalOSVulnerabilitiesEntries (line 19) | func TestUnmarshalOSVulnerabilitiesEntries(t *testing.T) {
  function TestParseVulnerabilitiesEntry (line 31) | func TestParseVulnerabilitiesEntry(t *testing.T) {
  function TestParseVulnerabilitiesAllEntries (line 798) | func TestParseVulnerabilitiesAllEntries(t *testing.T) {

FILE: grype/db/v5/build/transformers/vulnerability_metadata.go
  type VendorBaseMetrics (line 5) | type VendorBaseMetrics struct

FILE: grype/db/v5/build/writer.go
  constant nvdNamespace (line 27) | nvdNamespace             = "nvd:cpe"
  constant providerMetadataFileName (line 28) | providerMetadataFileName = "provider-metadata.json"
  type writer (line 33) | type writer struct
    method Write (line 81) | func (w *writer) Write(entries ...data.Entry) error {
    method addToBatch (line 123) | func (w *writer) addToBatch(op func() error) error {
    method Flush (line 136) | func (w *writer) Flush() error {
    method flushUnlocked (line 143) | func (w *writer) flushUnlocked() error {
    method metadataAndClose (line 168) | func (w *writer) metadataAndClose() (*distribution.Metadata, error) {
    method ProviderMetadata (line 193) | func (w *writer) ProviderMetadata() *ProviderMetadata {
    method Close (line 205) | func (w *writer) Close() error {
  type ProviderMetadata (line 47) | type ProviderMetadata struct
    method Write (line 264) | func (p ProviderMetadata) Write(path string) error {
  type Provider (line 51) | type Provider struct
  function NewWriter (line 56) | func NewWriter(directory string, dataAge time.Time, states provider.Stat...
  function NewProviderMetadata (line 187) | func NewProviderMetadata() ProviderMetadata {
  function normalizeSeverity (line 236) | func normalizeSeverity(metadata *db.VulnerabilityMetadata, reader db.Vul...

FILE: grype/db/v5/build/writer_test.go
  type mockReader (line 15) | type mockReader struct
    method GetVulnerabilityMetadata (line 35) | func (m mockReader) GetVulnerabilityMetadata(_, _ string) (*db.Vulnera...
    method GetAllVulnerabilityMetadata (line 39) | func (m mockReader) GetAllVulnerabilityMetadata() (*[]db.Vulnerability...
  function newMockReader (line 20) | func newMockReader(sev string) *mockReader {
  function newDeadMockReader (line 29) | func newDeadMockReader() *mockReader {
  function Test_normalizeSeverity (line 43) | func Test_normalizeSeverity(t *testing.T) {

FILE: grype/db/v5/cvss.go
  function NewCvss (line 7) | func NewCvss(m []Cvss) []vulnerability.Cvss {

FILE: grype/db/v5/diff.go
  constant DiffAdded (line 6) | DiffAdded   DiffReason = "added"
  constant DiffChanged (line 7) | DiffChanged DiffReason = "changed"
  constant DiffRemoved (line 8) | DiffRemoved DiffReason = "removed"
  type Diff (line 11) | type Diff struct

FILE: grype/db/v5/differ/differ.go
  type Differ (line 23) | type Differ struct
    method SetBaseDB (line 55) | func (d *Differ) SetBaseDB(base string) error {
    method SetTargetDB (line 59) | func (d *Differ) SetTargetDB(target string) error {
    method setOrDownload (line 63) | func (d *Differ) setOrDownload(curator *legacyDistribution.Curator, fi...
    method DiffDatabases (line 127) | func (d *Differ) DiffDatabases() (*[]v5.Diff, error) {
    method DeleteDatabases (line 145) | func (d *Differ) DeleteDatabases() error {
    method Present (line 155) | func (d *Differ) Present(outputFormat string, diff *[]v5.Diff, output ...
  function NewDiffer (line 28) | func NewDiffer(config legacyDistribution.Config) (*Differ, error) {
  function download (line 103) | func download(curator *legacyDistribution.Curator, listing *legacyDistri...
  function newTable (line 186) | func newTable(output io.Writer, columns []string) *tablewriter.Table {

FILE: grype/db/v5/differ/differ_test.go
  function TestNewDiffer (line 19) | func TestNewDiffer(t *testing.T) {
  function Test_DifferDirectory (line 31) | func Test_DifferDirectory(t *testing.T) {
  function TestPresent_Json (line 50) | func TestPresent_Json(t *testing.T) {
  function TestPresent_Table (line 76) | func TestPresent_Table(t *testing.T) {
  function TestPresent_Invalid (line 102) | func TestPresent_Invalid(t *testing.T) {

FILE: grype/db/v5/distribution/curator.go
  constant FileName (line 33) | FileName                = v5.VulnerabilityStoreFileName
  constant lastUpdateCheckFileName (line 34) | lastUpdateCheckFileName = "last_update_check"
  type Config (line 37) | type Config struct
  type Curator (line 51) | type Curator struct
    method SupportedSchema (line 98) | func (c Curator) SupportedSchema() int {
    method GetStore (line 102) | func (c *Curator) GetStore() (v5.StoreReader, error) {
    method Status (line 112) | func (c *Curator) Status() Status {
    method Delete (line 135) | func (c *Curator) Delete() error {
    method Update (line 140) | func (c *Curator) Update() (bool, error) { // nolint: funlen
    method isUpdateCheckAllowed (line 215) | func (c Curator) isUpdateCheckAllowed() bool {
    method durationSinceUpdateCheck (line 235) | func (c Curator) durationSinceUpdateCheck() (*time.Duration, error) {
    method setLastSuccessfulUpdateCheck (line 272) | func (c Curator) setLastSuccessfulUpdateCheck() {
    method IsUpdateAvailable (line 290) | func (c *Curator) IsUpdateAvailable() (bool, *Metadata, *ListingEntry,...
    method UpdateTo (line 320) | func (c *Curator) UpdateTo(listing *ListingEntry, downloadProgress, im...
    method Validate (line 347) | func (c *Curator) Validate() error {
    method ImportFrom (line 357) | func (c *Curator) ImportFrom(dbArchivePath string) error {
    method download (line 382) | func (c *Curator) download(listing *ListingEntry, downloadProgress *pr...
    method validateStaleness (line 408) | func (c *Curator) validateStaleness(m Metadata) error {
    method validateIntegrity (line 425) | func (c *Curator) validateIntegrity(dbDirPath string) (Metadata, error) {
    method activate (line 456) | func (c *Curator) activate(dbDirPath string) error {
    method ListingFromURL (line 477) | func (c Curator) ListingFromURL() (Listing, error) {
  function NewCurator (line 66) | func NewCurator(cfg Config) (Curator, error) {
  function defaultHTTPClient (line 504) | func defaultHTTPClient(fs afero.Fs, caCertPath string) (*http.Client, er...
  function unarchive (line 524) | func unarchive(source, destination string) error {

FILE: grype/db/v5/distribution/curator_test.go
  type testGetter (line 39) | type testGetter struct
    method GetFile (line 56) | func (g *testGetter) GetFile(dst, src string, _ ...*progress.Manual) e...
    method GetToDir (line 65) | func (g *testGetter) GetToDir(dst, src string, _ ...*progress.Manual) ...
  function newTestGetter (line 46) | func newTestGetter(fs afero.Fs, f, d map[string]string) *testGetter {
  function newTestCurator (line 73) | func newTestCurator(tb testing.TB, fs afero.Fs, getter file.Getter, dbDi...
  function Test_defaultHTTPClientHasCert (line 89) | func Test_defaultHTTPClientHasCert(t *testing.T) {
  function Test_defaultHTTPClientTimeout (line 124) | func Test_defaultHTTPClientTimeout(t *testing.T) {
  function generateCertFixture (line 130) | func generateCertFixture(t *testing.T) string {
  function TestCuratorDownload (line 191) | func TestCuratorDownload(t *testing.T) {
  function TestCuratorValidate (line 247) | func TestCuratorValidate(t *testing.T) {
  function TestCuratorDBPathHasSchemaVersion (line 314) | func TestCuratorDBPathHasSchemaVersion(t *testing.T) {
  function TestCurator_validateStaleness (line 323) | func TestCurator_validateStaleness(t *testing.T) {
  function Test_requireUpdateCheck (line 385) | func Test_requireUpdateCheck(t *testing.T) {
  function TestCuratorTimeoutBehavior (line 550) | func TestCuratorTimeoutBehavior(t *testing.T) {
  function TestCurator_IsUpdateCheckAllowed (line 624) | func TestCurator_IsUpdateCheckAllowed(t *testing.T) {
  function TestCurator_DurationSinceUpdateCheck (line 656) | func TestCurator_DurationSinceUpdateCheck(t *testing.T) {
  function TestCurator_SetLastSuccessfulUpdateCheck (line 701) | func TestCurator_SetLastSuccessfulUpdateCheck(t *testing.T) {
  type MockGetter (line 730) | type MockGetter struct
    method GetFile (line 734) | func (m *MockGetter) GetFile(dst, src string, monitor ...*progress.Man...
    method GetToDir (line 739) | func (m *MockGetter) GetToDir(dst, src string, monitor ...*progress.Ma...
  function TestCurator_Update_setLastSuccessfulUpdateCheck_notCalled (line 744) | func TestCurator_Update_setLastSuccessfulUpdateCheck_notCalled(t *testin...
  function Test_unarchive (line 771) | func Test_unarchive(t *testing.T) {

FILE: grype/db/v5/distribution/listing.go
  constant ListingFileName (line 12) | ListingFileName = "listing.json"
  type Listing (line 16) | type Listing struct
    method BestUpdate (line 69) | func (l *Listing) BestUpdate(targetSchema int) *ListingEntry {
    method Write (line 79) | func (l Listing) Write(toPath string) error {
  function NewListing (line 21) | func NewListing(entries ...ListingEntry) Listing {
  function NewListingFromFile (line 44) | func NewListingFromFile(fs afero.Fs, path string) (Listing, error) {

FILE: grype/db/v5/distribution/listing_entry.go
  type ListingEntry (line 19) | type ListingEntry struct
    method UnmarshalJSON (line 73) | func (l *ListingEntry) UnmarshalJSON(data []byte) error {
    method MarshalJSON (line 86) | func (l *ListingEntry) MarshalJSON() ([]byte, error) {
    method String (line 95) | func (l ListingEntry) String() string {
  type ListingEntryJSON (line 27) | type ListingEntryJSON struct
    method ToListingEntry (line 54) | func (l ListingEntryJSON) ToListingEntry() (ListingEntry, error) {
  function NewListingEntryFromArchive (line 35) | func NewListingEntryFromArchive(fs afero.Fs, metadata Metadata, dbArchiv...

FILE: grype/db/v5/distribution/listing_test.go
  function mustUrl (line 12) | func mustUrl(u *url.URL, err error) *url.URL {
  function TestNewListingFromPath (line 19) | func TestNewListingFromPath(t *testing.T) {
  function TestListingBestUpdate (line 108) | func TestListingBestUpdate(t *testing.T) {

FILE: grype/db/v5/distribution/metadata.go
  constant MetadataFileName (line 16) | MetadataFileName = "metadata.json"
  type Metadata (line 20) | type Metadata struct
    method UnmarshalJSON (line 77) | func (m *Metadata) UnmarshalJSON(data []byte) error {
    method IsSupersededBy (line 92) | func (m *Metadata) IsSupersededBy(entry *ListingEntry) bool {
    method String (line 115) | func (m Metadata) String() string {
    method Write (line 120) | func (m Metadata) Write(toPath string) error {
  type MetadataJSON (line 27) | type MetadataJSON struct
    method ToMetadata (line 34) | func (m MetadataJSON) ToMetadata() (Metadata, error) {
  function metadataPath (line 49) | func metadataPath(dir string) string {
  function NewMetadataFromDir (line 54) | func NewMetadataFromDir(fs afero.Fs, dir string) (*Metadata, error) {

FILE: grype/db/v5/distribution/metadata_test.go
  function TestMetadataParse (line 11) | func TestMetadataParse(t *testing.T) {
  function TestMetadataIsSupercededBy (line 59) | func TestMetadataIsSupercededBy(t *testing.T) {

FILE: grype/db/v5/distribution/status.go
  type Status (line 5) | type Status struct
    method Status (line 13) | func (s Status) Status() string {

FILE: grype/db/v5/distribution/testdata/tls/serve.py
  class Handler (line 9) | class Handler(SimpleHTTPRequestHandler):
    method __init__ (line 10) | def __init__(self, *args, **kwargs):
    method do_GET (line 13) | def do_GET(self):

FILE: grype/db/v5/fix.go
  type FixState (line 3) | type FixState
  constant UnknownFixState (line 6) | UnknownFixState FixState = "unknown"
  constant FixedState (line 7) | FixedState      FixState = "fixed"
  constant NotFixedState (line 8) | NotFixedState   FixState = "not-fixed"
  constant WontFixState (line 9) | WontFixState    FixState = "wont-fix"
  type Fix (line 13) | type Fix struct

FILE: grype/db/v5/id.go
  type ID (line 8) | type ID struct
  type IDReader (line 15) | type IDReader interface
  type IDWriter (line 19) | type IDWriter interface
  function NewID (line 23) | func NewID(age time.Time) ID {

FILE: grype/db/v5/match_exclusion_provider.go
  type MatchExclusionProvider (line 11) | type MatchExclusionProvider struct
    method IgnoreRules (line 47) | func (pr *MatchExclusionProvider) IgnoreRules(vulnerabilityID string) ...
  function NewMatchExclusionProvider (line 15) | func NewMatchExclusionProvider(reader VulnerabilityMatchExclusionStoreRe...
  function buildIgnoreRulesFromMatchExclusion (line 21) | func buildIgnoreRulesFromMatchExclusion(e VulnerabilityMatchExclusion) [...

FILE: grype/db/v5/namespace/cpe/namespace.go
  constant ID (line 12) | ID = "cpe"
  type Namespace (line 14) | type Namespace struct
    method Provider (line 47) | func (n *Namespace) Provider() string {
    method Resolver (line 51) | func (n *Namespace) Resolver() resolver.Resolver {
    method String (line 55) | func (n Namespace) String() string {
  function NewNamespace (line 19) | func NewNamespace(provider string) *Namespace {
  function FromString (line 26) | func FromString(namespaceStr string) (*Namespace, error) {
  function FromComponents (line 35) | func FromComponents(components []string) (*Namespace, error) {

FILE: grype/db/v5/namespace/cpe/namespace_test.go
  function TestFromString (line 9) | func TestFromString(t *testing.T) {

FILE: grype/db/v5/namespace/distro/namespace.go
  constant ID (line 13) | ID = "distro"
  type Namespace (line 15) | type Namespace struct
    method Provider (line 52) | func (n *Namespace) Provider() string {
    method DistroType (line 56) | func (n *Namespace) DistroType() distro.Type {
    method Version (line 60) | func (n *Namespace) Version() string {
    method Resolver (line 64) | func (n *Namespace) Resolver() resolver.Resolver {
    method String (line 68) | func (n Namespace) String() string {
  function NewNamespace (line 22) | func NewNamespace(provider string, distroType distro.Type, version strin...
  function FromString (line 31) | func FromString(namespaceStr string) (*Namespace, error) {
  function FromComponents (line 40) | func FromComponents(components []string) (*Namespace, error) {

FILE: grype/db/v5/namespace/distro/namespace_test.go
  function TestFromString (line 11) | func TestFromString(t *testing.T) {

FILE: grype/db/v5/namespace/from_string.go
  function FromString (line 13) | func FromString(namespaceStr string) (Namespace, error) {

FILE: grype/db/v5/namespace/from_string_test.go
  function TestFromString (line 15) | func TestFromString(t *testing.T) {

FILE: grype/db/v5/namespace/language/namespace.go
  constant ID (line 12) | ID = "language"
  type Namespace (line 14) | type Namespace struct
    method Provider (line 59) | func (n *Namespace) Provider() string {
    method Language (line 63) | func (n *Namespace) Language() syftPkg.Language {
    method PackageType (line 67) | func (n *Namespace) PackageType() syftPkg.Type {
    method Resolver (line 71) | func (n *Namespace) Resolver() resolver.Resolver {
    method String (line 75) | func (n Namespace) String() string {
  function NewNamespace (line 21) | func NewNamespace(provider string, language syftPkg.Language, packageTyp...
  function FromString (line 32) | func FromString(namespaceStr string) (*Namespace, error) {
  function FromComponents (line 41) | func FromComponents(components []string) (*Namespace, error) {

FILE: grype/db/v5/namespace/language/namespace_test.go
  function TestFromString (line 11) | func TestFromString(t *testing.T) {

FILE: grype/db/v5/namespace/namespace.go
  type Namespace (line 7) | type Namespace interface

FILE: grype/db/v5/pkg/qualifier/from_json.go
  function FromJSON (line 13) | func FromJSON(data []byte) ([]Qualifier, error) {

FILE: grype/db/v5/pkg/qualifier/platformcpe/qualifier.go
  type Qualifier (line 10) | type Qualifier struct
    method Parse (line 15) | func (q Qualifier) Parse() qualifier.Qualifier {
    method String (line 19) | func (q Qualifier) String() string {

FILE: grype/db/v5/pkg/qualifier/qualifier.go
  type Qualifier (line 9) | type Qualifier interface

FILE: grype/db/v5/pkg/qualifier/rpmmodularity/qualifier.go
  type Qualifier (line 10) | type Qualifier struct
    method Parse (line 15) | func (q Qualifier) Parse() qualifier.Qualifier {
    method String (line 19) | func (q Qualifier) String() string {

FILE: grype/db/v5/pkg/resolver/java/resolver.go
  type Resolver (line 13) | type Resolver struct
    method Normalize (line 16) | func (r *Resolver) Normalize(name string) string {
    method Resolve (line 20) | func (r *Resolver) Resolve(p grypePkg.Package) []string {

FILE: grype/db/v5/pkg/resolver/java/resolver_test.go
  function TestResolver_Normalize (line 12) | func TestResolver_Normalize(t *testing.T) {
  function TestResolver_Resolve (line 49) | func TestResolver_Resolve(t *testing.T) {

FILE: grype/db/v5/pkg/resolver/python/resolver.go
  type Resolver (line 10) | type Resolver struct
    method Normalize (line 13) | func (r *Resolver) Normalize(name string) string {
    method Resolve (line 22) | func (r *Resolver) Resolve(p grypePkg.Package) []string {

FILE: grype/db/v5/pkg/resolver/python/resolver_test.go
  function TestResolver_Normalize (line 9) | func TestResolver_Normalize(t *testing.T) {

FILE: grype/db/v5/pkg/resolver/resolver.go
  type Resolver (line 11) | type Resolver interface
  function FromLanguage (line 16) | func FromLanguage(language syftPkg.Language) (Resolver, error) {
  function PackageNames (line 31) | func PackageNames(p grypePkg.Package) []string {

FILE: grype/db/v5/pkg/resolver/resolver_test.go
  function TestFromLanguage (line 14) | func TestFromLanguage(t *testing.T) {

FILE: grype/db/v5/pkg/resolver/stock/resolver.go
  type Resolver (line 9) | type Resolver struct
    method Normalize (line 12) | func (r *Resolver) Normalize(name string) string {
    method Resolve (line 16) | func (r *Resolver) Resolve(p grypePkg.Package) []string {

FILE: grype/db/v5/pkg/resolver/stock/resolver_test.go
  function TestResolver_Normalize (line 9) | func TestResolver_Normalize(t *testing.T) {

FILE: grype/db/v5/provider_store.go
  type ProviderStore (line 8) | type ProviderStore struct

FILE: grype/db/v5/schema_version.go
  constant SchemaVersion (line 3) | SchemaVersion = 5

FILE: grype/db/v5/store.go
  type Store (line 5) | type Store interface
  type StoreReader (line 10) | type StoreReader interface
  type StoreWriter (line 19) | type StoreWriter interface
  type DiffReader (line 27) | type DiffReader interface

FILE: grype/db/v5/store/diff.go
  type storeKey (line 13) | type storeKey struct
  type storeVulnerabilityList (line 21) | type storeVulnerabilityList struct
  type storeVulnerability (line 25) | type storeVulnerability struct
  type storeMetadata (line 29) | type storeMetadata struct
  function trackDiff (line 35) | func trackDiff(total int64) (*progress.Manual, *progress.Manual, *progre...
  function buildVulnerabilityPkgsMap (line 53) | func buildVulnerabilityPkgsMap(models *[]v5.Vulnerability) *map[storeKey...
  function createDiff (line 69) | func createDiff(baseStore, targetStore *PkgMap, key storeKey, reason v5....
  function getVulnerabilityParentKey (line 101) | func getVulnerabilityParentKey(vuln v5.Vulnerability) storeKey {
  function getVulnerabilityKey (line 106) | func getVulnerabilityKey(vuln v5.Vulnerability) storeKey {
  type VulnerabilitySet (line 110) | type VulnerabilitySet struct
    method in (line 143) | func (v *VulnerabilitySet) in(item v5.Vulnerability) bool {
    method match (line 148) | func (v *VulnerabilitySet) match(item v5.Vulnerability) bool {
    method getUnmatched (line 164) | func (v *VulnerabilitySet) getUnmatched() ([]storeKey, []storeKey) {
  function NewVulnerabilitySet (line 114) | func NewVulnerabilitySet(models *[]v5.Vulnerability) *VulnerabilitySet {
  function diffVulnerabilities (line 185) | func diffVulnerabilities(baseModels, targetModels *[]v5.Vulnerability, b...
  type MetadataSet (line 228) | type MetadataSet struct
    method in (line 246) | func (v *MetadataSet) in(item v5.VulnerabilityMetadata) bool {
    method match (line 251) | func (v *MetadataSet) match(item v5.VulnerabilityMetadata) bool {
    method getUnmatched (line 259) | func (v *MetadataSet) getUnmatched() []storeKey {
  function NewMetadataSet (line 232) | func NewMetadataSet(models *[]v5.VulnerabilityMetadata) *MetadataSet {
  function diffVulnerabilityMetadata (line 269) | func diffVulnerabilityMetadata(baseModels, targetModels *[]v5.Vulnerabil...
  function getMetadataKey (line 303) | func getMetadataKey(metadata v5.VulnerabilityMetadata) storeKey {

FILE: grype/db/v5/store/diff_test.go
  function Test_GetAllVulnerabilities (line 13) | func Test_GetAllVulnerabilities(t *testing.T) {
  function Test_GetAllVulnerabilityMetadata (line 30) | func Test_GetAllVulnerabilityMetadata(t *testing.T) {
  function Test_Diff_Vulnerabilities (line 49) | func Test_Diff_Vulnerabilities(t *testing.T) {
  function Test_Diff_Metadata (line 155) | func Test_Diff_Metadata(t *testing.T) {

FILE: grype/db/v5/store/model/id.go
  constant IDTableName (line 11) | IDTableName = "id"
  type IDModel (line 14) | type IDModel struct
    method TableName (line 26) | func (IDModel) TableName() string {
    method Inflate (line 30) | func (m *IDModel) Inflate() (v5.ID, error) {
  function NewIDModel (line 19) | func NewIDModel(id v5.ID) IDModel {

FILE: grype/db/v5/store/model/vulnerability.go
  constant VulnerabilityTableName (line 13) | VulnerabilityTableName    = "vulnerability"
  constant GetVulnerabilityIndexName (line 14) | GetVulnerabilityIndexName = "get_vulnerability_index"
  type VulnerabilityModel (line 18) | type VulnerabilityModel struct
    method TableName (line 51) | func (VulnerabilityModel) TableName() string {
    method Inflate (line 56) | func (m *VulnerabilityModel) Inflate() (v5.Vulnerability, error) {
  function NewVulnerabilityModel (line 34) | func NewVulnerabilityModel(vulnerability v5.Vulnerability) Vulnerability...

FILE: grype/db/v5/store/model/vulnerability_match_exclusion.go
  constant VulnerabilityMatchExclusionTableName (line 13) | VulnerabilityMatchExclusionTableName    = "vulnerability_match_exclusion"
  constant GetVulnerabilityMatchExclusionIndexName (line 14) | GetVulnerabilityMatchExclusionIndexName = "get_vulnerability_match_exclu...
  type VulnerabilityMatchExclusionModel (line 18) | type VulnerabilityMatchExclusionModel struct
    method TableName (line 35) | func (VulnerabilityMatchExclusionModel) TableName() string {
    method Inflate (line 40) | func (m *VulnerabilityMatchExclusionModel) Inflate() (*v5.Vulnerabilit...
  function NewVulnerabilityMatchExclusionModel (line 26) | func NewVulnerabilityMatchExclusionModel(v v5.VulnerabilityMatchExclusio...

FILE: grype/db/v5/store/model/vulnerability_match_exclusion_test.go
  function TestVulnerabilityMatchExclusionModel_Inflate (line 12) | func TestVulnerabilityMatchExclusionModel_Inflate(t *testing.T) {

FILE: grype/db/v5/store/model/vulnerability_metadata.go
  constant VulnerabilityMetadataTableName (line 12) | VulnerabilityMetadataTableName = "vulnerability_metadata"
  type VulnerabilityMetadataModel (line 16) | type VulnerabilityMetadataModel struct
    method TableName (line 46) | func (VulnerabilityMetadataModel) TableName() string {
    method Inflate (line 51) | func (m *VulnerabilityMetadataModel) Inflate() (v5.VulnerabilityMetada...
  function NewVulnerabilityMetadataModel (line 28) | func NewVulnerabilityMetadataModel(metadata v5.VulnerabilityMetadata) Vu...

FILE: grype/db/v5/store/model/vulnerability_test.go
  function TestVulnerabilityModel_Inflate (line 15) | func TestVulnerabilityModel_Inflate(t *testing.T) {

FILE: grype/db/v5/store/store.go
  type store (line 19) | type store struct
    method GetID (line 45) | func (s *store) GetID() (*v5.ID, error) {
    method SetID (line 67) | func (s *store) SetID(id v5.ID) error {
    method GetVulnerabilityNamespaces (line 84) | func (s *store) GetVulnerabilityNamespaces() ([]string, error) {
    method GetVulnerability (line 91) | func (s *store) GetVulnerability(namespace, id string) ([]v5.Vulnerabi...
    method SearchForVulnerabilities (line 115) | func (s *store) SearchForVulnerabilities(namespace, packageName string...
    method AddVulnerability (line 133) | func (s *store) AddVulnerability(vulnerabilities ...v5.Vulnerability) ...
    method GetVulnerabilityMetadata (line 150) | func (s *store) GetVulnerabilityMetadata(id, namespace string) (*v5.Vu...
    method AddVulnerabilityMetadata (line 176) | func (s *store) AddVulnerabilityMetadata(metadata ...v5.VulnerabilityM...
    method GetVulnerabilityMatchExclusion (line 243) | func (s *store) GetVulnerabilityMatchExclusion(id string) ([]v5.Vulner...
    method AddVulnerabilityMatchExclusion (line 264) | func (s *store) AddVulnerabilityMatchExclusion(exclusions ...v5.Vulner...
    method Close (line 281) | func (s *store) Close() error {
    method GetAllVulnerabilities (line 313) | func (s *store) GetAllVulnerabilities() (*[]v5.Vulnerability, error) {
    method GetAllVulnerabilityMetadata (line 330) | func (s *store) GetAllVulnerabilityMetadata() (*[]v5.VulnerabilityMeta...
    method DiffStore (line 347) | func (s *store) DiffStore(targetStore v5.StoreReader) (*[]v5.Diff, err...
  function models (line 23) | func models() []any {
  function New (line 33) | func New(dbFilePath string, overwrite bool) (v5.Store, error) {

FILE: grype/db/v5/store/store_test.go
  function assertIDReader (line 16) | func assertIDReader(t *testing.T, reader v5.IDReader, expected v5.ID) {
  function TestStore_GetID_SetID (line 30) | func TestStore_GetID_SetID(t *testing.T) {
  function assertVulnerabilityReader (line 51) | func assertVulnerabilityReader(t *testing.T, reader v5.VulnerabilityStor...
  function TestStore_GetVulnerability_SetVulnerability (line 69) | func TestStore_GetVulnerability_SetVulnerability(t *testing.T) {
  function assertVulnerabilityMetadataReader (line 212) | func assertVulnerabilityMetadataReader(t *testing.T, reader v5.Vulnerabi...
  function sortMetadataCvss (line 249) | func sortMetadataCvss(cvss []v5.Cvss) {
  type CustomMetadata (line 266) | type CustomMetadata struct
  function TestStore_GetVulnerabilityMetadata_SetVulnerabilityMetadata (line 271) | func TestStore_GetVulnerabilityMetadata_SetVulnerabilityMetadata(t *test...
  function TestStore_MergeVulnerabilityMetadata (line 355) | func TestStore_MergeVulnerabilityMetadata(t *testing.T) {
  function TestCvssScoresInMetadata (line 790) | func TestCvssScoresInMetadata(t *testing.T) {
  function assertVulnerabilityMatchExclusionReader (line 1038) | func assertVulnerabilityMatchExclusionReader(t *testing.T, reader v5.Vul...
  function TestStore_GetVulnerabilityMatchExclusion_SetVulnerabilityMatchExclusion (line 1057) | func TestStore_GetVulnerabilityMatchExclusion_SetVulnerabilityMatchExclu...
  function Test_DiffStore (line 1213) | func Test_DiffStore(t *testing.T) {

FILE: grype/db/v5/vulnerability.go
  type Vulnerability (line 17) | type Vulnerability struct
    method Equal (line 36) | func (v *Vulnerability) Equal(vv Vulnerability) bool {
  type VulnerabilityReference (line 30) | type VulnerabilityReference struct
  function sortRelatedVulns (line 91) | func sortRelatedVulns(vulns []VulnerabilityReference) []VulnerabilityRef...
  function sortAdvisories (line 103) | func sortAdvisories(advisories []Advisory) []Advisory {
  function sortPackageQualifiers (line 115) | func sortPackageQualifiers(qualifiers []qualifierV5.Qualifier) []qualifi...
  function NewVulnerability (line 122) | func NewVulnerability(vuln Vulnerability) (*vulnerability.Vulnerability,...

FILE: grype/db/v5/vulnerability_match_exclusion.go
  type VulnerabilityMatchExclusion (line 9) | type VulnerabilityMatchExclusion struct
  type VulnerabilityMatchExclusionConstraint (line 16) | type VulnerabilityMatchExclusionConstraint struct
    method Usable (line 22) | func (c VulnerabilityMatchExclusionConstraint) Usable() bool {
    method UnmarshalJSON (line 26) | func (c *VulnerabilityMatchExclusionConstraint) UnmarshalJSON(data []b...
  type VulnerabilityExclusionConstraint (line 53) | type VulnerabilityExclusionConstraint struct
    method Usable (line 59) | func (v VulnerabilityExclusionConstraint) Usable() bool {
    method UnmarshalJSON (line 63) | func (v *VulnerabilityExclusionConstraint) UnmarshalJSON(data []byte) ...
  type PackageExclusionConstraint (line 90) | type PackageExclusionConstraint struct
    method Usable (line 99) | func (p PackageExclusionConstraint) Usable() bool {
    method UnmarshalJSON (line 103) | func (p *PackageExclusionConstraint) UnmarshalJSON(data []byte) error {

FILE: grype/db/v5/vulnerability_match_exclusion_store.go
  type VulnerabilityMatchExclusionStore (line 3) | type VulnerabilityMatchExclusionStore interface
  type VulnerabilityMatchExclusionStoreReader (line 8) | type VulnerabilityMatchExclusionStoreReader interface
  type VulnerabilityMatchExclusionStoreWriter (line 12) | type VulnerabilityMatchExclusionStoreWriter interface

FILE: grype/db/v5/vulnerability_metadata.go
  type VulnerabilityMetadata (line 10) | type VulnerabilityMetadata struct
    method Equal (line 57) | func (v *VulnerabilityMetadata) Equal(vv VulnerabilityMetadata) bool {
  type Cvss (line 22) | type Cvss struct
  type CvssMetrics (line 35) | type CvssMetrics struct
  function NewCvssMetrics (line 49) | func NewCvssMetrics(baseScore, exploitabilityScore, impactScore float64)...
  function NewMetadata (line 84) | func NewMetadata(m *VulnerabilityMetadata) (*vulnerability.Metadata, err...

FILE: grype/db/v5/vulnerability_metadata_store.go
  type VulnerabilityMetadataStore (line 3) | type VulnerabilityMetadataStore interface
  type VulnerabilityMetadataStoreReader (line 8) | type VulnerabilityMetadataStoreReader interface
  type VulnerabilityMetadataStoreWriter (line 13) | type VulnerabilityMetadataStoreWriter interface

FILE: grype/db/v5/vulnerability_store.go
  constant VulnerabilityStoreFileName (line 3) | VulnerabilityStoreFileName = "vulnerability.db"
  type VulnerabilityStore (line 5) | type VulnerabilityStore interface
  type VulnerabilityStoreReader (line 10) | type VulnerabilityStoreReader interface
  type VulnerabilityStoreWriter (line 20) | type VulnerabilityStoreWriter interface

FILE: grype/db/v6/affected_cpe_store.go
  type AffectedCPEStoreWriter (line 9) | type AffectedCPEStoreWriter interface
  type AffectedCPEStoreReader (line 13) | type AffectedCPEStoreReader interface
  type affectedCPEStore (line 17) | type affectedCPEStore struct
    method AddAffectedCPEs (line 31) | func (s *affectedCPEStore) AddAffectedCPEs(packages ...*AffectedCPEHan...
    method GetAffectedCPEs (line 35) | func (s *affectedCPEStore) GetAffectedCPEs(cpe *cpe.Attributes, config...
  function newAffectedCPEStore (line 23) | func newAffectedCPEStore(db *gorm.DB, bs *blobStore) *affectedCPEStore {

FILE: grype/db/v6/affected_cpe_store_test.go
  function TestAffectedCPEStore_AddAffectedCPEs (line 13) | func TestAffectedCPEStore_AddAffectedCPEs(t *testing.T) {
  function TestAffectedCPEStore_GetCPEs (line 58) | func TestAffectedCPEStore_GetCPEs(t *testing.T) {
  function TestAffectedCPEStore_GetExact (line 89) | func TestAffectedCPEStore_GetExact(t *testing.T) {
  function TestAffectedCPEStore_Get_CaseInsensitive (line 109) | func TestAffectedCPEStore_Get_CaseInsensitive(t *testing.T) {
  function TestAffectedCPEStore_PreventDuplicateCPEs (line 138) | func TestAffectedCPEStore_PreventDuplicateCPEs(t *testing.T) {
  function cpeFromProduct (line 213) | func cpeFromProduct(product string) *cpe.Attributes {
  function toCPE (line 219) | func toCPE(c *Cpe) *cpe.Attributes {
  function testAffectedCPEHandle (line 233) | func testAffectedCPEHandle() *AffectedCPEHandle {

FILE: grype/db/v6/affected_package_store.go
  type AffectedPackageStoreWriter (line 5) | type AffectedPackageStoreWriter interface
  type AffectedPackageStoreReader (line 9) | type AffectedPackageStoreReader interface
  type affectedPackageStore (line 13) | type affectedPackageStore struct
    method AddAffectedPackages (line 27) | func (s *affectedPackageStore) AddAffectedPackages(packages ...*Affect...
    method GetAffectedPackages (line 31) | func (s *affectedPackageStore) GetAffectedPackages(pkg *PackageSpecifi...
  function newAffectedPackageStore (line 19) | func newAffectedPackageStore(db *gorm.DB, bs *blobStore, oss *operatingS...

FILE: grype/db/v6/affected_package_store_test.go
  type affectedPackageHandlePreloadConfig (line 16) | type affectedPackageHandlePreloadConfig struct
  function defaultAffectedPackageHandlePreloadCases (line 25) | func defaultAffectedPackageHandlePreloadCases() []affectedPackageHandleP...
  function TestAffectedPackageStore_AddAffectedPackages (line 137) | func TestAffectedPackageStore_AddAffectedPackages(t *testing.T) {
  function TestAffectedPackageStore_GetAffectedPackages_ByCPE (line 431) | func TestAffectedPackageStore_GetAffectedPackages_ByCPE(t *testing.T) {
  function TestAffectedPackageStore_GetAffectedPackages_CaseInsensitive (line 597) | func TestAffectedPackageStore_GetAffectedPackages_CaseInsensitive(t *tes...
  function TestAffectedPackageStore_GetAffectedPackages_MultipleVulnerabilitySpecs (line 737) | func TestAffectedPackageStore_GetAffectedPackages_MultipleVulnerabilityS...
  function TestAffectedPackageStore_GetAffectedPackages (line 793) | func TestAffectedPackageStore_GetAffectedPackages(t *testing.T) {
  function TestAffectedPackageStore_ApplyPackageAlias (line 948) | func TestAffectedPackageStore_ApplyPackageAlias(t *testing.T) {
  function testDistro1AffectedPackage2Handle (line 988) | func testDistro1AffectedPackage2Handle() *AffectedPackageHandle {
  function testDistro2AffectedPackage2Handle (line 1017) | func testDistro2AffectedPackage2Handle() *AffectedPackageHandle {
  function testNonDistroAffectedPackage2Handle (line 1045) | func testNonDistroAffectedPackage2Handle() *AffectedPackageHandle {
  function expectErrIs (line 1067) | func expectErrIs(t *testing.T, expected error) require.ErrorAssertionFunc {
  function pkgFromName (line 1075) | func pkgFromName(name string) *PackageSpecifier {

FILE: grype/db/v6/blob_store.go
  type blobable (line 14) | type blobable interface
  type blobStore (line 21) | type blobStore struct
    method addBlobable (line 33) | func (s *blobStore) addBlobable(bs ...blobable) error {
    method addBlobs (line 51) | func (s *blobStore) addBlobs(blobs ...*Blob) error {
    method getBlobValues (line 72) | func (s *blobStore) getBlobValues(ids ...ID) ([]Blob, error) {
    method attachBlobValue (line 83) | func (s *blobStore) attachBlobValue(bs ...blobable) error {
  function newBlobStore (line 26) | func newBlobStore(db *gorm.DB) *blobStore {
  function newBlob (line 123) | func newBlob(obj any) *Blob {

FILE: grype/db/v6/blob_store_test.go
  function TestBlobWriter_AddBlobs (line 10) | func TestBlobWriter_AddBlobs(t *testing.T) {
  function TestBlob_computeDigest (line 36) | func TestBlob_computeDigest(t *testing.T) {

FILE: grype/db/v6/blobs.go
  type VulnerabilityBlob (line 11) | type VulnerabilityBlob struct
    method String (line 31) | func (v VulnerabilityBlob) String() string {
  type Reference (line 36) | type Reference struct
  type Severity (line 48) | type Severity struct
    method UnmarshalJSON (line 71) | func (s *Severity) UnmarshalJSON(data []byte) error {
  type severityAlias (line 63) | type severityAlias
  type severityUnmarshalProxy (line 65) | type severityUnmarshalProxy struct
  type CVSSSeverity (line 96) | type CVSSSeverity struct
    method String (line 104) | func (c CVSSSeverity) String() string {
  type PackageBlob (line 113) | type PackageBlob struct
    method String (line 124) | func (a PackageBlob) String() string {
  type PackageQualifiers (line 143) | type PackageQualifiers struct
  type Range (line 152) | type Range struct
    method String (line 160) | func (a Range) String() string {
  type Fix (line 165) | type Fix struct
    method String (line 176) | func (f Fix) String() string {
  type FixDetail (line 187) | type FixDetail struct
  type FixAvailability (line 195) | type FixAvailability struct
    method MarshalJSON (line 203) | func (f FixAvailability) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 221) | func (f *FixAvailability) UnmarshalJSON(data []byte) error {
  type Version (line 252) | type Version struct
  type KnownExploitedVulnerabilityBlob (line 260) | type KnownExploitedVulnerabilityBlob struct

FILE: grype/db/v6/blobs_test.go
  function TestFixAvailability_MarshalJSON (line 12) | func TestFixAvailability_MarshalJSON(t *testing.T) {
  function TestFixAvailability_UnmarshalJSON_SimpleDateFormat (line 27) | func TestFixAvailability_UnmarshalJSON_SimpleDateFormat(t *testing.T) {
  function TestFixAvailability_UnmarshalJSON_RFC3339Format (line 39) | func TestFixAvailability_UnmarshalJSON_RFC3339Format(t *testing.T) {
  function TestFixAvailability_RoundTripMarshalUnmarshal (line 51) | func TestFixAvailability_RoundTripMarshalUnmarshal(t *testing.T) {
  function TestPackageBlob_WithFixAvailability (line 72) | func TestPackageBlob_WithFixAvailability(t *testing.T) {
  function TestFixAvailability_UnmarshalJSON_InvalidDateFormat (line 116) | func TestFixAvailability_UnmarshalJSON_InvalidDateFormat(t *testing.T) {

FILE: grype/db/v6/build/archive.go
  function CreateArchive (line 19) | func CreateArchive(dbDir, overrideArchiveExtension string, compressorCom...
  function toProviders (line 83) | func toProviders(states []v6.Provider) provider.States {
  function resolveExtension (line 94) | func resolveExtension(overrideArchiveExtension string) (string, error) {
  function populateTar (line 115) | func populateTar(dbDir, tarName string, compressorCommands map[string]st...
  function writeLatestDocument (line 147) | func writeLatestDocument(tarPath string, metadata v6.DBMetadata) error {

FILE: grype/db/v6/build/processors.go
  type Config (line 19) | type Config struct
  type Option (line 23) | type Option
  function WithCPEParts (line 25) | func WithCPEParts(included []string) Option {
  function WithInferNVDFixVersions (line 31) | func WithInferNVDFixVersions(infer bool) Option {
  function NewConfig (line 37) | func NewConfig(options ...Option) Config {
  function Processors (line 46) | func Processors(cfg Config) []data.Processor {

FILE: grype/db/v6/build/transformers/entry.go
  type RelatedEntries (line 11) | type RelatedEntries struct
    method String (line 44) | func (re RelatedEntries) String() string {
  function NewEntries (line 17) | func NewEntries(models ...any) []data.Entry {

FILE: grype/db/v6/build/transformers/eol/transform.go
  function Transform (line 50) | func Transform(entry unmarshal.EndOfLifeDateRelease, state provider.Stat...
  function translateProductName (line 69) | func translateProductName(product string) string {
  function getOperatingSystemEOL (line 77) | func getOperatingSystemEOL(entry unmarshal.EndOfLifeDateRelease, distroN...
  function parseVersion (line 110) | func parseVersion(cycle string) (major, minor string) {
  function normalizeVersion (line 122) | func normalizeVersion(v string) string {

FILE: grype/db/v6/build/transformers/eol/transform_test.go
  function TestParseVersion (line 9) | func TestParseVersion(t *testing.T) {
  function TestNormalizeVersion (line 75) | func TestNormalizeVersion(t *testing.T) {
  function TestTranslateProductName (line 126) | func TestTranslateProductName(t *testing.T) {

FILE: grype/db/v6/build/transformers/epss/transform.go
  function Transform (line 15) | func Transform(entry unmarshal.EPSS, state provider.State) ([]data.Entry...
  function getEPSS (line 23) | func getEPSS(entry unmarshal.EPSS, date time.Time) db.EpssHandle {

FILE: grype/db/v6/build/transformers/epss/transform_test.go
  function TestTransform (line 19) | func TestTransform(t *testing.T) {
  function epssSlice (line 84) | func epssSlice(a ...db.EpssHandle) []any {
  function loadFixture (line 92) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.EPSS {

FILE: grype/db/v6/build/transformers/github/transform.go
  function Transform (line 20) | func Transform(vulnerability unmarshal.GitHubAdvisory, state provider.St...
  function getVulnerability (line 32) | func getVulnerability(vuln unmarshal.GitHubAdvisory, state provider.Stat...
  function getVulnStatus (line 55) | func getVulnStatus(vuln unmarshal.GitHubAdvisory) db.VulnerabilityStatus {
  function getAffectedPackage (line 63) | func getAffectedPackage(vuln unmarshal.GitHubAdvisory) []db.AffectedPack...
  function getRanges (line 92) | func getRanges(fixedInEntry unmarshal.GithubFixedIn) ([]db.Range, error) {
  function validateAffectedVersion (line 110) | func validateAffectedVersion(v db.Version) error {
  function getAffectedVersionFormat (line 130) | func getAffectedVersionFormat(fixedInEntry unmarshal.GithubFixedIn) stri...
  function getFix (line 140) | func getFix(fixedInEntry unmarshal.GithubFixedIn) *db.Fix {
  function getFixAvailability (line 163) | func getFixAvailability(fixedInEntry unmarshal.GithubFixedIn) *db.FixAva...
  type groupIndex (line 180) | type groupIndex struct
  function groupFixedIns (line 185) | func groupFixedIns(vuln unmarshal.GitHubAdvisory) map[groupIndex][]unmar...
  function getPackageType (line 199) | func getPackageType(ecosystem string) pkg.Type {
  function getPackage (line 243) | func getPackage(group groupIndex) *db.Package {
  function getSeverities (line 251) | func getSeverities(vulnerability unmarshal.GitHubAdvisory) []db.Severity {
  function getAliases (line 291) | func getAliases(vulnerability unmarshal.GitHubAdvisory) (aliases []strin...
  function getReferences (line 296) | func getReferences(vulnerability unmarshal.GitHubAdvisory) []db.Reference {

FILE: grype/db/v6/build/transformers/github/transform_test.go
  function TestTransform (line 19) | func TestTransform(t *testing.T) {
  function TestGetVulnerability (line 72) | func TestGetVulnerability(t *testing.T) {
  function TestGetAffectedPackage (line 403) | func TestGetAffectedPackage(t *testing.T) {
  function TestGetPackageType (line 625) | func TestGetPackageType(t *testing.T) {
  function TestGetRanges (line 670) | func TestGetRanges(t *testing.T) {
  function TestGetFixAvailability (line 725) | func TestGetFixAvailability(t *testing.T) {
  function TestGetFix (line 794) | func TestGetFix(t *testing.T) {
  function loadFixture (line 888) | func loadFixture(t *testing.T, path string) []unmarshal.GitHubAdvisory {

FILE: grype/db/v6/build/transformers/internal/sort.go
  type ByAffectedPackage (line 5) | type ByAffectedPackage
    method Len (line 7) | func (a ByAffectedPackage) Len() int      { return len(a) }
    method Swap (line 8) | func (a ByAffectedPackage) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
    method Less (line 9) | func (a ByAffectedPackage) Less(i, j int) bool {
  type ByUnaffectedPackage (line 13) | type ByUnaffectedPackage
    method Len (line 15) | func (a ByUnaffectedPackage) Len() int      { return len(a) }
    method Swap (line 16) | func (a ByUnaffectedPackage) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
    method Less (line 17) | func (a ByUnaffectedPackage) Less(i, j int) bool {
  function comparePackageHandles (line 22) | func comparePackageHandles(pkg1 *db.Package, ranges1 []db.Range, pkg2 *d...

FILE: grype/db/v6/build/transformers/internal/time.go
  function ParseTime (line 12) | func ParseTime(s string) *time.Time {

FILE: grype/db/v6/build/transformers/internal/time_test.go
  function TestParseTime (line 10) | func TestParseTime(t *testing.T) {

FILE: grype/db/v6/build/transformers/kev/transform.go
  function Transform (line 17) | func Transform(kev unmarshal.KnownExploitedVulnerability, state provider...
  function getKev (line 21) | func getKev(kev unmarshal.KnownExploitedVulnerability) db.KnownExploited...
  function getURLs (line 42) | func getURLs(aux []string, notes string) ([]string, string) {

FILE: grype/db/v6/build/transformers/kev/transform_test.go
  function TestTransform (line 18) | func TestTransform(t *testing.T) {
  function kevSlice (line 97) | func kevSlice(a ...db.KnownExploitedVulnerabilityHandle) []any {
  function loadFixture (line 105) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.KnownExpl...

FILE: grype/db/v6/build/transformers/msrc/transform.go
  function Transform (line 17) | func Transform(vulnerability unmarshal.MSRCVulnerability, state provider...
  function getVulnerability (line 27) | func getVulnerability(vuln unmarshal.MSRCVulnerability, state provider.S...
  function getAffectedPackage (line 42) | func getAffectedPackage(vuln unmarshal.MSRCVulnerability) db.AffectedPac...
  function getPackage (line 51) | func getPackage(vuln unmarshal.MSRCVulnerability) *db.Package {
  function getRanges (line 58) | func getRanges(vuln unmarshal.MSRCVulnerability) []db.Range {
  function getFix (line 75) | func getFix(vuln unmarshal.MSRCVulnerability) *db.Fix {
  function fixedInKB (line 92) | func fixedInKB(vulnerability unmarshal.MSRCVulnerability) (string, *db.F...
  function getReferences (line 110) | func getReferences(vuln unmarshal.MSRCVulnerability) []db.Reference {
  function getSeverities (line 120) | func getSeverities(vuln unmarshal.MSRCVulnerability) []db.Severity {

FILE: grype/db/v6/build/transformers/msrc/transform_test.go
  function TestUnmarshalMsrcVulnerabilities (line 20) | func TestUnmarshalMsrcVulnerabilities(t *testing.T) {
  function TestParseMSRCEntry (line 31) | func TestParseMSRCEntry(t *testing.T) {
  function timePtr (line 199) | func timePtr(t time.Time) *time.Time {

FILE: grype/db/v6/build/transformers/nvd/affected_range.go
  type affectedRangeSet (line 12) | type affectedRangeSet
    method addRanges (line 40) | func (s affectedRangeSet) addRanges(rs ...affectedCPERange) {
    method toSlice (line 46) | func (s affectedRangeSet) toSlice() []affectedCPERange {
  type affectedCPERange (line 14) | type affectedCPERange struct
    method String (line 75) | func (r affectedCPERange) String() string {
  function newAffectedRanges (line 24) | func newAffectedRanges(rs ...affectedCPERange) affectedRangeSet {
  function newAffectedRange (line 30) | func newAffectedRange(match nvd.CpeMatch) affectedCPERange {
  function nonEmptyValue (line 104) | func nonEmptyValue(value *string) string {

FILE: grype/db/v6/build/transformers/nvd/affected_range_test.go
  function Test_AffectedCPERange_String (line 11) | func Test_AffectedCPERange_String(t *testing.T) {
  function Test_newAffectedRange (line 130) | func Test_newAffectedRange(t *testing.T) {
  function stringPtr (line 181) | func stringPtr(s string) *string {

FILE: grype/db/v6/build/transformers/nvd/node.go
  type affectedPackageCandidate (line 13) | type affectedPackageCandidate struct
  function allCandidates (line 19) | func allCandidates(cve string, configs []nvd.Configuration, cfg Config) ...
  function processConfiguration (line 34) | func processConfiguration(cve string, config nvd.Configuration, cfg Conf...
  function processANDNodes (line 50) | func processANDNodes(cve string, nodes []nvd.Node, cfg Config, depth int...
  function processORNodes (line 119) | func processORNodes(cve string, nodes []nvd.Node, cfg Config, depth int)...
  function deduplicateCandidates (line 147) | func deduplicateCandidates(candidates []affectedPackageCandidate) []affe...
  function deriveRangesFromCPE (line 195) | func deriveRangesFromCPE(attr cpe.Attributes) []affectedCPERange {
  function extractVulnerableCPEs (line 214) | func extractVulnerableCPEs(node nvd.Node, cfg Config) ([]affectedPackage...
  function extractPlatformCPEs (line 254) | func extractPlatformCPEs(node nvd.Node) ([]cpe.Attributes, error) {
  function cpeKey (line 272) | func cpeKey(cpe cpe.Attributes) string {

FILE: grype/db/v6/build/transformers/nvd/node_test.go
  function TestDeduplicateCandidates (line 12) | func TestDeduplicateCandidates(t *testing.T) {
  function TestDeduplicateCandidates_SensitiveToAllCPEFields (line 409) | func TestDeduplicateCandidates_SensitiveToAllCPEFields(t *testing.T) {

FILE: grype/db/v6/build/transformers/nvd/transform.go
  type Config (line 24) | type Config struct
  function defaultConfig (line 29) | func defaultConfig() Config {
  function getVersionFormat (line 36) | func getVersionFormat(cpeProduct string) string {
  function Transformer (line 43) | func Transformer(cfg Config) data.NVDTransformerV2 {
  function transform (line 52) | func transform(cfg Config, vulnerability unmarshal.NVDVulnerability, sta...
  function getAssigner (line 82) | func getAssigner(vuln unmarshal.NVDVulnerability) []string {
  function getVulnStatus (line 96) | func getVulnStatus(vuln unmarshal.NVDVulnerability) db.VulnerabilityStat...
  function getAffected (line 153) | func getAffected(cfg Config, vulnerability unmarshal.NVDVulnerability) [...
  function getCWEs (line 168) | func getCWEs(vulnerability unmarshal.NVDVulnerability) []db.CWEHandle {
  function isValidCWE (line 186) | func isValidCWE(cwe string) bool {
  function encodeCPEs (line 199) | func encodeCPEs(cpes []cpe.Attributes) []string {
  function affectedApplicationPackage (line 207) | func affectedApplicationPackage(cfg Config, vulnerability unmarshal.NVDV...
  function getRanges (line 229) | func getRanges(cfg Config, c cpe.Attributes, ras []affectedCPERange, vul...
  function getRange (line 241) | func getRange(cfg Config, c cpe.Attributes, ra affectedCPERange, vulnID ...
  function getFix (line 251) | func getFix(cfg Config, vulnCPE cpe.Attributes, ra affectedCPERange, vul...
  function getCPEFromAttributes (line 305) | func getCPEFromAttributes(atts cpe.Attributes) *db.Cpe {
  function getSeverities (line 319) | func getSeverities(vuln unmarshal.NVDVulnerability) []db.Severity {
  function getReferences (line 341) | func getReferences(vuln unmarshal.NVDVulnerability) []db.Reference {

FILE: grype/db/v6/build/transformers/nvd/transform_test.go
  function inputProviderState (line 28) | func inputProviderState(name string) provider.State {
  function expectedProvider (line 38) | func expectedProvider(name string) *db.Provider {
  function TestTransform (line 48) | func TestTransform(t *testing.T) {
  function relatedEntries (line 1899) | func relatedEntries(items ...any) []any {
  function loadFixture (line 1903) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.NVDVulner...
  function timeRef (line 1923) | func timeRef(ti time.Time) *time.Time {
  function TestIsValidCWE (line 1927) | func TestIsValidCWE(t *testing.T) {
  function TestGetReferences (line 2000) | func TestGetReferences(t *testing.T) {

FILE: grype/db/v6/build/transformers/openvex/transform.go
  function AnnotatedTransform (line 20) | func AnnotatedTransform(wrapper unmarshal.AnnotatedOpenVEXVulnerability,...
  function Transform (line 24) | func Transform(vulnerability unmarshal.OpenVEXVulnerability, state provi...
  function transform (line 28) | func transform(vulnerability unmarshal.OpenVEXVulnerability, state provi...
  function getPackageHandles (line 55) | func getPackageHandles(vuln *unmarshal.OpenVEXVulnerability, fixes []unm...
  function getPackageHandle (line 99) | func getPackageHandle(product *govex.Product, vuln *unmarshal.OpenVEXVul...
  function getPURL (line 139) | func getPURL(product *govex.Product) (purl *packageurl.PackageURL, err e...
  function getAliases (line 157) | func getAliases(vuln *unmarshal.OpenVEXVulnerability) []string {
  function getName (line 165) | func getName(vuln *unmarshal.OpenVEXVulnerability) string {
  function getReferences (line 169) | func getReferences(vuln *unmarshal.OpenVEXVulnerability) []db.Reference {
  function getPackageBlob (line 178) | func getPackageBlob(aliases []string, ver string, ty string, fixState db...

FILE: grype/db/v6/build/transformers/openvex/transform_test.go
  function inputProviderState (line 26) | func inputProviderState() provider.State {
  function TestOpenVEXTransform (line 36) | func TestOpenVEXTransform(t *testing.T) {
  function Test_GetPackageHandles (line 301) | func Test_GetPackageHandles(t *testing.T) {

FILE: grype/db/v6/build/transformers/os/transform.go
  type advisoryKey (line 27) | type advisoryKey struct
  function Transform (line 32) | func Transform(vulnerability unmarshal.OSVulnerability, state provider.S...
  function getAffectedPackages (line 59) | func getAffectedPackages(vuln unmarshal.OSVulnerability) []db.AffectedPa...
  function getFix (line 106) | func getFix(fixedInEntry unmarshal.OSFixedIn) *db.Fix {
  function getFixAvailability (line 150) | func getFixAvailability(fixedInEntry unmarshal.OSFixedIn) *db.FixAvailab...
  function enforceConstraint (line 167) | func enforceConstraint(fixedVersion, vulnerableRange, format, vulnerabil...
  function deriveConstraintFromFix (line 184) | func deriveConstraintFromFix(fixVersion, vulnerabilityID string) string {
  type groupIndex (line 205) | type groupIndex struct
  function groupFixedIns (line 216) | func groupFixedIns(vuln unmarshal.OSVulnerability) map[groupIndex][]unma...
  function getPackageType (line 241) | func getPackageType(osName string) pkg.Type {
  function getPackage (line 256) | func getPackage(group groupIndex) *db.Package {
  type osInfo (line 264) | type osInfo struct
  function getOSInfo (line 271) | func getOSInfo(group string) osInfo {
  function normalizeOsName (line 302) | func normalizeOsName(id string) string {
  function getOperatingSystem (line 313) | func getOperatingSystem(osName, osID, osVersion, channel string) *db.Ope...
  function getReferences (line 343) | func getReferences(vuln unmarshal.OSVulnerability) []db.Reference {
  function getAliases (line 373) | func getAliases(vuln unmarshal.OSVulnerability) []string {
  function getSeverities (line 383) | func getSeverities(vuln unmarshal.OSVulnerability) []db.Severity {

FILE: grype/db/v6/build/transformers/os/transform_test.go
  function inputProviderState (line 25) | func inputProviderState(name string) provider.State {
  function expectedProvider (line 35) | func expectedProvider(name string) *db.Provider {
  function TestTransform (line 45) | func TestTransform(t *testing.T) {
  function TestGetOperatingSystem (line 1222) | func TestGetOperatingSystem(t *testing.T) {
  function TestGetOSInfo (line 1297) | func TestGetOSInfo(t *testing.T) {
  function TestGetFixAvailability (line 1386) | func TestGetFixAvailability(t *testing.T) {
  function TestGetFixWithDetail (line 1451) | func TestGetFixWithDetail(t *testing.T) {
  function TestGetFixWithDetailFixtures (line 1579) | func TestGetFixWithDetailFixtures(t *testing.T) {
  function affectedPkgSlice (line 1658) | func affectedPkgSlice(a ...db.AffectedPackageHandle) []any {
  function loadFixture (line 1666) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.OSVulnera...
  function timeRef (line 1680) | func timeRef(ti time.Time) *time.Time {
  function strRef (line 1684) | func strRef(s string) *string {

FILE: grype/db/v6/build/transformers/osv/transform.go
  constant almaLinux (line 25) | almaLinux = "almalinux"
  function Transform (line 28) | func Transform(vulnerability unmarshal.OSVVulnerability, state provider....
  function getAffectedPackages (line 76) | func getAffectedPackages(vuln unmarshal.OSVVulnerability) []db.AffectedP...
  function getPackageQualifiers (line 119) | func getPackageQualifiers(affected models.Affected, cpes any, withCPE bo...
  function extractRpmModularity (line 142) | func extractRpmModularity(affected models.Affected) string {
  function getGrypeRangesFromRange (line 208) | func getGrypeRangesFromRange(r models.Range, ecosystem string) []db.Rang...
  function normalizeConstraint (line 302) | func normalizeConstraint(constraint string, rangeType string) string {
  function normalizeFix (line 309) | func normalizeFix(fix string, detail *db.FixDetail) *db.Fix {
  function normalizeRangeType (line 323) | func normalizeRangeType(t models.RangeType, ecosystem string) string {
  function getPackage (line 337) | func getPackage(p models.Package) *db.Package {
  function getPackageTypeFromEcosystem (line 363) | func getPackageTypeFromEcosystem(ecosystem string) pkg.Type {
  function getReferences (line 382) | func getReferences(vuln unmarshal.OSVVulnerability) []db.Reference {
  function extractCVSSInfo (line 405) | func extractCVSSInfo(cvss string) (string, string, error) {
  function normalizeSeverity (line 416) | func normalizeSeverity(severity models.Severity) (db.Severity, error) {
  function getSeverities (line 439) | func getSeverities(vuln unmarshal.OSVVulnerability) ([]db.Severity, erro...
  function getOperatingSystemFromEcosystem (line 465) | func getOperatingSystemFromEcosystem(ecosystem string) *db.OperatingSyst...
  function normalizeOSName (line 514) | func normalizeOSName(osName string) string {
  function isAdvisoryRecord (line 526) | func isAdvisoryRecord(vuln unmarshal.OSVVulnerability) bool {
  function getUnaffectedPackages (line 555) | func getUnaffectedPackages(vuln unmarshal.OSVVulnerability) []db.Unaffec...
  function getUnaffectedBlob (line 578) | func getUnaffectedBlob(aliases []string, ranges []models.Range, affected...
  function getGrypeUnaffectedRangesFromRange (line 597) | func getGrypeUnaffectedRangesFromRange(r models.Range, ecosystem string)...
  function extractFixAvailability (line 609) | func extractFixAvailability(r models.Range) map[string]db.FixAvailability {
  function parseSingleFixEntry (line 640) | func parseSingleFixEntry(fixEntry any, fixByVersion map[string]db.FixAva...
  function buildUnaffectedRangesFromEvents (line 659) | func buildUnaffectedRangesFromEvents(events []models.Event, fixByVersion...
  function createUnaffectedRange (line 673) | func createUnaffectedRange(fixedVersion string, fixByVersion map[string]...

FILE: grype/db/v6/build/transformers/osv/transform_test.go
  function inputProviderState (line 26) | func inputProviderState() provider.State {
  function expectedProvider (line 36) | func expectedProvider() *db.Provider {
  function timeRef (line 46) | func timeRef(t time.Time) *time.Time {
  function loadFixture (line 50) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.OSVVulner...
  function affectedPkgSlice (line 64) | func affectedPkgSlice(a ...db.AffectedPackageHandle) []any {
  function unaffectedPkgSlice (line 72) | func unaffectedPkgSlice(u ...db.UnaffectedPackageHandle) []any {
  function TestTransform (line 80) | func TestTransform(t *testing.T) {
  function Test_getGrypeRangesFromRange (line 308) | func Test_getGrypeRangesFromRange(t *testing.T) {
  function Test_getPackage (line 477) | func Test_getPackage(t *testing.T) {
  function Test_extractCVSSInfo (line 536) | func Test_extractCVSSInfo(t *testing.T) {
  function Test_extractRpmModularity (line 593) | func Test_extractRpmModularity(t *testing.T) {
  function Test_getPackageQualifiers (line 655) | func Test_getPackageQualifiers(t *testing.T) {
  function stringRef (line 723) | func stringRef(s string) *string {

FILE: grype/db/v6/build/transformers/references.go
  function DeduplicateReferences (line 7) | func DeduplicateReferences(references []db.Reference) []db.Reference {
  function refsAreEqual (line 34) | func refsAreEqual(a, b db.Reference) bool {

FILE: grype/db/v6/build/writer.go
  type writer (line 19) | type writer struct
    method Write (line 81) | func (w *writer) Write(entries ...data.Entry) error {
    method writeEntry (line 100) | func (w *writer) writeEntry(entry transformers.RelatedEntries) error {
    method writeRelatedEntry (line 139) | func (w *writer) writeRelatedEntry(vulnHandle *db.VulnerabilityHandle,...
    method writeAffectedPackage (line 182) | func (w *writer) writeAffectedPackage(vulnHandle *db.VulnerabilityHand...
    method writeAffectedCPE (line 215) | func (w *writer) writeAffectedCPE(vulnHandle *db.VulnerabilityHandle, ...
    method writeUnaffectedPackage (line 230) | func (w *writer) writeUnaffectedPackage(vulnHandle *db.VulnerabilityHa...
    method writeUnaffectedCPE (line 244) | func (w *writer) writeUnaffectedCPE(vulnHandle *db.VulnerabilityHandle...
    method fillInMissingSeverity (line 261) | func (w *writer) fillInMissingSeverity(handle *db.VulnerabilityHandle) {
    method addToParentBatch (line 316) | func (w *writer) addToParentBatch(op func() error) error {
    method addToChildBatch (line 330) | func (w *writer) addToChildBatch(op func() error) error {
    method flushParentBatch (line 349) | func (w *writer) flushParentBatch() error {
    method flushParentBatchLocked (line 356) | func (w *writer) flushParentBatchLocked() error {
    method flushChildBatch (line 376) | func (w *writer) flushChildBatch() error {
    method flushChildBatchLocked (line 383) | func (w *writer) flushChildBatchLocked() error {
    method Close (line 402) | func (w *writer) Close() error {
    method writeOperatingSystemEOL (line 469) | func (w *writer) writeOperatingSystemEOL(row db.OperatingSystemEOLHand...
  type ProviderMetadata (line 40) | type ProviderMetadata struct
  type Provider (line 44) | type Provider struct
  function NewWriter (line 49) | func NewWriter(directory string, states provider.States, failOnMissingFi...
  function filterUnknownSeverities (line 424) | func filterUnknownSeverities(sevs []db.Severity) []db.Severity {
  function isKnownSeverity (line 434) | func isKnownSeverity(s db.Severity) bool {
  function ensureFixDates (line 443) | func ensureFixDates(row *db.AffectedPackageHandle) error {
  function isFixVersion (line 465) | func isFixVersion(v string) bool {

FILE: grype/db/v6/build/writer_test.go
  function TestFillInMissingSeverity (line 19) | func TestFillInMissingSeverity(t *testing.T) {
  function TestFilterUnknownSeverities (line 137) | func TestFilterUnknownSeverities(t *testing.T) {
  function TestIsKnownSeverity (line 196) | func TestIsKnownSeverity(t *testing.T) {
  function TestEnsureFixDates (line 242) | func TestEnsureFixDates(t *testing.T) {
  function TestWrite_FailsOnMissingFixDate (line 562) | func TestWrite_FailsOnMissingFixDate(t *testing.T) {
  function TestIsFixVersion (line 603) | func TestIsFixVersion(t *testing.T) {
  function TestBatchedWritesEquivalence (line 664) | func TestBatchedWritesEquivalence(t *testing.T) {
  function TestBatchAccumulation (line 727) | func TestBatchAccumulation(t *testing.T) {
  function TestBatchMetrics (line 760) | func TestBatchMetrics(t *testing.T) {
  function TestBatchSizeConfiguration (line 790) | func TestBatchSizeConfiguration(t *testing.T) {
  function createTestEntries (line 830) | func createTestEntries(count int) []data.Entry {

FILE: grype/db/v6/cache.go
  constant cpesTableCacheKey (line 9) | cpesTableCacheKey             = "cpes"
  constant packagesTableCacheKey (line 10) | packagesTableCacheKey         = "packages"
  constant operatingSystemsTableCacheKey (line 11) | operatingSystemsTableCacheKey = "operating_systems"
  constant vulnerabilitiesTableCacheKey (line 12) | vulnerabilitiesTableCacheKey  = "vulnerabilities"
  constant cacheKey (line 15) | cacheKey = contextKey("multiModelCache")
  type contextKey (line 17) | type contextKey
  type cachable (line 19) | type cachable interface
  type cacheIDManager (line 24) | type cacheIDManager interface
  type cacheStringIDManager (line 29) | type cacheStringIDManager interface
  function withCacheContext (line 34) | func withCacheContext(ctx context.Context, c *cache) context.Context {
  function cacheFromContext (line 38) | func cacheFromContext(ctx context.Context) (*cache, bool) {
  type cache (line 43) | type cache struct
    method getID (line 56) | func (c *cache) getID(ca cachable) (ID, bool) {
    method getString (line 66) | func (c *cache) getString(ca cachable) (string, bool) {
    method set (line 76) | func (c *cache) set(ca cachable) {
    method setStringEntry (line 87) | func (c *cache) setStringEntry(id string, ca cachable) {
    method setIDEntry (line 101) | func (c *cache) setIDEntry(id ID, ca cachable) {
  function newCache (line 49) | func newCache() *cache {

FILE: grype/db/v6/cache_test.go
  type mockCachableID (line 10) | type mockCachableID struct
    method cacheKey (line 16) | func (m *mockCachableID) cacheKey() string  { return m.key }
    method tableName (line 17) | func (m *mockCachableID) tableName() string { return m.table }
    method rowID (line 18) | func (m *mockCachableID) rowID() ID         { return m.id }
    method setRowID (line 19) | func (m *mockCachableID) setRowID(id ID)    { m.id = id }
  type mockCachableString (line 21) | type mockCachableString struct
    method cacheKey (line 27) | func (m *mockCachableString) cacheKey() string   { return m.key }
    method tableName (line 28) | func (m *mockCachableString) tableName() string  { return m.table }
    method rowID (line 29) | func (m *mockCachableString) rowID() string      { return m.id }
    method setRowID (line 30) | func (m *mockCachableString) setRowID(id string) { m.id = id }
  function newTestCachableString (line 32) | func newTestCachableString(key, table, id string) *mockCachableString {
  function newTestCachableID (line 36) | func newTestCachableID(key, table string, id ID) *mockCachableID {
  function TestCache_GetString_Found (line 40) | func TestCache_GetString_Found(t *testing.T) {
  function TestCache_GetString_NotFound (line 51) | func TestCache_GetString_NotFound(t *testing.T) {
  function TestCache_Set_ID (line 60) | func TestCache_Set_ID(t *testing.T) {
  function TestCache_Set_String (line 71) | func TestCache_Set_String(t *testing.T) {
  function TestCache_Set_Panic (line 82) | func TestCache_Set_Panic(t *testing.T) {
  function TestCache_SetStringEntry_New (line 91) | func TestCache_SetStringEntry_New(t *testing.T) {
  function TestCache_SetStringEntry_Update (line 102) | func TestCache_SetStringEntry_Update(t *testing.T) {
  function TestCache_SetIDEntry_New (line 114) | func TestCache_SetIDEntry_New(t *testing.T) {
  function TestCache_SetIDEntry_Update (line 125) | func TestCache_SetIDEntry_Update(t *testing.T) {
  function TestWithCacheContext (line 137) | func TestWithCacheContext(t *testing.T) {
  function TestCacheFromContext_NotFound (line 146) | func TestCacheFromContext_NotFound(t *testing.T) {

FILE: grype/db/v6/cpe_store.go
  type cpeHandleStore (line 14) | type cpeHandleStore interface
  type cpeHandleAccessor (line 18) | type cpeHandleAccessor interface
  type GetCPEOptions (line 22) | type GetCPEOptions struct
  type cpeStore (line 31) | type cpeStore struct
    method handleCPE (line 195) | func (s *cpeStore) handleCPE(query *gorm.DB, c *cpe.Attributes, allowB...
    method handleVulnerabilityOptions (line 204) | func (s *cpeStore) handleVulnerabilityOptions(query *gorm.DB, configs ...
    method handlePreload (line 214) | func (s *cpeStore) handlePreload(query *gorm.DB, config GetCPEOptions)...
  function newCPEStore (line 36) | func newCPEStore(db *gorm.DB, bs *blobStore) *cpeStore {
  function addCPEs (line 43) | func addCPEs[T cpeHandleStore](s *cpeStore, packages ...T) error {
  function addCPEHandles (line 101) | func addCPEHandles[T cpeHandleStore](s *cpeStore, packages ...T) error {
  function getCPEHandles (line 118) | func getCPEHandles[T cpeHandleStore]( // nolint:funlen

FILE: grype/db/v6/data.go
  function KnownOperatingSystemSpecifierOverrides (line 10) | func KnownOperatingSystemSpecifierOverrides() []OperatingSystemSpecifier...
  function KnownPackageSpecifierOverrides (line 102) | func KnownPackageSpecifierOverrides() []PackageSpecifierOverride {
  function ptr (line 160) | func ptr[T any](v T) *T {

FILE: grype/db/v6/db.go
  constant ModelVersion (line 21) | ModelVersion = 6
  constant Revision (line 24) | Revision = 1
  constant Addition (line 27) | Addition = 4
  constant VulnerabilityDBFileName (line 43) | VulnerabilityDBFileName = "vulnerability.db"
  constant batchSize (line 49) | batchSize = 300
  type ReadWriter (line 54) | type ReadWriter interface
  type Reader (line 59) | type Reader interface
  type Writer (line 73) | type Writer interface
  type Curator (line 86) | type Curator interface
  type Config (line 94) | type Config struct
    method DBFilePath (line 99) | func (c Config) DBFilePath() string {
  function NewReader (line 103) | func NewReader(cfg Config) (Reader, error) {
  function NewWriter (line 107) | func NewWriter(cfg Config) (ReadWriter, error) {
  function Hydrater (line 111) | func Hydrater() func(string) error {
  function NewLowLevelDB (line 126) | func NewLowLevelDB(dbFilePath string, empty, writable, debug bool) (*gor...

FILE: grype/db/v6/db_metadata_store.go
  type DBMetadataStoreWriter (line 12) | type DBMetadataStoreWriter interface
  type DBMetadataStoreReader (line 16) | type DBMetadataStoreReader interface
  type dbMetadataStore (line 20) | type dbMetadataStore struct
    method GetDBMetadata (line 30) | func (s *dbMetadataStore) GetDBMetadata() (*DBMetadata, error) {
    method SetDBMetadata (line 37) | func (s *dbMetadataStore) SetDBMetadata() error {
  function newDBMetadataStore (line 24) | func newDBMetadataStore(db *gorm.DB) *dbMetadataStore {

FILE: grype/db/v6/db_metadata_store_test.go
  function TestDbMetadataStore_empty (line 11) | func TestDbMetadataStore_empty(t *testing.T) {
  function TestDbMetadataStore_oldDb (line 22) | func TestDbMetadataStore_oldDb(t *testing.T) {
  function TestDbMetadataStore (line 33) | func TestDbMetadataStore(t *testing.T) {
  function setupTestStore (line 58) | func setupTestStore(t testing.TB, d ...string) *store {
  function setupReadOnlyTestStore (line 80) | func setupReadOnlyTestStore(t testing.TB, dir string) *store {

FILE: grype/db/v6/description.go
  type Description (line 16) | type Description struct
    method String (line 92) | func (m Description) String() string {
  type Time (line 24) | type Time struct
    method MarshalJSON (line 28) | func (t Time) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 32) | func (t *Time) UnmarshalJSON(data []byte) error {
    method String (line 48) | func (t Time) String() string {
  function DescriptionFromMetadata (line 52) | func DescriptionFromMetadata(m *DBMetadata) *Description {
  function ReadDescription (line 62) | func ReadDescription(dbFilePath string) (*Description, error) {

FILE: grype/db/v6/description_test.go
  function TestReadDescription (line 15) | func TestReadDescription(t *testing.T) {
  function TestTime_JSONMarshalling (line 37) | func TestTime_JSONMarshalling(t *testing.T) {
  function TestTime_JSONUnmarshalling (line 64) | func TestTime_JSONUnmarshalling(t *testing.T) {

FILE: grype/db/v6/distribution/client.go
  type Config (line 25) | type Config struct
  type Client (line 40) | type Client interface
  type client (line 47) | type client struct
    method IsUpdateAvailable (line 85) | func (c client) IsUpdateAvailable(current *v6.Description) (*Archive, ...
    method isUpdateAvailable (line 107) | func (c client) isUpdateAvailable(current *v6.Description, candidate *...
    method ResolveArchiveURL (line 130) | func (c client) ResolveArchiveURL(archive Archive) (string, error) {
    method Download (line 150) | func (c client) Download(archiveURL, dest string, downloadProgress *pr...
    method Latest (line 174) | func (c client) Latest() (*LatestDocument, error) {
    method latestURL (line 195) | func (c client) latestURL() string {
  function DefaultConfig (line 54) | func DefaultConfig() Config {
  function NewClient (line 63) | func NewClient(cfg Config) (Client, error) {
  function withClientTimeout (line 205) | func withClientTimeout(timeout time.Duration) func(*http.Client) {
  function withUserAgent (line 211) | func withUserAgent(id clio.Identification) func(*http.Client) {
  function defaultHTTPClient (line 217) | func defaultHTTPClient(fs afero.Fs, caCertPath string, postProcessor ......
  function removeAllOrLog (line 242) | func removeAllOrLog(fs afero.Fs, dir string) {
  function isSupersededBy (line 248) | func isSupersededBy(current *v6.Description, candidate v6.Description) b...
  function newHTTPClientWithDefaultUserAgent (line 281) | func newHTTPClientWithDefaultUserAgent(baseTransport http.RoundTripper, ...
  type roundTripperWithUserAgent (line 290) | type roundTripperWithUserAgent struct
    method RoundTrip (line 295) | func (r roundTripperWithUserAgent) RoundTrip(req *http.Request) (*http...

FILE: grype/db/v6/distribution/client_test.go
  type mockGetter (line 20) | type mockGetter struct
    method GetFile (line 24) | func (m *mockGetter) GetFile(dst, src string, manuals ...*progress.Man...
    method GetToDir (line 29) | func (m *mockGetter) GetToDir(dst, src string, manuals ...*progress.Ma...
  function TestClient_Latest (line 34) | func TestClient_Latest(t *testing.T) {
  function TestClient_Download (line 132) | func TestClient_Download(t *testing.T) {
  function TestClient_IsUpdateAvailable (line 188) | func TestClient_IsUpdateAvailable(t *testing.T) {
  function TestDatabaseDescription_IsSupersededBy (line 304) | func TestDatabaseDescription_IsSupersededBy(t *testing.T) {
  function Test_latestURL (line 380) | func Test_latestURL(t *testing.T) {

FILE: grype/db/v6/distribution/latest.go
  constant LatestFileName (line 19) | LatestFileName = "latest.json"
  type LatestDocument (line 21) | type LatestDocument struct
    method Write (line 103) | func (l LatestDocument) Write(writer io.Writer) error {
  type Archive (line 29) | type Archive struct
  function NewLatestDocument (line 41) | func NewLatestDocument(entries ...Archive) *LatestDocument {
  function NewLatestFromReader (line 64) | func NewLatestFromReader(reader io.Reader) (*LatestDocument, error) {
  function NewLatestFromFile (line 77) | func NewLatestFromFile(fs afero.Fs, path string) (*LatestDocument, error) {
  function NewArchive (line 86) | func NewArchive(path string, t time.Time, model, revision, addition int)...
  function calculateArchiveDigest (line 133) | func calculateArchiveDigest(dbFilePath string) (string, error) {

FILE: grype/db/v6/distribution/latest_test.go
  function TestNewLatestDocument (line 19) | func TestNewLatestDocument(t *testing.T) {
  function TestNewLatestFromReader (line 66) | func TestNewLatestFromReader(t *testing.T) {
  function TestLatestDocument_Write (line 104) | func TestLatestDocument_Write(t *testing.T) {
  function TestNewArchive (line 237) | func TestNewArchive(t *testing.T) {

FILE: grype/db/v6/distribution/status.go
  type Status (line 3) | type Status
  constant LifecycleStatus (line 5) | LifecycleStatus = StatusActive
  constant StatusActive (line 9) | StatusActive Status = "active"
  constant StatusDeprecated (line 12) | StatusDeprecated Status = "deprecated"
  constant StatusEndOfLife (line 15) | StatusEndOfLife Status = "eol"

FILE: grype/db/v6/enumerations.go
  type VulnerabilityStatus (line 7) | type VulnerabilityStatus
  constant UnknownVulnerabilityStatus (line 10) | UnknownVulnerabilityStatus VulnerabilityStatus = ""
  constant VulnerabilityActive (line 13) | VulnerabilityActive VulnerabilityStatus = "active"
  constant VulnerabilityAnalyzing (line 16) | VulnerabilityAnalyzing VulnerabilityStatus = "analyzing"
  constant VulnerabilityRejected (line 19) | VulnerabilityRejected VulnerabilityStatus = "rejected"
  constant VulnerabilityDisputed (line 22) | VulnerabilityDisputed VulnerabilityStatus = "disputed"
  type SeverityScheme (line 26) | type SeverityScheme
  constant UnknownSeverityScheme (line 29) | UnknownSeverityScheme SeverityScheme = ""
  constant SeveritySchemeCVSS (line 32) | SeveritySchemeCVSS SeverityScheme = "CVSS"
  constant SeveritySchemeHML (line 35) | SeveritySchemeHML SeverityScheme = "HML"
  constant SeveritySchemeCHML (line 38) | SeveritySchemeCHML SeverityScheme = "CHML"
  constant SeveritySchemeCHMLN (line 41) | SeveritySchemeCHMLN SeverityScheme = "CHMLN"
  type FixStatus (line 45) | type FixStatus
  constant UnknownFixStatus (line 48) | UnknownFixStatus FixStatus = ""
  constant FixedStatus (line 51) | FixedStatus FixStatus = "fixed"
  constant NotFixedStatus (line 54) | NotFixedStatus FixStatus = "not-fixed"
  constant WontFixStatus (line 57) | WontFixStatus FixStatus = "wont-fix"
  constant NotAffectedFixStatus (line 60) | NotAffectedFixStatus FixStatus = "not-affected"
  constant AdvisoryReferenceTag (line 65) | AdvisoryReferenceTag = "advisory"
  function ParseVulnerabilityStatus (line 68) | func ParseVulnerabilityStatus(s string) VulnerabilityStatus {
  function ParseSeverityScheme (line 83) | func ParseSeverityScheme(s string) SeverityScheme {
  function ParseFixStatus (line 98) | func ParseFixStatus(s string) FixStatus {
  function NormalizeReferenceTags (line 113) | func NormalizeReferenceTags(tags []string) []string {
  function replaceAny (line 121) | func replaceAny(input string, newStr string, searchFor ...string) string {

FILE: grype/db/v6/enumerations_test.go
  function TestParseVulnerabilityStatus (line 9) | func TestParseVulnerabilityStatus(t *testing.T) {
  function TestParseSeverityScheme (line 30) | func TestParseSeverityScheme(t *testing.T) {
  function TestParseFixStatus (line 50) | func TestParseFixStatus(t *testing.T) {
  function TestReplaceAny (line 70) | func TestReplaceAny(t *testing.T) {

FILE: grype/db/v6/fillers.go
  function fillAffectedPackageHandles (line 8) | func fillAffectedPackageHandles(reader Reader, handles []*AffectedPackag...
  function affectedPackageHandleOperatingSystemRef (line 17) | func affectedPackageHandleOperatingSystemRef(t *AffectedPackageHandle) i...
  function affectedPackageHandlePackageRef (line 24) | func affectedPackageHandlePackageRef(t *AffectedPackageHandle) idRef[Pac...
  function affectedPackageHandleVulnerabilityHandleRef (line 31) | func affectedPackageHandleVulnerabilityHandleRef(t *AffectedPackageHandl...
  function fillAffectedCPEHandles (line 39) | func fillAffectedCPEHandles(reader Reader, handles []*AffectedCPEHandle)...
  function affectedCPEHandleCpeRef (line 47) | func affectedCPEHandleCpeRef(t *AffectedCPEHandle) idRef[Cpe] {
  function affectedCPEHandleVulnerabilityHandleRef (line 54) | func affectedCPEHandleVulnerabilityHandleRef(t *AffectedCPEHandle) idRef...
  function fillUnaffectedPackageHandles (line 62) | func fillUnaffectedPackageHandles(reader Reader, handles []*UnaffectedPa...
  function unaffectedPackageHandleOperatingSystemRef (line 71) | func unaffectedPackageHandleOperatingSystemRef(t *UnaffectedPackageHandl...
  function unaffectedPackageHandlePackageRef (line 78) | func unaffectedPackageHandlePackageRef(t *UnaffectedPackageHandle) idRef...
  function unaffectedPackageHandleVulnerabilityHandleRef (line 85) | func unaffectedPackageHandleVulnerabilityHandleRef(t *UnaffectedPackageH...
  function fillUnaffectedCPEHandles (line 93) | func fillUnaffectedCPEHandles(reader Reader, handles []*UnaffectedCPEHan...
  function unaffectedCPEHandleCpeRef (line 101) | func unaffectedCPEHandleCpeRef(t *UnaffectedCPEHandle) idRef[Cpe] {
  function unaffectedCPEHandleVulnerabilityHandleRef (line 108) | func unaffectedCPEHandleVulnerabilityHandleRef(t *UnaffectedCPEHandle) i...
  function fillVulnerabilityHandles (line 116) | func fillVulnerabilityHandles[T any](reader Reader, handles []*T, vulnHa...
  function vulnerabilityHandleID (line 137) | func vulnerabilityHandleID(h *VulnerabilityHandle) ID {
  function cpeHandleID (line 141) | func cpeHandleID(h *Cpe) ID {
  function operatingSystemID (line 145) | func operatingSystemID(h *OperatingSystem) ID {
  function packageID (line 149) | func packageID(h *Package) ID {
  function toBlobables (line 153) | func toBlobables[T blobable](handles []T) []blobable {

FILE: grype/db/v6/import_metadata.go
  constant ImportMetadataFileName (line 18) | ImportMetadataFileName = "import.json"
  type ImportMetadata (line 20) | type ImportMetadata struct
  function ReadImportMetadata (line 26) | func ReadImportMetadata(fs afero.Fs, dir string) (*ImportMetadata, error) {
  function CalculateDBDigest (line 54) | func CalculateDBDigest(fs afero.Fs, dbFilePath string) (string, error) {
  function WriteImportMetadata (line 62) | func WriteImportMetadata(fs afero.Fs, dbDir, source string) (*ImportMeta...
  function writeImportMetadata (line 78) | func writeImportMetadata(writer io.Writer, checksums, source string) (*I...

FILE: grype/db/v6/import_metadata_test.go
  function TestReadImportMetadata (line 17) | func TestReadImportMetadata(t *testing.T) {
  function TestWriteImportMetadata (line 82) | func TestWriteImportMetadata(t *testing.T) {
  function TestCalculateDBDigest (line 131) | func TestCalculateDBDigest(t *testing.T) {

FILE: grype/db/v6/installation/curator.go
  constant lastUpdateCheckFileName (line 33) | lastUpdateCheckFileName = "last_update_check"
  type monitor (line 35) | type monitor struct
    method SetCompleted (line 701) | func (m monitor) SetCompleted() {
  type Config (line 42) | type Config struct
    method DBFilePath (line 63) | func (c Config) DBFilePath() string {
    method DBDirectoryPath (line 67) | func (c Config) DBDirectoryPath() string {
  function DefaultConfig (line 53) | func DefaultConfig(id clio.Identification) Config {
  type curator (line 71) | type curator struct
    method Reader (line 87) | func (c curator) Reader() (db.Reader, error) {
    method Status (line 160) | func (c curator) Status() vulnerability.ProviderStatus {
    method Delete (line 203) | func (c curator) Delete() error {
    method Update (line 208) | func (c curator) Update() (bool, error) {
    method isUpdateCheckAllowed (line 259) | func (c curator) isUpdateCheckAllowed() bool {
    method update (line 279) | func (c curator) update(current *db.Description) (*distribution.Archiv...
    method durationSinceUpdateCheck (line 374) | func (c curator) durationSinceUpdateCheck() (*time.Duration, error) {
    method setLastSuccessfulUpdateCheck (line 411) | func (c curator) setLastSuccessfulUpdateCheck() {
    method Import (line 428) | func (c curator) Import(reference string) error {
    method activate (line 494) | func (c curator) activate(dbDirPath, url string, mon monitor) error {
    method hydrate (line 511) | func (c curator) hydrate(dbDirPath, from string, mon monitor) error {
    method replaceDB (line 533) | func (c curator) replaceDB(dbDirPath string) error {
    method validateIntegrity (line 561) | func (c curator) validateIntegrity(description *db.Description) (strin...
    method validateAge (line 598) | func (c curator) validateAge(m *db.Description) error {
  function NewCurator (line 78) | func NewCurator(cfg Config, downloader distribution.Client) (db.Curator,...
  function isRehydrationNeeded (line 337) | func isRehydrationNeeded(fs afero.Fs, dirPath string, currentDBVersion *...
  function isURL (line 489) | func isURL(reference string) bool {
  function removeAllOrLog (line 619) | func removeAllOrLog(fs afero.Fs, dir string) {
  function unarchive (line 625) | func unarchive(source, destination string) error {
  function newMonitor (line 674) | func newMonitor() monitor {
  type completionMonitor (line 708) | type completionMonitor struct
    method SetCompleted (line 712) | func (m completionMonitor) SetCompleted() {

FILE: grype/db/v6/installation/curator_test.go
  type mockClient (line 24) | type mockClient struct
    method IsUpdateAvailable (line 28) | func (m *mockClient) IsUpdateAvailable(current *db.Description) (*dist...
    method ResolveArchiveURL (line 40) | func (m *mockClient) ResolveArchiveURL(_ distribution.Archive) (string...
    method Download (line 44) | func (m *mockClient) Download(url, dest string, downloadProgress *prog...
    method Latest (line 49) | func (m *mockClient) Latest() (*distribution.LatestDocument, error) {
  function newTestCurator (line 54) | func newTestCurator(t *testing.T) curator {
  type setupConfig (line 66) | type setupConfig struct
  type setupOption (line 70) | type setupOption
  function withWorkingUpdateIntegrations (line 72) | func withWorkingUpdateIntegrations() setupOption {
  function setupCuratorForUpdate (line 78) | func setupCuratorForUpdate(t *testing.T, opts ...setupOption) curator {
  function writeTestDescriptionToDB (line 117) | func writeTestDescriptionToDB(t *testing.T, dir string, desc db.Descript...
  function writeTestImportMetadata (line 149) | func writeTestImportMetadata(t *testing.T, fs afero.Fs, dir string, chec...
  function writeTestImportMetadataWithCustomVersion (line 153) | func writeTestImportMetadataWithCustomVersion(t *testing.T, fs afero.Fs,...
  function writeTestDB (line 172) | func writeTestDB(t *testing.T, fs afero.Fs, dir string) string {
  function TestCurator_Update (line 190) | func TestCurator_Update(t *testing.T) {
  function TestCurator_IsUpdateCheckAllowed (line 262) | func TestCurator_IsUpdateCheckAllowed(t *testing.T) {
  function TestCurator_DurationSinceUpdateCheck (line 320) | func TestCurator_DurationSinceUpdateCheck(t *testing.T) {
  function TestCurator_SetLastSuccessfulUpdateCheck (line 368) | func TestCurator_SetLastSuccessfulUpdateCheck(t *testing.T) {
  function TestCurator_validateAge (line 419) | func TestCurator_validateAge(t *testing.T) {
  function TestCurator_validateIntegrity (line 502) | func TestCurator_validateIntegrity(t *testing.T) {
  function TestReplaceDB (line 575) | func TestReplaceDB(t *testing.T) {
  function Test_isRehydrationNeeded (line 682) | func Test_isRehydrationNeeded(t *testing.T) {
  function TestCurator_Update_UsesDBRootDirForDownloadTempBase (line 772) | func TestCurator_Update_UsesDBRootDirForDownloadTempBase(t *testing.T) {
  function TestCurator_Update_CleansUpDownloadDirOnActivationFailure (line 819) | func TestCurator_Update_CleansUpDownloadDirOnActivationFailure(t *testin...
  function TestCurator_Import_URL_UsesDBRootDirForDownloadTempBaseAndCleansUp (line 860) | func TestCurator_Import_URL_UsesDBRootDirForDownloadTempBaseAndCleansUp(...
  function Test_unarchive (line 919) | func Test_unarchive(t *testing.T) {
  function setupTestDB (line 949) | func setupTestDB(t *testing.T, dbDir string) db.ReadWriter {
  function setupReadOnlyTestDB (line 958) | func setupReadOnlyTestDB(t *testing.T, dbDir string) db.Reader {
  function testConfig (line 967) | func testConfig() Config {

FILE: grype/db/v6/log_dropped.go
  function logDroppedVulnerability (line 12) | func logDroppedVulnerability(vuln string, reason any, fields logger.Fiel...

FILE: grype/db/v6/models.go
  function Models (line 33) | func Models() []any {
  type ID (line 69) | type ID
  type Blob (line 73) | type Blob struct
    method computeDigest (line 78) | func (b Blob) computeDigest() string {
  type DBMetadata (line 89) | type DBMetadata struct
  function newSchemaVerFromDBMetadata (line 96) | func newSchemaVerFromDBMetadata(m DBMetadata) schemaver.SchemaVer {
  type Provider (line 105) | type Provider struct
    method String (line 122) | func (p *Provider) String() string {
    method cacheKey (line 133) | func (p *Provider) cacheKey() string {
    method tableName (line 137) | func (p *Provider) tableName() string {
    method rowID (line 141) | func (p *Provider) rowID() string {
    method setRowID (line 145) | func (p *Provider) setRowID(i string) {
    method BeforeCreate (line 149) | func (p *Provider) BeforeCreate(tx *gorm.DB) (err error) {
    method AfterCreate (line 159) | func (p *Provider) AfterCreate(tx *gorm.DB) (err error) {
  type VulnerabilityHandle (line 170) | type VulnerabilityHandle struct
    method String (line 195) | func (v VulnerabilityHandle) String() string {
    method getBlobValue (line 199) | func (v VulnerabilityHandle) getBlobValue() any {
    method setBlobID (line 206) | func (v *VulnerabilityHandle) setBlobID(id ID) {
    method getBlobID (line 210) | func (v VulnerabilityHandle) getBlobID() ID {
    method setBlob (line 214) | func (v *VulnerabilityHandle) setBlob(rawBlobValue []byte) error {
    method cacheKey (line 224) | func (v *VulnerabilityHandle) cacheKey() string {
    method rowID (line 232) | func (v *VulnerabilityHandle) rowID() ID {
    method tableName (line 236) | func (v *VulnerabilityHandle) tableName() string {
    method setRowID (line 240) | func (v *VulnerabilityHandle) setRowID(i ID) {
    method BeforeCreate (line 244) | func (v *VulnerabilityHandle) BeforeCreate(tx *gorm.DB) (err error) {
    method AfterCreate (line 256) | func (v *VulnerabilityHandle) AfterCreate(tx *gorm.DB) (err error) {
  type VulnerabilityAlias (line 263) | type VulnerabilityAlias struct
  type packageHandle (line 275) | type packageHandle struct
    method vulnerability (line 290) | func (ph packageHandle) vulnerability() string {
    method String (line 302) | func (ph packageHandle) String() string {
    method getBlobValue (line 332) | func (ph packageHandle) getBlobValue() any {
    method setBlobID (line 339) | func (ph *packageHandle) setBlobID(id ID) {
    method getBlobID (line 343) | func (ph packageHandle) getBlobID() ID {
    method setBlob (line 347) | func (ph *packageHandle) setBlob(rawBlobValue []byte) error {
  type AffectedPackageHandle (line 364) | type AffectedPackageHandle
    method getPackageHandle (line 366) | func (ph *AffectedPackageHandle) getPackageHandle() *packageHandle {
    method vulnerability (line 370) | func (ph AffectedPackageHandle) vulnerability() string { // nolint:unu...
    method String (line 374) | func (ph AffectedPackageHandle) String() string {
    method getBlobValue (line 378) | func (ph AffectedPackageHandle) getBlobValue() any {
    method setBlobID (line 382) | func (ph *AffectedPackageHandle) setBlobID(id ID) {
    method getBlobID (line 386) | func (ph AffectedPackageHandle) getBlobID() ID {
    method setBlob (line 390) | func (ph *AffectedPackageHandle) setBlob(rawBlobValue []byte) error {
  type UnaffectedPackageHandle (line 395) | type UnaffectedPackageHandle
    method getPackageHandle (line 397) | func (ph *UnaffectedPackageHandle) getPackageHandle() *packageHandle {
    method vulnerability (line 401) | func (ph UnaffectedPackageHandle) vulnerability() string { // nolint:u...
    method String (line 405) | func (ph UnaffectedPackageHandle) String() string {
    method getBlobValue (line 409) | func (ph UnaffectedPackageHandle) getBlobValue() any {
    method setBlobID (line 413) | func (ph *UnaffectedPackageHandle) setBlobID(id ID) {
    method getBlobID (line 417) | func (ph UnaffectedPackageHandle) getBlobID() ID {
    method setBlob (line 421) | func (ph *UnaffectedPackageHandle) setBlob(rawBlobValue []byte) error {
  type Package (line 426) | type Package struct
    method String (line 439) | func (p Package) String() string {
    method cacheKey (line 456) | func (p Package) cacheKey() string {
    method rowID (line 465) | func (p Package) rowID() ID {
    method tableName (line 469) | func (p *Package) tableName() string {
    method setRowID (line 473) | func (p *Package) setRowID(i ID) {
    method BeforeCreate (line 477) | func (p *Package) BeforeCreate(tx *gorm.DB) (err error) { // nolint:go...
    method AfterCreate (line 517) | func (p *Package) AfterCreate(tx *gorm.DB) (err error) {
  type PackageSpecifierOverride (line 528) | type PackageSpecifierOverride struct
  type OperatingSystem (line 539) | type OperatingSystem struct
    method VersionNumber (line 569) | func (o *OperatingSystem) VersionNumber() string {
    method Version (line 579) | func (o *OperatingSystem) Version() string {
    method String (line 603) | func (o OperatingSystem) String() string {
    method cacheKey (line 607) | func (o OperatingSystem) cacheKey() string {
    method rowID (line 611) | func (o OperatingSystem) rowID() ID {
    method tableName (line 615) | func (o *OperatingSystem) tableName() string {
    method setRowID (line 619) | func (o *OperatingSystem) setRowID(i ID) {
    method clean (line 623) | func (o *OperatingSystem) clean() {
    method BeforeCreate (line 628) | func (o *OperatingSystem) BeforeCreate(tx *gorm.DB) (err error) {
    method AfterCreate (line 641) | func (o *OperatingSystem) AfterCreate(tx *gorm.DB) (err error) {
  type OperatingSystemSpecifierOverride (line 649) | type OperatingSystemSpecifierOverride struct
    method BeforeCreate (line 678) | func (os *OperatingSystemSpecifierOverride) BeforeCreate(_ *gorm.DB) (...
  type cpeHandle (line 690) | type cpeHandle struct
    method vulnerability (line 702) | func (ch cpeHandle) vulnerability() string {
    method String (line 714) | func (ch cpeHandle) String() string {
    method getBlobID (line 739) | func (ch cpeHandle) getBlobID() ID {
    method getBlobValue (line 743) | func (ch cpeHandle) getBlobValue() any {
    method setBlobID (line 750) | func (ch *cpeHandle) setBlobID(id ID) {
    method setBlob (line 754) | func (ch *cpeHandle) setBlob(rawBlobValue []byte) error {
  type AffectedCPEHandle (line 770) | type AffectedCPEHandle
    method getCPEHandle (line 772) | func (ch *AffectedCPEHandle) getCPEHandle() *cpeHandle {
    method vulnerability (line 776) | func (ch AffectedCPEHandle) vulnerability() string {
    method String (line 780) | func (ch AffectedCPEHandle) String() string {
    method getBlobID (line 784) | func (ch AffectedCPEHandle) getBlobID() ID {
    method getBlobValue (line 788) | func (ch AffectedCPEHandle) getBlobValue() any {
    method setBlobID (line 792) | func (ch *AffectedCPEHandle) setBlobID(id ID) {
    method setBlob (line 796) | func (ch *AffectedCPEHandle) setBlob(rawBlobValue []byte) error {
  type UnaffectedCPEHandle (line 800) | type UnaffectedCPEHandle
    method getCPEHandle (line 802) | func (ch *UnaffectedCPEHandle) getCPEHandle() *cpeHandle {
    method vulnerability (line 806) | func (ch UnaffectedCPEHandle) vulnerability() string { // nolint:unuse...
    method String (line 810) | func (ch UnaffectedCPEHandle) String() string {
    method getBlobID (line 814) | func (ch UnaffectedCPEHandle) getBlobID() ID {
    method getBlobValue (line 818) | func (ch UnaffectedCPEHandle) getBlobValue() any {
    method setBlobID (line 822) | func (ch *UnaffectedCPEHandle) setBlobID(id ID) {
    method setBlob (line 826) | func (ch *UnaffectedCPEHandle) setBlob(rawBlobValue []byte) error {
  type Cpe (line 830) | type Cpe struct
    method String (line 847) | func (c Cpe) String() string {
    method cacheKey (line 857) | func (c *Cpe) cacheKey() string {
    method tableName (line 861) | func (c *Cpe) tableName() string {
    method rowID (line 865) | func (c *Cpe) rowID() ID {
    method setRowID (line 869) | func (c *Cpe) setRowID(i ID) {
    method BeforeCreate (line 873) | func (c *Cpe) BeforeCreate(tx *gorm.DB) (err error) {
    method AfterCreate (line 891) | func (c *Cpe) AfterCreate(tx *gorm.DB) (err error) {
  type PackageCpe (line 899) | type PackageCpe struct
    method TableName (line 904) | func (PackageCpe) TableName() string {
  type KnownExploitedVulnerabilityHandle (line 910) | type KnownExploitedVulnerabilityHandle struct
    method getBlobValue (line 919) | func (v KnownExploitedVulnerabilityHandle) getBlobValue() any {
    method setBlobID (line 926) | func (v *KnownExploitedVulnerabilityHandle) setBlobID(id ID) {
    method getBlobID (line 930) | func (v KnownExploitedVulnerabilityHandle) getBlobID() ID {
    method setBlob (line 934) | func (v *KnownExploitedVulnerabilityHandle) setBlob(rawBlobValue []byt...
  type EpssMetadata (line 944) | type EpssMetadata struct
  type EpssHandle (line 948) | type EpssHandle struct
  type CWEHandle (line 957) | type CWEHandle struct
    method String (line 965) | func (c CWEHandle) String() string {
  type OperatingSystemEOLHandle (line 971) | type OperatingSystemEOLHandle struct
    method String (line 980) | func (o OperatingSystemEOLHandle) String() string {

FILE: grype/db/v6/models_test.go
  function TestOperatingSystemAlias_VersionMutualExclusivity (line 11) | func TestOperatingSystemAlias_VersionMutualExclusivity(t *testing.T) {
  function TestOperatingSystem_VersionNumber (line 61) | func TestOperatingSystem_VersionNumber(t *testing.T) {
  function TestOperatingSystem_Version (line 91) | func TestOperatingSystem_Version(t *testing.T) {
  function TestOperatingSystem_clean (line 136) | func TestOperatingSystem_clean(t *testing.T) {

FILE: grype/db/v6/name/java.go
  type JavaResolver (line 12) | type JavaResolver struct
    method Normalize (line 15) | func (r *JavaResolver) Normalize(name string) string {
    method Names (line 19) | func (r *JavaResolver) Names(p grypePkg.Package) []string {

FILE: grype/db/v6/name/java_test.go
  function TestJavaResolver_Normalize (line 12) | func TestJavaResolver_Normalize(t *testing.T) {
  function TestJavaResolver_Names (line 50) | func TestJavaResolver_Names(t *testing.T) {

FILE: grype/db/v6/name/python.go
  type PythonResolver (line 9) | type PythonResolver struct
    method Normalize (line 12) | func (r *PythonResolver) Normalize(name string) string {
    method Names (line 21) | func (r *PythonResolver) Names(p grypePkg.Package) []string {

FILE: grype/db/v6/name/python_test.go
  function TestPythonResolver_Normalize (line 9) | func TestPythonResolver_Normalize(t *testing.T) {

FILE: grype/db/v6/name/resolver.go
  type Resolver (line 8) | type Resolver interface
  function FromType (line 13) | func FromType(t syftPkg.Type) Resolver {
  function PackageNames (line 24) | func PackageNames(p grypePkg.Package) []string {
  function Normalize (line 38) | func Normalize(name string, pkgType syftPkg.Type) string {

FILE: grype/db/v6/operating_system_store.go
  type OSSpecifiers (line 16) | type OSSpecifiers
    method String (line 93) | func (d OSSpecifiers) String() string {
    method IsAny (line 104) | func (d OSSpecifiers) IsAny() bool {
  type OSSpecifier (line 19) | type OSSpecifier struct
    method clean (line 47) | func (d *OSSpecifier) clean() {
    method String (line 52) | func (d *OSSpecifier) String() string {
    method version (line 79) | func (d OSSpecifier) version() string {
    method matchesVersionPattern (line 114) | func (d OSSpecifier) matchesVersionPattern(pattern string) bool {
  type OperatingSystemStoreReader (line 132) | type OperatingSystemStoreReader interface
  type OperatingSystemStoreWriter (line 136) | type OperatingSystemStoreWriter interface
  type operatingSystemStore (line 142) | type operatingSystemStore struct
    method addOsFromPackages (line 156) | func (s *operatingSystemStore) addOsFromPackages(packages ...*packageH...
    method GetOperatingSystems (line 211) | func (s *operatingSystemStore) GetOperatingSystems(d OSSpecifier) ([]O...
    method applyOSAlias (line 235) | func (s *operatingSystemStore) applyOSAlias(d *OSSpecifier) error {
    method prepareQuery (line 338) | func (s *operatingSystemStore) prepareQuery(d OSSpecifier) *gorm.DB {
    method searchForOSExactVersions (line 358) | func (s *operatingSystemStore) searchForOSExactVersions(query *gorm.DB...
    method UpdateOperatingSystemEOL (line 425) | func (s *operatingSystemStore) UpdateOperatingSystemEOL(spec OSSpecifi...
  function newOperatingSystemStore (line 148) | func newOperatingSystemStore(db *gorm.DB, bs *blobStore) *operatingSyste...
  function applyOSSpecifierOverrides (line 252) | func applyOSSpecifierOverrides(d *OSSpecifier, overrides []OperatingSyst...
  function applyOverride (line 283) | func applyOverride(d *OSSpecifier, override OperatingSystemSpecifierOver...
  function canUseOverride (line 318) | func canUseOverride(override OperatingSystemSpecifierOverride, clientVer...
  function trimZeroes (line 461) | func trimZeroes(s string) string {

FILE: grype/db/v6/operating_system_store_test.go
  function TestOperatingSystemStore_ResolveOperatingSystem (line 14) | func TestOperatingSystemStore_ResolveOperatingSystem(t *testing.T) {
  function TestOSSpecifier_String (line 384) | func TestOSSpecifier_String(t *testing.T) {
  function TestTrimZeroes (line 461) | func TestTrimZeroes(t *testing.T) {
  function TestOSSpecifier_clean (line 542) | func TestOSSpecifier_clean(t *testing.T) {
  function TestApplyOverride (line 586) | func TestApplyOverride(t *testing.T) {
  function TestApplyOSSpecifierOverrides (line 760) | func TestApplyOSSpecifierOverrides(t *testing.T) {
  function strPtr (line 957) | func strPtr(s string) *string {

FILE: grype/db/v6/package_store.go
  constant anyPkg (line 18) | anyPkg = "any"
  constant anyOS (line 19) | anyOS  = "any"
  type GetPackageOptions (line 29) | type GetPackageOptions struct
  type PackageSpecifiers (line 41) | type PackageSpecifiers
    method String (line 74) | func (p PackageSpecifiers) String() string {
  type PackageSpecifier (line 43) | type PackageSpecifier struct
    method String (line 49) | func (p *PackageSpecifier) String() string {
  type packageHandleStore (line 86) | type packageHandleStore interface
  type packageHandleAccessor (line 90) | type packageHandleAccessor interface
  type packageStore (line 94) | type packageStore struct
    method handlePackage (line 291) | func (s *packageStore) handlePackage(query *gorm.DB, p *PackageSpecifi...
    method handleVulnerabilityOptions (line 320) | func (s *packageStore) handleVulnerabilityOptions(query *gorm.DB, conf...
    method handleOSOptions (line 329) | func (s *packageStore) handleOSOptions(query *gorm.DB, configs []*OSSp...
    method applyPackageAlias (line 379) | func (s *packageStore) applyPackageAlias(d *PackageSpecifier) error {
    method handlePreload (line 416) | func (s *packageStore) handlePreload(query *gorm.DB, config GetPackage...
  function newPackageStore (line 100) | func newPackageStore(db *gorm.DB, bs *blobStore, oss *operatingSystemSto...
  function addPackages (line 108) | func addPackages[T packageHandleStore](s *packageStore, packages ...T) (...
  function addPackagesWithOS (line 179) | func addPackagesWithOS[T packageHandleStore](s *packageStore, packages ....
  function getPackages (line 209) | func getPackages[T packageHandleStore]( //nolint:funlen
  function handleCPEOptions (line 444) | func handleCPEOptions(query *gorm.DB, c *cpe.Attributes, allowBroad bool...
  function queryCPEAttributeScope (line 457) | func queryCPEAttributeScope(query *gorm.DB, value string, dbColumn strin...
  function hasOSSpecified (line 479) | func hasOSSpecified(d *OSSpecifier) bool {

FILE: grype/db/v6/provider_store.go
  type ProviderStoreReader (line 12) | type ProviderStoreReader interface
  type ProviderStoreWriter (line 18) | type ProviderStoreWriter interface
  type providerStore (line 22) | type providerStore struct
    method AddProvider (line 32) | func (s *providerStore) AddProvider(p Provider) error {
    method GetProvider (line 41) | func (s *providerStore) GetProvider(name string) (*Provider, error) {
    method AllProviders (line 53) | func (s *providerStore) AllProviders() ([]Provider, error) {
    method fillProviders (line 69) | func (s *providerStore) fillProviders(handles []ref[string, Provider])...
  function newProviderStore (line 26) | func newProviderStore(db *gorm.DB) *providerStore {

FILE: grype/db/v6/provider_store_test.go
  function TestProviderStore (line 12) | func TestProviderStore(t *testing.T) {
  function TestProviderStore_GetProvider (line 76) | func TestProviderStore_GetProvider(t *testing.T) {

FILE: grype/db/v6/refs.go
  type ref (line 9) | type ref struct
  type idRef (line 14) | type idRef
  type refProvider (line 16) | type refProvider
  type idProvider (line 18) | type idProvider
  function fillRefs (line 20) | func fillRefs[T, R any](reader Reader, handles []*T, getRef refProvider[...
  function ptrs (line 68) | func ptrs[T any](values []T) []*T {
  type lowLevelReader (line 79) | type lowLevelReader interface

FILE: grype/db/v6/schema/main.go
  function main (line 23) | func main() {
  function generateSQLSchema (line 45) | func generateSQLSchema(version string) error {
  function normalizeCreateTable (line 93) | func normalizeCreateTable(stmt string) string {
  function querySchemaSorted (line 134) | func querySchemaSorted(db *sql.DB, objectType string) ([]string, error) {
  function generateBlobSchema (line 174) | func generateBlobSchema(version string, comments map[string]map[string]s...
  function buildUnifiedBlobSchema (line 181) | func buildUnifiedBlobSchema(version string, comments map[string]map[stri...
  function mergeDefinitions (line 218) | func mergeDefinitions(target, source map[string]*jsonschema.Schema) {
  function applyComments (line 224) | func applyComments(definitions map[string]*jsonschema.Schema, comments m...
  function encode (line 256) | func encode(schema *jsonschema.Schema) []byte {
  function writeFile (line 270) | func writeFile(content, component, version, extension string) error {
  function parseCommentsFromPackages (line 331) | func parseCommentsFromPackages(pkgPatterns []string) map[string]map[stri...
  function parseFileComments (line 356) | func parseFileComments(node *ast.File) map[string]map[string]string {
  function cleanComment (line 410) | func cleanComment(comment string) string {
  function getJSONTag (line 420) | func getJSONTag(field *ast.Field) string {
  function repoRoot (line 432) | func repoRoot() string {

FILE: grype/db/v6/search_query.go
  type searchQuery (line 14) | type searchQuery struct
  function newSearchQuery (line 24) | func newSearchQuery(criteriaSet []vulnerability.Criteria) (*searchQuery,...
  type searchQueryBuilder (line 36) | type searchQueryBuilder struct
    method ApplyCriteria (line 50) | func (b *searchQueryBuilder) ApplyCriteria(criteriaSet []vulnerability...
    method handlePackageName (line 84) | func (b *searchQueryBuilder) handlePackageName(c *search.PackageNameCr...
    method handleUnaffected (line 91) | func (b *searchQueryBuilder) handleUnaffected(_ *search.UnaffectedCrit...
    method handleEcosystem (line 95) | func (b *searchQueryBuilder) handleEcosystem(c *search.EcosystemCriter...
    method handleID (line 116) | func (b *searchQueryBuilder) handleID(c *search.IDCriteria) {
    method handleCPE (line 122) | func (b *searchQueryBuilder) handleCPE(c *search.CPECriteria) error {
    method handleDistro (line 140) | func (b *searchQueryBuilder) handleDistro(c *search.DistroCriteria) {
    method setDefaultOS (line 173) | func (b *searchQueryBuilder) setDefaultOS() {
    method normalizePackageName (line 182) | func (b *searchQueryBuilder) normalizePackageName() {
    method extractVersionMatcher (line 189) | func (b *searchQueryBuilder) extractVersionMatcher() {
    method Build (line 210) | func (b *searchQueryBuilder) Build() (*searchQuery, []vulnerability.Cr...
  function newSearchQueryBuilder (line 42) | func newSearchQueryBuilder() *searchQueryBuilder {

FILE: grype/db/v6/search_query_test.go
  function TestNewSearchCriteria (line 15) | func TestNewSearchCriteria(t *testing.T) {
  function TestQueryBuilder_ApplyCriteria (line 83) | func TestQueryBuilder_ApplyCriteria(t *testing.T) {
  function TestQueryBuilder_CPEErrorHandling (line 180) | func TestQueryBuilder_CPEErrorHandling(t *testing.T) {
  function TestQueryBuilder_PostProcess (line 200) | func TestQueryBuilder_PostProcess(t *testing.T) {
  function TestQueryBuilder_Build (line 271) | func TestQueryBuilder_Build(t *testing.T) {
  function TestQueryBuilder_ExactDistroCriteria (line 287) | func TestQueryBuilder_ExactDistroCriteria(t *testing.T) {
  function TestQueryBuilder_IntegrationWithRealCriteria (line 347) | func TestQueryBuilder_IntegrationWithRealCriteria(t *testing.T) {

FILE: grype/db/v6/severity.go
  function extractSeverities (line 11) | func extractSeverities(vuln *VulnerabilityHandle) (vulnerability.Severit...
  function extractSeverity (line 27) | func extractSeverity(severity any) (vulnerability.Severity, error) {
  function interpretCVSS (line 45) | func interpretCVSS(score float64, version string) vulnerability.Severity {
  function interpretCVSSv2 (line 56) | func interpretCVSSv2(score float64) vulnerability.Severity {
  function interpretCVSSv3Plus (line 75) | func interpretCVSSv3Plus(score float64) vulnerability.Severity {
  function toCvss (line 97) | func toCvss(severities ...Severity) []vulnerability.Cvss {
  function legacyCVSSType (line 134) | func legacyCVSSType(rank int) string {

FILE: grype/db/v6/severity_test.go
  function TestExtractSeverity (line 12) | func TestExtractSeverity(t *testing.T) {
  function TestExtractSeverities (line 129) | func TestExtractSeverities(t *testing.T) {

FILE: grype/db/v6/store.go
  type store (line 12) | type store struct
    method GetDB (line 29) | func (s *store) GetDB() *gorm.DB {
    method attachBlobValue (line 33) | func (s *store) attachBlobValue(values ...blobable) error {
    method Close (line 108) | func (s *store) Close() error {
  function InitialData (line 37) | func InitialData() []any {
  function newStore (line 51) | func newStore(cfg Config, empty, writable bool) (*store, error) {
  function dropAllIndexes (line 144) | func dropAllIndexes(db *gorm.DB) error {

FILE: grype/db/v6/store_test.go
  function TestStoreClose (line 12) | func TestStoreClose(t *testing.T) {
  function Test_oldDbV5 (line 60) | func Test_oldDbV5(t *testing.T) {
  function Test_oldDbWithMetadata (line 70) | func Test_oldDbWithMetadata(t *testing.T) {

FILE: grype/db/v6/unaffected_cpe_store.go
  type UnaffectedCPEStoreWriter (line 9) | type UnaffectedCPEStoreWriter interface
  type UnaffectedCPEStoreReader (line 13) | type UnaffectedCPEStoreReader interface
  type unaffectedCPEStore (line 17) | type unaffectedCPEStore struct
    method AddUnaffectedCPEs (line 31) | func (s *unaffectedCPEStore) AddUnaffectedCPEs(packages ...*Unaffected...
    method GetUnaffectedCPEs (line 35) | func (s *unaffectedCPEStore) GetUnaffectedCPEs(cpe *cpe.Attributes, co...
  function newUnaffectedCPEStore (line 23) | func newUnaffectedCPEStore(db *gorm.DB, bs *blobStore) *unaffectedCPESto...

FILE: grype/db/v6/unaffected_cpe_store_test.go
  function TestUnaffectedCPEStore_AddUnaffectedCPEs (line 11) | func TestUnaffectedCPEStore_AddUnaffectedCPEs(t *testing.T) {
  function TestUnaffectedCPEStore_GetCPEs (line 56) | func TestUnaffectedCPEStore_GetCPEs(t *testing.T) {
  function TestUnaffectedCPEStore_GetExact (line 87) | func TestUnaffectedCPEStore_GetExact(t *testing.T) {
  function TestUnaffectedCPEStore_Get_CaseInsensitive (line 107) | func TestUnaffectedCPEStore_Get_CaseInsensitive(t *testing.T) {
  function TestUnaffectedCPEStore_PreventDuplicateCPEs (line 136) | func TestUnaffectedCPEStore_PreventDuplicateCPEs(t *testing.T) {
  function testUnaffectedCPEHandle (line 211) | func testUnaffectedCPEHandle() *UnaffectedCPEHandle {

FILE: grype/db/v6/unaffected_package_store.go
  type UnaffectedPackageStoreWriter (line 5) | type UnaffectedPackageStoreWriter interface
  type UnaffectedPackageStoreReader (line 9) | type UnaffectedPackageStoreReader interface
  type unaffectedPackageStore (line 12) | type unaffectedPackageStore struct
    method AddUnaffectedPackages (line 26) | func (s *unaffectedPackageStore) AddUnaffectedPackages(packages ...*Un...
    method GetUnaffectedPackages (line 30) | func (s *unaffectedPackageStore) GetUnaffectedPackages(pkg *PackageSpe...
  function newUnaffectedPackageStore (line 18) | func newUnaffectedPackageStore(db *gorm.DB, bs *blobStore, oss *operatin...

FILE: grype/db/v6/unaffected_package_store_test.go
  type unaffectedPackageHandlePreloadConfig (line 16) | type unaffectedPackageHandlePreloadConfig struct
  function defaultUnaffectedPackageHandlePreloadCases (line 25) | func defaultUnaffectedPackageHandlePreloadCases() []unaffectedPackageHan...
  function TestUnaffectedPackageStore_AddUnaffectedPackages (line 137) | func TestUnaffectedPackageStore_AddUnaffectedPackages(t *testing.T) {
  function TestUnaffectedPackageStore_GetUnaffectedPackages_ByCPE (line 431) | func TestUnaffectedPackageStore_GetUnaffectedPackages_ByCPE(t *testing.T) {
  function TestUnaffectedPackageStore_GetUnaffectedPackages_CaseInsensitive (line 597) | func TestUnaffectedPackageStore_GetUnaffectedPackages_CaseInsensitive(t ...
  function TestUnaffectedPackageStore_GetUnaffectedPackages_MultipleVulnerabilitySpecs (line 737) | func TestUnaffectedPackageStore_GetUnaffectedPackages_MultipleVulnerabil...
  function TestUnaffectedPackageStore_GetUnaffectedPackages (line 793) | func TestUnaffectedPackageStore_GetUnaffectedPackages(t *testing.T) {
  function TestUnaffectedPackageStore_ApplyPackageAlias (line 948) | func TestUnaffectedPackageStore_ApplyPackageAlias(t *testing.T) {
  function testDistro1UnaffectedPackage2Handle (line 988) | func testDistro1UnaffectedPackage2Handle() *UnaffectedPackageHandle {
  function testDistro2UnaffectedPackage2Handle (line 1017) | func testDistro2UnaffectedPackage2Handle() *UnaffectedPackageHandle {
  function testNonDistroUnaffectedPackage2Handle (line 1045) | func testNonDistroUnaffectedPackage2Handle() *UnaffectedPackageHandle {

FILE: grype/db/v6/vulnerability.go
  constant nvdProvider (line 21) | nvdProvider    = "nvd"
  constant githubProvider (line 22) | githubProvider = "github"
  constant v5NvdNamespace (line 23) | v5NvdNamespace = "nvd:cpe"
  function newVulnerabilityFromAffectedPackageHandle (line 26) | func newVulnerabilityFromAffectedPackageHandle(affected AffectedPackageH...
  function newVulnerabilityFromAffectedCPEHandle (line 39) | func newVulnerabilityFromAffectedCPEHandle(affected AffectedCPEHandle, a...
  function newVulnerabilityFromUnaffectedPackageHandle (line 46) | func newVulnerabilityFromUnaffectedPackageHandle(unaffected UnaffectedPa...
  function newVulnerabilityFromUnaffectedCPEHandle (line 63) | func newVulnerabilityFromUnaffectedCPEHandle(unaffected UnaffectedCPEHan...
  function newVulnerabilityFromParts (line 74) | func newVulnerabilityFromParts(packageName string, vuln *VulnerabilityHa...
  function getVersionConstraint (line 107) | func getVersionConstraint(affectedRanges []Range) (version.Constraint, e...
  function getRelatedVulnerabilities (line 141) | func getRelatedVulnerabilities(vuln *VulnerabilityHandle, affected *Pack...
  function getPackageQualifiers (line 190) | func getPackageQualifiers(affected *PackageBlob) []qualifier.Qualifier {
  function MimicV5Namespace (line 201) | func MimicV5Namespace(vuln *VulnerabilityHandle, affected *AffectedPacka...
  function mimicV5GithubNamespace (line 274) | func mimicV5GithubNamespace(provider, language string) string {
  function toPackageQualifiers (line 301) | func toPackageQualifiers(qualifiers *PackageQualifiers) []qualifier.Qual...
  function toFix (line 315) | func toFix(affectedRanges []Range) vulnerability.Fix {
  function toAdvisories (line 359) | func toAdvisories(affectedRanges []Range) []vulnerability.Advisory {
  function toCPEs (line 379) | func toCPEs(affectedPackageHandle *AffectedPackageHandle, affectedCPEHan...

FILE: grype/db/v6/vulnerability_decorator_store.go
  type VulnerabilityDecoratorStoreWriter (line 14) | type VulnerabilityDecoratorStoreWriter interface
  type VulnerabilityDecoratorStoreReader (line 20) | type VulnerabilityDecoratorStoreReader interface
  type vulnerabilityDecoratorStore (line 26) | type vulnerabilityDecoratorStore struct
    method AddEpss (line 54) | func (s *vulnerabilityDecoratorStore) AddEpss(epss ...*EpssHandle) err...
    method AddCWE (line 74) | func (s *vulnerabilityDecoratorStore) AddCWE(cwe ...*CWEHandle) error {
    method setEPSSMetadata (line 90) | func (s *vulnerabilityDecoratorStore) setEPSSMetadata(date time.Time) ...
    method getEPSSMetadata (line 121) | func (s *vulnerabilityDecoratorStore) getEPSSMetadata() (*EpssMetadata...
    method GetEpss (line 130) | func (s *vulnerabilityDecoratorStore) GetEpss(cve string) ([]EpssHandl...
    method GetCWEs (line 175) | func (s *vulnerabilityDecoratorStore) GetCWEs(cve string) ([]CWEHandle...
    method AddKnownExploitedVulnerabilities (line 210) | func (s *vulnerabilityDecoratorStore) AddKnownExploitedVulnerabilities...
    method GetKnownExploitedVulnerabilities (line 230) | func (s *vulnerabilityDecoratorStore) GetKnownExploitedVulnerabilities...
  type vulnerabilityDecoratorCapabilities (line 33) | type vulnerabilityDecoratorCapabilities struct
  function newVulnerabilityDecoratorStore (line 39) | func newVulnerabilityDecoratorStore(db *gorm.DB, bs *blobStore, dbVersio...

FILE: grype/db/v6/vulnerability_decorator_store_test.go
  function TestVulnerabilityDecoratorStore (line 16) | func TestVulnerabilityDecoratorStore(t *testing.T) {
  function TestVulnerabilityDecoratorStore_AddKnownExploitedVulnerabilities_VersionCompatibility (line 142) | func TestVulnerabilityDecoratorStore_AddKnownExploitedVulnerabilities_Ve...
  function TestVulnerabilityDecoratorStore_GetKnownExploitedVulnerabilities_VersionCompatibility (line 210) | func TestVulnerabilityDecoratorStore_GetKnownExploitedVulnerabilities_Ve...
  function TestVulnerabilityDecoratorCapabilities_AllCapabilitiesCovered (line 297) | func TestVulnerabilityDecoratorCapabilities_AllCapabilitiesCovered(t *te...
  function timeRef (line 380) | func timeRef(t time.Time) *time.Time {

FILE: grype/db/v6/vulnerability_provider.go
  function NewVulnerabilityProvider (line 31) | func NewVulnerabilityProvider(rdr Reader) vulnerability.Provider {
  type vulnerabilityProvider (line 37) | type vulnerabilityProvider struct
    method VulnerabilityMetadata (line 42) | func (vp vulnerabilityProvider) VulnerabilityMetadata(ref vulnerabilit...
    method getVulnerabilityMetadata (line 65) | func (vp vulnerabilityProvider) getVulnerabilityMetadata(vuln *Vulnera...
    method fetchCWE (line 86) | func (vp vulnerabilityProvider) fetchCWE(cves []string) ([]vulnerabili...
    method DataProvenance (line 131) | func (vp vulnerabilityProvider) DataProvenance() (map[string]vulnerabi...
    method fetchVulnerability (line 151) | func (vp vulnerabilityProvider) fetchVulnerability(ref vulnerability.R...
    method fetchKnownExploited (line 163) | func (vp vulnerabilityProvider) fetchKnownExploited(cves []string) ([]...
    method fetchEpss (line 190) | func (vp vulnerabilityProvider) fetchEpss(cves []string) ([]vulnerabil...
    method PackageSearchNames (line 211) | func (vp vulnerabilityProvider) PackageSearchNames(p pkg.Package) []st...
    method Close (line 215) | func (
Condensed preview — 1026 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,509K chars).
[
  {
    "path": ".binny.yaml",
    "chars": 2284,
    "preview": "tools:\n  # we want to use a pinned version of binny to manage the toolchain (so binny manages itself!)\n  - name: binny\n "
  },
  {
    "path": ".bouncer.yaml",
    "chars": 2205,
    "preview": "permit:\n  - BSD.*\n  - CC0.*\n  - MIT.*\n  - Apache.*\n  - MPL.*\n  - ISC\n  - WTFPL\n\nignore-packages:\n  # packageurl-go is re"
  },
  {
    "path": ".chronicle.yaml",
    "chars": 93,
    "preview": "enforce-v0: true # don't make breaking-change label bump major version before 1.0.\ntitle: \"\"\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 837,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**What happened"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 250,
    "preview": "contact_links:\n\n  - name: Join our Discourse community 💬\n    # link to our community Discourse site\n    url: https://anc"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 281,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**Wh"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/match_issue.md",
    "chars": 1294,
    "preview": "---\nname: Vulnerability Match Issue\nabout: Report an issue with vulnerability matching\ntitle: ''\nlabels: [ bug, false-po"
  },
  {
    "path": ".github/actions/bootstrap/action.yaml",
    "chars": 2366,
    "preview": "name: \"Bootstrap\"\ndescription: \"Bootstrap all tools and dependencies\"\ninputs:\n  go-version:\n    description: \"Go version"
  },
  {
    "path": ".github/dependabot.yaml",
    "chars": 501,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: daily\n    c"
  },
  {
    "path": ".github/scripts/check-syft-version-is-release.sh",
    "chars": 618,
    "preview": "#!/usr/bin/env bash\nset -e\n\nversion=$(grep -E \"github.com/anchore/syft\" go.mod | awk '{print $NF}')\n\n# ensure that the v"
  },
  {
    "path": ".github/scripts/ci-check.sh",
    "chars": 239,
    "preview": "#!/usr/bin/env bash\n\nred=$(tput setaf 1)\nbold=$(tput bold)\nnormal=$(tput sgr0)\n\n# assert we are running in CI (or die!)\n"
  },
  {
    "path": ".github/scripts/coverage.py",
    "chars": 861,
    "preview": "#!/usr/bin/env python3\nimport subprocess\nimport sys\nimport shlex\n\n\nclass bcolors:\n    HEADER = '\\033[95m'\n    OKBLUE = '"
  },
  {
    "path": ".github/scripts/db-schema-drift-check.sh",
    "chars": 597,
    "preview": "#!/usr/bin/env bash\nset -u\n\nif [ \"$(git status --porcelain | wc -l)\" -ne \"0\" ]; then\n  echo \"  🔴 there are uncommitted c"
  },
  {
    "path": ".github/scripts/go-mod-tidy-check.sh",
    "chars": 974,
    "preview": "#!/usr/bin/env bash\nset -eu\n\nORIGINAL_STATE_DIR=$(mktemp -d \"TEMP-original-state-XXXXXXXXX\")\nTIDY_STATE_DIR=$(mktemp -d "
  },
  {
    "path": ".github/scripts/json-schema-drift-check.sh",
    "chars": 434,
    "preview": "#!/usr/bin/env bash\nset -u\n\nif [ \"$(git status --porcelain | wc -l)\" -ne \"0\" ]; then\n  echo \"  🔴 there are uncommitted c"
  },
  {
    "path": ".github/scripts/trigger-release.sh",
    "chars": 1942,
    "preview": "#!/usr/bin/env bash\nset -eu\n\nbold=$(tput bold)\nnormal=$(tput sgr0)\n\nGH_CLI=.tool/gh\n\nif ! [ -x \"$(command -v $GH_CLI)\" ]"
  },
  {
    "path": ".github/workflows/codeql-analysis.yml",
    "chars": 419,
    "preview": "name: CodeQL Security Scan\n\non:\n  workflow_dispatch:\n  push:\n    paths:\n     - '**'\n     - '!**.md'\n     - '!LICENSE'\n  "
  },
  {
    "path": ".github/workflows/dependabot-automation.yaml",
    "chars": 177,
    "preview": "name: Dependabot Automation\non:\n  pull_request:\n\npermissions:\n  pull-requests: write\n\njobs:\n  run:\n    uses: anchore/wor"
  },
  {
    "path": ".github/workflows/oss-project-board-add.yaml",
    "chars": 305,
    "preview": "name: Add to OSS board\n\npermissions:\n  contents: read\n\non:\n  issues:\n    types:\n      - opened\n      - reopened\n      - "
  },
  {
    "path": ".github/workflows/release.yaml",
    "chars": 11067,
    "preview": "name: \"Release\"\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: tag the latest commit on main w"
  },
  {
    "path": ".github/workflows/remove-awaiting-response-label.yaml",
    "chars": 311,
    "preview": "name: \"Manage Awaiting Response Label\"\n\non:\n  issue_comment:\n    types: [created]\n\njobs:\n  run:\n    permissions:\n      i"
  },
  {
    "path": ".github/workflows/scorecards.yml",
    "chars": 1437,
    "preview": "name: Scorecards supply-chain security\non:\n  # Only the default branch is supported.\n  branch_protection_rule:\n  push:\n "
  },
  {
    "path": ".github/workflows/update-anchore-dependencies.yml",
    "chars": 1673,
    "preview": "name: PR to update Anchore dependencies\non:\n  workflow_dispatch:\n    inputs:\n      repos:\n        description: \"List of "
  },
  {
    "path": ".github/workflows/update-bootstrap-tools.yml",
    "chars": 2025,
    "preview": "name: PR for latest versions of tools\non:\n  schedule:\n    - cron: \"0 8 * * *\" # 3 AM EST\n\n  workflow_dispatch:\n\npermissi"
  },
  {
    "path": ".github/workflows/update-generated-code.yml",
    "chars": 2407,
    "preview": "name: PR to update OS codename generated code\non:\n  schedule:\n    - cron: \"0 1 * * 1\" # every Monday at 1 AM UTC\n\n  work"
  },
  {
    "path": ".github/workflows/update-quality-gate-db.yml",
    "chars": 1335,
    "preview": "name: PR for upgrading quality gate test DB\non:\n  schedule:\n    - cron: \"0 16 1 * *\" # first day of each month @ 11 AM E"
  },
  {
    "path": ".github/workflows/validate-github-actions.yaml",
    "chars": 864,
    "preview": "name: \"Validate GitHub Actions\"\n\non:\n  pull_request:\n    paths:\n      - '.github/workflows/**'\n      - '.github/actions/"
  },
  {
    "path": ".github/workflows/validations.yaml",
    "chars": 10894,
    "preview": "name: \"Validations\"\n\non:\n  workflow_dispatch:\n  pull_request:\n  push:\n    branches:\n      - main\n\npermissions:\n  content"
  },
  {
    "path": ".github/zizmor.yml",
    "chars": 156,
    "preview": "rules:\n  unpinned-uses:\n    config:\n      policies:\n        # anchore/workflows is an internal repository; using @main i"
  },
  {
    "path": ".gitignore",
    "chars": 1028,
    "preview": "# AI\n.claude\nCLAUDE.MD\n\n# local development tailoring\ngo.work\ngo.work.sum\n.tool-versions\n.jj/\nmise.toml\nspecs/\n*.xxh64\n\n"
  },
  {
    "path": ".gitmodules",
    "chars": 182,
    "preview": "[submodule \"test/quality/vulnerability-match-labels\"]\n\tpath = test/quality/vulnerability-match-labels\n\turl = https://git"
  },
  {
    "path": ".golangci.yaml",
    "chars": 3236,
    "preview": "version: \"2\"\nlinters:\n    # inverted configuration with `enable-all` and `disable` is not scalable during updates of gol"
  },
  {
    "path": ".goreleaser.yaml",
    "chars": 11239,
    "preview": "version: 2\n\nrelease:\n  prerelease: auto\n  draft: false\n\nenv:\n  # required to support multi architecture docker builds\n  "
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 288,
    "preview": "# Code of Conduct\n\nAll contributors for any Anchore project must follow the [Contributor Covenant Code of Conduct](https"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1246,
    "preview": "# Contributing\n\nThank you for your interest in contributing to Grype!\n\nPlease see the [contribution guide](https://oss.a"
  },
  {
    "path": "Dockerfile",
    "chars": 1126,
    "preview": "FROM gcr.io/distroless/static-debian12:latest AS build\n\nFROM scratch\n# needed for version check HTTPS request\nCOPY --fro"
  },
  {
    "path": "Dockerfile.debug",
    "chars": 981,
    "preview": "FROM gcr.io/distroless/static-debian12:debug-nonroot\n\n# create the /tmp dir, which is needed for image content cache\nWOR"
  },
  {
    "path": "Dockerfile.nonroot",
    "chars": 975,
    "preview": "FROM gcr.io/distroless/static-debian12:nonroot\n\n# create the /tmp dir, which is needed for image content cache\nWORKDIR /"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "Makefile",
    "chars": 1277,
    "preview": "TOOL_DIR = .tool\nBINNY = $(TOOL_DIR)/binny\nTASK = $(TOOL_DIR)/task\n\n.DEFAULT_GOAL := make-default\n\n## Bootstrapping targ"
  },
  {
    "path": "README.md",
    "chars": 6161,
    "preview": "<p align=\"center\">\n    <img alt=\"Grype logo\" src=\"https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-c"
  },
  {
    "path": "RELEASE.md",
    "chars": 2074,
    "preview": "# Release\n\nA release of grype comprises:\n- a new semver git tag from the current tip of the main branch\n- a new [github "
  },
  {
    "path": "SECURITY.md",
    "chars": 648,
    "preview": "# Security Policy\n\n## Supported Versions\n\nSecurity updates are applied only to the most recent release, try to always be"
  },
  {
    "path": "Taskfile.yaml",
    "chars": 13563,
    "preview": "version: \"3\"\nvars:\n  OWNER: anchore\n  PROJECT: grype\n\n  # static file dirs\n  TOOL_DIR: .tool\n  TMP_DIR: .tmp\n\n  # used f"
  },
  {
    "path": "artifacthub-repo.yml",
    "chars": 218,
    "preview": "# See documentation here: https://github.com/artifacthub/hub/blob/v1.6.0/docs/metadata/artifacthub-repo.yml\nrepositoryID"
  },
  {
    "path": "cmd/grype/cli/cli.go",
    "chars": 4303,
    "preview": "package cli\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/mue"
  },
  {
    "path": "cmd/grype/cli/cli_test.go",
    "chars": 316,
    "preview": "package cli\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/anchore/clio\"\n)\n\nfunc Test_Comman"
  },
  {
    "path": "cmd/grype/cli/commands/completion.go",
    "chars": 3398,
    "preview": "package commands\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docke"
  },
  {
    "path": "cmd/grype/cli/commands/db.go",
    "chars": 484,
    "preview": "package commands\n\nimport (\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n)\n\nconst (\n\tjsonOutputFormat  = \"json\"\n"
  },
  {
    "path": "cmd/grype/cli/commands/db_check.go",
    "chars": 3797,
    "preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\""
  },
  {
    "path": "cmd/grype/cli/commands/db_check_test.go",
    "chars": 3424,
    "preview": "package commands\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/st"
  },
  {
    "path": "cmd/grype/cli/commands/db_delete.go",
    "chars": 1319,
    "preview": "package commands\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/cmd/"
  },
  {
    "path": "cmd/grype/cli/commands/db_import.go",
    "chars": 1957,
    "preview": "package commands\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/cmd/"
  },
  {
    "path": "cmd/grype/cli/commands/db_list.go",
    "chars": 3505,
    "preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"os\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/ancho"
  },
  {
    "path": "cmd/grype/cli/commands/db_list_test.go",
    "chars": 4708,
    "preview": "package commands\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"g"
  },
  {
    "path": "cmd/grype/cli/commands/db_providers.go",
    "chars": 3830,
    "preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anc"
  },
  {
    "path": "cmd/grype/cli/commands/db_providers_test.go",
    "chars": 2077,
    "preview": "package commands\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestDisplayDBProv"
  },
  {
    "path": "cmd/grype/cli/commands/db_search.go",
    "chars": 7798,
    "preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/spf13/cobr"
  },
  {
    "path": "cmd/grype/cli/commands/db_search_test.go",
    "chars": 3924,
    "preview": "package commands\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\t\"github."
  },
  {
    "path": "cmd/grype/cli/commands/db_search_vuln.go",
    "chars": 6393,
    "preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/hashicorp/go-multierro"
  },
  {
    "path": "cmd/grype/cli/commands/db_search_vuln_test.go",
    "chars": 2550,
    "preview": "package commands\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/anchore/grype/cmd/gr"
  },
  {
    "path": "cmd/grype/cli/commands/db_status.go",
    "chars": 2955,
    "preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/"
  },
  {
    "path": "cmd/grype/cli/commands/db_status_test.go",
    "chars": 3919,
    "preview": "package commands\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"git"
  },
  {
    "path": "cmd/grype/cli/commands/db_update.go",
    "chars": 2029,
    "preview": "package commands\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/cmd/"
  },
  {
    "path": "cmd/grype/cli/commands/explain.go",
    "chars": 1954,
    "preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\"github"
  },
  {
    "path": "cmd/grype/cli/commands/internal/dbsearch/affected_packages.go",
    "chars": 9039,
    "preview": "package dbsearch\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\tv6 \"github.com/anchore/grype/grype/db/v6\"\n\t\"github.com/anchore/grype/inter"
  },
  {
    "path": "cmd/grype/cli/commands/internal/dbsearch/affected_packages_test.go",
    "chars": 31172,
    "preview": "package dbsearch\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/st"
  },
  {
    "path": "cmd/grype/cli/commands/internal/dbsearch/common.go",
    "chars": 2148,
    "preview": "package dbsearch\n\nimport v6 \"github.com/anchore/grype/grype/db/v6\"\n\nconst (\n\tfixStateFixed    = \"fixed\"\n\tfixStateNotFixe"
  },
  {
    "path": "cmd/grype/cli/commands/internal/dbsearch/matches.go",
    "chars": 4167,
    "preview": "package dbsearch\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/hashicorp/go-multierror\"\n\n\tv6 \"github.com/anchore/gryp"
  },
  {
    "path": "cmd/grype/cli/commands/internal/dbsearch/matches_test.go",
    "chars": 7268,
    "preview": "package dbsearch\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tv6 \"github.com/anchore/grype/grype/db/v6\""
  },
  {
    "path": "cmd/grype/cli/commands/internal/dbsearch/versions.go",
    "chars": 1183,
    "preview": "package dbsearch\n\nconst (\n\t// MatchesSchemaVersion is the schema version for the `db search` command\n\tMatchesSchemaVersi"
  },
  {
    "path": "cmd/grype/cli/commands/internal/dbsearch/vulnerabilities.go",
    "chars": 9239,
    "preview": "package dbsearch\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\t\"time\"\n\n\tv6 \"github.com/anchore/grype/grype/db/v6\"\n\t\"github.com/anc"
  },
  {
    "path": "cmd/grype/cli/commands/internal/dbsearch/vulnerabilities_test.go",
    "chars": 12301,
    "preview": "package dbsearch\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmp"
  },
  {
    "path": "cmd/grype/cli/commands/internal/dbsearch/vulnerability_decorations.go",
    "chars": 3684,
    "preview": "package dbsearch\n\nimport (\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/hashicorp/go-multierror\"\n\t\"github.com/scylladb/go-set/strset"
  },
  {
    "path": "cmd/grype/cli/commands/internal/jsonschema/main.go",
    "chars": 6994,
    "preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"s"
  },
  {
    "path": "cmd/grype/cli/commands/root.go",
    "chars": 18817,
    "preview": "package commands\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\t\"github.com/wagood"
  },
  {
    "path": "cmd/grype/cli/commands/root_test.go",
    "chars": 9966,
    "preview": "package commands\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\t\"github."
  },
  {
    "path": "cmd/grype/cli/commands/testdata/provider-metadata.json",
    "chars": 217,
    "preview": "{\n  \"providers\": [\n    {\n      \"name\": \"provider1\",\n      \"lastSuccessfulRun\": \"2024-10-16T01:33:16.844201Z\"\n    },\n    "
  },
  {
    "path": "cmd/grype/cli/commands/update.go",
    "chars": 2119,
    "preview": "package commands\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/anchore/clio\"\n\thashiVersion \"github.com/anc"
  },
  {
    "path": "cmd/grype/cli/commands/update_test.go",
    "chars": 5342,
    "preview": "package commands\n\nimport (\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"github.com/anchore/clio\"\n\thashiVersion \"github"
  },
  {
    "path": "cmd/grype/cli/commands/util.go",
    "chars": 2891,
    "preview": "package commands\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/hashicorp/go-multierror\"\n\t\"github.com/ole"
  },
  {
    "path": "cmd/grype/cli/commands/util_test.go",
    "chars": 3099,
    "preview": "package commands\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"testing\"\n\n\t\"github.com/hashicorp/go-multierror\"\n\t\"github.com/"
  },
  {
    "path": "cmd/grype/cli/options/alerts.go",
    "chars": 803,
    "preview": "package options\n\nimport \"github.com/anchore/clio\"\n\n// Alerts configures how alerts are generated and displayed.\ntype Ale"
  },
  {
    "path": "cmd/grype/cli/options/alerts_test.go",
    "chars": 302,
    "preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestDefaultAlerts(t *testing.T) {\n\ta"
  },
  {
    "path": "cmd/grype/cli/options/database.go",
    "chars": 4145,
    "preview": "package options\n\nimport (\n\t\"time\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/go-homedir\"\n\t\"github.com/anchore/gryp"
  },
  {
    "path": "cmd/grype/cli/options/database_command.go",
    "chars": 1550,
    "preview": "package options\n\nimport (\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/db/v6/distribution\"\n\t\"github.com/a"
  },
  {
    "path": "cmd/grype/cli/options/database_search_bounds.go",
    "chars": 564,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/anchore/clio\"\n)\n\ntype DBSearchBounds struct {\n\tRecordLimit int `yaml:\"lim"
  },
  {
    "path": "cmd/grype/cli/options/database_search_format.go",
    "chars": 887,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/scylladb/go-set/strset\"\n\n\t\"github.com/anchore/clio\"\n)\n\ntype DB"
  },
  {
    "path": "cmd/grype/cli/options/database_search_os.go",
    "chars": 2635,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/anchore/clio\"\n\tv6 \"github.com/anchore/grype/grype/d"
  },
  {
    "path": "cmd/grype/cli/options/database_search_os_test.go",
    "chars": 2390,
    "preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/stretchr/testify/require\"\n\n\tv6 \"githu"
  },
  {
    "path": "cmd/grype/cli/options/database_search_packages.go",
    "chars": 2949,
    "preview": "package options\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/anchore/clio\"\n\tv6 \"github.com/anchore/grype/grype/db"
  },
  {
    "path": "cmd/grype/cli/options/database_search_packages_test.go",
    "chars": 2763,
    "preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/stretchr/testify/require\"\n\n\tv6 \"githu"
  },
  {
    "path": "cmd/grype/cli/options/database_search_vulnerabilities.go",
    "chars": 3453,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/araddon/dateparse\"\n\n\t\"github.com/anchore/clio\"\n\tv6 \"github.com/an"
  },
  {
    "path": "cmd/grype/cli/options/database_search_vulnerabilities_test.go",
    "chars": 3726,
    "preview": "package options\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/stretchr/testify/require\"\n\n\tv"
  },
  {
    "path": "cmd/grype/cli/options/datasources.go",
    "chars": 1705,
    "preview": "package options\n\nimport (\n\t\"time\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/matcher/java\"\n)\n\nconst (\n"
  },
  {
    "path": "cmd/grype/cli/options/experimental.go",
    "chars": 271,
    "preview": "package options\n\n// Experimental options are opt-in features that are...\n// ...not stable\n// ...not yet fully supported\n"
  },
  {
    "path": "cmd/grype/cli/options/fix_channels.go",
    "chars": 2081,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/distro\"\n)\n\ntype"
  },
  {
    "path": "cmd/grype/cli/options/grype.go",
    "chars": 11258,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/match\"\n\t\"github"
  },
  {
    "path": "cmd/grype/cli/options/grype_test.go",
    "chars": 976,
    "preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_flatten(t *testing.T) {\n\ttests "
  },
  {
    "path": "cmd/grype/cli/options/match.go",
    "chars": 8703,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/version\"\n)\n\n// matchConfig"
  },
  {
    "path": "cmd/grype/cli/options/match_test.go",
    "chars": 5341,
    "preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"gi"
  },
  {
    "path": "cmd/grype/cli/options/registry.go",
    "chars": 4327,
    "preview": "package options\n\nimport (\n\t\"os\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/stereoscope/pkg/image\"\n)\n\ntype Registry"
  },
  {
    "path": "cmd/grype/cli/options/registry_test.go",
    "chars": 2727,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/anchore/stereoscope/pkg"
  },
  {
    "path": "cmd/grype/cli/options/search.go",
    "chars": 1693,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/syft/syft/cataloging\"\n\t\"github.com/anc"
  },
  {
    "path": "cmd/grype/cli/options/secret.go",
    "chars": 582,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/internal/redact\"\n)\n\ntype secret "
  },
  {
    "path": "cmd/grype/cli/options/sort_by.go",
    "chars": 1158,
    "preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/scylladb/go-set/strset\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.c"
  },
  {
    "path": "cmd/grype/cli/ui/__snapshots__/handle_database_diff_started_test.snap",
    "chars": 260,
    "preview": "\n[TestHandler_handleDatabaseDiffStarted/DB_diff_started - 1]\n ⠋ Comparing Vulnerability DBs     ━━━━━━━━━━━━━━━━━━━━  [c"
  },
  {
    "path": "cmd/grype/cli/ui/__snapshots__/handle_update_vulnerability_database_test.snap",
    "chars": 266,
    "preview": "\n[TestHandler_handleUpdateVulnerabilityDatabase/downloading_DB - 1]\n ⠋ Vulnerability DB                ━━━━━━━━━━━━━━━━━"
  },
  {
    "path": "cmd/grype/cli/ui/__snapshots__/handle_vulnerability_scanning_started_test.snap",
    "chars": 822,
    "preview": "\n[TestHandler_handleVulnerabilityScanningStarted/vulnerability_scanning_in_progress/task_line - 1]\n ⠋ Scanning for vulne"
  },
  {
    "path": "cmd/grype/cli/ui/handle_database_diff_started.go",
    "chars": 1466,
    "preview": "package ui\n\nimport (\n\t\"fmt\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/wagoodman/go-partybus\"\n\t\"github.com/"
  },
  {
    "path": "cmd/grype/cli/ui/handle_database_diff_started_test.go",
    "chars": 2089,
    "preview": "package ui\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/gkampitakis/go-snaps/sna"
  },
  {
    "path": "cmd/grype/cli/ui/handle_update_vulnerability_database.go",
    "chars": 1718,
    "preview": "package ui\n\nimport (\n\t\"fmt\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/dustin/go-humanize\"\n\t\"github.com/wag"
  },
  {
    "path": "cmd/grype/cli/ui/handle_update_vulnerability_database_test.go",
    "chars": 1966,
    "preview": "package ui\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/gkampitakis/go-snaps/sna"
  },
  {
    "path": "cmd/grype/cli/ui/handle_vulnerability_scanning_started.go",
    "chars": 5723,
    "preview": "package ui\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbrac"
  },
  {
    "path": "cmd/grype/cli/ui/handle_vulnerability_scanning_started_test.go",
    "chars": 3694,
    "preview": "package ui\n\nimport (\n\t\"sort\"\n\t\"testing\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/gkampitakis/go-s"
  },
  {
    "path": "cmd/grype/cli/ui/handler.go",
    "chars": 1380,
    "preview": "package ui\n\nimport (\n\t\"sync\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/wagoodman/go-partybus\"\n\n\t\"github.co"
  },
  {
    "path": "cmd/grype/cli/ui/new_task_progress.go",
    "chars": 483,
    "preview": "package ui\n\nimport \"github.com/anchore/bubbly/bubbles/taskprogress\"\n\nfunc (m Handler) newTaskProgress(title taskprogress"
  },
  {
    "path": "cmd/grype/cli/ui/util_test.go",
    "chars": 1513,
    "preview": "package ui\n\nimport (\n\t\"reflect\"\n\t\"sync\"\n\t\"testing\"\n\t\"unsafe\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n)\n\nfunc runModel"
  },
  {
    "path": "cmd/grype/internal/constants.go",
    "chars": 60,
    "preview": "package internal\n\nconst (\n\tNotProvided = \"[not provided]\"\n)\n"
  },
  {
    "path": "cmd/grype/internal/ui/__snapshots__/post_ui_event_writer_test.snap",
    "chars": 683,
    "preview": "\n[Test_postUIEventWriter_write/no_events/stdout - 1]\n\n---\n\n[Test_postUIEventWriter_write/no_events/stderr - 1]\n\n---\n\n[Te"
  },
  {
    "path": "cmd/grype/internal/ui/no_ui.go",
    "chars": 861,
    "preview": "package ui\n\nimport (\n\t\"os\"\n\n\t\"github.com/wagoodman/go-partybus\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/g"
  },
  {
    "path": "cmd/grype/internal/ui/post_ui_event_writer.go",
    "chars": 3482,
    "preview": "package ui\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/hashicorp/go-multierror\""
  },
  {
    "path": "cmd/grype/internal/ui/post_ui_event_writer_test.go",
    "chars": 1993,
    "preview": "package ui\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/gkampitakis/go-snaps/snaps\"\n\t\"github.com/stretchr/testify/require"
  },
  {
    "path": "cmd/grype/internal/ui/ui.go",
    "chars": 5662,
    "preview": "package ui\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/wagoodman/go-p"
  },
  {
    "path": "cmd/grype/main.go",
    "chars": 789,
    "preview": "package main\n\nimport (\n\t_ \"github.com/glebarez/sqlite\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/cmd/grype/"
  },
  {
    "path": "go.mod",
    "chars": 17928,
    "preview": "module github.com/anchore/grype\n\ngo 1.25.8\n\nrequire (\n\tgithub.com/CycloneDX/cyclonedx-go v0.10.0\n\tgithub.com/Masterminds"
  },
  {
    "path": "go.sum",
    "chars": 156781,
    "preview": "cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=\ncel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ"
  },
  {
    "path": "grype/cpe/cpe.go",
    "chars": 800,
    "preview": "package cpe\n\nimport (\n\t\"github.com/facebookincubator/nvdtools/wfn\"\n\n\t\"github.com/anchore/grype/internal/log\"\n\t\"github.co"
  },
  {
    "path": "grype/cpe/cpe_test.go",
    "chars": 4579,
    "preview": "package cpe\n\nimport (\n\t\"testing\"\n\n\t\"github.com/sergi/go-diff/diffmatchpatch\"\n\n\t\"github.com/anchore/syft/syft/cpe\"\n)\n\nfun"
  },
  {
    "path": "grype/db/build.go",
    "chars": 8103,
    "preview": "package db\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"sort\"\n\t\"time\"\n\n\t\"github.com/dustin/go-humanize\"\n\t\"github.com/spf13/afero\"\n\n\t\"gith"
  },
  {
    "path": "grype/db/data/entry.go",
    "chars": 302,
    "preview": "package data\n\n// Entry is a data structure responsible for capturing an individual writable entry from a data.Processor "
  },
  {
    "path": "grype/db/data/processor.go",
    "chars": 367,
    "preview": "package data\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/provider\"\n)\n\n// Processor takes individual feed group "
  },
  {
    "path": "grype/db/data/severity.go",
    "chars": 699,
    "preview": "package data\n\nimport \"strings\"\n\ntype Severity string\n\nconst (\n\tSeverityUnknown    Severity = \"Unknown\"\n\tSeverityNegligib"
  },
  {
    "path": "grype/db/data/severity_test.go",
    "chars": 745,
    "preview": "package data\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestParseSeverity(t *testing.T) {\n\ttest"
  },
  {
    "path": "grype/db/data/transformers.go",
    "chars": 2088,
    "preview": "package data\n\nimport (\n\t\"github.com/anchore/grype/grype/db/internal/provider/unmarshal\"\n\t\"github.com/anchore/grype/grype"
  },
  {
    "path": "grype/db/data/writer.go",
    "chars": 337,
    "preview": "package data\n\n// Writer knows how to persist one or more data.Entry objects to a database. Note that the backing impleme"
  },
  {
    "path": "grype/db/default_schema_version.go",
    "chars": 107,
    "preview": "package db\n\nimport db \"github.com/anchore/grype/grype/db/v6\"\n\nconst DefaultSchemaVersion = db.ModelVersion\n"
  },
  {
    "path": "grype/db/generate.go",
    "chars": 70,
    "preview": "package db\n\n//go:generate go run ./internal/codename/generate/main.go\n"
  },
  {
    "path": "grype/db/internal/codename/codename.go",
    "chars": 680,
    "preview": "package codename\n\nimport \"strings\"\n\nfunc LookupOS(osName, majorVersion, minorVersion string) string {\n\tmajorVersion = st"
  },
  {
    "path": "grype/db/internal/codename/codename_test.go",
    "chars": 2261,
    "preview": "package codename\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestLookupOSCodename(t *testing.T) "
  },
  {
    "path": "grype/db/internal/codename/codenames_generated.go",
    "chars": 1743,
    "preview": "// DO NOT EDIT: generated by grype/db/internal/codename/generate/main.go\n\npackage codename\n\nvar normalizedOSCodenames = "
  },
  {
    "path": "grype/db/internal/codename/generate/main.go",
    "chars": 3437,
    "preview": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/dave/jennifer/jen\"\n)\n\nco"
  },
  {
    "path": "grype/db/internal/gormadapter/logger.go",
    "chars": 1789,
    "preview": "package gormadapter\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"gorm.io/gorm/logger\"\n\n\tanchoreLogger \"github.com/anchore/go-l"
  },
  {
    "path": "grype/db/internal/gormadapter/open.go",
    "chars": 8195,
    "preview": "package gormadapter\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/glebarez/sqlite\"\n\t\"gorm.io/"
  },
  {
    "path": "grype/db/internal/gormadapter/open_test.go",
    "chars": 5276,
    "preview": "package gormadapter\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestConf"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/annotated_openvex_vulnerability.go",
    "chars": 662,
    "preview": "package unmarshal\n\nimport (\n\t\"io\"\n\n\tgovex \"github.com/openvex/go-vex/pkg/vex\"\n)\n\ntype AnnotatedOpenVEXVulnerability stru"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/eol.go",
    "chars": 3691,
    "preview": "package unmarshal\n\nimport \"io\"\n\n// EndOfLifeDateRelease represents a single release entry from the endoflife.date API v1"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/epss.go",
    "chars": 349,
    "preview": "package unmarshal\n\nimport \"io\"\n\ntype EPSS struct {\n\tCVE        string  `json:\"cve\"`\n\tEPSS       float64 `json:\"epss\"`\n\tP"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/errors.go",
    "chars": 466,
    "preview": "package unmarshal\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nfunc handleJSONUnmarshalError(err error) error {\n\tif ute, ok := e"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/github_advisory.go",
    "chars": 1780,
    "preview": "package unmarshal\n\nimport (\n\t\"io\"\n)\n\ntype GitHubAdvisory struct {\n\tAdvisory struct {\n\t\tClassification string\n\t\tCVE      "
  },
  {
    "path": "grype/db/internal/provider/unmarshal/items_envelope.go",
    "chars": 592,
    "preview": "package unmarshal\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n)\n\ntype ItemsEnvelope struct {\n\tSchema     string          `ya"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/known_exploited_vulnerability.go",
    "chars": 965,
    "preview": "package unmarshal\n\nimport \"io\"\n\ntype KnownExploitedVulnerability struct {\n\tCveID                      string   `json:\"cv"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/match_exclusion.go",
    "chars": 827,
    "preview": "package unmarshal\n\nimport (\n\t\"io\"\n)\n\ntype MatchExclusion struct {\n\tID          string `json:\"id\"`\n\tConstraints []struct "
  },
  {
    "path": "grype/db/internal/provider/unmarshal/msrc_vulnerability.go",
    "chars": 1146,
    "preview": "package unmarshal\n\nimport (\n\t\"io\"\n)\n\n// MSRCVulnerability represents a single Msrc entry with vulnerability metadata\ntyp"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/nvd/cve.go",
    "chars": 10447,
    "preview": "package nvd\n\nimport (\n\t\"sort\"\n\n\t\"github.com/Masterminds/semver/v3\"\n\t\"github.com/jinzhu/copier\"\n\t\"golang.org/x/text/cases"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/nvd/cve_test.go",
    "chars": 6683,
    "preview": "package nvd\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n)\n\nfunc TestCv"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/nvd/cvss20/cvss20.go",
    "chars": 5067,
    "preview": "package cvss20\n\n// note: this was autogenerated with some manual tweaking\n\ntype Cvss20 struct {\n\t// AccessComplexity    "
  },
  {
    "path": "grype/db/internal/provider/unmarshal/nvd/cvss30/cvss30.go",
    "chars": 7159,
    "preview": "package cvss30\n\n// note: this was autogenerated with some manual tweaking\n\ntype Cvss30 struct {\n\t// AttackComplexity    "
  },
  {
    "path": "grype/db/internal/provider/unmarshal/nvd/cvss31/cvss31.go",
    "chars": 7156,
    "preview": "package cvss31\n\n// note: this was autogenerated with some manual tweaking\n\ntype Cvss31 struct {\n\t// AttackComplexity    "
  },
  {
    "path": "grype/db/internal/provider/unmarshal/nvd/cvss40/cvss40.go",
    "chars": 3007,
    "preview": "package cvss40\n\n// note: this was autogenerated with some manual tweaking\n\ntype Cvss40 struct {\n\tVersion      string    "
  },
  {
    "path": "grype/db/internal/provider/unmarshal/nvd_vulnerability.go",
    "chars": 287,
    "preview": "package unmarshal\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/internal/provider/unmarshal/nvd\"\n)\n\ntype (\n\tNVDVu"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/openvex_vulnerability.go",
    "chars": 274,
    "preview": "package unmarshal\n\nimport (\n\t\"io\"\n\n\tgovex \"github.com/openvex/go-vex/pkg/vex\"\n)\n\ntype OpenVEXVulnerability = govex.State"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/os_vulnerability.go",
    "chars": 4345,
    "preview": "package unmarshal\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/anchore/grype/grype/version\"\n)\n\ntyp"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/os_vulnerability_test.go",
    "chars": 5390,
    "preview": "package unmarshal\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_OSFixedIns_FilterToHighestMod"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/osv_vulnerability.go",
    "chars": 264,
    "preview": "package unmarshal\n\nimport (\n\t\"io\"\n\n\t\"github.com/google/osv-scanner/pkg/models\"\n)\n\ntype OSVVulnerability = models.Vulnera"
  },
  {
    "path": "grype/db/internal/provider/unmarshal/single_or_multi.go",
    "chars": 668,
    "preview": "package unmarshal\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n)\n\nfunc unmarshalSingleOrMulti[T interface{}](reader "
  },
  {
    "path": "grype/db/internal/sqlite/nullable_types.go",
    "chars": 1120,
    "preview": "package sqlite\n\nimport (\n\t\"database/sql\"\n\t\"encoding/json\"\n)\n\ntype NullString struct {\n\tsql.NullString\n}\n\nfunc NewNullStr"
  },
  {
    "path": "grype/db/internal/sqlite/nullable_types_test.go",
    "chars": 2663,
    "preview": "package sqlite\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestToNullString(t *testing.T) {\n\ttes"
  },
  {
    "path": "grype/db/internal/tarutil/file_entry.go",
    "chars": 653,
    "preview": "package tarutil\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\nvar _ Entry = (*FileEntry)(nil)\n\ntype FileEntry struct {\n\tPath string\n}\n"
  },
  {
    "path": "grype/db/internal/tarutil/file_entry_test.go",
    "chars": 1972,
    "preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/google/uuid\"\n\t\"github."
  },
  {
    "path": "grype/db/internal/tarutil/populate.go",
    "chars": 718,
    "preview": "package tarutil\n\n// PopulateWithPaths creates a compressed tar from the given paths.\nfunc PopulateWithPaths(tarPath stri"
  },
  {
    "path": "grype/db/internal/tarutil/populate_test.go",
    "chars": 1640,
    "preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"compress/gzip\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.c"
  },
  {
    "path": "grype/db/internal/tarutil/reader_entry.go",
    "chars": 3809,
    "preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/anchore/grype/internal/log\"\n)\n\nvar _ "
  },
  {
    "path": "grype/db/internal/tarutil/reader_entry_test.go",
    "chars": 4937,
    "preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t"
  },
  {
    "path": "grype/db/internal/tarutil/tar.go",
    "chars": 520,
    "preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"io\"\n)\n\n// Writer represents a facade for writing entries to a tar file.\ntype "
  },
  {
    "path": "grype/db/internal/tarutil/writer.go",
    "chars": 4583,
    "preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"bufio\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"github.co"
  },
  {
    "path": "grype/db/internal/tarutil/writer_test.go",
    "chars": 2179,
    "preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"compress/gzip\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.c"
  },
  {
    "path": "grype/db/internal/testutil/utils.go",
    "chars": 147,
    "preview": "package testutil\n\nimport (\n\t\"log\"\n\t\"os\"\n)\n\nfunc CloseFile(f *os.File) {\n\terr := f.Close()\n\n\tif err != nil {\n\t\tlog.Fatal("
  },
  {
    "path": "grype/db/internal/versionutil/clean_fixed_in_version.go",
    "chars": 205,
    "preview": "package versionutil\n\nimport \"strings\"\n\nfunc CleanFixedInVersion(version string) string {\n\tswitch strings.TrimSpace(strin"
  },
  {
    "path": "grype/db/internal/versionutil/constraint.go",
    "chars": 737,
    "preview": "package versionutil\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n)\n\n// match examples:\n// >= 5.0.0\n// <= 6.1.2.beta\n// >= 5.0.0\n// < 6"
  },
  {
    "path": "grype/db/internal/versionutil/constraint_test.go",
    "chars": 539,
    "preview": "package versionutil\n\nimport \"testing\"\n\nfunc TestEnforceSemVerConstraint(t *testing.T) {\n\ttests := []struct {\n\t\tvalue    "
  },
  {
    "path": "grype/db/package.go",
    "chars": 707,
    "preview": "package db\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\n\tgrypeDBLegacyDistribution \"github.com/anchore/grype/grype/db/v5/distributi"
  },
  {
    "path": "grype/db/package_legacy.go",
    "chars": 4508,
    "preview": "package db\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/scylladb/go-set/s"
  },
  {
    "path": "grype/db/processors/annotated_openvex_processor.go",
    "chars": 1341,
    "preview": "package processors // nolint:dupl\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/"
  },
  {
    "path": "grype/db/processors/eol_processor.go",
    "chars": 1292,
    "preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
  },
  {
    "path": "grype/db/processors/eol_processor_test.go",
    "chars": 3147,
    "preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
  },
  {
    "path": "grype/db/processors/epss_processor.go",
    "chars": 1286,
    "preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
  },
  {
    "path": "grype/db/processors/epss_processor_test.go",
    "chars": 2053,
    "preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
  },
  {
    "path": "grype/db/processors/github_processor.go",
    "chars": 1802,
    "preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
  },
  {
    "path": "grype/db/processors/github_processor_test.go",
    "chars": 2058,
    "preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
  },
  {
    "path": "grype/db/processors/kev_processor.go",
    "chars": 1359,
    "preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
  },
  {
    "path": "grype/db/processors/kev_processor_test.go",
    "chars": 2127,
    "preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
  },
  {
    "path": "grype/db/processors/match_exclusion_processor.go",
    "chars": 1376,
    "preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
  },
  {
    "path": "grype/db/processors/match_exclusion_processor_test.go",
    "chars": 2029,
    "preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
  },
  {
    "path": "grype/db/processors/msrc_processor.go",
    "chars": 1934,
    "preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
  },
  {
    "path": "grype/db/processors/msrc_processor_test.go",
    "chars": 1966,
    "preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
  },
  {
    "path": "grype/db/processors/nvd_processor.go",
    "chars": 1744,
    "preview": "package processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/grype/db/intern"
  },
  {
    "path": "grype/db/processors/nvd_processor_test.go",
    "chars": 1953,
    "preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
  },
  {
    "path": "grype/db/processors/openvex_processor.go",
    "chars": 1343,
    "preview": "package processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/grype/db/intern"
  },
  {
    "path": "grype/db/processors/openvex_processor_test.go",
    "chars": 2198,
    "preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
  }
]

// ... and 826 more files (download for full content)

About this extraction

This page contains the full source code of the anchore/grype GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1026 files (4.6 MB), approximately 1.3M tokens, and a symbol index with 4164 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!