From dc072f72beececd483edeac1cc1376a7a5246866 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Wed, 29 Oct 2025 15:33:20 -0400 Subject: [PATCH 1/2] finalize caps section Signed-off-by: Alex Goodman --- assets/scss/_capability_tables.scss | 65 +- assets/scss/_page-meta.scss | 31 + assets/scss/_sidebar.scss | 26 + assets/scss/_styles_project.scss | 1 + content/docs/capabilities/alpm.md | 1 + content/docs/capabilities/apk.md | 3 +- content/docs/capabilities/binary.md | 59 ++ content/docs/capabilities/bitnami.md | 7 + content/docs/capabilities/conda.md | 1 + content/docs/capabilities/cpp.md | 3 + content/docs/capabilities/dart.md | 1 + content/docs/capabilities/dotnet.md | 4 + content/docs/capabilities/dpkg.md | 7 +- content/docs/capabilities/elixir.md | 1 + content/docs/capabilities/erlang.md | 1 + content/docs/capabilities/github-actions.md | 1 + content/docs/capabilities/go.md | 1 + content/docs/capabilities/haskell.md | 1 + content/docs/capabilities/homebrew.md | 1 + content/docs/capabilities/java.md | 8 + content/docs/capabilities/javascript.md | 1 + content/docs/capabilities/linux.md | 1 + content/docs/capabilities/lua.md | 1 + content/docs/capabilities/nix.md | 1 + content/docs/capabilities/ocaml.md | 1 + content/docs/capabilities/php.md | 1 + content/docs/capabilities/portage.md | 3 +- content/docs/capabilities/prolog.md | 1 + content/docs/capabilities/python.md | 1 + content/docs/capabilities/r.md | 1 + content/docs/capabilities/rpm.md | 1 + content/docs/capabilities/ruby.md | 1 + content/docs/capabilities/rust.md | 1 + content/docs/capabilities/sbom.md | 1 + content/docs/capabilities/snap.md | 1 + .../snippets/ecosystem/alpm/os.md | 11 +- .../snippets/ecosystem/alpm/package.md | 31 +- .../snippets/ecosystem/alpm/vulnerability.md | 17 +- .../capabilities/snippets/ecosystem/apk/os.md | 25 +- .../snippets/ecosystem/apk/package.md | 33 +- .../snippets/ecosystem/apk/vulnerability.md | 17 +- .../binary/binary-package-details.md | 360 +++++++++ .../ecosystem/binary/grype-app-config.md | 5 +- .../snippets/ecosystem/binary/package.md | 23 +- .../ecosystem/binary/vulnerability.md | 17 +- .../snippets/ecosystem/bitnami/package.md | 31 +- .../ecosystem/bitnami/vulnerability.md | 17 +- .../ecosystem/c++/grype-app-config.md | 5 +- .../snippets/ecosystem/c++/package.md | 37 +- .../snippets/ecosystem/c++/vulnerability.md | 17 +- .../ecosystem/conda/grype-app-config.md | 5 +- .../snippets/ecosystem/conda/package.md | 31 +- .../snippets/ecosystem/conda/vulnerability.md | 17 +- .../ecosystem/dart/grype-app-config.md | 5 +- .../snippets/ecosystem/dart/package.md | 29 +- .../snippets/ecosystem/dart/vulnerability.md | 17 +- .../ecosystem/dotnet/grype-app-config.md | 5 +- .../snippets/ecosystem/dotnet/package.md | 45 +- .../ecosystem/dotnet/syft-app-config.md | 5 +- .../ecosystem/dotnet/vulnerability.md | 17 +- .../snippets/ecosystem/dpkg/os.md | 25 +- .../snippets/ecosystem/dpkg/package.md | 35 +- .../snippets/ecosystem/dpkg/vulnerability.md | 17 +- .../ecosystem/elixir/grype-app-config.md | 5 +- .../snippets/ecosystem/elixir/package.md | 27 +- .../ecosystem/elixir/vulnerability.md | 17 +- .../ecosystem/erlang/grype-app-config.md | 5 +- .../snippets/ecosystem/erlang/package.md | 31 +- .../ecosystem/erlang/vulnerability.md | 17 +- .../ecosystem/github-actions/package.md | 21 +- .../ecosystem/github-actions/vulnerability.md | 17 +- .../snippets/ecosystem/go/grype-app-config.md | 5 +- .../snippets/ecosystem/go/package.md | 41 +- .../snippets/ecosystem/go/syft-app-config.md | 5 +- .../snippets/ecosystem/go/vulnerability.md | 17 +- .../ecosystem/haskell/grype-app-config.md | 5 +- .../snippets/ecosystem/haskell/package.md | 37 +- .../ecosystem/haskell/vulnerability.md | 17 +- .../ecosystem/homebrew/grype-app-config.md | 5 +- .../snippets/ecosystem/homebrew/package.md | 21 +- .../ecosystem/homebrew/vulnerability.md | 17 +- .../ecosystem/java/grype-app-config.md | 5 +- .../snippets/ecosystem/java/package.md | 71 +- .../ecosystem/java/syft-app-config.md | 5 +- .../snippets/ecosystem/java/vulnerability.md | 17 +- .../ecosystem/javascript/grype-app-config.md | 5 +- .../snippets/ecosystem/javascript/package.md | 41 +- .../ecosystem/javascript/syft-app-config.md | 5 +- .../ecosystem/javascript/vulnerability.md | 17 +- .../ecosystem/linux/grype-app-config.md | 5 +- .../snippets/ecosystem/linux/package.md | 21 +- .../ecosystem/linux/syft-app-config.md | 5 +- .../snippets/ecosystem/linux/vulnerability.md | 17 +- .../ecosystem/lua/grype-app-config.md | 5 +- .../snippets/ecosystem/lua/package.md | 25 +- .../snippets/ecosystem/lua/vulnerability.md | 17 +- .../ecosystem/nix/grype-app-config.md | 5 +- .../snippets/ecosystem/nix/package.md | 41 +- .../snippets/ecosystem/nix/syft-app-config.md | 5 +- .../snippets/ecosystem/nix/vulnerability.md | 17 +- .../ecosystem/ocaml/grype-app-config.md | 5 +- .../snippets/ecosystem/ocaml/package.md | 25 +- .../snippets/ecosystem/ocaml/vulnerability.md | 17 +- .../ecosystem/php/grype-app-config.md | 5 +- .../snippets/ecosystem/php/package.md | 45 +- .../snippets/ecosystem/php/vulnerability.md | 17 +- .../snippets/ecosystem/portage/os.md | 11 +- .../snippets/ecosystem/portage/package.md | 29 +- .../ecosystem/portage/vulnerability.md | 17 +- .../ecosystem/prolog/grype-app-config.md | 5 +- .../snippets/ecosystem/prolog/package.md | 25 +- .../ecosystem/prolog/vulnerability.md | 17 +- .../ecosystem/python/grype-app-config.md | 5 +- .../snippets/ecosystem/python/package.md | 55 +- .../ecosystem/python/syft-app-config.md | 5 +- .../ecosystem/python/vulnerability.md | 17 +- .../snippets/ecosystem/r/grype-app-config.md | 5 +- .../snippets/ecosystem/r/package.md | 21 +- .../snippets/ecosystem/r/vulnerability.md | 17 +- .../capabilities/snippets/ecosystem/rpm/os.md | 41 +- .../snippets/ecosystem/rpm/package.md | 45 +- .../snippets/ecosystem/rpm/vulnerability.md | 17 +- .../ecosystem/ruby/grype-app-config.md | 5 +- .../snippets/ecosystem/ruby/package.md | 37 +- .../snippets/ecosystem/ruby/vulnerability.md | 17 +- .../ecosystem/rust/grype-app-config.md | 5 +- .../snippets/ecosystem/rust/package.md | 35 +- .../snippets/ecosystem/rust/vulnerability.md | 17 +- .../ecosystem/sbom/grype-app-config.md | 5 +- .../snippets/ecosystem/sbom/package.md | 21 +- .../snippets/ecosystem/sbom/vulnerability.md | 17 +- .../ecosystem/snap/grype-app-config.md | 5 +- .../snippets/ecosystem/snap/package.md | 21 +- .../snippets/ecosystem/snap/vulnerability.md | 17 +- .../ecosystem/swift/grype-app-config.md | 5 +- .../snippets/ecosystem/swift/package.md | 31 +- .../snippets/ecosystem/swift/vulnerability.md | 17 +- .../ecosystem/terraform/grype-app-config.md | 5 +- .../snippets/ecosystem/terraform/package.md | 27 +- .../ecosystem/terraform/vulnerability.md | 17 +- .../ecosystem/wordpress/grype-app-config.md | 5 +- .../snippets/ecosystem/wordpress/package.md | 21 +- .../ecosystem/wordpress/vulnerability.md | 17 +- .../docs/capabilities/snippets/overview/os.md | 73 +- .../capabilities/snippets/overview/package.md | 61 +- content/docs/capabilities/swift.md | 1 + content/docs/capabilities/terraform.md | 1 + content/docs/capabilities/wordpress.md | 1 + .../format/examples/cyclonedx-json.md | 20 +- .../snippets/format/examples/cyclonedx-xml.md | 20 +- .../snippets/format/examples/github-json.md | 6 +- .../sbom/snippets/format/examples/json.md | 111 +-- .../snippets/format/examples/spdx-json.md | 70 +- .../format/examples/spdx-tag-value.md | 68 +- .../sbom/snippets/format/examples/text.md | 4 +- .../jq-queries/all-executables/output.md | 32 +- .../snippets/jq-queries/all-purls/output.md | 28 +- .../jq-queries/binaries-not-owned/output.md | 100 +-- .../binaries-with-security-features/output.md | 2 +- .../jq-queries/binary-digests/output.md | 62 +- .../jq-queries/binary-imports/output.md | 8 +- .../dependency-relationships/output.md | 80 +- .../jq-queries/files-by-mime-type/output.md | 34 +- .../snippets/jq-queries/large-files/output.md | 24 +- .../templates/executable-digests/output.md | 32 +- content/docs/reference/syft/cli.md | 18 +- content/docs/reference/syft/json/15.md | 1 + content/docs/reference/syft/json/16.md | 1 + .../capabilities/syft-package-catalogers.json | 549 +++++++++++++- data/capabilities/vulnerability-data.yaml | 52 +- data/syft/cli/version/output.txt | 23 +- hugo.yaml | 7 + layouts/partials/sidebar-tree.html | 61 +- scripts/generate_capability_package_tables.py | 526 +++++++------ ...enerate_capability_vulnerability_tables.py | 573 +++++--------- scripts/generate_format_examples.py | 72 +- scripts/generate_format_versions.py | 101 +-- scripts/generate_jq_query_examples.py | 122 +-- scripts/generate_reference_cli_docs.py | 120 +-- scripts/generate_reference_config_docs.py | 106 ++- .../generate_reference_syft_json_schema.py | 203 +++-- scripts/generate_template_examples.py | 88 ++- scripts/release-to-hugo.py | 4 +- scripts/utils/cache.py | 8 +- scripts/utils/cataloger.py | 11 +- scripts/utils/constants.py | 164 ++++ scripts/utils/data.py | 22 +- scripts/utils/html_table.py | 702 ++++++++++++++++++ scripts/utils/{logging.py => log.py} | 10 +- scripts/utils/markdown.py | 163 ++++ scripts/utils/output_manager.py | 187 +++++ scripts/utils/sbom.py | 16 +- scripts/utils/syft.py | 32 +- scripts/utils/version.py | 302 ++++++++ tasks.d/generate.yaml | 2 +- 195 files changed, 5179 insertions(+), 2476 deletions(-) create mode 100644 assets/scss/_page-meta.scss create mode 100644 content/docs/capabilities/snippets/ecosystem/binary/binary-package-details.md create mode 100644 scripts/utils/constants.py create mode 100644 scripts/utils/html_table.py rename scripts/utils/{logging.py => log.py} (89%) create mode 100644 scripts/utils/markdown.py create mode 100644 scripts/utils/output_manager.py create mode 100644 scripts/utils/version.py diff --git a/assets/scss/_capability_tables.scss b/assets/scss/_capability_tables.scss index bbfb1acc..3c762f14 100644 --- a/assets/scss/_capability_tables.scss +++ b/assets/scss/_capability_tables.scss @@ -16,7 +16,6 @@ } .capability-table thead th { - box-shadow: 0 3px 6px rgba(29, 78, 216, 0.4); padding: 0.625rem 0.5rem; text-align: left; font-weight: 600; @@ -366,16 +365,40 @@ svg use[href='#icon-dash'] { border: none !important; } +/* Deprecated Pill - Inline with cataloger name */ + +.deprecated-pill { + display: inline-block; + padding: 0.125rem 0.375rem; + margin-left: 0.5rem; + border-radius: 3px; + font-size: 0.7rem; + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.025em; + vertical-align: middle; + + [data-bs-theme='light'] & { + background-color: #fed7aa; + color: #92400e; + } + [data-bs-theme='dark'] & { + background-color: #92400e; + color: #fed7aa; + } +} + /* Header Help Tooltips */ -/* Abbr element containing help icon - remove default styling and set up tooltip positioning */ +/* Abbr element wrapping column header text - set up tooltip positioning and styling */ .header-help { position: relative; /* position context for custom tooltip */ - text-decoration: none; + text-decoration: underline dotted; + text-underline-offset: 0.25em; /* move dotted line lower below text */ + text-decoration-thickness: 1px; border: none; cursor: help; display: inline-block; - margin-left: 0.25rem; vertical-align: middle; } @@ -487,18 +510,35 @@ th:first-child .header-help::before { transform: translateX(0); } -/* Evidence Tooltips for Capability Icons */ +/* Cataloger Condition Indicator - Inline Gear Icon */ + +.cataloger-condition-wrapper { + display: inline-block; + margin-left: 0.375rem; + vertical-align: middle; + position: relative; + cursor: help; +} + +.cataloger-condition-wrapper .inline-icon { + width: 16px; + height: 16px; +} + +/* Unified Tooltips for Capability Icons and Cataloger Conditions */ -/* Capability icon wrapper with evidence - set up tooltip positioning */ -.capability-icon-wrapper[data-evidence] { +/* Set up tooltip positioning for capability icons and cataloger conditions */ +.capability-icon-wrapper[data-tooltip], +.cataloger-condition-wrapper[data-tooltip] { position: relative; cursor: help; display: inline-block; /* needed for proper positioning */ } /* Tooltip content */ -.capability-icon-wrapper[data-evidence]::after { - content: attr(data-evidence); +.capability-icon-wrapper[data-tooltip]::after, +.cataloger-condition-wrapper[data-tooltip]::after { + content: attr(data-tooltip); position: absolute; bottom: calc(100% + 8px); /* position above with gap */ left: 50%; @@ -544,20 +584,21 @@ th:first-child .header-help::before { } /* Show tooltip on hover */ -.capability-icon-wrapper[data-evidence]:hover::after { +.capability-icon-wrapper[data-tooltip]:hover::after, +.cataloger-condition-wrapper[data-tooltip]:hover::after { opacity: 1; visibility: visible; } /* Adjust positioning for tooltips in cells near right edge */ -td:nth-last-child(-n + 2) .capability-icon-wrapper[data-evidence]::after { +td:nth-last-child(-n + 2) .capability-icon-wrapper[data-tooltip]::after { left: auto; right: 0; transform: translateX(0); } /* Adjust positioning for tooltips in cells near left edge */ -td:first-child .capability-icon-wrapper[data-evidence]::after { +td:first-child .capability-icon-wrapper[data-tooltip]::after { left: 0; transform: translateX(0); } diff --git a/assets/scss/_page-meta.scss b/assets/scss/_page-meta.scss new file mode 100644 index 00000000..57b6c179 --- /dev/null +++ b/assets/scss/_page-meta.scss @@ -0,0 +1,31 @@ +// page metadata styling (e.g., last modified info) + +.td-page-meta__lastmod { + font-size: 0.8rem; + color: #6c757d; // muted grey for light mode + margin-top: 2rem; + + a { + color: #6c757d; // muted grey for links + text-decoration: underline; // preserve underline + + &:hover { + color: #495057; // slightly darker on hover + } + } +} + +// dark mode adjustments +[data-bs-theme='dark'] { + .td-page-meta__lastmod { + color: #adb5bd; // lighter grey for dark mode + + a { + color: #adb5bd; + + &:hover { + color: #ced4da; // lighter on hover + } + } + } +} diff --git a/assets/scss/_sidebar.scss b/assets/scss/_sidebar.scss index 9772cded..8011e1c0 100644 --- a/assets/scss/_sidebar.scss +++ b/assets/scss/_sidebar.scss @@ -41,6 +41,32 @@ } } +// sidebar group headers for organizing menu sections +.td-sidebar-group-header { + padding: 1rem 0 0.5rem 0; + margin-top: 0.75rem; + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + pointer-events: none; + list-style: none; + + [data-bs-theme='light'] & { + color: $syft-purple-blue; + border-top: 1px solid rgba(0, 0, 0, 0.08); + } + [data-bs-theme='dark'] & { + color: $syft-purple-blue; + border-top: 1px solid rgba(255, 255, 255, 0.12); + } + + &:first-child { + margin-top: 0; + border-top: none; + } +} + // improved sidebar spacing and typography .td-sidebar { .td-sidebar-nav { diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index de41f9eb..5b73b946 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -18,6 +18,7 @@ @import 'navbar'; @import 'sidebar'; @import 'page-actions'; +@import 'page-meta'; // Feature-specific styles @import 'landing/landing'; diff --git a/content/docs/capabilities/alpm.md b/content/docs/capabilities/alpm.md index a4ef3533..41d2e54e 100644 --- a/content/docs/capabilities/alpm.md +++ b/content/docs/capabilities/alpm.md @@ -3,6 +3,7 @@ title = "ALPM" description = "ALPM package format used by Arch-based Linux distributions" weight = 10 type = "docs" +menu_group = "os" [params] sidebar_badge = "arch" +++ diff --git a/content/docs/capabilities/apk.md b/content/docs/capabilities/apk.md index b3437b79..3ea32cdd 100644 --- a/content/docs/capabilities/apk.md +++ b/content/docs/capabilities/apk.md @@ -3,6 +3,7 @@ title = "APK" description = "APK package format analysis and vulnerability scanning capabilities" weight = 20 type = "docs" +menu_group = "os" [params] sidebar_badge = "alpine+" +++ @@ -19,7 +20,7 @@ sidebar_badge = "alpine+" {{< readfile file="/content/docs/capabilities/snippets/ecosystem/apk/os.md" >}} -The APK vulnerability database (a.k.a. "SecDB") includes data from the Alpine Security Tracker, which provides detailed information on vulnerabilities affecting Alpine Linux packages. +The APK vulnerability database (a.k.a. "SecDB") includes data from the Alpine Security Tracker, which provides fix information for known vulnerabilities that affect Alpine Linux packages. This database only includes vulnerabilities that have fixes available and does not track unfixed vulnerabilities. The maintainers of the SecDB intend for the primary source of truth for disclosures to be the [National Vulnerability Database](https://nvd.nist.gov/developers/vulnerabilities) (NVD). diff --git a/content/docs/capabilities/binary.md b/content/docs/capabilities/binary.md index 8ee57108..620592ce 100644 --- a/content/docs/capabilities/binary.md +++ b/content/docs/capabilities/binary.md @@ -3,12 +3,71 @@ title = "Binary" description = "Binary package analysis and vulnerability scanning capabilities" weight = 30 type = "docs" +menu_group = "other" +++ +## File analysis + +Within the `.files[].executable` sections of the Syft JSON there is an analysis of what features and claims were found within a binary file. + +This includes: + +- Imported libraries (shared libraries) +- Exported symbols +- Security features (like NX, PIE, RELRO, etc) + +Security features that can be detected include: + +- if debugging symbols have been stripped +- presence of _Stack Canaries_ to protect against stack smashing (which lead to buffer overflows) +- _NoExecute_ (NX) bit support to prevent execution of code on the stack or heap +- _Relocation Read-Only_ (RelRO) to protect the Global Offset Table (GOT) from being overwritten (can be "partial" or "full") +- _Position Independent Executable_ (PIE) support such that offsets are used instead of absolute addresses +- if it is a _Dynamic Shared Object_ (DSO) (not a security feature, but important for analysis) +- [LLVM SafeStack](https://clang.llvm.org/docs/SafeStack.html) partitioning is in use, which separates unsafe stack objects from safe stack objects to mitigate stack-based memory corruption vulnerabilities +- [LLVM Control Flow Integrity](https://clang.llvm.org/docs/ControlFlowIntegrity.html) (CFI) is in use, which adds runtime checks to ensure that indirect function calls only target valid functions, helping to prevent control-flow hijacking attacks +- [Clang Fortified Builds](https://clang.llvm.org/docs/ClangFortifyBuild.html) is enabled, which adds additional runtime checks for certain standard library functions to detect buffer overflows and other memory errors + +When it comes to shared library requirement claims and exported symbol claims, these are used by Syft to: + +- associate file-to-file relationships (in the case of executables/shared libraries being distributed without a package manager) +- associate file-to-package relationships (when an executable imports a shared library that is managed by a package manager) + +Say that all package manager information has been stripped from a container image, leaving behind a collection of binary files (some of which may be executables or shared libraries). +In this case Syft can still synthesize a dependency graph from the imported libraries and exported symbols found within the binaries, allowing for a more complete SBOM to be generated. +In a mixed case, where there are some packages managed by package managers and some binaries without package manager metadata, Syft can still use the binary analysis to fill in the gaps. +Package-level relationships are preferred over file-level relationships when both are available, which simplifies the dependency graph. + ## Package analysis {{< readfile file="/content/docs/capabilities/snippets/ecosystem/binary/package.md" >}} +{{< readfile file="/content/docs/capabilities/snippets/ecosystem/binary/binary-package-details.md" >}} + +### ELF package notes + +Syft is capable of looking at ELF formatted binaries, specifically the `.note.package` note, that are formatted using the [convention established by the systemd project](https://systemd.io/PACKAGE_METADATA_FOR_EXECUTABLE_FILES/). +This spec requires a PE/COFF section that wraps a json payload describing the package metadata for the binary, however, syft does not require the PE/COFF wrapping and can extract the json payload directly from the ELF note. + +Here's an example of what the json payload looks like: + +```json +{ + "name": "my-application", + "version": "1.2.3", + "purl": "pkg:deb/debian/my-application@1.2.3?arch=amd64&distro=debian-12", + "cpe": "cpe:2.3:a:vendor:my-application:1.2.3:*:*:*:*:*:*:*", + "license": "Apache-2.0", + "type": "deb" +} +``` + +Which, if stored in `payload.json`, can be injected into an existing ELF binary using the following command: + +```bash +objcopy --add-section .note.package=payload.json --set-section-flags .note.package=noload,readonly +``` + ## Vulnerability scanning {{< readfile file="/content/docs/capabilities/snippets/ecosystem/binary/vulnerability.md" >}} diff --git a/content/docs/capabilities/bitnami.md b/content/docs/capabilities/bitnami.md index 94c990b1..ad56ea59 100644 --- a/content/docs/capabilities/bitnami.md +++ b/content/docs/capabilities/bitnami.md @@ -3,12 +3,19 @@ title = "Bitnami" description = "Bitnami package analysis and vulnerability scanning capabilities" weight = 40 type = "docs" +menu_group = "other" +++ ## Package analysis {{< readfile file="/content/docs/capabilities/snippets/ecosystem/bitnami/package.md" >}} +Since all package data is gathered from SPDX SBOMs, the quality of the package analysis is dependent on the quality of the provided SBOMs. + +## Vulnerability scanning + +{{< readfile file="/content/docs/capabilities/snippets/ecosystem/bitnami/vulnerability.md" >}} + ## Next steps - [Syft package analysis]({{< ref "docs/guides/sbom" >}}) diff --git a/content/docs/capabilities/conda.md b/content/docs/capabilities/conda.md index 5801922c..0b2cc1ed 100644 --- a/content/docs/capabilities/conda.md +++ b/content/docs/capabilities/conda.md @@ -3,6 +3,7 @@ title = "Conda" description = "Conda package analysis and vulnerability scanning capabilities" weight = 50 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/cpp.md b/content/docs/capabilities/cpp.md index 4b6281e1..34a9b31e 100644 --- a/content/docs/capabilities/cpp.md +++ b/content/docs/capabilities/cpp.md @@ -3,12 +3,15 @@ title = "C/C++" description = "C/C++ package analysis and vulnerability scanning capabilities" weight = 60 type = "docs" +menu_group = "language" +++ ## Package analysis {{< readfile file="/content/docs/capabilities/snippets/ecosystem/c++/package.md" >}} +We support package detection for [v1](https://docs.conan.io/1/versioning/lockfiles.html#lockfiles) and [v2](https://docs.conan.io/2/tutorial/versioning/lockfiles.html) formatted `conan.lock` files. + ## Vulnerability scanning {{< readfile file="/content/docs/capabilities/snippets/ecosystem/c++/vulnerability.md" >}} diff --git a/content/docs/capabilities/dart.md b/content/docs/capabilities/dart.md index 425fe6fd..3777187e 100644 --- a/content/docs/capabilities/dart.md +++ b/content/docs/capabilities/dart.md @@ -3,6 +3,7 @@ title = "Dart" description = "Dart package analysis and vulnerability scanning capabilities" weight = 70 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/dotnet.md b/content/docs/capabilities/dotnet.md index 5ff856ce..5ce38285 100644 --- a/content/docs/capabilities/dotnet.md +++ b/content/docs/capabilities/dotnet.md @@ -3,6 +3,7 @@ title = ".NET" description = ".NET package analysis and vulnerability scanning capabilities" weight = 90 type = "docs" +menu_group = "language" +++ ## Package analysis @@ -11,6 +12,9 @@ type = "docs" {{< readfile file="/content/docs/capabilities/snippets/ecosystem/dotnet/syft-app-config.md" >}} +When scanning a .NET application evidence from deps.json (compiler output) as well as any built binaries are used together to identify packages. +This way we can enrich missing data from any one source and synthesize a more complete and accurate package graph. + ## Vulnerability scanning {{< readfile file="/content/docs/capabilities/snippets/ecosystem/dotnet/vulnerability.md" >}} diff --git a/content/docs/capabilities/dpkg.md b/content/docs/capabilities/dpkg.md index d0b6a2bc..463e9355 100644 --- a/content/docs/capabilities/dpkg.md +++ b/content/docs/capabilities/dpkg.md @@ -3,6 +3,7 @@ title = "DPKG" description = "Debian package format used by Debian-based Linux distributions" weight = 80 type = "docs" +menu_group = "os" [params] sidebar_badge = "debian+" +++ @@ -11,10 +12,10 @@ sidebar_badge = "debian+" {{< readfile file="/content/docs/capabilities/snippets/ecosystem/dpkg/package.md" >}} -**Notable capabilities:** +There is additional functionality for: -- **OPKG compatibility**: Syft supports OpenWrt's OPKG package manager format using the same cataloger. -- **Distroless images**: Syft automatically detects and supports Google distroless images that use `/var/lib/dpkg/status.d/`. +- the detection of [OpenWrt's](https://openwrt.org/) [OPKG packages](https://openwrt.org/docs/guide-user/additional-software/opkg) +- the detection of [Google Distroless image](https://github.com/GoogleContainerTools/distroless) debian-based packages ## Vulnerability scanning diff --git a/content/docs/capabilities/elixir.md b/content/docs/capabilities/elixir.md index 2d882d65..572d1138 100644 --- a/content/docs/capabilities/elixir.md +++ b/content/docs/capabilities/elixir.md @@ -3,6 +3,7 @@ title = "Elixir" description = "Elixir package analysis and vulnerability scanning capabilities" weight = 100 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/erlang.md b/content/docs/capabilities/erlang.md index 9b9e2357..3f969b1d 100644 --- a/content/docs/capabilities/erlang.md +++ b/content/docs/capabilities/erlang.md @@ -3,6 +3,7 @@ title = "Erlang" description = "Erlang package analysis and vulnerability scanning capabilities" weight = 110 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/github-actions.md b/content/docs/capabilities/github-actions.md index e7155863..d0af998d 100644 --- a/content/docs/capabilities/github-actions.md +++ b/content/docs/capabilities/github-actions.md @@ -3,6 +3,7 @@ title = "GitHub Actions" description = "GitHub Actions package analysis and vulnerability scanning capabilities" weight = 120 type = "docs" +menu_group = "other" +++ ## Package analysis diff --git a/content/docs/capabilities/go.md b/content/docs/capabilities/go.md index d1a7f77c..60ffbfb4 100644 --- a/content/docs/capabilities/go.md +++ b/content/docs/capabilities/go.md @@ -3,6 +3,7 @@ title = "Go" description = "Go package analysis and vulnerability scanning capabilities" weight = 130 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/haskell.md b/content/docs/capabilities/haskell.md index 2bb49409..32ca27d2 100644 --- a/content/docs/capabilities/haskell.md +++ b/content/docs/capabilities/haskell.md @@ -3,6 +3,7 @@ title = "Haskell" description = "Haskell package analysis and vulnerability scanning capabilities" weight = 140 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/homebrew.md b/content/docs/capabilities/homebrew.md index 4f07a68a..6b4f50a2 100644 --- a/content/docs/capabilities/homebrew.md +++ b/content/docs/capabilities/homebrew.md @@ -3,6 +3,7 @@ title = "Homebrew" description = "Homebrew package analysis and vulnerability scanning capabilities" weight = 150 type = "docs" +menu_group = "other" +++ ## Package analysis diff --git a/content/docs/capabilities/java.md b/content/docs/capabilities/java.md index b619c774..2629b32c 100644 --- a/content/docs/capabilities/java.md +++ b/content/docs/capabilities/java.md @@ -3,6 +3,7 @@ title = "Java" description = "Java package analysis and vulnerability scanning capabilities" weight = 160 type = "docs" +menu_group = "language" +++ ## Package analysis @@ -11,6 +12,13 @@ type = "docs" {{< readfile file="/content/docs/capabilities/snippets/ecosystem/java/syft-app-config.md" >}} +### Archives + +When scanning a Java archive (e.g. `jar`, `war`, `ear`, ...), Syft will look for `maven` project evidence within the archive recursively. +This means that if a `jar` file contains other `jar` files, Syft will also look for `pom.xml` files within those nested `jar` files to identify packages (such as with [shaded jars](https://maven.apache.org/plugins/maven-shade-plugin/)). + +Additionally, if opted-in via configuration, Syft will scan non-java archive files (e.g., `zip`, `tar`, `tar.gz`, ...) for Java package evidence as well. + ## Vulnerability scanning {{< readfile file="/content/docs/capabilities/snippets/ecosystem/java/vulnerability.md" >}} diff --git a/content/docs/capabilities/javascript.md b/content/docs/capabilities/javascript.md index 9a780709..a068a887 100644 --- a/content/docs/capabilities/javascript.md +++ b/content/docs/capabilities/javascript.md @@ -3,6 +3,7 @@ title = "JavaScript" description = "JavaScript package analysis and vulnerability scanning capabilities" weight = 170 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/linux.md b/content/docs/capabilities/linux.md index 2da98e48..cc2d89a2 100644 --- a/content/docs/capabilities/linux.md +++ b/content/docs/capabilities/linux.md @@ -3,6 +3,7 @@ title = "Linux Kernel" description = "Linux kernel archive and module analysis and vulnerability scanning capabilities" weight = 180 type = "docs" +menu_group = "os" +++ ## Package analysis diff --git a/content/docs/capabilities/lua.md b/content/docs/capabilities/lua.md index 98e2fc5b..ed711460 100644 --- a/content/docs/capabilities/lua.md +++ b/content/docs/capabilities/lua.md @@ -3,6 +3,7 @@ title = "Lua" description = "Lua package analysis and vulnerability scanning capabilities" weight = 190 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/nix.md b/content/docs/capabilities/nix.md index 362a8635..c1639467 100644 --- a/content/docs/capabilities/nix.md +++ b/content/docs/capabilities/nix.md @@ -3,6 +3,7 @@ title = "Nix" description = "Nix package analysis and vulnerability scanning capabilities" weight = 200 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/ocaml.md b/content/docs/capabilities/ocaml.md index af9fce06..41a63596 100644 --- a/content/docs/capabilities/ocaml.md +++ b/content/docs/capabilities/ocaml.md @@ -3,6 +3,7 @@ title = "OCaml" description = "OCaml package analysis and vulnerability scanning capabilities" weight = 210 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/php.md b/content/docs/capabilities/php.md index 2c915f9d..47df7419 100644 --- a/content/docs/capabilities/php.md +++ b/content/docs/capabilities/php.md @@ -3,6 +3,7 @@ title = "PHP" description = "PHP package analysis and vulnerability scanning capabilities" weight = 220 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/portage.md b/content/docs/capabilities/portage.md index c2ec7ea2..f5f95107 100644 --- a/content/docs/capabilities/portage.md +++ b/content/docs/capabilities/portage.md @@ -1,8 +1,9 @@ +++ title = "Portage" -description = "Debian package format used by Debian-based Linux distributions" +description = "Portage package format used by Gentoo-based Linux distributions" weight = 230 type = "docs" +menu_group = "os" [params] sidebar_badge = "gentoo" +++ diff --git a/content/docs/capabilities/prolog.md b/content/docs/capabilities/prolog.md index 2dae2e60..8138c985 100644 --- a/content/docs/capabilities/prolog.md +++ b/content/docs/capabilities/prolog.md @@ -3,6 +3,7 @@ title = "Prolog" description = "Prolog package analysis and vulnerability scanning capabilities" weight = 240 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/python.md b/content/docs/capabilities/python.md index 91ac8ced..b387dd64 100644 --- a/content/docs/capabilities/python.md +++ b/content/docs/capabilities/python.md @@ -3,6 +3,7 @@ title = "Python" description = "Python package analysis and vulnerability scanning capabilities" weight = 250 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/r.md b/content/docs/capabilities/r.md index 4a4d04c0..deb6876a 100644 --- a/content/docs/capabilities/r.md +++ b/content/docs/capabilities/r.md @@ -3,6 +3,7 @@ title = "R" description = "R package analysis and vulnerability scanning capabilities" weight = 260 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/rpm.md b/content/docs/capabilities/rpm.md index 5cd02961..ef80ab8f 100644 --- a/content/docs/capabilities/rpm.md +++ b/content/docs/capabilities/rpm.md @@ -3,6 +3,7 @@ title = "RPM" description = "Red Hat Package Manager format used by Red Hat-based Linux distributions" weight = 270 type = "docs" +menu_group = "os" [params] sidebar_badge = "redhat+" +++ diff --git a/content/docs/capabilities/ruby.md b/content/docs/capabilities/ruby.md index 9be86f01..01cadaea 100644 --- a/content/docs/capabilities/ruby.md +++ b/content/docs/capabilities/ruby.md @@ -3,6 +3,7 @@ title = "Ruby" description = "Ruby package analysis and vulnerability scanning capabilities" weight = 280 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/rust.md b/content/docs/capabilities/rust.md index 147d4cd7..3b858e33 100644 --- a/content/docs/capabilities/rust.md +++ b/content/docs/capabilities/rust.md @@ -3,6 +3,7 @@ title = "Rust" description = "Rust package analysis and vulnerability scanning capabilities" weight = 290 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/sbom.md b/content/docs/capabilities/sbom.md index 409a0dfd..a824b1e8 100644 --- a/content/docs/capabilities/sbom.md +++ b/content/docs/capabilities/sbom.md @@ -3,6 +3,7 @@ title = "SBOM" description = "SBOM package analysis and vulnerability scanning capabilities" weight = 300 type = "docs" +menu_group = "other" +++ ## Package analysis diff --git a/content/docs/capabilities/snap.md b/content/docs/capabilities/snap.md index 1d0dddb8..84f846d2 100644 --- a/content/docs/capabilities/snap.md +++ b/content/docs/capabilities/snap.md @@ -3,6 +3,7 @@ title = "Snap" description = "Snap package analysis and vulnerability scanning capabilities" weight = 310 type = "docs" +menu_group = "other" +++ ## Package analysis diff --git a/content/docs/capabilities/snippets/ecosystem/alpm/os.md b/content/docs/capabilities/snippets/ecosystem/alpm/os.md index c1522d93..33d5176f 100644 --- a/content/docs/capabilities/snippets/ecosystem/alpm/os.md +++ b/content/docs/capabilities/snippets/ecosystem/alpm/os.md @@ -1,20 +1,21 @@ + - - - - + + + + - + diff --git a/content/docs/capabilities/snippets/ecosystem/alpm/package.md b/content/docs/capabilities/snippets/ecosystem/alpm/package.md index 7344764c..9433d945 100644 --- a/content/docs/capabilities/snippets/ecosystem/alpm/package.md +++ b/content/docs/capabilities/snippets/ecosystem/alpm/package.md @@ -1,33 +1,34 @@ +
Operating System Supported Versions Provider Data Source Operating SystemSupported VersionsProviderData Source
Arch Linux minimal support (CPE-based)nvdnvd National Vulnerability Database (NVD)
- - - - + + + + - - - - - - + + + + + + - - - - - + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/alpm/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/alpm/vulnerability.md index 4c362677..a616d352 100644 --- a/content/docs/capabilities/snippets/ecosystem/alpm/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/alpm/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
alpm-db-cataloger
var/lib/pacman/local/**/desc
transitivecompleteruntimeTransitiveCompleteRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/apk/os.md b/content/docs/capabilities/snippets/ecosystem/apk/os.md index 5ddbba5b..4735323a 100644 --- a/content/docs/capabilities/snippets/ecosystem/apk/os.md +++ b/content/docs/capabilities/snippets/ecosystem/apk/os.md @@ -1,38 +1,39 @@ +
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - - - + + + + - - + + - - + + - - + + - - + + diff --git a/content/docs/capabilities/snippets/ecosystem/apk/package.md b/content/docs/capabilities/snippets/ecosystem/apk/package.md index 5786f479..b980042b 100644 --- a/content/docs/capabilities/snippets/ecosystem/apk/package.md +++ b/content/docs/capabilities/snippets/ecosystem/apk/package.md @@ -1,34 +1,35 @@ +
Operating System Supported Versions Provider Data Source Operating SystemSupported VersionsProviderData Source
Alpine Linux3.2+, edgealpine3.2+, edgealpine Alpine SecDB
Chainguard OSrollingchainguardrollingchainguard Chainguard Security
MinimOSrollingminimosrollingminimos MINIMOS Security
Wolfirollingwolfirollingwolfi Wolfi Security
- - - - + + + + - - - - - - + + + + + + - - - - - - + + + + + +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
apk-db-cataloger
lib/apk/db/installed
directcompleteruntimeTransitiveCompleteRuntime
diff --git a/content/docs/capabilities/snippets/ecosystem/apk/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/apk/vulnerability.md index 6f190458..5af9f97f 100644 --- a/content/docs/capabilities/snippets/ecosystem/apk/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/apk/vulnerability.md @@ -1,19 +1,20 @@ + - - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/binary/binary-package-details.md b/content/docs/capabilities/snippets/ecosystem/binary/binary-package-details.md new file mode 100644 index 00000000..84b0d894 --- /dev/null +++ b/content/docs/capabilities/snippets/ecosystem/binary/binary-package-details.md @@ -0,0 +1,360 @@ + + + + + +
Binary Package Details
+
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ClassCriteriaPURLCPEs
arangodb-binaryarangoshpkg:generic/arangodbcpe:2.3:a:arangodb:arangodb:*:*:*:*:*:*:*:*
bash-binarybashpkg:generic/bashcpe:2.3:a:gnu:bash:*:*:*:*:*:*:*:*
busybox-binarybusyboxpkg:generic/busyboxcpe:2.3:a:busybox:busybox:*:*:*:*:*:*:*:*
chrome-binarychromepkg:generic/chromecpe:2.3:a:google:chrome:*:*:*:*:*:*:*:*
consul-binaryconsulpkg:golang/github.com/hashicorp/consulcpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*
curl-binarycurlpkg:generic/curlcpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*
dart-binarydartpkg:generic/dartcpe:2.3:a:dart:dart_software_development_kit:*:*:*:*:*:*:*:*
erlang-alpine-binarybeam.smppkg:generic/erlangcpe:2.3:a:erlang:erlang/otp:*:*:*:*:*:*:*:*
erlang-binaryerlexecpkg:generic/erlangcpe:2.3:a:erlang:erlang/otp:*:*:*:*:*:*:*:*
erlang-libraryliberts_internal.apkg:generic/erlangcpe:2.3:a:erlang:erlang/otp:*:*:*:*:*:*:*:*
ffmpeg-binaryffmpegpkg:generic/ffmpegcpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*
ffmpeg-librarylibav*pkg:generic/ffmpegcpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*
ffmpeg-librarylibswresample*pkg:generic/ffmpegcpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*
fluent-bit-binaryfluent-bitpkg:github/fluent/fluent-bitcpe:2.3:a:treasuredata:fluent_bit:*:*:*:*:*:*:*:*
gcc-binarygccpkg:generic/gcccpe:2.3:a:gnu:gcc:*:*:*:*:*:*:*:*
go-binarygopkg:generic/gocpe:2.3:a:golang:go:*:*:*:*:*:*:*:*
go-binary-hintVERSION*pkg:generic/gocpe:2.3:a:golang:go:*:*:*:*:*:*:*:*
gzip-binarygzippkg:generic/gzipcpe:2.3:a:gnu:gzip:*:*:*:*:*:*:*:*
haproxy-binaryhaproxypkg:generic/haproxycpe:2.3:a:haproxy:haproxy:*:*:*:*:*:*:*:*
hashicorp-vault-binaryvaultpkg:golang/github.com/hashicorp/vaultcpe:2.3:a:hashicorp:vault:*:*:*:*:*:*:*:*
haskell-cabal-binarycabalpkg:generic/haskell/cabalcpe:2.3:a:haskell:cabal:*:*:*:*:*:*:*:*
haskell-ghc-binaryghc*pkg:generic/haskell/ghccpe:2.3:a:haskell:ghc:*:*:*:*:*:*:*:*
haskell-stack-binarystackpkg:generic/haskell/stackcpe:2.3:a:haskell:stack:*:*:*:*:*:*:*:*
helmhelmpkg:golang/helm.sh/helmcpe:2.3:a:helm:helm:*:*:*:*:*:*:*:*
httpd-binaryhttpdpkg:generic/httpdcpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*
java-binaryjavapkg:/-
java-jdb-binaryjdbpkg:/-
jq-binaryjqpkg:generic/jqcpe:2.3:a:jqlang:jq:*:*:*:*:*:*:*:*
julia-binarylibjulia-internal.sopkg:generic/juliacpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*
lighttpd-binarylighttpdpkg:generic/lighttpdcpe:2.3:a:lighttpd:lighttpd:*:*:*:*:*:*:*:*
mariadb-binary{mariadb,mysql}pkg:generic/mariadbcpe:2.3:a:mariadb:mariadb:*:*:*:*:*:*:*:*
memcached-binarymemcachedpkg:generic/memcachedcpe:2.3:a:memcached:memcached:*:*:*:*:*:*:*:*
mysql-binarymysqlpkg:generic/mysqlcpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*
mysql-binarymysqlpkg:generic/percona-servercpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*
cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*
mysql-binarymysqlpkg:generic/percona-xtradb-clustercpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*
cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*
cpe:2.3:a:percona:xtradb_cluster:*:*:*:*:*:*:*:*
nginx-binarynginxpkg:generic/nginxcpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*
cpe:2.3:a:nginx:nginx:*:*:*:*:*:*:*:*
nodejs-binarynodepkg:generic/nodecpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*
openssl-binaryopensslpkg:generic/opensslcpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*
perl-binaryperlpkg:generic/perlcpe:2.3:a:perl:perl:*:*:*:*:*:*:*:*
php-composer-binarycomposer*pkg:generic/composercpe:2.3:a:getcomposer:composer:*:*:*:*:*:*:*:*
postgresql-binarypostgrespkg:generic/postgresqlcpe:2.3:a:postgresql:postgresql:*:*:*:*:*:*:*:*
proftpd-binaryproftpdpkg:generic/proftpdcpe:2.3:a:proftpd:proftpd:*:*:*:*:*:*:*:*
pypy-binary-liblibpypy*.so*pkg:generic/pypy-
python-binarypython*pkg:generic/pythoncpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*
cpe:2.3:a:python:python:*:*:*:*:*:*:*:*
python-binary-liblibpython*.so*pkg:generic/pythoncpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*
cpe:2.3:a:python:python:*:*:*:*:*:*:*:*
redis-binaryredis-serverpkg:generic/rediscpe:2.3:a:redislabs:redis:*:*:*:*:*:*:*:*
cpe:2.3:a:redis:redis:*:*:*:*:*:*:*:*
ruby-binaryrubypkg:generic/rubycpe:2.3:a:ruby-lang:ruby:*:*:*:*:*:*:*:*
rust-standard-library-linuxlibstd-????????????????.sopkg:generic/rustcpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*
rust-standard-library-macoslibstd-????????????????.dylibpkg:generic/rustcpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*
sqlcipher-binarysqlcipherpkg:generic/sqlciphercpe:2.3:a:zetetic:sqlcipher:*:*:*:*:*:*:*:*
swipl-binaryswiplpkg:generic/swiplcpe:2.3:a:erlang:erlang/otp:*:*:*:*:*:*:*:*
traefik-binarytraefikpkg:generic/traefikcpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*
util-linux-binarygetoptpkg:generic/util-linuxcpe:2.3:a:kernel:util-linux:*:*:*:*:*:*:*:*
wordpress-cli-binarywppkg:generic/wp-clicpe:2.3:a:wp-cli:wp-cli:*:*:*:*:*:*:*:*
xtrabackup-binaryxtrabackuppkg:generic/percona-xtrabackupcpe:2.3:a:percona:xtrabackup:*:*:*:*:*:*:*:*
xz-binaryxzpkg:generic/xzcpe:2.3:a:tukaani:xz:*:*:*:*:*:*:*:*
zstd-binaryzstdpkg:generic/zstdcpe:2.3:a:facebook:zstandard:*:*:*:*:*:*:*:*
diff --git a/content/docs/capabilities/snippets/ecosystem/binary/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/binary/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/binary/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/binary/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/binary/package.md b/content/docs/capabilities/snippets/ecosystem/binary/package.md index aa196a18..5a8367d1 100644 --- a/content/docs/capabilities/snippets/ecosystem/binary/package.md +++ b/content/docs/capabilities/snippets/ecosystem/binary/package.md @@ -1,27 +1,28 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + diff --git a/content/docs/capabilities/snippets/ecosystem/binary/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/binary/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/binary/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/binary/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
binary-classifier-cataloger
arangodb-binaryarangosh bash-binarybash busybox-binarybusybox chrome-binarychrome consul-binaryconsul curl-binarycurl dart-binarydart erlang-alpine-binarybeam.smp erlang-binaryerlexec erlang-libraryliberts_internal.a ffmpeg-binaryffmpeg ffmpeg-librarylibav*, libswresample* fluent-bit-binaryfluent-bit gcc-binarygcc go-binarygo go-binary-hintVERSION* gzip-binarygzip haproxy-binaryhaproxy hashicorp-vault-binaryvault haskell-cabal-binarycabal haskell-ghc-binaryghc* haskell-stack-binarystack helmhelm httpd-binaryhttpd java-binaryjava java-jdb-binaryjdb jq-binaryjq julia-binarylibjulia-internal.so lighttpd-binarylighttpd mariadb-binary{mariadb,mysql} memcached-binarymemcached mysql-binarymysql nginx-binarynginx nodejs-binarynode openssl-binaryopenssl perl-binaryperl php-composer-binarycomposer* postgresql-binarypostgres proftpd-binaryproftpd pypy-binary-liblibpypy*.so* python-binarypython* python-binary-liblibpython*.so* redis-binaryredis-server ruby-binaryruby rust-standard-library-linuxlibstd-????????????????.so rust-standard-library-macoslibstd-????????????????.dylib sqlcipher-binarysqlcipher swipl-binaryswipl traefik-binarytraefik util-linux-binarygetopt wordpress-cli-binarywp xtrabackup-binaryxtrabackup xz-binaryxz zstd-binaryzstd
binary-classifier-cataloger
(see table below)
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/bitnami/package.md b/content/docs/capabilities/snippets/ecosystem/bitnami/package.md index 0be88c4c..9042695e 100644 --- a/content/docs/capabilities/snippets/ecosystem/bitnami/package.md +++ b/content/docs/capabilities/snippets/ecosystem/bitnami/package.md @@ -1,32 +1,33 @@ +
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - - - + + + + - - - - - - + + + + + + - - - - - + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/bitnami/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/bitnami/vulnerability.md index e10ecc9b..8cab8f96 100644 --- a/content/docs/capabilities/snippets/ecosystem/bitnami/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/bitnami/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
bitnami-cataloger
/opt/bitnami/**/.spdx-*.spdx
transitivecompleteruntimeTransitiveCompleteRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/c++/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/c++/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/c++/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/c++/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/c++/package.md b/content/docs/capabilities/snippets/ecosystem/c++/package.md index 5f244414..4e924c55 100644 --- a/content/docs/capabilities/snippets/ecosystem/c++/package.md +++ b/content/docs/capabilities/snippets/ecosystem/c++/package.md @@ -1,41 +1,42 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + - + - + - + @@ -43,9 +44,9 @@ - - - + + + diff --git a/content/docs/capabilities/snippets/ecosystem/c++/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/c++/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/c++/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/c++/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
conan-cataloger
conan.lock
transitiveTransitive runtime, buildRuntime, Build
conan-cataloger
conanfile.txt
directDirect runtimeRuntime
conan-info-cataloger
conaninfo.txt
directflatruntimeDirectFlatRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/conda/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/conda/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/conda/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/conda/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/conda/package.md b/content/docs/capabilities/snippets/ecosystem/conda/package.md index 5e94acf0..dfd2dc81 100644 --- a/content/docs/capabilities/snippets/ecosystem/conda/package.md +++ b/content/docs/capabilities/snippets/ecosystem/conda/package.md @@ -1,34 +1,35 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - - - - + + + +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
conda-meta-cataloger
conda-meta/*.json
directDirect runtimeRuntime
diff --git a/content/docs/capabilities/snippets/ecosystem/conda/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/conda/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/conda/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/conda/vulnerability.md @@ -1,19 +1,20 @@ + - - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/dart/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/dart/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/dart/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/dart/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/dart/package.md b/content/docs/capabilities/snippets/ecosystem/dart/package.md index ecb6cd1e..a83b8aec 100644 --- a/content/docs/capabilities/snippets/ecosystem/dart/package.md +++ b/content/docs/capabilities/snippets/ecosystem/dart/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + @@ -33,9 +34,9 @@ - + - + diff --git a/content/docs/capabilities/snippets/ecosystem/dart/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/dart/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/dart/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/dart/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
dart-pubspec-cataloger
pubspec.yml, pubspec.yaml
directDirect runtimeRuntime
dart-pubspec-lock-cataloger
pubspec.lock
transitiveTransitive runtime, devRuntime, Dev
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/dotnet/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/dotnet/grype-app-config.md index 124bbd17..e9f37980 100644 --- a/content/docs/capabilities/snippets/ecosystem/dotnet/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/dotnet/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/dotnet/package.md b/content/docs/capabilities/snippets/ecosystem/dotnet/package.md index 44e7a67b..d3aac589 100644 --- a/content/docs/capabilities/snippets/ecosystem/dotnet/package.md +++ b/content/docs/capabilities/snippets/ecosystem/dotnet/package.md @@ -1,41 +1,42 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - - - + + + - + - - - + + + @@ -43,15 +44,15 @@ - - - + + + - + - + diff --git a/content/docs/capabilities/snippets/ecosystem/dotnet/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/dotnet/syft-app-config.md index db16b99a..3ba95eb4 100644 --- a/content/docs/capabilities/snippets/ecosystem/dotnet/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/dotnet/syft-app-config.md @@ -1,13 +1,14 @@ +
Syft Configuration
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
dotnet-deps-binary-cataloger
*.deps.json, *.dll, *.exe
transitivecompleteruntimeTransitiveCompleteRuntime
dotnet-deps-cataloger
*.deps.json
dotnet-deps-cataloger deprecated
*.deps.json
transitivecompleteruntimeTransitiveCompleteRuntime
dotnet-packages-lock-cataloger
packages.lock.json
transitivecompleteruntime, dev, buildTransitiveCompleteRuntime, Dev, Build
dotnet-portable-executable-cataloger
*.dll, *.exe
dotnet-portable-executable-cataloger deprecated
*.dll, *.exe
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/dotnet/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/dotnet/vulnerability.md index 67082dd7..3efca18f 100644 --- a/content/docs/capabilities/snippets/ecosystem/dotnet/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/dotnet/vulnerability.md @@ -1,19 +1,20 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/dpkg/os.md b/content/docs/capabilities/snippets/ecosystem/dpkg/os.md index 961c0a2a..a2d2d64e 100644 --- a/content/docs/capabilities/snippets/ecosystem/dpkg/os.md +++ b/content/docs/capabilities/snippets/ecosystem/dpkg/os.md @@ -1,38 +1,39 @@ +
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - - - + + + + - - + + - - + + - - + + - - + + diff --git a/content/docs/capabilities/snippets/ecosystem/dpkg/package.md b/content/docs/capabilities/snippets/ecosystem/dpkg/package.md index 96933a97..c4d661d7 100644 --- a/content/docs/capabilities/snippets/ecosystem/dpkg/package.md +++ b/content/docs/capabilities/snippets/ecosystem/dpkg/package.md @@ -1,22 +1,23 @@ +
Operating System Supported Versions Provider Data Source Operating SystemSupported VersionsProviderData Source
Debian7 (wheezy), 8 (jessie), 9 (stretch), 10 (buster), 11 (bullseye), 12 (bookworm), 13 (trixie), 14, unstabledebian7 (wheezy), 8 (jessie), 9 (stretch), 10 (buster), 11 (bullseye), 12 (bookworm), 13 (trixie), 14, unstabledebian Debian Security Tracker
Echo OSrollingechorollingecho ECHO Security
Raspberry Pi OS7 (wheezy), 8 (jessie), 9 (stretch), 10 (buster), 11 (bullseye), 12 (bookworm), 13 (trixie), 14, unstabledebian7 (wheezy), 8 (jessie), 9 (stretch), 10 (buster), 11 (bullseye), 12 (bookworm), 13 (trixie), 14, unstabledebian Debian Security Tracker
Ubuntu12.04 (precise), 12.10 (quantal), 13.04 (raring), 14.04 (trusty), 14.10 (utopic), 15.04 (vivid), 15.10 (wily), 16.04 (xenial), 16.10 (yakkety), 17.04 (zesty), 17.10 (artful), 18.04 (bionic), 18.10 (cosmic), 19.04 (disco), 19.10 (eoan), 20.04 (focal), 20.10 (groovy), 21.04 (hirsute), 21.10 (impish), 22.04 (jammy), 22.10 (kinetic), 23.04 (lunar), 23.10 (mantic), 24.04 (noble), 24.10 (oracular), 25.04 (plucky), 25.10ubuntu12.04 (precise), 12.10 (quantal), 13.04 (raring), 14.04 (trusty), 14.10 (utopic), 15.04 (vivid), 15.10 (wily), 16.04 (xenial), 16.10 (yakkety), 17.04 (zesty), 17.10 (artful), 18.04 (bionic), 18.10 (cosmic), 19.04 (disco), 19.10 (eoan), 20.04 (focal), 20.10 (groovy), 21.04 (hirsute), 21.10 (impish), 22.04 (jammy), 22.10 (kinetic), 23.04 (lunar), 23.10 (mantic), 24.04 (noble), 24.10 (oracular), 25.04 (plucky), 25.10ubuntu Ubuntu CVE Tracker
- - - - + + + + - - - - - - + + + + + + @@ -26,18 +27,18 @@ - - + + - - - - - + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/dpkg/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/dpkg/vulnerability.md index 6c60afed..d4cf31a4 100644 --- a/content/docs/capabilities/snippets/ecosystem/dpkg/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/dpkg/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
dpkg-db-cataloger
lib/dpkg/status, lib/dpkg/status.d/*, lib/opkg/info/*.control, lib/opkg/status
transitivecompleteruntimeTransitiveCompleteRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/elixir/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/elixir/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/elixir/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/elixir/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/elixir/package.md b/content/docs/capabilities/snippets/ecosystem/elixir/package.md index c949540e..fab38d61 100644 --- a/content/docs/capabilities/snippets/ecosystem/elixir/package.md +++ b/content/docs/capabilities/snippets/ecosystem/elixir/package.md @@ -1,34 +1,35 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + - +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
elixir-mix-lock-cataloger
mix.lock
transitiveTransitive runtime, devRuntime, Dev
diff --git a/content/docs/capabilities/snippets/ecosystem/elixir/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/elixir/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/elixir/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/elixir/vulnerability.md @@ -1,19 +1,20 @@ + - - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/erlang/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/erlang/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/erlang/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/erlang/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/erlang/package.md b/content/docs/capabilities/snippets/ecosystem/erlang/package.md index 39985e2e..734ebc8d 100644 --- a/content/docs/capabilities/snippets/ecosystem/erlang/package.md +++ b/content/docs/capabilities/snippets/ecosystem/erlang/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + @@ -33,12 +34,12 @@ - + - + - +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
erlang-otp-application-cataloger
*.app
directDirect runtime, devRuntime, Dev
erlang-rebar-lock-cataloger
rebar.lock
directDirect runtime, devRuntime, Dev
diff --git a/content/docs/capabilities/snippets/ecosystem/erlang/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/erlang/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/erlang/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/erlang/vulnerability.md @@ -1,19 +1,20 @@ + - - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/github-actions/package.md b/content/docs/capabilities/snippets/ecosystem/github-actions/package.md index 15d9b67b..78cb0ea5 100644 --- a/content/docs/capabilities/snippets/ecosystem/github-actions/package.md +++ b/content/docs/capabilities/snippets/ecosystem/github-actions/package.md @@ -1,22 +1,23 @@ +
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - - - + + + + - - - - - - + + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/github-actions/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/github-actions/vulnerability.md index a9a384e6..1882f8cd 100644 --- a/content/docs/capabilities/snippets/ecosystem/github-actions/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/github-actions/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/go/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/go/grype-app-config.md index 6d3cc030..8c977595 100644 --- a/content/docs/capabilities/snippets/ecosystem/go/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/go/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/go/package.md b/content/docs/capabilities/snippets/ecosystem/go/package.md index 5fd94fab..45dd3003 100644 --- a/content/docs/capabilities/snippets/ecosystem/go/package.md +++ b/content/docs/capabilities/snippets/ecosystem/go/package.md @@ -1,44 +1,45 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - - - - + + + + - + - - - - + + + + - +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
go-module-binary-cataloger
application/x-executable, application/x-mach-binary, application/x-elf, application/x-sharedlib, application/vnd.microsoft.portable-executable, application/x-executable (mimetype)
transitiveflatruntime, devTransitiveFlatRuntime, Dev
go-module-file-cataloger
go.mod
transitiveflatruntime, devTransitiveFlatRuntime, Dev
diff --git a/content/docs/capabilities/snippets/ecosystem/go/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/go/syft-app-config.md index 3dfed429..931dca57 100644 --- a/content/docs/capabilities/snippets/ecosystem/go/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/go/syft-app-config.md @@ -1,13 +1,14 @@ +
Syft Configuration
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/go/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/go/vulnerability.md index 67082dd7..3efca18f 100644 --- a/content/docs/capabilities/snippets/ecosystem/go/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/go/vulnerability.md @@ -1,19 +1,20 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/haskell/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/haskell/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/haskell/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/haskell/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/haskell/package.md b/content/docs/capabilities/snippets/ecosystem/haskell/package.md index c9a98b60..d6805dd2 100644 --- a/content/docs/capabilities/snippets/ecosystem/haskell/package.md +++ b/content/docs/capabilities/snippets/ecosystem/haskell/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + @@ -33,22 +34,22 @@ - + - + - + - + - + - +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
haskell-cataloger
cabal.project.freeze
transitiveTransitive runtime, devRuntime, Dev
haskell-cataloger
stack.yaml.lock
transitiveTransitive runtime, devRuntime, Dev
haskell-cataloger
stack.yaml
directDirect runtime, devRuntime, Dev
diff --git a/content/docs/capabilities/snippets/ecosystem/haskell/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/haskell/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/haskell/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/haskell/vulnerability.md @@ -1,19 +1,20 @@ + - - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/homebrew/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/homebrew/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/homebrew/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/homebrew/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/homebrew/package.md b/content/docs/capabilities/snippets/ecosystem/homebrew/package.md index 6fb9dfe2..39cf88fe 100644 --- a/content/docs/capabilities/snippets/ecosystem/homebrew/package.md +++ b/content/docs/capabilities/snippets/ecosystem/homebrew/package.md @@ -1,22 +1,23 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/homebrew/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/homebrew/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/homebrew/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/homebrew/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/java/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/java/grype-app-config.md index 713f1613..17af43d8 100644 --- a/content/docs/capabilities/snippets/ecosystem/java/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/java/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/java/package.md b/content/docs/capabilities/snippets/ecosystem/java/package.md index aa55ae26..277e013b 100644 --- a/content/docs/capabilities/snippets/ecosystem/java/package.md +++ b/content/docs/capabilities/snippets/ecosystem/java/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - - - + + + @@ -33,39 +34,39 @@ - - - + + + - + - + - - - + + + - + - + - - - + + + - + - + - + @@ -73,19 +74,19 @@ - + - - + + - - - + + + diff --git a/content/docs/capabilities/snippets/ecosystem/java/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/java/syft-app-config.md index fa78dbca..a9461f0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/java/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/java/syft-app-config.md @@ -1,13 +1,14 @@ +
Syft Configuration
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
graalvm-native-image-cataloger
application/x-executable, application/x-mach-binary, application/x-elf, application/x-sharedlib, application/vnd.microsoft.portable-executable (mimetype)
transitivecompleteruntime, devTransitiveCompleteRuntime, Dev
java-archive-cataloger
*.jar, *.war, *.ear, *.par, *.sar, *.nar, *.jpi, *.hpi, *.kar, *.lpkg
transitivecompleteruntime, devTransitiveCompleteRuntime, Dev
java-archive-cataloger
*.zip
java-archive-cataloger
*.zip
transitivecompleteruntime, devTransitiveCompleteRuntime, Dev
java-archive-cataloger
*.tar, *.tar.gz, *.tgz, *.tar.bz, *.tar.bz2, *.tbz, *.tbz2, *.tar.br, *.tbr, *.tar.lz4, *.tlz4, *.tar.sz, *.tsz, *.tar.xz, *.txz, *.tar.zst, *.tzst, *.tar.zstd, *.tzstd
java-archive-cataloger
*.tar, *.tar.gz, *.tgz, *.tar.bz, *.tar.bz2, *.tbz, *.tbz2, *.tar.br, *.tbr, *.tar.lz4, *.tlz4, *.tar.sz, *.tsz, *.tar.xz, *.txz, *.tar.zst, *.tzst, *.tar.zstd, *.tzstd
transitivecompleteruntime, devTransitiveCompleteRuntime, Dev
java-gradle-lockfile-cataloger
gradle.lockfile*
transitiveTransitive runtime, devRuntime, Dev
java-jvm-cataloger
release
transitiveTransitive runtime, devRuntime, Dev
java-pom-cataloger
*pom.xml
directcompleteruntime, devDirectCompleteRuntime, Dev
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/java/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/java/vulnerability.md index 67082dd7..3efca18f 100644 --- a/content/docs/capabilities/snippets/ecosystem/java/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/java/vulnerability.md @@ -1,19 +1,20 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/javascript/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/javascript/grype-app-config.md index bcc84a35..18c7fadd 100644 --- a/content/docs/capabilities/snippets/ecosystem/javascript/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/javascript/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/javascript/package.md b/content/docs/capabilities/snippets/ecosystem/javascript/package.md index 20e4a294..e7e2353c 100644 --- a/content/docs/capabilities/snippets/ecosystem/javascript/package.md +++ b/content/docs/capabilities/snippets/ecosystem/javascript/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + @@ -33,29 +34,29 @@ - + - + - + - + - + - + - + - + diff --git a/content/docs/capabilities/snippets/ecosystem/javascript/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/javascript/syft-app-config.md index c4ca2067..117c4776 100644 --- a/content/docs/capabilities/snippets/ecosystem/javascript/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/javascript/syft-app-config.md @@ -1,13 +1,14 @@ +
Syft Configuration
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
javascript-lock-cataloger
pnpm-lock.yaml
transitiveTransitive runtimeRuntime
javascript-lock-cataloger
yarn.lock
transitiveTransitive runtime, devRuntime, Dev
javascript-lock-cataloger
package-lock.json
transitiveTransitive runtimeRuntime
javascript-package-cataloger
package.json
directDirect runtimeRuntime
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/javascript/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/javascript/vulnerability.md index 67082dd7..3efca18f 100644 --- a/content/docs/capabilities/snippets/ecosystem/javascript/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/javascript/vulnerability.md @@ -1,19 +1,20 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/linux/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/linux/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/linux/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/linux/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/linux/package.md b/content/docs/capabilities/snippets/ecosystem/linux/package.md index 8ab3207f..11aa9a7c 100644 --- a/content/docs/capabilities/snippets/ecosystem/linux/package.md +++ b/content/docs/capabilities/snippets/ecosystem/linux/package.md @@ -1,22 +1,23 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/linux/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/linux/syft-app-config.md index 25c1526d..1d0585f1 100644 --- a/content/docs/capabilities/snippets/ecosystem/linux/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/linux/syft-app-config.md @@ -1,13 +1,14 @@ +
Syft Configuration
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/linux/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/linux/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/linux/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/linux/vulnerability.md @@ -1,19 +1,20 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/lua/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/lua/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/lua/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/lua/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/lua/package.md b/content/docs/capabilities/snippets/ecosystem/lua/package.md index 4115cf3c..62573cfc 100644 --- a/content/docs/capabilities/snippets/ecosystem/lua/package.md +++ b/content/docs/capabilities/snippets/ecosystem/lua/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + diff --git a/content/docs/capabilities/snippets/ecosystem/lua/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/lua/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/lua/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/lua/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
lua-rock-cataloger
*.rockspec
directDirect runtimeRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/nix/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/nix/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/nix/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/nix/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/nix/package.md b/content/docs/capabilities/snippets/ecosystem/nix/package.md index b4c02706..524426f1 100644 --- a/content/docs/capabilities/snippets/ecosystem/nix/package.md +++ b/content/docs/capabilities/snippets/ecosystem/nix/package.md @@ -1,44 +1,45 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - - - + + + - + - + - - - - + + + + - +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
nix-cataloger
nix/var/nix/db/db.sqlite, nix/store/*, nix/store/*.drv
transitivecompleteruntimeTransitiveCompleteRuntime
nix-store-cataloger
nix/store/*, nix/store/*.drv
nix-store-cataloger deprecated
nix/store/*, nix/store/*.drv
transitivecompleteruntimeTransitiveCompleteRuntime
diff --git a/content/docs/capabilities/snippets/ecosystem/nix/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/nix/syft-app-config.md index 9639e5ba..b3a1d3bd 100644 --- a/content/docs/capabilities/snippets/ecosystem/nix/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/nix/syft-app-config.md @@ -1,13 +1,14 @@ +
Syft Configuration
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/nix/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/nix/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/nix/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/nix/vulnerability.md @@ -1,19 +1,20 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/ocaml/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/ocaml/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/ocaml/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/ocaml/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/ocaml/package.md b/content/docs/capabilities/snippets/ecosystem/ocaml/package.md index ee1799a9..025f701a 100644 --- a/content/docs/capabilities/snippets/ecosystem/ocaml/package.md +++ b/content/docs/capabilities/snippets/ecosystem/ocaml/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + diff --git a/content/docs/capabilities/snippets/ecosystem/ocaml/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/ocaml/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/ocaml/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/ocaml/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
opam-cataloger
*opam
directDirect runtimeRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/php/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/php/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/php/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/php/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/php/package.md b/content/docs/capabilities/snippets/ecosystem/php/package.md index 9c924b75..4d7c0de1 100644 --- a/content/docs/capabilities/snippets/ecosystem/php/package.md +++ b/content/docs/capabilities/snippets/ecosystem/php/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + @@ -33,9 +34,9 @@ - + - + @@ -43,9 +44,9 @@ - - - + + + @@ -53,19 +54,19 @@ - + - + - + - + - + diff --git a/content/docs/capabilities/snippets/ecosystem/php/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/php/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/php/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/php/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
php-composer-installed-cataloger
installed.json
transitiveTransitive runtime, devRuntime, Dev
php-composer-lock-cataloger
composer.lock
transitiveTransitive runtimeRuntime
php-interpreter-cataloger
php*/**/*.so, php-fpm*, apache*/**/libphp*.so
directflatruntimeDirectFlatRuntime
php-pear-serialized-cataloger
php/.registry/**/*.reg
directDirect runtimeRuntime
php-pecl-serialized-cataloger
php/.registry/.channel.*/*.reg
php-pecl-serialized-cataloger deprecated
php/.registry/.channel.*/*.reg
directDirect runtimeRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/portage/os.md b/content/docs/capabilities/snippets/ecosystem/portage/os.md index b6657c9f..82b5f778 100644 --- a/content/docs/capabilities/snippets/ecosystem/portage/os.md +++ b/content/docs/capabilities/snippets/ecosystem/portage/os.md @@ -1,20 +1,21 @@ +
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - - - + + + + - + diff --git a/content/docs/capabilities/snippets/ecosystem/portage/package.md b/content/docs/capabilities/snippets/ecosystem/portage/package.md index 41ae5cb8..5f359d04 100644 --- a/content/docs/capabilities/snippets/ecosystem/portage/package.md +++ b/content/docs/capabilities/snippets/ecosystem/portage/package.md @@ -1,33 +1,34 @@ +
Operating System Supported Versions Provider Data Source Operating SystemSupported VersionsProviderData Source
Gentoo Linux minimal support (CPE-based)nvdnvd National Vulnerability Database (NVD)
- - - - + + + + - - - - - - + + + + + + - + - - - + + + diff --git a/content/docs/capabilities/snippets/ecosystem/portage/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/portage/vulnerability.md index 4c362677..a616d352 100644 --- a/content/docs/capabilities/snippets/ecosystem/portage/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/portage/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
portage-cataloger
var/db/pkg/*/*/CONTENTS
directDirect runtimeRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/prolog/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/prolog/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/prolog/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/prolog/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/prolog/package.md b/content/docs/capabilities/snippets/ecosystem/prolog/package.md index 60a9be31..4facf524 100644 --- a/content/docs/capabilities/snippets/ecosystem/prolog/package.md +++ b/content/docs/capabilities/snippets/ecosystem/prolog/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + diff --git a/content/docs/capabilities/snippets/ecosystem/prolog/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/prolog/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/prolog/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/prolog/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
swipl-pack-cataloger
pack.pl
directDirect runtime, devRuntime, Dev
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/python/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/python/grype-app-config.md index 940dcfdd..2301e809 100644 --- a/content/docs/capabilities/snippets/ecosystem/python/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/python/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/python/package.md b/content/docs/capabilities/snippets/ecosystem/python/package.md index d4136fe4..7711ed5f 100644 --- a/content/docs/capabilities/snippets/ecosystem/python/package.md +++ b/content/docs/capabilities/snippets/ecosystem/python/package.md @@ -1,41 +1,42 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - - - - - + + + + + - - - + + + @@ -43,7 +44,7 @@ - + @@ -53,19 +54,19 @@ - + - + - + - - - + + + @@ -73,9 +74,9 @@ - + - + diff --git a/content/docs/capabilities/snippets/ecosystem/python/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/python/syft-app-config.md index 1657fc1a..7d9e4b40 100644 --- a/content/docs/capabilities/snippets/ecosystem/python/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/python/syft-app-config.md @@ -1,13 +1,14 @@ +
Syft Configuration
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
python-installed-package-cataloger
*.egg-info, *dist-info/METADATA, *egg-info/PKG-INFO, *DIST-INFO/METADATA, *EGG-INFO/PKG-INFO
directcompleteruntimeDirectCompleteRuntime
python-package-cataloger
uv.lock
transitivecompletedev, optionalTransitiveCompleteDev, Optional
python-package-cataloger
setup.py
directDirect
python-package-cataloger
Pipfile.lock
transitiveTransitive runtimeRuntime
python-package-cataloger
poetry.lock
transitivecompletedev, optionalTransitiveCompleteDev, Optional
python-package-cataloger
*requirements*.txt
Direct Any
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/python/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/python/vulnerability.md index 67082dd7..3efca18f 100644 --- a/content/docs/capabilities/snippets/ecosystem/python/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/python/vulnerability.md @@ -1,19 +1,20 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/r/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/r/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/r/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/r/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/r/package.md b/content/docs/capabilities/snippets/ecosystem/r/package.md index 35125c0e..b18d45fc 100644 --- a/content/docs/capabilities/snippets/ecosystem/r/package.md +++ b/content/docs/capabilities/snippets/ecosystem/r/package.md @@ -1,22 +1,23 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/r/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/r/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/r/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/r/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/rpm/os.md b/content/docs/capabilities/snippets/ecosystem/rpm/os.md index aa9eb9ec..7ffe0e77 100644 --- a/content/docs/capabilities/snippets/ecosystem/rpm/os.md +++ b/content/docs/capabilities/snippets/ecosystem/rpm/os.md @@ -1,62 +1,63 @@ +
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - - - + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/content/docs/capabilities/snippets/ecosystem/rpm/package.md b/content/docs/capabilities/snippets/ecosystem/rpm/package.md index 9cbf5ec1..32db8744 100644 --- a/content/docs/capabilities/snippets/ecosystem/rpm/package.md +++ b/content/docs/capabilities/snippets/ecosystem/rpm/package.md @@ -1,41 +1,42 @@ +
Operating System Supported Versions Provider Data Source Operating SystemSupported VersionsProviderData Source
Amazon Linux2, 2022, 2023amazon2, 2022, 2023amazon Amazon Linux Security Center
Azure Linux3.0mariner3.0mariner Microsoft CBL-Mariner OVAL
CentOS5, 6, 7, 8rhel5, 6, 7, 8rhel Red Hat Security Data API
CBL-Mariner1.0, 2.0mariner1.0, 2.0mariner Microsoft CBL-Mariner OVAL
Oracle Linux5, 6, 7, 8, 9, 10oracle5, 6, 7, 8, 9, 10oracle Oracle Linux Security
Red Hat Enterprise Linux5, 6, 7, 8, 9, 10
EUS: 5.9, 6.4+, 7, 8.1, 8.2, 8.4, 8.6, 8.8, 9
rhel5, 6, 7, 8, 9, 10
EUS: 5.9, 6.4+, 7, 8.1, 8.2, 8.4, 8.6, 8.8, 9
rhel Red Hat Security Data API
Rocky Linux5, 6, 7, 8, 9, 10rhel5, 6, 7, 8, 9, 10rhel Red Hat Security Data API
SUSE Linux Enterprise Server11, 12, 15sles11, 12, 15sles SUSE Security OVAL
- - - - + + + + - - - - - - + + + + + + - - - - - + + + + + - + - + @@ -43,11 +44,11 @@ - - - - - + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/rpm/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/rpm/vulnerability.md index 480c4fb8..25d4dea0 100644 --- a/content/docs/capabilities/snippets/ecosystem/rpm/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/rpm/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
rpm-archive-cataloger
*.rpm
directcompleteruntime
rpm-db-cataloger
var/lib/rpmmanifest/container-manifest-2
transitiveTransitive runtimeRuntime
rpm-db-cataloger
{var/lib,usr/share,usr/lib/sysimage}/rpm/{Packages,Packages.db,rpmdb.sqlite}
transitivecompleteruntimeTransitiveCompleteRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/ruby/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/ruby/grype-app-config.md index 83fecef0..5e66123b 100644 --- a/content/docs/capabilities/snippets/ecosystem/ruby/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/ruby/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/ruby/package.md b/content/docs/capabilities/snippets/ecosystem/ruby/package.md index d56e1780..32bc491f 100644 --- a/content/docs/capabilities/snippets/ecosystem/ruby/package.md +++ b/content/docs/capabilities/snippets/ecosystem/ruby/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + @@ -33,20 +34,20 @@ - + - - + + - + - - + + diff --git a/content/docs/capabilities/snippets/ecosystem/ruby/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/ruby/vulnerability.md index 67082dd7..3efca18f 100644 --- a/content/docs/capabilities/snippets/ecosystem/ruby/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/ruby/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
ruby-gemfile-cataloger
Gemfile.lock
transitiveTransitive runtime, devRuntime, Dev
ruby-gemspec-cataloger
*.gemspec
directDirect runtimeRuntime
ruby-installed-gemspec-cataloger
specifications/**/*.gemspec
transitiveTransitive runtimeRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/rust/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/rust/grype-app-config.md index 43ce3e2d..3fb3d874 100644 --- a/content/docs/capabilities/snippets/ecosystem/rust/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/rust/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/rust/package.md b/content/docs/capabilities/snippets/ecosystem/rust/package.md index 2a20df8f..30a3d6e1 100644 --- a/content/docs/capabilities/snippets/ecosystem/rust/package.md +++ b/content/docs/capabilities/snippets/ecosystem/rust/package.md @@ -1,31 +1,32 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - - - + + + @@ -33,12 +34,12 @@ - - - + + + - +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
cargo-auditable-binary-cataloger
application/x-executable, application/x-mach-binary, application/x-elf, application/x-sharedlib, application/vnd.microsoft.portable-executable, application/x-executable (mimetype)
transitivecompleteruntimeTransitiveCompleteRuntime
rust-cargo-lock-cataloger
Cargo.lock
transitivecompleteruntime, dev, buildTransitiveCompleteRuntime, Dev, Build
diff --git a/content/docs/capabilities/snippets/ecosystem/rust/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/rust/vulnerability.md index 67082dd7..3efca18f 100644 --- a/content/docs/capabilities/snippets/ecosystem/rust/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/rust/vulnerability.md @@ -1,19 +1,20 @@ + - - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/sbom/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/sbom/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/sbom/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/sbom/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/sbom/package.md b/content/docs/capabilities/snippets/ecosystem/sbom/package.md index 8c0fc694..4841d175 100644 --- a/content/docs/capabilities/snippets/ecosystem/sbom/package.md +++ b/content/docs/capabilities/snippets/ecosystem/sbom/package.md @@ -1,22 +1,23 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/sbom/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/sbom/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/sbom/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/sbom/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/snap/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/snap/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/snap/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/snap/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/snap/package.md b/content/docs/capabilities/snippets/ecosystem/snap/package.md index 180e2087..fa802ad6 100644 --- a/content/docs/capabilities/snippets/ecosystem/snap/package.md +++ b/content/docs/capabilities/snippets/ecosystem/snap/package.md @@ -1,22 +1,23 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/snap/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/snap/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/snap/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/snap/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/swift/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/swift/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/swift/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/swift/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/swift/package.md b/content/docs/capabilities/snippets/ecosystem/swift/package.md index e7b38802..71667262 100644 --- a/content/docs/capabilities/snippets/ecosystem/swift/package.md +++ b/content/docs/capabilities/snippets/ecosystem/swift/package.md @@ -1,41 +1,42 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + - + - + - + diff --git a/content/docs/capabilities/snippets/ecosystem/swift/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/swift/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/swift/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/swift/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
cocoapods-cataloger
Podfile.lock
transitiveTransitive runtimeRuntime
swift-package-manager-cataloger
Package.resolved, .package.resolved
transitiveTransitive runtimeRuntime
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/terraform/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/terraform/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/terraform/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/terraform/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/terraform/package.md b/content/docs/capabilities/snippets/ecosystem/terraform/package.md index 1a64c223..9464cd10 100644 --- a/content/docs/capabilities/snippets/ecosystem/terraform/package.md +++ b/content/docs/capabilities/snippets/ecosystem/terraform/package.md @@ -1,34 +1,35 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + - + - + - +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
terraform-lock-cataloger
.terraform.lock.hcl
directDirect runtimeRuntime
diff --git a/content/docs/capabilities/snippets/ecosystem/terraform/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/terraform/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/terraform/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/terraform/vulnerability.md @@ -1,19 +1,20 @@ + - - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/wordpress/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/wordpress/grype-app-config.md index 97783fe5..3a71cc0f 100644 --- a/content/docs/capabilities/snippets/ecosystem/wordpress/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/wordpress/grype-app-config.md @@ -1,12 +1,13 @@ +
Grype Configuration
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - + + diff --git a/content/docs/capabilities/snippets/ecosystem/wordpress/package.md b/content/docs/capabilities/snippets/ecosystem/wordpress/package.md index 09eb757c..fd7e43fb 100644 --- a/content/docs/capabilities/snippets/ecosystem/wordpress/package.md +++ b/content/docs/capabilities/snippets/ecosystem/wordpress/package.md @@ -1,22 +1,23 @@ +
Configuration Key Description Configuration KeyDescription
- - - - + + + + - - - - - - + + + + + + diff --git a/content/docs/capabilities/snippets/ecosystem/wordpress/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/wordpress/vulnerability.md index cf68404f..b276db76 100644 --- a/content/docs/capabilities/snippets/ecosystem/wordpress/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/wordpress/vulnerability.md @@ -1,19 +1,20 @@ +
Cataloger + Evidence License Dependencies Package Manager Claims Cataloger + EvidenceLicenseDependenciesPackage Manager Claims
Depth Edges Kinds Files Digests Integrity Hash DepthEdgesKindsFilesDigestsIntegrity Hash
- - - - + + + + - - - - + + + + diff --git a/content/docs/capabilities/snippets/overview/os.md b/content/docs/capabilities/snippets/overview/os.md index abefc0b7..f8077ffa 100644 --- a/content/docs/capabilities/snippets/overview/os.md +++ b/content/docs/capabilities/snippets/overview/os.md @@ -1,110 +1,111 @@ +
Data Source Disclosures Fixes Track by
Source
Package
Data SourceDisclosuresFixesTrack by
Source
Package
Affected Date Versions Date AffectedDateVersionsDate
- - - - + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + diff --git a/content/docs/capabilities/snippets/overview/package.md b/content/docs/capabilities/snippets/overview/package.md index 40276dab..42b38712 100644 --- a/content/docs/capabilities/snippets/overview/package.md +++ b/content/docs/capabilities/snippets/overview/package.md @@ -1,15 +1,16 @@ +
Operating System Supported Versions Vunnel Provider Data Source Operating SystemSupported VersionsVunnel ProviderData Source
Alpine Linux3.2+, edgealpine3.2+, edgealpine Alpine SecDB
Amazon Linux2, 2022, 2023amazon2, 2022, 2023amazon Amazon Linux Security Center
Azure Linux3.0mariner3.0mariner Microsoft CBL-Mariner OVAL
CentOS5, 6, 7, 8rhel5, 6, 7, 8rhel Red Hat Security Data API
Chainguard OSrollingchainguardrollingchainguard Chainguard Security
Debian7 (wheezy), 8 (jessie), 9 (stretch), 10 (buster), 11 (bullseye), 12 (bookworm), 13 (trixie), 14, unstabledebian7 (wheezy), 8 (jessie), 9 (stretch), 10 (buster), 11 (bullseye), 12 (bookworm), 13 (trixie), 14, unstabledebian Debian Security Tracker
Echo OSrollingechorollingecho ECHO Security
CBL-Mariner1.0, 2.0mariner1.0, 2.0mariner Microsoft CBL-Mariner OVAL
MinimOSrollingminimosrollingminimos MINIMOS Security
Oracle Linux5, 6, 7, 8, 9, 10oracle5, 6, 7, 8, 9, 10oracle Oracle Linux Security
Raspberry Pi OS7 (wheezy), 8 (jessie), 9 (stretch), 10 (buster), 11 (bullseye), 12 (bookworm), 13 (trixie), 14, unstabledebian7 (wheezy), 8 (jessie), 9 (stretch), 10 (buster), 11 (bullseye), 12 (bookworm), 13 (trixie), 14, unstabledebian Debian Security Tracker
Red Hat Enterprise Linux5, 6, 7, 8, 9, 10
EUS: 5.9, 6.4+, 7, 8.1, 8.2, 8.4, 8.6, 8.8, 9
rhel5, 6, 7, 8, 9, 10
EUS: 5.9, 6.4+, 7, 8.1, 8.2, 8.4, 8.6, 8.8, 9
rhel Red Hat Security Data API
Rocky Linux5, 6, 7, 8, 9, 10rhel5, 6, 7, 8, 9, 10rhel Red Hat Security Data API
SUSE Linux Enterprise Server11, 12, 15sles11, 12, 15sles SUSE Security OVAL
Ubuntu12.04 (precise), 12.10 (quantal), 13.04 (raring), 14.04 (trusty), 14.10 (utopic), 15.04 (vivid), 15.10 (wily), 16.04 (xenial), 16.10 (yakkety), 17.04 (zesty), 17.10 (artful), 18.04 (bionic), 18.10 (cosmic), 19.04 (disco), 19.10 (eoan), 20.04 (focal), 20.10 (groovy), 21.04 (hirsute), 21.10 (impish), 22.04 (jammy), 22.10 (kinetic), 23.04 (lunar), 23.10 (mantic), 24.04 (noble), 24.10 (oracular), 25.04 (plucky), 25.10ubuntu12.04 (precise), 12.10 (quantal), 13.04 (raring), 14.04 (trusty), 14.10 (utopic), 15.04 (vivid), 15.10 (wily), 16.04 (xenial), 16.10 (yakkety), 17.04 (zesty), 17.10 (artful), 18.04 (bionic), 18.10 (cosmic), 19.04 (disco), 19.10 (eoan), 20.04 (focal), 20.10 (groovy), 21.04 (hirsute), 21.10 (impish), 22.04 (jammy), 22.10 (kinetic), 23.04 (lunar), 23.10 (mantic), 24.04 (noble), 24.10 (oracular), 25.04 (plucky), 25.10ubuntu Ubuntu CVE Tracker
Wolfirollingwolfirollingwolfi Wolfi Security
- - - - - + + + + + @@ -18,14 +19,14 @@ - + - + @@ -49,9 +50,9 @@ - + - + @@ -77,7 +78,7 @@ - + @@ -97,13 +98,13 @@ - + - + @@ -147,13 +148,13 @@ - + - + @@ -197,13 +198,13 @@ - + - + @@ -218,7 +219,7 @@ - + @@ -273,7 +274,7 @@ - + @@ -285,7 +286,7 @@ - + @@ -298,10 +299,10 @@ - + - + @@ -336,7 +337,7 @@ - + @@ -346,7 +347,7 @@ - + @@ -360,7 +361,7 @@ - + @@ -389,7 +390,7 @@ - + @@ -403,8 +404,8 @@ - - + + @@ -416,7 +417,7 @@ - + @@ -429,13 +430,13 @@ - + - + diff --git a/content/docs/capabilities/swift.md b/content/docs/capabilities/swift.md index 75f36d77..96deaa0a 100644 --- a/content/docs/capabilities/swift.md +++ b/content/docs/capabilities/swift.md @@ -3,6 +3,7 @@ title = "Swift" description = "Swift package analysis and vulnerability scanning capabilities" weight = 320 type = "docs" +menu_group = "language" +++ ## Package analysis diff --git a/content/docs/capabilities/terraform.md b/content/docs/capabilities/terraform.md index 151ca4d7..f3436da1 100644 --- a/content/docs/capabilities/terraform.md +++ b/content/docs/capabilities/terraform.md @@ -3,6 +3,7 @@ title = "Terraform" description = "Terraform package analysis and vulnerability scanning capabilities" weight = 330 type = "docs" +menu_group = "other" +++ ## Package analysis diff --git a/content/docs/capabilities/wordpress.md b/content/docs/capabilities/wordpress.md index d7c32921..8bfbff4a 100644 --- a/content/docs/capabilities/wordpress.md +++ b/content/docs/capabilities/wordpress.md @@ -3,6 +3,7 @@ title = "Wordpress" description = "Wordpress package analysis and vulnerability scanning capabilities" weight = 340 type = "docs" +menu_group = "other" +++ ## Package analysis diff --git a/content/docs/guides/sbom/snippets/format/examples/cyclonedx-json.md b/content/docs/guides/sbom/snippets/format/examples/cyclonedx-json.md index 4c0456ee..9ff552d6 100644 --- a/content/docs/guides/sbom/snippets/format/examples/cyclonedx-json.md +++ b/content/docs/guides/sbom/snippets/format/examples/cyclonedx-json.md @@ -5,30 +5,30 @@ "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", "bomFormat": "CycloneDX", "specVersion": "1.6", - "serialNumber": "urn:uuid:16b64a7f-f004-4dc8-9901-15800a374335", + "serialNumber": "urn:uuid:8a80f804-a4f4-4676-bbdf-274a12ff9baa", "version": 1, "metadata": { - "timestamp": "2025-10-23T01:25:11Z", + "timestamp": "2025-10-28T13:53:47Z", "tools": { "components": [ { "type": "application", "author": "anchore", "name": "syft", - "version": "1.33.0" + "version": "1.33.0-SNAPSHOT-1510db7c" } ] }, "component": { - "bom-ref": "84d86520b9546322", + "bom-ref": "2c93ec6538b05582", "type": "container", "name": "busybox", - "version": "sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3" + "version": "sha256:182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c" } }, "components": [ { - "bom-ref": "pkg:generic/busybox@1.37.0?package-id=74d9294c42941b37", + "bom-ref": "pkg:generic/busybox@1.37.0?package-id=5ac87151014646ee", "type": "application", "name": "busybox", "version": "1.37.0", @@ -49,7 +49,7 @@ }, { "name": "syft:location:0:layerID", - "value": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "value": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "name": "syft:location:0:path", @@ -92,17 +92,17 @@ ] }, { - "bom-ref": "de0bf36b25443562", + "bom-ref": "236898de58a38d00", "type": "file", "name": "/bin/[", "hashes": [ { "alg": "SHA-1", - "content": "99f9c7cb06f6f8f074b5c16245f295e33844855a" + "content": "5b35fda458b860954b919ccd4f94b9bc32b8403d" }, { "alg": "SHA-256", - "content": "8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add" + "content": "91a25e00cc7850644994ba476846d2489651d8d1645be39aacdb116c83c22379" } ] } diff --git a/content/docs/guides/sbom/snippets/format/examples/cyclonedx-xml.md b/content/docs/guides/sbom/snippets/format/examples/cyclonedx-xml.md index c24d9080..1b4f8f17 100644 --- a/content/docs/guides/sbom/snippets/format/examples/cyclonedx-xml.md +++ b/content/docs/guides/sbom/snippets/format/examples/cyclonedx-xml.md @@ -2,25 +2,25 @@ ```xml - + - 2025-10-23T01:25:11Z + 2025-10-28T13:53:48Z anchore syft - 1.33.0 + 1.33.0-SNAPSHOT-1510db7c - + busybox - sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3 + sha256:182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c - + busybox 1.37.0 cpe:2.3:a:busybox:busybox:1.37.0:*:*:*:*:*:*:* @@ -29,7 +29,7 @@ binary-classifier-cataloger binary binary-signature - sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 + sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a /bin/[ @@ -46,11 +46,11 @@ 1.37.0 - + /bin/[ - 99f9c7cb06f6f8f074b5c16245f295e33844855a - 8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add + 5b35fda458b860954b919ccd4f94b9bc32b8403d + 91a25e00cc7850644994ba476846d2489651d8d1645be39aacdb116c83c22379 diff --git a/content/docs/guides/sbom/snippets/format/examples/github-json.md b/content/docs/guides/sbom/snippets/format/examples/github-json.md index 224ee7de..88b21fa1 100644 --- a/content/docs/guides/sbom/snippets/format/examples/github-json.md +++ b/content/docs/guides/sbom/snippets/format/examples/github-json.md @@ -7,7 +7,7 @@ "detector": { "name": "syft", "url": "https://github.com/anchore/syft", - "version": "1.33.0" + "version": "1.33.0-SNAPSHOT-1510db7c" }, "metadata": { "syft:distro": "pkg:generic/busybox@1.37.0?like=busybox" @@ -19,7 +19,7 @@ "source_location": "busybox:latest:/bin/busybox" }, "metadata": { - "syft:filesystem": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "syft:filesystem": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "resolved": { "pkg:generic/busybox@1.37.0": { @@ -30,6 +30,6 @@ } } }, - "scanned": "2025-10-23T01:25:12Z" + "scanned": "2025-10-28T13:53:49Z" } ``` diff --git a/content/docs/guides/sbom/snippets/format/examples/json.md b/content/docs/guides/sbom/snippets/format/examples/json.md index ed27d6d6..6b14fcdb 100644 --- a/content/docs/guides/sbom/snippets/format/examples/json.md +++ b/content/docs/guides/sbom/snippets/format/examples/json.md @@ -4,7 +4,7 @@ { "artifacts": [ { - "id": "74d9294c42941b37", + "id": "5ac87151014646ee", "name": "busybox", "version": "1.37.0", "type": "binary", @@ -12,7 +12,7 @@ "locations": [ { "path": "/bin/[", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19", + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a", "accessPath": "/bin/busybox", "annotations": { "evidence": "primary" @@ -35,7 +35,7 @@ "classifier": "busybox-binary", "location": { "path": "/bin/[", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19", + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a", "accessPath": "/bin/busybox", "annotations": { "evidence": "primary" @@ -48,25 +48,25 @@ ], "artifactRelationships": [ { - "parent": "74d9294c42941b37", - "child": "de0bf36b25443562", + "parent": "182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c", + "child": "5ac87151014646ee", + "type": "contains" + }, + { + "parent": "5ac87151014646ee", + "child": "236898de58a38d00", "type": "evident-by", "metadata": { "kind": "primary" } - }, - { - "parent": "cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3", - "child": "74d9294c42941b37", - "type": "contains" } ], "files": [ { - "id": "de0bf36b25443562", + "id": "236898de58a38d00", "location": { "path": "/bin/[", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "metadata": { "mode": 755, @@ -74,16 +74,16 @@ "userID": 0, "groupID": 0, "mimeType": "application/x-sharedlib", - "size": 1119784 + "size": 1017400 }, "digests": [ { "algorithm": "sha1", - "value": "99f9c7cb06f6f8f074b5c16245f295e33844855a" + "value": "5b35fda458b860954b919ccd4f94b9bc32b8403d" }, { "algorithm": "sha256", - "value": "8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add" + "value": "91a25e00cc7850644994ba476846d2489651d8d1645be39aacdb116c83c22379" } ], "executable": { @@ -103,10 +103,10 @@ } }, { - "id": "b240ee11665506ce", + "id": "11a9326bac8f8c54", "location": { "path": "/bin/getconf", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", @@ -126,10 +126,10 @@ "unknowns": ["unknowns-labeler: no package identified in executable file"] }, { - "id": "48a6e9fa63c5f6cc", + "id": "d75d617f020bb2b3", "location": { - "path": "/lib/ld-linux-aarch64.so.1", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "path": "/lib/ld-linux-x86-64.so.2", + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", @@ -138,7 +138,7 @@ "importedLibraries": [], "elfSecurityFeatures": { "symbolTableStripped": true, - "stackCanary": true, + "stackCanary": false, "nx": true, "relRO": "full", "pie": false, @@ -149,16 +149,16 @@ "unknowns": ["unknowns-labeler: no package identified in executable file"] }, { - "id": "a2dc8cb35e1e0485", + "id": "408b15110698ae17", "location": { "path": "/lib/libc.so.6", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", "hasExports": true, "hasEntrypoint": true, - "importedLibraries": ["ld-linux-aarch64.so.1"], + "importedLibraries": ["ld-linux-x86-64.so.2"], "elfSecurityFeatures": { "symbolTableStripped": true, "stackCanary": true, @@ -172,16 +172,16 @@ "unknowns": ["unknowns-labeler: no package identified in executable file"] }, { - "id": "8746a5a87ab9e597", + "id": "d164b64c94bcb8a5", "location": { "path": "/lib/libm.so.6", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", "hasExports": true, "hasEntrypoint": false, - "importedLibraries": ["libc.so.6", "ld-linux-aarch64.so.1"], + "importedLibraries": ["libc.so.6", "ld-linux-x86-64.so.2"], "elfSecurityFeatures": { "symbolTableStripped": true, "stackCanary": true, @@ -195,16 +195,16 @@ "unknowns": ["unknowns-labeler: no package identified in executable file"] }, { - "id": "75835d9334e3cd14", + "id": "8687368b6ef726b6", "location": { "path": "/lib/libnss_compat.so.2", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", "hasExports": true, "hasEntrypoint": false, - "importedLibraries": ["libc.so.6", "ld-linux-aarch64.so.1"], + "importedLibraries": ["libc.so.6"], "elfSecurityFeatures": { "symbolTableStripped": true, "stackCanary": true, @@ -218,10 +218,10 @@ "unknowns": ["unknowns-labeler: no package identified in executable file"] }, { - "id": "a75d014485c88e79", + "id": "75d93c7a58c1287f", "location": { "path": "/lib/libnss_dns.so.2", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", @@ -241,10 +241,10 @@ "unknowns": ["unknowns-labeler: no package identified in executable file"] }, { - "id": "b5abc725c65d58cf", + "id": "1b24799b00791035", "location": { "path": "/lib/libnss_files.so.2", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", @@ -264,16 +264,16 @@ "unknowns": ["unknowns-labeler: no package identified in executable file"] }, { - "id": "8570ef9dff59aa56", + "id": "cb5847e3eb9a3780", "location": { "path": "/lib/libnss_hesiod.so.2", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", "hasExports": true, "hasEntrypoint": false, - "importedLibraries": ["libresolv.so.2", "libc.so.6", "ld-linux-aarch64.so.1"], + "importedLibraries": ["libresolv.so.2", "libc.so.6"], "elfSecurityFeatures": { "symbolTableStripped": true, "stackCanary": true, @@ -287,10 +287,10 @@ "unknowns": ["unknowns-labeler: no package identified in executable file"] }, { - "id": "585855f0b92c8232", + "id": "a3c671d656d293e8", "location": { "path": "/lib/libpthread.so.0", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", @@ -310,16 +310,16 @@ "unknowns": ["unknowns-labeler: no package identified in executable file"] }, { - "id": "ee8c205846a71e54", + "id": "7168278800c9ea6e", "location": { "path": "/lib/libresolv.so.2", - "layerID": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "layerID": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, "executable": { "format": "elf", "hasExports": true, "hasEntrypoint": false, - "importedLibraries": ["libc.so.6", "ld-linux-aarch64.so.1"], + "importedLibraries": ["libc.so.6"], "elfSecurityFeatures": { "symbolTableStripped": true, "stackCanary": true, @@ -334,30 +334,30 @@ } ], "source": { - "id": "cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3", + "id": "182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c", "name": "busybox", - "version": "sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3", + "version": "sha256:182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c", "type": "image", "metadata": { "userInput": "busybox:latest", - "imageID": "sha256:e8291c1a323abf610ebeb32699b8df3e8046823b5dfbf795d888c9c6a73aeff8", - "manifestDigest": "sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3", + "imageID": "sha256:0ed463b26daee791b094dc3fff25edb3e79f153d37d274e5c2936923c38dac2b", + "manifestDigest": "sha256:182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c", "mediaType": "application/vnd.oci.image.manifest.v1+json", "tags": [], - "imageSize": 4170750, + "imageSize": 4429350, "layers": [ { "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", - "digest": "sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19", - "size": 4170750 + "digest": "sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a", + "size": 4429350 } ], - "manifest": "ewoJInNjaGVtYVZlcnNpb24iOiAyLAoJIm1lZGlhVHlwZSI6ICJhcHBsaWNhdGlvbi92bmQub2NpLmltYWdlLm1hbmlmZXN0LnYxK2pzb24iLAoJImNvbmZpZyI6IHsKCQkibWVkaWFUeXBlIjogImFwcGxpY2F0aW9uL3ZuZC5vY2kuaW1hZ2UuY29uZmlnLnYxK2pzb24iLAoJCSJkaWdlc3QiOiAic2hhMjU2OmU4MjkxYzFhMzIzYWJmNjEwZWJlYjMyNjk5YjhkZjNlODA0NjgyM2I1ZGZiZjc5NWQ4ODhjOWM2YTczYWVmZjgiLAoJCSJzaXplIjogNDc3Cgl9LAoJImxheWVycyI6IFsKCQl7CgkJCSJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLm9jaS5pbWFnZS5sYXllci52MS50YXIrZ3ppcCIsCgkJCSJkaWdlc3QiOiAic2hhMjU2OjQ5OWJjZjNjOGVhZDhlZjI1NzBmN2VlOGU0YWI1YTQ0ODk2NDdkNjdkZDFjMWI0MjVmZGJkNGE3NGY0YjQzODYiLAoJCQkic2l6ZSI6IDE5MDI3NjYKCQl9CgldLAoJImFubm90YXRpb25zIjogewoJCSJvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsIjogImh0dHBzOi8vZ2l0aHViLmNvbS9kb2NrZXItbGlicmFyeS9idXN5Ym94IiwKCQkib3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb24iOiAiMS4zNy4wLWdsaWJjIgoJfQp9Cg==", - "config": "ewoJImNvbmZpZyI6IHsKCQkiQ21kIjogWwoJCQkic2giCgkJXSwKCQkiRW52IjogWwoJCQkiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iCgkJXQoJfSwKCSJjcmVhdGVkIjogIjIwMjQtMDktMjZUMjE6MzE6NDJaIiwKCSJoaXN0b3J5IjogWwoJCXsKCQkJImNyZWF0ZWQiOiAiMjAyNC0wOS0yNlQyMTozMTo0MloiLAoJCQkiY3JlYXRlZF9ieSI6ICJCdXN5Qm94IDEuMzcuMCAoZ2xpYmMpLCBEZWJpYW4gMTMiCgkJfQoJXSwKCSJyb290ZnMiOiB7CgkJInR5cGUiOiAibGF5ZXJzIiwKCQkiZGlmZl9pZHMiOiBbCgkJCSJzaGEyNTY6NmFiYTVlMGQzMmQ5MWUzZTkyMzg1NGRjYjMwNTg4ZGM0MTEyYmZhMWRhZTgyYjg5NTM1YWQzMWQzMjJhN2IxOSIKCQldCgl9LAoJImFyY2hpdGVjdHVyZSI6ICJhcm02NCIsCgkib3MiOiAibGludXgiLAoJInZhcmlhbnQiOiAidjgiCn0K", + "manifest": "ewoJInNjaGVtYVZlcnNpb24iOiAyLAoJIm1lZGlhVHlwZSI6ICJhcHBsaWNhdGlvbi92bmQub2NpLmltYWdlLm1hbmlmZXN0LnYxK2pzb24iLAoJImNvbmZpZyI6IHsKCQkibWVkaWFUeXBlIjogImFwcGxpY2F0aW9uL3ZuZC5vY2kuaW1hZ2UuY29uZmlnLnYxK2pzb24iLAoJCSJkaWdlc3QiOiAic2hhMjU2OjBlZDQ2M2IyNmRhZWU3OTFiMDk0ZGMzZmZmMjVlZGIzZTc5ZjE1M2QzN2QyNzRlNWMyOTM2OTIzYzM4ZGFjMmIiLAoJCSJzaXplIjogNDU5Cgl9LAoJImxheWVycyI6IFsKCQl7CgkJCSJtZWRpYVR5cGUiOiAiYXBwbGljYXRpb24vdm5kLm9jaS5pbWFnZS5sYXllci52MS50YXIrZ3ppcCIsCgkJCSJkaWdlc3QiOiAic2hhMjU2OjgwYmZiYjhhNDFhMmIyN2Q5Mzc2M2U5NmY1YmRjY2I4Y2EyODkzODc5NDZlNDA2ZTZmMjQwNTNmNmE4ZTg0OTQiLAoJCQkic2l6ZSI6IDIyMTMwODIKCQl9CgldLAoJImFubm90YXRpb25zIjogewoJCSJvcmcub3BlbmNvbnRhaW5lcnMuaW1hZ2UudXJsIjogImh0dHBzOi8vZ2l0aHViLmNvbS9kb2NrZXItbGlicmFyeS9idXN5Ym94IiwKCQkib3JnLm9wZW5jb250YWluZXJzLmltYWdlLnZlcnNpb24iOiAiMS4zNy4wLWdsaWJjIgoJfQp9Cg==", + "config": "ewoJImNvbmZpZyI6IHsKCQkiQ21kIjogWwoJCQkic2giCgkJXSwKCQkiRW52IjogWwoJCQkiUEFUSD0vdXNyL2xvY2FsL3NiaW46L3Vzci9sb2NhbC9iaW46L3Vzci9zYmluOi91c3IvYmluOi9zYmluOi9iaW4iCgkJXQoJfSwKCSJjcmVhdGVkIjogIjIwMjQtMDktMjZUMjE6MzE6NDJaIiwKCSJoaXN0b3J5IjogWwoJCXsKCQkJImNyZWF0ZWQiOiAiMjAyNC0wOS0yNlQyMTozMTo0MloiLAoJCQkiY3JlYXRlZF9ieSI6ICJCdXN5Qm94IDEuMzcuMCAoZ2xpYmMpLCBEZWJpYW4gMTMiCgkJfQoJXSwKCSJyb290ZnMiOiB7CgkJInR5cGUiOiAibGF5ZXJzIiwKCQkiZGlmZl9pZHMiOiBbCgkJCSJzaGEyNTY6ODBlODQwZGU2MzBkMDhhNmExZTBlZTMwZTdjODM3OGNmMWVkNmE0MjQzMTVkN2U0MzdmNTQ3ODBhZWU2YmY1YSIKCQldCgl9LAoJImFyY2hpdGVjdHVyZSI6ICJhbWQ2NCIsCgkib3MiOiAibGludXgiCn0K", "repoDigests": [ - "index.docker.io/library/busybox@sha256:d82f458899c9696cb26a7c02d5568f81c8c8223f8661bb2a7988b269c8b9051e" + "index.docker.io/library/busybox@sha256:2f590fc602ce325cbff2ccfc39499014d039546dc400ef8bbf5c6ffb860632e7" ], - "architecture": "arm64", + "architecture": "amd64", "os": "linux" } }, @@ -371,7 +371,7 @@ }, "descriptor": { "name": "syft", - "version": "1.33.0", + "version": "1.33.0-SNAPSHOT-1510db7c", "configuration": { "catalogers": { "requested": { @@ -410,6 +410,7 @@ "r-package-cataloger", "rpm-db-cataloger", "ruby-installed-gemspec-cataloger", + "snap-cataloger", "wordpress-plugins-cataloger" ] }, @@ -483,6 +484,8 @@ "jq-binary", "chrome-binary", "ffmpeg-binary", + "ffmpeg-library", + "ffmpeg-library", "java-binary", "java-jdb-binary" ], diff --git a/content/docs/guides/sbom/snippets/format/examples/spdx-json.md b/content/docs/guides/sbom/snippets/format/examples/spdx-json.md index f36ada82..09079649 100644 --- a/content/docs/guides/sbom/snippets/format/examples/spdx-json.md +++ b/content/docs/guides/sbom/snippets/format/examples/spdx-json.md @@ -6,16 +6,16 @@ "dataLicense": "CC0-1.0", "SPDXID": "SPDXRef-DOCUMENT", "name": "busybox", - "documentNamespace": "https://anchore.com/syft/image/busybox-5c53b32e-ffbc-4b4a-a34e-6717808cf391", + "documentNamespace": "https://anchore.com/syft/image/busybox-b62f90c3-4108-407e-bdc3-1be4685577e5", "creationInfo": { "licenseListVersion": "3.27", - "creators": ["Organization: Anchore, Inc", "Tool: syft-1.33.0"], - "created": "2025-10-23T01:25:11Z" + "creators": ["Organization: Anchore, Inc", "Tool: syft-1.33.0-SNAPSHOT-1510db7c"], + "created": "2025-10-28T13:53:48Z" }, "packages": [ { "name": "busybox", - "SPDXID": "SPDXRef-Package-binary-busybox-74d9294c42941b37", + "SPDXID": "SPDXRef-Package-binary-busybox-5ac87151014646ee", "versionInfo": "1.37.0", "supplier": "NOASSERTION", "downloadLocation": "NOASSERTION", @@ -40,14 +40,14 @@ { "name": "busybox", "SPDXID": "SPDXRef-DocumentRoot-Image-busybox", - "versionInfo": "sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3", + "versionInfo": "sha256:182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c", "supplier": "NOASSERTION", "downloadLocation": "NOASSERTION", "filesAnalyzed": false, "checksums": [ { "algorithm": "SHA256", - "checksumValue": "cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3" + "checksumValue": "182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c" } ], "licenseConcluded": "NOASSERTION", @@ -57,7 +57,7 @@ { "referenceCategory": "PACKAGE-MANAGER", "referenceType": "purl", - "referenceLocator": "pkg:oci/busybox@sha256%3Acddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3?arch=arm64&tag=latest" + "referenceLocator": "pkg:oci/busybox@sha256%3A182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c?arch=amd64&tag=latest" } ], "primaryPackagePurpose": "CONTAINER" @@ -66,26 +66,26 @@ "files": [ { "fileName": "bin/[", - "SPDXID": "SPDXRef-File-bin---de0bf36b25443562", + "SPDXID": "SPDXRef-File-bin---236898de58a38d00", "fileTypes": ["APPLICATION", "BINARY"], "checksums": [ { "algorithm": "SHA1", - "checksumValue": "99f9c7cb06f6f8f074b5c16245f295e33844855a" + "checksumValue": "5b35fda458b860954b919ccd4f94b9bc32b8403d" }, { "algorithm": "SHA256", - "checksumValue": "8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add" + "checksumValue": "91a25e00cc7850644994ba476846d2489651d8d1645be39aacdb116c83c22379" } ], "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "fileName": "bin/getconf", - "SPDXID": "SPDXRef-File-bin-getconf-b240ee11665506ce", + "SPDXID": "SPDXRef-File-bin-getconf-11a9326bac8f8c54", "checksums": [ { "algorithm": "SHA1", @@ -95,11 +95,11 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { - "fileName": "lib/ld-linux-aarch64.so.1", - "SPDXID": "SPDXRef-File-lib-ld-linux-aarch64.so.1-48a6e9fa63c5f6cc", + "fileName": "lib/ld-linux-x86-64.so.2", + "SPDXID": "SPDXRef-File-lib-ld-linux-x86-64.so.2-d75d617f020bb2b3", "checksums": [ { "algorithm": "SHA1", @@ -109,11 +109,11 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "fileName": "lib/libc.so.6", - "SPDXID": "SPDXRef-File-lib-libc.so.6-a2dc8cb35e1e0485", + "SPDXID": "SPDXRef-File-lib-libc.so.6-408b15110698ae17", "checksums": [ { "algorithm": "SHA1", @@ -123,11 +123,11 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "fileName": "lib/libm.so.6", - "SPDXID": "SPDXRef-File-lib-libm.so.6-8746a5a87ab9e597", + "SPDXID": "SPDXRef-File-lib-libm.so.6-d164b64c94bcb8a5", "checksums": [ { "algorithm": "SHA1", @@ -137,11 +137,11 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "fileName": "lib/libnss_compat.so.2", - "SPDXID": "SPDXRef-File-lib-libnss-compat.so.2-75835d9334e3cd14", + "SPDXID": "SPDXRef-File-lib-libnss-compat.so.2-8687368b6ef726b6", "checksums": [ { "algorithm": "SHA1", @@ -151,11 +151,11 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "fileName": "lib/libnss_dns.so.2", - "SPDXID": "SPDXRef-File-lib-libnss-dns.so.2-a75d014485c88e79", + "SPDXID": "SPDXRef-File-lib-libnss-dns.so.2-75d93c7a58c1287f", "checksums": [ { "algorithm": "SHA1", @@ -165,11 +165,11 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "fileName": "lib/libnss_files.so.2", - "SPDXID": "SPDXRef-File-lib-libnss-files.so.2-b5abc725c65d58cf", + "SPDXID": "SPDXRef-File-lib-libnss-files.so.2-1b24799b00791035", "checksums": [ { "algorithm": "SHA1", @@ -179,11 +179,11 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "fileName": "lib/libnss_hesiod.so.2", - "SPDXID": "SPDXRef-File-lib-libnss-hesiod.so.2-8570ef9dff59aa56", + "SPDXID": "SPDXRef-File-lib-libnss-hesiod.so.2-cb5847e3eb9a3780", "checksums": [ { "algorithm": "SHA1", @@ -193,11 +193,11 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "fileName": "lib/libpthread.so.0", - "SPDXID": "SPDXRef-File-lib-libpthread.so.0-585855f0b92c8232", + "SPDXID": "SPDXRef-File-lib-libpthread.so.0-a3c671d656d293e8", "checksums": [ { "algorithm": "SHA1", @@ -207,11 +207,11 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" }, { "fileName": "lib/libresolv.so.2", - "SPDXID": "SPDXRef-File-lib-libresolv.so.2-ee8c205846a71e54", + "SPDXID": "SPDXRef-File-lib-libresolv.so.2-7168278800c9ea6e", "checksums": [ { "algorithm": "SHA1", @@ -221,19 +221,19 @@ "licenseConcluded": "NOASSERTION", "licenseInfoInFiles": ["NOASSERTION"], "copyrightText": "NOASSERTION", - "comment": "layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19" + "comment": "layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a" } ], "relationships": [ { - "spdxElementId": "SPDXRef-Package-binary-busybox-74d9294c42941b37", - "relatedSpdxElement": "SPDXRef-File-bin---de0bf36b25443562", + "spdxElementId": "SPDXRef-Package-binary-busybox-5ac87151014646ee", + "relatedSpdxElement": "SPDXRef-File-bin---236898de58a38d00", "relationshipType": "OTHER", "comment": "evident-by: indicates the package's existence is evident by the given file" }, { "spdxElementId": "SPDXRef-DocumentRoot-Image-busybox", - "relatedSpdxElement": "SPDXRef-Package-binary-busybox-74d9294c42941b37", + "relatedSpdxElement": "SPDXRef-Package-binary-busybox-5ac87151014646ee", "relationshipType": "CONTAINS" }, { diff --git a/content/docs/guides/sbom/snippets/format/examples/spdx-tag-value.md b/content/docs/guides/sbom/snippets/format/examples/spdx-tag-value.md index 90c317a4..725be050 100644 --- a/content/docs/guides/sbom/snippets/format/examples/spdx-tag-value.md +++ b/content/docs/guides/sbom/snippets/format/examples/spdx-tag-value.md @@ -5,124 +5,124 @@ SPDXVersion: SPDX-2.3 DataLicense: CC0-1.0 SPDXID: SPDXRef-DOCUMENT DocumentName: busybox -DocumentNamespace: https://anchore.com/syft/image/busybox-7dbf6be8-1e2a-48a3-bd62-b53e2f2f5ab0 +DocumentNamespace: https://anchore.com/syft/image/busybox-983d674e-a973-4505-81c3-e2e1e716d6bc LicenseListVersion: 3.27 Creator: Organization: Anchore, Inc -Creator: Tool: syft-1.33.0 -Created: 2025-10-23T01:25:12Z +Creator: Tool: syft-1.33.0-SNAPSHOT-1510db7c +Created: 2025-10-28T13:53:48Z ##### Unpackaged files FileName: bin/[ -SPDXID: SPDXRef-File-bin---de0bf36b25443562 +SPDXID: SPDXRef-File-bin---236898de58a38d00 FileType: APPLICATION FileType: BINARY -FileChecksum: SHA1: 99f9c7cb06f6f8f074b5c16245f295e33844855a -FileChecksum: SHA256: 8a4212147744cedcf7f679c81921942c81eb3b8d356bbb2b08b51336b2fe8add +FileChecksum: SHA1: 5b35fda458b860954b919ccd4f94b9bc32b8403d +FileChecksum: SHA256: 91a25e00cc7850644994ba476846d2489651d8d1645be39aacdb116c83c22379 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a FileName: bin/getconf -SPDXID: SPDXRef-File-bin-getconf-b240ee11665506ce +SPDXID: SPDXRef-File-bin-getconf-11a9326bac8f8c54 FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a -FileName: lib/ld-linux-aarch64.so.1 -SPDXID: SPDXRef-File-lib-ld-linux-aarch64.so.1-48a6e9fa63c5f6cc +FileName: lib/ld-linux-x86-64.so.2 +SPDXID: SPDXRef-File-lib-ld-linux-x86-64.so.2-d75d617f020bb2b3 FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a FileName: lib/libc.so.6 -SPDXID: SPDXRef-File-lib-libc.so.6-a2dc8cb35e1e0485 +SPDXID: SPDXRef-File-lib-libc.so.6-408b15110698ae17 FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a FileName: lib/libm.so.6 -SPDXID: SPDXRef-File-lib-libm.so.6-8746a5a87ab9e597 +SPDXID: SPDXRef-File-lib-libm.so.6-d164b64c94bcb8a5 FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a FileName: lib/libnss_compat.so.2 -SPDXID: SPDXRef-File-lib-libnss-compat.so.2-75835d9334e3cd14 +SPDXID: SPDXRef-File-lib-libnss-compat.so.2-8687368b6ef726b6 FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a FileName: lib/libnss_dns.so.2 -SPDXID: SPDXRef-File-lib-libnss-dns.so.2-a75d014485c88e79 +SPDXID: SPDXRef-File-lib-libnss-dns.so.2-75d93c7a58c1287f FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a FileName: lib/libnss_files.so.2 -SPDXID: SPDXRef-File-lib-libnss-files.so.2-b5abc725c65d58cf +SPDXID: SPDXRef-File-lib-libnss-files.so.2-1b24799b00791035 FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a FileName: lib/libnss_hesiod.so.2 -SPDXID: SPDXRef-File-lib-libnss-hesiod.so.2-8570ef9dff59aa56 +SPDXID: SPDXRef-File-lib-libnss-hesiod.so.2-cb5847e3eb9a3780 FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a FileName: lib/libpthread.so.0 -SPDXID: SPDXRef-File-lib-libpthread.so.0-585855f0b92c8232 +SPDXID: SPDXRef-File-lib-libpthread.so.0-a3c671d656d293e8 FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a FileName: lib/libresolv.so.2 -SPDXID: SPDXRef-File-lib-libresolv.so.2-ee8c205846a71e54 +SPDXID: SPDXRef-File-lib-libresolv.so.2-7168278800c9ea6e FileChecksum: SHA1: 0000000000000000000000000000000000000000 LicenseConcluded: NOASSERTION LicenseInfoInFile: NOASSERTION FileCopyrightText: NOASSERTION -FileComment: layerID: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 +FileComment: layerID: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a ##### Package: busybox PackageName: busybox SPDXID: SPDXRef-DocumentRoot-Image-busybox -PackageVersion: sha256:cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3 +PackageVersion: sha256:182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c PackageSupplier: NOASSERTION PackageDownloadLocation: NOASSERTION PrimaryPackagePurpose: CONTAINER FilesAnalyzed: false -PackageChecksum: SHA256: cddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3 +PackageChecksum: SHA256: 182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c PackageLicenseConcluded: NOASSERTION PackageLicenseDeclared: NOASSERTION PackageCopyrightText: NOASSERTION -ExternalRef: PACKAGE-MANAGER purl pkg:oci/busybox@sha256%3Acddc8af5547af9de5e6fb66b36d66ef7418561204e1255ae528d0b2c919d09a3?arch=arm64&tag=latest +ExternalRef: PACKAGE-MANAGER purl pkg:oci/busybox@sha256%3A182014572d8981d8323fe9944876f63b39694e16ce08ae6296e97686c52b150c?arch=amd64&tag=latest ##### Package: busybox PackageName: busybox -SPDXID: SPDXRef-Package-binary-busybox-74d9294c42941b37 +SPDXID: SPDXRef-Package-binary-busybox-5ac87151014646ee PackageVersion: 1.37.0 PackageSupplier: NOASSERTION PackageDownloadLocation: NOASSERTION @@ -136,8 +136,8 @@ ExternalRef: PACKAGE-MANAGER purl pkg:generic/busybox@1.37.0 ##### Relationships -Relationship: SPDXRef-Package-binary-busybox-74d9294c42941b37 OTHER SPDXRef-File-bin---de0bf36b25443562 +Relationship: SPDXRef-Package-binary-busybox-5ac87151014646ee OTHER SPDXRef-File-bin---236898de58a38d00 RelationshipComment: evident-by: indicates the package's existence is evident by the given file -Relationship: SPDXRef-DocumentRoot-Image-busybox CONTAINS SPDXRef-Package-binary-busybox-74d9294c42941b37 +Relationship: SPDXRef-DocumentRoot-Image-busybox CONTAINS SPDXRef-Package-binary-busybox-5ac87151014646ee Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DocumentRoot-Image-busybox ``` diff --git a/content/docs/guides/sbom/snippets/format/examples/text.md b/content/docs/guides/sbom/snippets/format/examples/text.md index 55ca2f91..b7137106 100644 --- a/content/docs/guides/sbom/snippets/format/examples/text.md +++ b/content/docs/guides/sbom/snippets/format/examples/text.md @@ -3,8 +3,8 @@ ``` [Image] Layer: 0 - Digest: sha256:6aba5e0d32d91e3e923854dcb30588dc4112bfa1dae82b89535ad31d322a7b19 - Size: 4170750 + Digest: sha256:80e840de630d08a6a1e0ee30e7c8378cf1ed6a424315d7e437f54780aee6bf5a + Size: 4429350 MediaType: application/vnd.oci.image.layer.v1.tar+gzip [busybox] diff --git a/content/docs/guides/sbom/snippets/jq-queries/all-executables/output.md b/content/docs/guides/sbom/snippets/jq-queries/all-executables/output.md index e20fb296..28330d8e 100644 --- a/content/docs/guides/sbom/snippets/jq-queries/all-executables/output.md +++ b/content/docs/guides/sbom/snippets/jq-queries/all-executables/output.md @@ -3,11 +3,11 @@ "path": "/bin/busybox", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { - "path": "/lib/ld-musl-aarch64.so.1", + "path": "/lib/ld-musl-x86_64.so.1", "format": "elf", "importedLibraries": [] } @@ -15,7 +15,7 @@ "path": "/lib/libcrypto.so.1.1", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { @@ -23,14 +23,14 @@ "format": "elf", "importedLibraries": [ "libcrypto.so.1.1", - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { "path": "/lib/libz.so.1.2.11", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { @@ -40,42 +40,42 @@ "libssl.so.1.1", "libcrypto.so.1.1", "libz.so.1", - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { "path": "/sbin/mkmntdirs", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { "path": "/usr/bin/getconf", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { "path": "/usr/bin/getent", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { "path": "/usr/bin/iconv", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { "path": "/usr/bin/scanelf", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { @@ -83,7 +83,7 @@ "format": "elf", "importedLibraries": [ "libtls-standalone.so.1", - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { @@ -91,21 +91,21 @@ "format": "elf", "importedLibraries": [ "libcrypto.so.1.1", - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { "path": "/usr/lib/engines-1.1/capi.so", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { "path": "/usr/lib/engines-1.1/padlock.so", "format": "elf", "importedLibraries": [ - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { @@ -114,7 +114,7 @@ "importedLibraries": [ "libssl.so.1.1", "libcrypto.so.1.1", - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } ``` diff --git a/content/docs/guides/sbom/snippets/jq-queries/all-purls/output.md b/content/docs/guides/sbom/snippets/jq-queries/all-purls/output.md index eede3ddd..9b876135 100644 --- a/content/docs/guides/sbom/snippets/jq-queries/all-purls/output.md +++ b/content/docs/guides/sbom/snippets/jq-queries/all-purls/output.md @@ -2,71 +2,71 @@ { "name": "alpine-baselayout", "version": "3.1.0-r3", - "purl": "pkg:apk/alpine/alpine-baselayout@3.1.0-r3?arch=aarch64&distro=alpine-3.9.2" + "purl": "pkg:apk/alpine/alpine-baselayout@3.1.0-r3?arch=x86_64&distro=alpine-3.9.2" } { "name": "alpine-keys", "version": "2.1-r1", - "purl": "pkg:apk/alpine/alpine-keys@2.1-r1?arch=aarch64&distro=alpine-3.9.2" + "purl": "pkg:apk/alpine/alpine-keys@2.1-r1?arch=x86_64&distro=alpine-3.9.2" } { "name": "apk-tools", "version": "2.10.3-r1", - "purl": "pkg:apk/alpine/apk-tools@2.10.3-r1?arch=aarch64&distro=alpine-3.9.2" + "purl": "pkg:apk/alpine/apk-tools@2.10.3-r1?arch=x86_64&distro=alpine-3.9.2" } { "name": "busybox", "version": "1.29.3-r10", - "purl": "pkg:apk/alpine/busybox@1.29.3-r10?arch=aarch64&distro=alpine-3.9.2" + "purl": "pkg:apk/alpine/busybox@1.29.3-r10?arch=x86_64&distro=alpine-3.9.2" } { "name": "ca-certificates-cacert", "version": "20190108-r0", - "purl": "pkg:apk/alpine/ca-certificates-cacert@20190108-r0?arch=aarch64&distro=alpine-3.9.2&upstream=ca-certificates" + "purl": "pkg:apk/alpine/ca-certificates-cacert@20190108-r0?arch=x86_64&distro=alpine-3.9.2&upstream=ca-certificates" } { "name": "libc-utils", "version": "0.7.1-r0", - "purl": "pkg:apk/alpine/libc-utils@0.7.1-r0?arch=aarch64&distro=alpine-3.9.2&upstream=libc-dev" + "purl": "pkg:apk/alpine/libc-utils@0.7.1-r0?arch=x86_64&distro=alpine-3.9.2&upstream=libc-dev" } { "name": "libcrypto1.1", "version": "1.1.1a-r1", - "purl": "pkg:apk/alpine/libcrypto1.1@1.1.1a-r1?arch=aarch64&distro=alpine-3.9.2&upstream=openssl" + "purl": "pkg:apk/alpine/libcrypto1.1@1.1.1a-r1?arch=x86_64&distro=alpine-3.9.2&upstream=openssl" } { "name": "libssl1.1", "version": "1.1.1a-r1", - "purl": "pkg:apk/alpine/libssl1.1@1.1.1a-r1?arch=aarch64&distro=alpine-3.9.2&upstream=openssl" + "purl": "pkg:apk/alpine/libssl1.1@1.1.1a-r1?arch=x86_64&distro=alpine-3.9.2&upstream=openssl" } { "name": "libtls-standalone", "version": "2.7.4-r6", - "purl": "pkg:apk/alpine/libtls-standalone@2.7.4-r6?arch=aarch64&distro=alpine-3.9.2" + "purl": "pkg:apk/alpine/libtls-standalone@2.7.4-r6?arch=x86_64&distro=alpine-3.9.2" } { "name": "musl", "version": "1.1.20-r3", - "purl": "pkg:apk/alpine/musl@1.1.20-r3?arch=aarch64&distro=alpine-3.9.2" + "purl": "pkg:apk/alpine/musl@1.1.20-r3?arch=x86_64&distro=alpine-3.9.2" } { "name": "musl-utils", "version": "1.1.20-r3", - "purl": "pkg:apk/alpine/musl-utils@1.1.20-r3?arch=aarch64&distro=alpine-3.9.2&upstream=musl" + "purl": "pkg:apk/alpine/musl-utils@1.1.20-r3?arch=x86_64&distro=alpine-3.9.2&upstream=musl" } { "name": "scanelf", "version": "1.2.3-r0", - "purl": "pkg:apk/alpine/scanelf@1.2.3-r0?arch=aarch64&distro=alpine-3.9.2&upstream=pax-utils" + "purl": "pkg:apk/alpine/scanelf@1.2.3-r0?arch=x86_64&distro=alpine-3.9.2&upstream=pax-utils" } { "name": "ssl_client", "version": "1.29.3-r10", - "purl": "pkg:apk/alpine/ssl_client@1.29.3-r10?arch=aarch64&distro=alpine-3.9.2&upstream=busybox" + "purl": "pkg:apk/alpine/ssl_client@1.29.3-r10?arch=x86_64&distro=alpine-3.9.2&upstream=busybox" } { "name": "zlib", "version": "1.2.11-r1", - "purl": "pkg:apk/alpine/zlib@1.2.11-r1?arch=aarch64&distro=alpine-3.9.2" + "purl": "pkg:apk/alpine/zlib@1.2.11-r1?arch=x86_64&distro=alpine-3.9.2" } ``` diff --git a/content/docs/guides/sbom/snippets/jq-queries/binaries-not-owned/output.md b/content/docs/guides/sbom/snippets/jq-queries/binaries-not-owned/output.md index f3edc834..a09ed3b1 100644 --- a/content/docs/guides/sbom/snippets/jq-queries/binaries-not-owned/output.md +++ b/content/docs/guides/sbom/snippets/jq-queries/binaries-not-owned/output.md @@ -1,203 +1,203 @@ ```json { "path": "/usr/local/apache2/bin/ab", - "sha256": "1aa76de1f9eb534fe22d35a01ccbf7ede03e250f6f5d0a00553e687187565d3a" + "sha256": "14e4fd045dfbdfffeeff3e68ec4606bc6cc479a9dd573a577bd82eb18f959fee" } { "path": "/usr/local/apache2/bin/checkgid", - "sha256": "af3372d60eee3f8132d2bdd10fb8670db8a9965b2e056c267131586184ba11fb" + "sha256": "4bb1bbf3de789ea44e6aa9b5a7499d965bde217062c7f4de3c5ed99e89f94868" } { "path": "/usr/local/apache2/bin/fcgistarter", - "sha256": "eea2fa75671e7e647692cd0352405ef8a0b17167a05770b9552602a3c720bfdb" + "sha256": "723df8ced1e2689697a096c66aeae7c0bf5d1132b589008bbb4f3bb8af10bf21" } { "path": "/usr/local/apache2/bin/htcacheclean", - "sha256": "94e0fd5f0f5cf6231080177072846a4e99846f1f534224911e3bed17ce27ec38" + "sha256": "280b7c4bfe6c0ea3798f2bc0f862127a3ba5c1724bf4e3a15edd05e96ff6ecd1" } { "path": "/usr/local/apache2/bin/htdbm", - "sha256": "e2a41d96c92cb16c98972a043ac380c06f19b5bddbafe0b2d2082ed174f8cfe3" + "sha256": "95b2de4ec3b80b5586df9c1f8132925b3c653569f8ac79badf4fd92d49da50d0" } { "path": "/usr/local/apache2/bin/htdigest", - "sha256": "0881598a4fd15455297c186fa301fdb1656ff26d0f77626d54a15421095e047f" + "sha256": "504acfd46f933f883689b4b008d56b28daf0017fd11dc61e200df322d6b0c1da" } { "path": "/usr/local/apache2/bin/htpasswd", - "sha256": "871ef0aa4ae0914747a471bf3917405548abf768dd6c94e3e0177c8e87334d9e" + "sha256": "54799fdd10c82be5a59cd01b286e00ca5fbb2ce4f08ebc54be0ffba56b4ded81" } { "path": "/usr/local/apache2/bin/httpd", - "sha256": "4ee82f26958e62065b51ca56ab4c55b32988f27a8402ed518b05d48ed2342142" + "sha256": "52c948ac8d7b4f00ef0b3dc4b8e218bf867a959fabcd6ef36eac526968b43a6e" } { "path": "/usr/local/apache2/bin/httxt2dbm", - "sha256": "1d5eb8e5d910760aa859c45e79b541362a84499f08fb79b8773bf9b8faf7bbdb" + "sha256": "28f3d2eafbf1f76f5ac29cb75b3b4e6ed81ca4e0ca681dbb700de6da2da19ae4" } { "path": "/usr/local/apache2/bin/logresolve", - "sha256": "de8ed1fa5184170fca09980025f40c55d9fbf14b47c73b2575bc90ac1c9bf20e" + "sha256": "e65e425258337b577618c2c48ed29c4e89f9dd44bfcfad2ccaeb564a5c79a9b8" } { "path": "/usr/local/apache2/bin/rotatelogs", - "sha256": "f5ed895712cddcec7f542dee08a1ff74fd00ae3a9b0d92ede429e04ec2b9b8ae" + "sha256": "579b1a2083d1d5b5271e504ea4ea8de2f90c3702d75a8e78fd81d11ebe39987c" } { "path": "/usr/local/apache2/bin/suexec", - "sha256": "264efc529c09a60fed57fcde9e7a2c36f8bb414ae0e1afc9bb85595113ab4ec2" + "sha256": "9ff3782c4b03c9a51e8db6f7cdbc1c73c091a0bbbd63830ad60ddb4a859dc379" } { "path": "/usr/local/apache2/modules/mod_access_compat.so", - "sha256": "0d6322b7d7d3d6c459751f8b271f733fa05a8b56eecd75f608100a5dbf464fc2" + "sha256": "2c877b8d43a21a7508355802457cb2a981b2dabe95335a2713986467480ae26c" } { "path": "/usr/local/apache2/modules/mod_actions.so", - "sha256": "6dc5dea7137ec0ae139c545b26efd860c6de7bcc19d2e31db213399c86bf2ead" + "sha256": "48b922041084528594513ec24cb7da606d782b288f32f10e7ae791b85b06065a" } { "path": "/usr/local/apache2/modules/mod_alias.so", - "sha256": "bb422c4486600ec349ac9b89acaa3793265d69498c30370e678a362900daea04" + "sha256": "a457e3544f8ee626d3595f1c5ff417886d50ded7139b4182c74282ccaeca7e92" } { "path": "/usr/local/apache2/modules/mod_allowmethods.so", - "sha256": "99a9db80c8f18fe3defb315731af3bceef321a98bd52f518f068ca2632596cee" + "sha256": "1cc414caae084c32fa8ed56cbf9b6a0c1d1fbb5679d675542f276b02ac228115" } { "path": "/usr/local/apache2/modules/mod_asis.so", - "sha256": "039014ad5ad3f357e811b570bd9977a772e74f191856981a503e57263b88cc44" + "sha256": "49ce8276c2e978bcf46ba10974a0cd8f2b88b3fcbe13ba47452dceb61a9123a3" } { "path": "/usr/local/apache2/modules/mod_auth_basic.so", - "sha256": "1f9534187df98194fa60259c3d9feca05f1b2564d49b37b49da040232e7a327b" + "sha256": "74f1a51ab145a9f61e77e836370d7fc651e5d8c720c5024f4f10d9607d5b0830" } { "path": "/usr/local/apache2/modules/mod_auth_digest.so", - "sha256": "ad77d0457b773c9d13097adf47bebcd95297466fc9fb6886b7bff85e2acdd99d" + "sha256": "62e331425820f28812642349ac127578ba7b28e59b8e9b014d3cc6a9d428db50" } { "path": "/usr/local/apache2/modules/mod_auth_form.so", - "sha256": "ceb56183d83c22ff08853982b0f35f122185cf69d3bcfd948eeb1df32dd12bbb" + "sha256": "e643554b77b8b6440e8365d036dccaf341f9b470d4a43b06a9e7a9d4cc09572b" } { "path": "/usr/local/apache2/modules/mod_authn_anon.so", - "sha256": "44308e1d5a65ab64232d27f24a827aa1afdb2fef580dd1a8454788431ebd639f" + "sha256": "62b1c69d6f9bbc30f24d2380057a9e9e7ee86db5625bf42fdb13db8c6fbb36ab" } { "path": "/usr/local/apache2/modules/mod_authn_core.so", - "sha256": "9cbf85b1a20da26483ca4a57186161a2876ca296dd1174ed5a5af9f5301fe5e8" + "sha256": "a01e1c8bfadef322fded4b4e1eab1a43375db2c18e357d442f886d932173b4bd" } { "path": "/usr/local/apache2/modules/mod_authn_dbd.so", - "sha256": "08dc7b848a67131a091563046e3fc6914e86f248740bd2f23905f2f6df3ce541" + "sha256": "02ec2e747dceeb5ccd2700804f5b1711762132665a9fed939551ed741b45d3df" } { "path": "/usr/local/apache2/modules/mod_authn_dbm.so", - "sha256": "1e5900c8b41ca227b59ba54738154e04841cef2045d8040747e4b7887526a763" + "sha256": "320ad3b9a4577314170e67726dc898db064de9d482c5157d1095c4348468c7cf" } { "path": "/usr/local/apache2/modules/mod_authn_file.so", - "sha256": "74f83d5717276ae6a37f4a2d0c54f8d23e57ae1c3f73bb2b332c77860b7421ed" + "sha256": "7c03a9d8609c3d48febfb7bca00645e8448d671a31324220fa07f10136b25c3e" } { "path": "/usr/local/apache2/modules/mod_authn_socache.so", - "sha256": "2f51212b62c5bbda54ddec0c1a07f523e96c2b56d987fefa43e0cc42dbf6f5d0" + "sha256": "cc320ac42a05782fd9a7cee74cb2fa358405d5ecf7c7b007f9b0f215dad98535" } { "path": "/usr/local/apache2/modules/mod_authnz_fcgi.so", - "sha256": "4fa0fa7d3d4b742b3f73a781d2e8d4625d477c76aa0698aa0d499f87e6985554" + "sha256": "3cd59d332bc3492b2e4ddeda47f7e1ea239db72e3b7908a505700e815208dae7" } { "path": "/usr/local/apache2/modules/mod_authnz_ldap.so", - "sha256": "dccffc453f46d201ecb1003b372a6ca417ac40a33036500a2215697b2e5ac0af" + "sha256": "7d3fb03c6ad76b1491aab810723f4f0887c90105a102d3ed7bd8c67b48b4e0f4" } { "path": "/usr/local/apache2/modules/mod_authz_core.so", - "sha256": "e2b825ec9e2992b1cc157aef12c4ecd75960604658c3b7aa4a370088e89455b5" + "sha256": "6eefe02f93ff2f0d0e85c4ba63d1205c93493e05b36288d500f25d8b3bf2524b" } { "path": "/usr/local/apache2/modules/mod_authz_dbd.so", - "sha256": "61b427078b5d11b3fd8693cbfa22cb5871dc9784b08d3182b73ad3e99b8579d9" + "sha256": "6187daebe46e719ca39c1f3c316f7014fa1b50b3678cc3d5f7656dcd426c9c90" } { "path": "/usr/local/apache2/modules/mod_authz_dbm.so", - "sha256": "1d99ed703743d9dd2185a0d7e9e351fa38066b3234ae997e87efa6dc1e4513eb" + "sha256": "6a4cc707575172407c1f177f7eb36e0b794fb93676e4d2716d015ce5529bc28e" } { "path": "/usr/local/apache2/modules/mod_authz_groupfile.so", - "sha256": "3e9adb775d41a8b01802ff610dda01f8e62a0d282ea0522d297a252207453c4d" + "sha256": "9df757775a160967e7c53d7a868ccffe65eb0b916d5de660b7b633d0d5d557ff" } { "path": "/usr/local/apache2/modules/mod_authz_host.so", - "sha256": "c0fcd53dc9596fd6bc280c55d14b61c72dc12470bf5c1bc86e369217af05cb2c" + "sha256": "976c2be87903e51c3bc0bbb3decbeb33b3816caafd6eea41dff8a084c862e8ac" } { "path": "/usr/local/apache2/modules/mod_authz_owner.so", - "sha256": "e8923ef5f11e03c37b4579e18d396758ee085bae4dadc0519374ca63da86c932" + "sha256": "9f678a2249e7de0a813762fff1823a56146d07725d66ed7f2ecfcc9511e2116f" } { "path": "/usr/local/apache2/modules/mod_authz_user.so", - "sha256": "3c5674a1e7af6b7d09e8c66f973a3138fed0dde4dfaee98fc132c89730cd9156" + "sha256": "83b3a46815d4762f0f0246028bc23229245ec1ccd63a386543918355b445ff65" } { "path": "/usr/local/apache2/modules/mod_autoindex.so", - "sha256": "2d992f31f40be2c0ec34a29981191c3bfb9e4448a2099f11a4876ba4d394dc2f" + "sha256": "e77c9d15b9f2888e4d09b84f2d111e8177ddec466554e7fb69143bc2ca050303" } { "path": "/usr/local/apache2/modules/mod_brotli.so", - "sha256": "73bfe5aeff2040a7b56a0bf822bc4069ce3e9954186f81322060697f5cf0546f" + "sha256": "c701208729f73e75ba666e0ce7bed110631e69197032e0b5d805ea4200089f4e" } { "path": "/usr/local/apache2/modules/mod_bucketeer.so", - "sha256": "9f146159e928405d2a007dba3690566a45e5793cde87871a30dbfd1dc9114db1" + "sha256": "6629498f998ed6908ee65256b038d86df5a0a294366c201db43620a5a91a2484" } { "path": "/usr/local/apache2/modules/mod_buffer.so", - "sha256": "710bd1b238a7814963b2857eb92c891bafeff61d9e40f807d68ded700c8c37f2" + "sha256": "ba4ff1c20ff28047bff00cec015f64742fd3afd2afc912994927d15cbc6252d4" } { "path": "/usr/local/apache2/modules/mod_cache.so", - "sha256": "976222e2c7ddb317d8804383801b310be33c6b3542f6972edd12c38ddc527e38" + "sha256": "e2445d2eda9de66c039ad6f79ab413804c5c78952b7945183491fdcd41cee2d9" } { "path": "/usr/local/apache2/modules/mod_cache_disk.so", - "sha256": "c5359004a563b9b01bf0416cbe856bb50de642bf06649383ffcae26490dc69c8" + "sha256": "351c6245fca2da4815e03be544d54db9d1d594ae9b53849a5dece02ec160b38c" } { "path": "/usr/local/apache2/modules/mod_cache_socache.so", - "sha256": "94abdf3779a9f7d258b1720021e1e3f10c630e625f5aa13c683c3c811b8dac10" + "sha256": "9d8a4a9322ea15ad2e1b64e6e461a0da5c61ce31762047e2f0eed62f1ebde430" } { "path": "/usr/local/apache2/modules/mod_case_filter.so", - "sha256": "79a0a336c1bacd06c0fc5ca14cfc97223c92f0f5b0c88ec95f7e163e8cdf917d" + "sha256": "be8ba2b4409d2297b80337dce0d63fe8b145061e7fd68478a8c671645e8ea840" } { "path": "/usr/local/apache2/modules/mod_case_filter_in.so", - "sha256": "aa5e1c9452e1be3789a8a867a98dab700e4a579c0ea1ff7180adf4e41b8495e3" + "sha256": "458d3a19ef79dd9db8df518758c6e4a48b037e0b869eb49556ffd6ab6be277c4" } { "path": "/usr/local/apache2/modules/mod_cern_meta.so", - "sha256": "1a6da74d768c01b1a96f5c0f0e74686d5b0f51c3d7f1149fa1124cdf10ba842a" + "sha256": "37a88c41ee1cf4449676f167ded1e215c77dce1f5f1832af172cce2e86bb8ce8" } { "path": "/usr/local/apache2/modules/mod_cgi.so", - "sha256": "f2716c663f4f7db8cd78f456e5bd098a62c1b8fde86253ed4617edfe9cdb93b2" + "sha256": "650d9fb76cb9927004a8dbd25ece4793ecfcf7138667b71946082f3d39b46e7b" } { "path": "/usr/local/apache2/modules/mod_cgid.so", - "sha256": "d5a19aeeb7b9063bac25e4a172ea7578e83bb32da4fe21ecd858409115de166c" + "sha256": "24349e3080644bb3eaa3aaed8eb339e526631e791d4536e289fde73e3b61365a" } { "path": "/usr/local/apache2/modules/mod_charset_lite.so", - "sha256": "9c4a1b27532c5f47eea7cfc61f65a7cf2f132286e556175ec28e313024641c9d" + "sha256": "7bcf49fc0d2dfb75ba3ad46a82c12a6e14decacabf6f04339271d9a3ce31126b" } { "path": "/usr/local/apache2/modules/mod_data.so", - "sha256": "4dcae9a704c7d9861497e57b15423b9ce3fc7dda6544096ecfff64e4223f3684" + "sha256": "f6bf8b05dad2f050764154d018057d23246a4c5de74298ce84a42a8f6ffd8a5a" } { "path": "/usr/local/apache2/modules/mod_dav.so", - "sha256": "1a33728b16ad05b12fbecf637168608cb10f258ef7a355bd37cef8ce2ed86fd7" + "sha256": "2f2967435998f0a3c18fff50e2e8aa9bbb9063ce6bb9d7d3e35a6b0e9e83556c" } ... diff --git a/content/docs/guides/sbom/snippets/jq-queries/binaries-with-security-features/output.md b/content/docs/guides/sbom/snippets/jq-queries/binaries-with-security-features/output.md index fef80ed6..91231eb7 100644 --- a/content/docs/guides/sbom/snippets/jq-queries/binaries-with-security-features/output.md +++ b/content/docs/guides/sbom/snippets/jq-queries/binaries-with-security-features/output.md @@ -6,7 +6,7 @@ "nx": true } { - "path": "/lib/ld-musl-aarch64.so.1", + "path": "/lib/ld-musl-x86_64.so.1", "pie": false, "stackCanary": true, "nx": true diff --git a/content/docs/guides/sbom/snippets/jq-queries/binary-digests/output.md b/content/docs/guides/sbom/snippets/jq-queries/binary-digests/output.md index 4d483583..3397de37 100644 --- a/content/docs/guides/sbom/snippets/jq-queries/binary-digests/output.md +++ b/content/docs/guides/sbom/snippets/jq-queries/binary-digests/output.md @@ -4,24 +4,24 @@ "digests": [ { "algorithm": "sha1", - "value": "7423801dfb28659fcaaaa5e8d41051d470b19008" + "value": "7448dd02af2b09251816b41e5254afcdd1edcad6" }, { "algorithm": "sha256", - "value": "2c1276c3c02ccec8a0e1737d3144cdf03db883f479c86fbd9c7ea4fd9b35eac5" + "value": "e16ab33dc871e43b8d1bb5a4b8b1b84963dbeca33cb42a6eb9884d611aa38399" } ] } { - "path": "/lib/ld-musl-aarch64.so.1", + "path": "/lib/ld-musl-x86_64.so.1", "digests": [ { "algorithm": "sha1", - "value": "0b83c1eb91d633379e0c17349e7dae821fa36dbb" + "value": "0ff8bd56a5be96de41934100f140e81da887afc8" }, { "algorithm": "sha256", - "value": "0132814479f1acc1e264ef59f73fd91563235897e8dc1bd52765f974cde382ca" + "value": "42a0167325aaa5308e8f56cdfbfe3693fbceb49ab6514e6cd7048b9991353847" } ] } @@ -30,11 +30,11 @@ "digests": [ { "algorithm": "sha1", - "value": "e9d1540e5bbd9e77b388ab0e6e2f52603eb032a4" + "value": "ed6923d5306cb6665a8c20e0a7e116713d64f55f" }, { "algorithm": "sha256", - "value": "6c597c8ad195eeb7a9130ad832dfa4cbf140f42baf96304711b2dbd43ba8e617" + "value": "17ef79be58d6a6fac381ecb3da3169b59872f0369d83f2cb556525752f033053" } ] } @@ -43,11 +43,11 @@ "digests": [ { "algorithm": "sha1", - "value": "a8d5036010b52a80402b900c626fe862ab06bd8b" + "value": "c594750898ea085cb47b31ee896dca3548769b93" }, { "algorithm": "sha256", - "value": "fb72f4615fb4574bd6eeabfdb86be47012618b9076d75aeb1510941c585cae64" + "value": "bb74e17676bda5909d41e6277c929827d1a41bd3eeba156355a265a53c3a5231" } ] } @@ -56,11 +56,11 @@ "digests": [ { "algorithm": "sha1", - "value": "83378fc7a19ff908a7e92a9fd0ca39eee90d0a3c" + "value": "2a83d998a8b50c763144e6793a16c297eb05f405" }, { "algorithm": "sha256", - "value": "19e790eb36a09eba397b5af16852f3bea21a242026bbba3da7b16442b8ba305b" + "value": "7c8aad287832213129abdbfdf4d03679d6df88d992ee9236c9db43b6a5c3190d" } ] } @@ -69,11 +69,11 @@ "digests": [ { "algorithm": "sha1", - "value": "adac7738917adecff81d4a6f9f0c7971b173859a" + "value": "ada8e5b398684ed7b22bf72b62eb6490877853e9" }, { "algorithm": "sha256", - "value": "22d7d85bd24923f1f274ce765d16602191097829e22ac632748302817ce515d8" + "value": "75a942c8b866d3cb6cc97b941a271a0ef368f583f575457b864f2d9246d034c7" } ] } @@ -82,11 +82,11 @@ "digests": [ { "algorithm": "sha1", - "value": "fff9b110ad6c659a39681e7be3b2a036fbbcca7b" + "value": "2ad5d792e81a8feaf06a7ddc0dc8118e1e965250" }, { "algorithm": "sha256", - "value": "a14a5a28525220224367616ef46d4713ef7bd00d22baa761e058e8bdd4c0af1b" + "value": "bc9a2b20273927028177aaf5f2f6896593c161cb58f5055e2fd7138a042c7f30" } ] } @@ -95,11 +95,11 @@ "digests": [ { "algorithm": "sha1", - "value": "06ed40070e1c2ad6d4171095eff4a6bdf9c8489b" + "value": "78393df1b72be819340315bead1226ed81c0206d" }, { "algorithm": "sha256", - "value": "82bcde66ead19bc3b9ff850f66c2dbf5eaff36d481f1ec154100f73f6265d2ef" + "value": "8febf7f34f34223138953e31301b94f687c33421c2943e6e30e088b965859c46" } ] } @@ -108,11 +108,11 @@ "digests": [ { "algorithm": "sha1", - "value": "c318a3a780fc27ed7dba57827a825191fa7ee8bd" + "value": "339c27944283131c8520d1bf2087e72e3f2864fd" }, { "algorithm": "sha256", - "value": "53ffb508150e91838d795831e8ecc71f2bc3a7db036c6d7f9512c3973418bb5e" + "value": "dbe90a610ab8f3fe41c8f8f15f554fd65ef7fe0d45ea41192ac1dcdcc92ba2dd" } ] } @@ -121,11 +121,11 @@ "digests": [ { "algorithm": "sha1", - "value": "eb98f04742e41cfc3ed44109b0e059d13e5523ea" + "value": "0cd93d73528ffbcae4ad9a2aa13632ec88efca7a" }, { "algorithm": "sha256", - "value": "1c99d1f4edcb8da6db1da60958051c413de45a4c15cd3b7f7285ed87f9a250ff" + "value": "303661a0b60349247ff1e95f35b165c878ae0f5f046f96174e143b4d99777754" } ] } @@ -134,11 +134,11 @@ "digests": [ { "algorithm": "sha1", - "value": "cb085d106f35862e44e17849026927bd05845bff" + "value": "82b0ee78eb356f353324210af484cd71e437f5bf" }, { "algorithm": "sha256", - "value": "908da485ad2edea35242f8989c7beb9536414782abc94357c72b7d840bb1fda2" + "value": "1f854b8a9dedf87b1148846400143e22d3b3fe91322d7c0dde7b283e1c5f55e4" } ] } @@ -147,11 +147,11 @@ "digests": [ { "algorithm": "sha1", - "value": "7e17cb64c3fce832e5fa52a3b2ed1e1ccd26acd0" + "value": "cf41503fb9b9badf4e31587b411f5d9d5cdeed1c" }, { "algorithm": "sha256", - "value": "67ab7f3a1ba35630f439d1ca4f73c7d95f8b7aa0e6f6db6ea1743f136f074ab4" + "value": "fdaf5fe91369e3d83dff8e46d3e2463a9066025593f4e98e47036473c15c1cfd" } ] } @@ -160,11 +160,11 @@ "digests": [ { "algorithm": "sha1", - "value": "6bd2c385e3884109c581659a8b184592c86e7cee" + "value": "94f132da9009b81146939081947efa2e5c4f52f8" }, { "algorithm": "sha256", - "value": "ea7c2f48bc741fd828d79a304dbf713e20e001c0187f3f534d959886af87f4af" + "value": "28235d3670e8ee47973e23d5ef561b4a1adf35894677bc702309e1e977865dff" } ] } @@ -173,11 +173,11 @@ "digests": [ { "algorithm": "sha1", - "value": "41bb990b6f8e2013487980fd430455cc3b59905f" + "value": "7bc020762baaed89771f780a4801ddfbe6b3cc3f" }, { "algorithm": "sha256", - "value": "b461ed43f0f244007d872e84760a446023b69b178c970acf10ed2666198942c6" + "value": "529fa687249d140df0397e1224bb659415d45023e18e4818269397a03d769d69" } ] } @@ -186,11 +186,11 @@ "digests": [ { "algorithm": "sha1", - "value": "82d8308700f481884fd77c882e0e9406fb17b317" + "value": "53a84c21461e0595ab7e0f4c8f9006e677ada13e" }, { "algorithm": "sha256", - "value": "0ccb04f040afb0216da1cea2c1db7a0b91d990ce061e232782aedbd498483649" + "value": "164c1fb578c0bd2605d3c9b5595f8755664c81a7c1963fc49cb16b5cdf560d2c" } ] } diff --git a/content/docs/guides/sbom/snippets/jq-queries/binary-imports/output.md b/content/docs/guides/sbom/snippets/jq-queries/binary-imports/output.md index ac43a654..a9eee519 100644 --- a/content/docs/guides/sbom/snippets/jq-queries/binary-imports/output.md +++ b/content/docs/guides/sbom/snippets/jq-queries/binary-imports/output.md @@ -3,7 +3,7 @@ "path": "/lib/libssl.so.1.1", "imports": [ "libcrypto.so.1.1", - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { @@ -12,14 +12,14 @@ "libssl.so.1.1", "libcrypto.so.1.1", "libz.so.1", - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { "path": "/usr/lib/engines-1.1/afalg.so", "imports": [ "libcrypto.so.1.1", - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } { @@ -27,7 +27,7 @@ "imports": [ "libssl.so.1.1", "libcrypto.so.1.1", - "libc.musl-aarch64.so.1" + "libc.musl-x86_64.so.1" ] } ``` diff --git a/content/docs/guides/sbom/snippets/jq-queries/dependency-relationships/output.md b/content/docs/guides/sbom/snippets/jq-queries/dependency-relationships/output.md index 7fba51e2..cff44b6d 100644 --- a/content/docs/guides/sbom/snippets/jq-queries/dependency-relationships/output.md +++ b/content/docs/guides/sbom/snippets/jq-queries/dependency-relationships/output.md @@ -1,94 +1,94 @@ ```json { - "parent": "ca-certificates-bundle", + "parent": "libcrypto3", + "child": "ssl_client" +} +{ + "parent": "libcrypto3", "child": "apk-tools" } { - "parent": "alpine-keys", - "child": "alpine-release" + "parent": "libcrypto3", + "child": "libssl3" } { "parent": "alpine-baselayout-data", "child": "alpine-baselayout" } { - "parent": "musl", - "child": "ssl_client" + "parent": "ca-certificates-bundle", + "child": "apk-tools" } { - "parent": "musl", - "child": "libgcc" + "parent": "libgcc", + "child": "libstdc++" } { - "parent": "musl", - "child": "libstdc++" + "parent": "busybox", + "child": "busybox-binsh" } { - "parent": "musl", - "child": "musl-utils" + "parent": "busybox-binsh", + "child": "alpine-baselayout" } { - "parent": "musl", - "child": "libssl3" + "parent": "zlib", + "child": "apk-tools" } { - "parent": "musl", - "child": "busybox" + "parent": "libssl3", + "child": "ssl_client" } { - "parent": "musl", + "parent": "libssl3", "child": "apk-tools" } { "parent": "musl", - "child": "scanelf" + "child": "libcrypto3" } { "parent": "musl", - "child": "libcrypto3" + "child": "ssl_client" } { "parent": "musl", - "child": "zlib" + "child": "libgcc" } { - "parent": "libgcc", - "child": "libstdc++" + "parent": "musl", + "child": "busybox" } { - "parent": "libssl3", - "child": "ssl_client" + "parent": "musl", + "child": "musl-utils" } { - "parent": "libssl3", + "parent": "musl", "child": "apk-tools" } { - "parent": "busybox", - "child": "busybox-binsh" -} -{ - "parent": "scanelf", - "child": "musl-utils" + "parent": "musl", + "child": "zlib" } { - "parent": "busybox-binsh", - "child": "alpine-baselayout" + "parent": "musl", + "child": "libssl3" } { - "parent": "libcrypto3", - "child": "ssl_client" + "parent": "musl", + "child": "scanelf" } { - "parent": "libcrypto3", - "child": "libssl3" + "parent": "musl", + "child": "libstdc++" } { - "parent": "libcrypto3", - "child": "apk-tools" + "parent": "scanelf", + "child": "musl-utils" } { - "parent": "zlib", - "child": "apk-tools" + "parent": "alpine-keys", + "child": "alpine-release" } ``` diff --git a/content/docs/guides/sbom/snippets/jq-queries/files-by-mime-type/output.md b/content/docs/guides/sbom/snippets/jq-queries/files-by-mime-type/output.md index 0737ed0d..ae09fa20 100644 --- a/content/docs/guides/sbom/snippets/jq-queries/files-by-mime-type/output.md +++ b/content/docs/guides/sbom/snippets/jq-queries/files-by-mime-type/output.md @@ -2,81 +2,81 @@ { "path": "/bin/busybox", "mimeType": "application/x-sharedlib", - "size": 841320 + "size": 796240 } { - "path": "/lib/ld-musl-aarch64.so.1", + "path": "/lib/ld-musl-x86_64.so.1", "mimeType": "application/x-sharedlib", - "size": 616960 + "size": 584304 } { "path": "/lib/libcrypto.so.1.1", "mimeType": "application/x-sharedlib", - "size": 2321984 + "size": 2593440 } { "path": "/lib/libssl.so.1.1", "mimeType": "application/x-sharedlib", - "size": 515376 + "size": 519632 } { "path": "/lib/libz.so.1.2.11", "mimeType": "application/x-sharedlib", - "size": 91888 + "size": 100144 } { "path": "/sbin/apk", "mimeType": "application/x-sharedlib", - "size": 218928 + "size": 211304 } { "path": "/sbin/mkmntdirs", "mimeType": "application/x-sharedlib", - "size": 5712 + "size": 13968 } { "path": "/usr/bin/getconf", "mimeType": "application/x-sharedlib", - "size": 33544 + "size": 36728 } { "path": "/usr/bin/getent", "mimeType": "application/x-sharedlib", - "size": 48704 + "size": 51912 } { "path": "/usr/bin/iconv", "mimeType": "application/x-sharedlib", - "size": 21968 + "size": 25216 } { "path": "/usr/bin/scanelf", "mimeType": "application/x-sharedlib", - "size": 79592 + "size": 83744 } { "path": "/usr/bin/ssl_client", "mimeType": "application/x-sharedlib", - "size": 9808 + "size": 13968 } { "path": "/usr/lib/engines-1.1/afalg.so", "mimeType": "application/x-sharedlib", - "size": 18568 + "size": 22768 } { "path": "/usr/lib/engines-1.1/capi.so", "mimeType": "application/x-sharedlib", - "size": 5672 + "size": 13856 } { "path": "/usr/lib/engines-1.1/padlock.so", "mimeType": "application/x-sharedlib", - "size": 5672 + "size": 13864 } { "path": "/usr/lib/libtls-standalone.so.1.0.0", "mimeType": "application/x-sharedlib", - "size": 96032 + "size": 96096 } ``` diff --git a/content/docs/guides/sbom/snippets/jq-queries/large-files/output.md b/content/docs/guides/sbom/snippets/jq-queries/large-files/output.md index d0a3d98e..c89c239f 100644 --- a/content/docs/guides/sbom/snippets/jq-queries/large-files/output.md +++ b/content/docs/guides/sbom/snippets/jq-queries/large-files/output.md @@ -2,22 +2,22 @@ [ { "path": "/lib/libcrypto.so.1.1", - "size": 2321984, + "size": 2593440, "mimeType": "application/x-sharedlib" }, { "path": "/bin/busybox", - "size": 841320, + "size": 796240, "mimeType": "application/x-sharedlib" }, { - "path": "/lib/ld-musl-aarch64.so.1", - "size": 616960, + "path": "/lib/ld-musl-x86_64.so.1", + "size": 584304, "mimeType": "application/x-sharedlib" }, { "path": "/lib/libssl.so.1.1", - "size": 515376, + "size": 519632, "mimeType": "application/x-sharedlib" }, { @@ -27,27 +27,27 @@ }, { "path": "/sbin/apk", - "size": 218928, + "size": 211304, "mimeType": "application/x-sharedlib" }, { - "path": "/usr/lib/libtls-standalone.so.1.0.0", - "size": 96032, + "path": "/lib/libz.so.1.2.11", + "size": 100144, "mimeType": "application/x-sharedlib" }, { - "path": "/lib/libz.so.1.2.11", - "size": 91888, + "path": "/usr/lib/libtls-standalone.so.1.0.0", + "size": 96096, "mimeType": "application/x-sharedlib" }, { "path": "/usr/bin/scanelf", - "size": 79592, + "size": 83744, "mimeType": "application/x-sharedlib" }, { "path": "/usr/bin/getent", - "size": 48704, + "size": 51912, "mimeType": "application/x-sharedlib" } ] diff --git a/content/docs/guides/sbom/snippets/templates/executable-digests/output.md b/content/docs/guides/sbom/snippets/templates/executable-digests/output.md index 85e11263..de25a5c7 100644 --- a/content/docs/guides/sbom/snippets/templates/executable-digests/output.md +++ b/content/docs/guides/sbom/snippets/templates/executable-digests/output.md @@ -1,33 +1,33 @@ ```text -/bin/busybox: 2c1276c3c02ccec8a0e1737d3144cdf03db883f479c86fbd9c7ea4fd9b35eac5 +/bin/busybox: e16ab33dc871e43b8d1bb5a4b8b1b84963dbeca33cb42a6eb9884d611aa38399 -/lib/ld-musl-aarch64.so.1: 0132814479f1acc1e264ef59f73fd91563235897e8dc1bd52765f974cde382ca +/lib/ld-musl-x86_64.so.1: 42a0167325aaa5308e8f56cdfbfe3693fbceb49ab6514e6cd7048b9991353847 -/lib/libcrypto.so.1.1: 6c597c8ad195eeb7a9130ad832dfa4cbf140f42baf96304711b2dbd43ba8e617 +/lib/libcrypto.so.1.1: 17ef79be58d6a6fac381ecb3da3169b59872f0369d83f2cb556525752f033053 -/lib/libssl.so.1.1: fb72f4615fb4574bd6eeabfdb86be47012618b9076d75aeb1510941c585cae64 +/lib/libssl.so.1.1: bb74e17676bda5909d41e6277c929827d1a41bd3eeba156355a265a53c3a5231 -/lib/libz.so.1.2.11: 19e790eb36a09eba397b5af16852f3bea21a242026bbba3da7b16442b8ba305b +/lib/libz.so.1.2.11: 7c8aad287832213129abdbfdf4d03679d6df88d992ee9236c9db43b6a5c3190d -/sbin/apk: 22d7d85bd24923f1f274ce765d16602191097829e22ac632748302817ce515d8 +/sbin/apk: 75a942c8b866d3cb6cc97b941a271a0ef368f583f575457b864f2d9246d034c7 -/sbin/mkmntdirs: a14a5a28525220224367616ef46d4713ef7bd00d22baa761e058e8bdd4c0af1b +/sbin/mkmntdirs: bc9a2b20273927028177aaf5f2f6896593c161cb58f5055e2fd7138a042c7f30 -/usr/bin/getconf: 82bcde66ead19bc3b9ff850f66c2dbf5eaff36d481f1ec154100f73f6265d2ef +/usr/bin/getconf: 8febf7f34f34223138953e31301b94f687c33421c2943e6e30e088b965859c46 -/usr/bin/getent: 53ffb508150e91838d795831e8ecc71f2bc3a7db036c6d7f9512c3973418bb5e +/usr/bin/getent: dbe90a610ab8f3fe41c8f8f15f554fd65ef7fe0d45ea41192ac1dcdcc92ba2dd -/usr/bin/iconv: 1c99d1f4edcb8da6db1da60958051c413de45a4c15cd3b7f7285ed87f9a250ff +/usr/bin/iconv: 303661a0b60349247ff1e95f35b165c878ae0f5f046f96174e143b4d99777754 -/usr/bin/scanelf: 908da485ad2edea35242f8989c7beb9536414782abc94357c72b7d840bb1fda2 +/usr/bin/scanelf: 1f854b8a9dedf87b1148846400143e22d3b3fe91322d7c0dde7b283e1c5f55e4 -/usr/bin/ssl_client: 67ab7f3a1ba35630f439d1ca4f73c7d95f8b7aa0e6f6db6ea1743f136f074ab4 +/usr/bin/ssl_client: fdaf5fe91369e3d83dff8e46d3e2463a9066025593f4e98e47036473c15c1cfd -/usr/lib/engines-1.1/afalg.so: ea7c2f48bc741fd828d79a304dbf713e20e001c0187f3f534d959886af87f4af +/usr/lib/engines-1.1/afalg.so: 28235d3670e8ee47973e23d5ef561b4a1adf35894677bc702309e1e977865dff -/usr/lib/engines-1.1/capi.so: b461ed43f0f244007d872e84760a446023b69b178c970acf10ed2666198942c6 +/usr/lib/engines-1.1/capi.so: 529fa687249d140df0397e1224bb659415d45023e18e4818269397a03d769d69 -/usr/lib/engines-1.1/padlock.so: 0ccb04f040afb0216da1cea2c1db7a0b91d990ce061e232782aedbd498483649 +/usr/lib/engines-1.1/padlock.so: 164c1fb578c0bd2605d3c9b5595f8755664c81a7c1963fc49cb16b5cdf560d2c -/usr/lib/libtls-standalone.so.1.0.0: 7f4c2ff4010e30a69f588ab4f213fdf9ce61a524a0eecd3f5af31dc760e8006c +/usr/lib/libtls-standalone.so.1.0.0: 37b016468b279d21be84ea77bf63af4fcd683b6a639774c74bfdcbfc0c27e3e3 ``` diff --git a/content/docs/reference/syft/cli.md b/content/docs/reference/syft/cli.md index 5d379834..14cb3d67 100644 --- a/content/docs/reference/syft/cli.md +++ b/content/docs/reference/syft/cli.md @@ -274,14 +274,14 @@ Flags: ### `syft version` +Show version information. + ``` -Application: syft -Version: 1.33.0-SNAPSHOT-1510db7c -BuildDate: 2025-10-14T14:06:38Z -GitCommit: 1510db7c4ea279ff41bc5f0dca627ec2c1c200d0 -GitDescription: v1.33.0-35-g1510db7c -Platform: linux/amd64 -GoVersion: go1.24.4 -Compiler: gc -SchemaVersion: 16.0.40 +Usage: + syft version [flags] + +Flags: + -h, --help help for version + -o, --output string the format to show the results (allowable: [text json]) (default "text") + ``` diff --git a/content/docs/reference/syft/json/15.md b/content/docs/reference/syft/json/15.md index a881b4f9..0da41b1d 100644 --- a/content/docs/reference/syft/json/15.md +++ b/content/docs/reference/syft/json/15.md @@ -9,6 +9,7 @@ url = "/docs/reference/syft/json/15" + ## Document {#document}
Ecosystem Cataloger + Evidence Licenses Dependencies Files EcosystemCataloger + EvidenceLicensesDependenciesFiles
alpm-db-cataloger
var/lib/pacman/local/**/desc
APK
apk-db-cataloger
lib/apk/db/installed
Binary
Bitnami
bitnami-cataloger
/opt/bitnami/**/.spdx-*.spdx
C/C++
conda-meta-cataloger
conda-meta/*.json
Dart
deb-archive-cataloger
*.deb
dpkg-db-cataloger
lib/dpkg/status, lib/dpkg/status.d/*, lib/opkg/info/*.control, lib/opkg/status
Elixir
Go
go-module-binary-cataloger
application/x-executable, application/x-mach-binary, application/x-elf, application/x-sharedlib, application/vnd.microsoft.portable-executable, application/x-executable (mimetype)
go-module-file-cataloger
go.mod
java-archive-cataloger
*.zip
java-archive-cataloger
*.zip
java-archive-cataloger
*.tar, *.tar.gz, *.tgz, *.tar.bz, *.tar.bz2, *.tbz, *.tbz2, *.tar.br, *.tbr, *.tar.lz4, *.tlz4, *.tar.sz, *.tsz, *.tar.xz, *.txz, *.tar.zst, *.tzst, *.tar.zstd, *.tzstd
java-archive-cataloger
*.tar, *.tar.gz, *.tgz, *.tar.bz, *.tar.bz2, *.tbz, *.tbz2, *.tar.br, *.tbr, *.tar.lz4, *.tlz4, *.tar.sz, *.tsz, *.tar.xz, *.txz, *.tar.zst, *.tzst, *.tar.zstd, *.tzstd
java-jvm-cataloger
release
java-pom-cataloger
*pom.xml
dotnet-deps-cataloger
*.deps.json
dotnet-deps-cataloger deprecated
*.deps.json
dotnet-portable-executable-cataloger
*.dll, *.exe
dotnet-portable-executable-cataloger deprecated
*.dll, *.exe
nix-store-cataloger
nix/store/*, nix/store/*.drv
nix-store-cataloger deprecated
nix/store/*, nix/store/*.drv
OCaml
php-pecl-serialized-cataloger
php/.registry/.channel.*/*.reg
php-pecl-serialized-cataloger deprecated
php/.registry/.channel.*/*.reg
portage-cataloger
var/db/pkg/*/*/CONTENTS
Prolog
python-installed-package-cataloger
*.egg-info, *dist-info/METADATA, *egg-info/PKG-INFO, *DIST-INFO/METADATA, *EGG-INFO/PKG-INFO
python-package-cataloger
uv.lock
python-package-cataloger
*requirements*.txt
RPM
rpm-archive-cataloger
*.rpm
rpm-db-cataloger
var/lib/rpmmanifest/container-manifest-2
rpm-db-cataloger
{var/lib,usr/share,usr/lib/sysimage}/rpm/{Packages,Packages.db,rpmdb.sqlite}
Ruby
ruby-gemspec-cataloger
*.gemspec
ruby-installed-gemspec-cataloger
specifications/**/*.gemspec
Rust
diff --git a/content/docs/reference/syft/json/16.md b/content/docs/reference/syft/json/16.md index 352b20db..238c1066 100644 --- a/content/docs/reference/syft/json/16.md +++ b/content/docs/reference/syft/json/16.md @@ -13,6 +13,7 @@ sidebar_badge = "latest" + ## Document {#document}

Represents the syft cataloging findings as a JSON document

diff --git a/data/capabilities/syft-package-catalogers.json b/data/capabilities/syft-package-catalogers.json index 6ecac1d6..e88ebda0 100644 --- a/data/capabilities/syft-package-catalogers.json +++ b/data/capabilities/syft-package-catalogers.json @@ -1,9 +1,20 @@ { "catalogers": [ { - "ecosystem": "arch", + "ecosystem": "alpm", "name": "alpm-db-cataloger", "type": "generic", + "selectors": [ + "alpm", + "archlinux", + "directory", + "image", + "installed", + "linux", + "os", + "package", + "pacman" + ], "patterns": [ { "method": "glob", @@ -64,6 +75,16 @@ "ecosystem": "alpine", "name": "apk-db-cataloger", "type": "generic", + "selectors": [ + "alpine", + "apk", + "directory", + "image", + "installed", + "linux", + "os", + "package" + ], "patterns": [ { "method": "glob", @@ -84,7 +105,8 @@ { "name": "dependency.depth", "default": [ - "direct" + "direct", + "indirect" ] }, { @@ -126,6 +148,14 @@ "ecosystem": "binary", "name": "binary-classifier-cataloger", "type": "custom", + "selectors": [ + "binary", + "declared", + "directory", + "image", + "installed", + "package" + ], "patterns": [ { "method": "glob", @@ -1475,6 +1505,16 @@ "ecosystem": "binary", "name": "elf-binary-package-cataloger", "type": "custom", + "selectors": [ + "binary", + "declared", + "directory", + "elf", + "elf-package", + "image", + "installed", + "package" + ], "patterns": [ { "method": "mimetype", @@ -1529,6 +1569,18 @@ "ecosystem": "binary", "name": "pe-binary-package-cataloger", "type": "generic", + "selectors": [ + "binary", + "declared", + "directory", + "dll", + "exe", + "image", + "installed", + "package", + "pe", + "pe-package" + ], "patterns": [ { "method": "glob", @@ -1579,6 +1631,12 @@ "ecosystem": "bitnami", "name": "bitnami-cataloger", "type": "generic", + "selectors": [ + "bitnami", + "image", + "installed", + "package" + ], "patterns": [ { "method": "glob", @@ -1594,7 +1652,7 @@ "capabilities": [ { "name": "license", - "default": false + "default": true }, { "name": "dependency.depth", @@ -1636,6 +1694,15 @@ "ecosystem": "rust", "name": "cargo-auditable-binary-cataloger", "type": "generic", + "selectors": [ + "binary", + "directory", + "image", + "installed", + "language", + "package", + "rust" + ], "patterns": [ { "method": "mimetype", @@ -1695,6 +1762,14 @@ "ecosystem": "rust", "name": "rust-cargo-lock-cataloger", "type": "generic", + "selectors": [ + "cargo", + "declared", + "directory", + "language", + "package", + "rust" + ], "patterns": [ { "method": "glob", @@ -1754,6 +1829,14 @@ "ecosystem": "swift", "name": "cocoapods-cataloger", "type": "generic", + "selectors": [ + "cocoapods", + "declared", + "directory", + "language", + "package", + "swift" + ], "patterns": [ { "method": "glob", @@ -1811,6 +1894,14 @@ "ecosystem": "swift", "name": "swift-package-manager-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "language", + "package", + "spm", + "swift" + ], "patterns": [ { "method": "glob", @@ -1866,6 +1957,14 @@ "ecosystem": "c++", "name": "conan-cataloger", "type": "generic", + "selectors": [ + "conan", + "cpp", + "declared", + "directory", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -1912,7 +2011,11 @@ }, { "name": "package_manager.package_integrity_hash", - "default": false + "default": true, + "evidence": [ + "ConanV1LockEntry.Ref", + "ConanV2LockEntry.RecipeRevision" + ] } ] }, @@ -1968,6 +2071,14 @@ "ecosystem": "c++", "name": "conan-info-cataloger", "type": "generic", + "selectors": [ + "conan", + "cpp", + "image", + "installed", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -2021,6 +2132,12 @@ "ecosystem": "conda", "name": "conda-meta-cataloger", "type": "generic", + "selectors": [ + "conda", + "directory", + "installed", + "package" + ], "patterns": [ { "method": "glob", @@ -2071,7 +2188,11 @@ }, { "name": "package_manager.package_integrity_hash", - "default": true + "default": true, + "evidence": [ + "CondaMetaPackage.MD5", + "CondaMetaPackage.SHA256" + ] } ] } @@ -2081,6 +2202,13 @@ "ecosystem": "dart", "name": "dart-pubspec-cataloger", "type": "generic", + "selectors": [ + "dart", + "declared", + "directory", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -2135,6 +2263,13 @@ "ecosystem": "dart", "name": "dart-pubspec-lock-cataloger", "type": "generic", + "selectors": [ + "dart", + "declared", + "directory", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -2187,9 +2322,19 @@ ] }, { - "ecosystem": "debian", + "ecosystem": "dpkg", "name": "dpkg-db-cataloger", "type": "generic", + "selectors": [ + "debian", + "directory", + "dpkg", + "image", + "installed", + "linux", + "os", + "package" + ], "patterns": [ { "method": "glob", @@ -2250,9 +2395,18 @@ ] }, { - "ecosystem": "debian", + "ecosystem": "dpkg", "name": "deb-archive-cataloger", "type": "generic", + "selectors": [ + "deb", + "debian", + "declared", + "directory", + "linux", + "os", + "package" + ], "patterns": [ { "method": "glob", @@ -2308,6 +2462,15 @@ "ecosystem": "dotnet", "name": "dotnet-deps-binary-cataloger", "type": "custom", + "selectors": [ + "c#", + "directory", + "dotnet", + "image", + "installed", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -2366,6 +2529,11 @@ "ecosystem": "dotnet", "name": "dotnet-deps-cataloger", "type": "custom", + "selectors": [ + "deprecated", + "package" + ], + "deprecated": true, "patterns": [ { "method": "glob", @@ -2420,6 +2588,15 @@ "ecosystem": "dotnet", "name": "dotnet-packages-lock-cataloger", "type": "generic", + "selectors": [ + "c#", + "declared", + "directory", + "dotnet", + "image", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -2479,6 +2656,11 @@ "ecosystem": "dotnet", "name": "dotnet-portable-executable-cataloger", "type": "custom", + "selectors": [ + "deprecated", + "package" + ], + "deprecated": true, "patterns": [ { "method": "glob", @@ -2554,6 +2736,13 @@ "ecosystem": "elixir", "name": "elixir-mix-lock-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "elixir", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -2613,6 +2802,14 @@ "ecosystem": "erlang", "name": "erlang-otp-application-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "erlang", + "language", + "otp", + "package" + ], "patterns": [ { "method": "glob", @@ -2664,6 +2861,13 @@ "ecosystem": "erlang", "name": "erlang-rebar-lock-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "erlang", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -2722,6 +2926,13 @@ "ecosystem": "github-actions", "name": "github-action-workflow-usage-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "github", + "github-actions", + "package" + ], "patterns": [ { "method": "glob", @@ -2772,6 +2983,13 @@ "ecosystem": "github-actions", "name": "github-actions-usage-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "github", + "github-actions", + "package" + ], "patterns": [ { "method": "glob", @@ -2865,6 +3083,17 @@ "ecosystem": "go", "name": "go-module-binary-cataloger", "type": "generic", + "selectors": [ + "binary", + "directory", + "go", + "golang", + "gomod", + "image", + "installed", + "language", + "package" + ], "patterns": [ { "method": "mimetype", @@ -2982,6 +3211,15 @@ "ecosystem": "go", "name": "go-module-file-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "go", + "golang", + "gomod", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -3096,6 +3334,15 @@ "ecosystem": "java", "name": "java-archive-cataloger", "type": "custom", + "selectors": [ + "directory", + "image", + "installed", + "java", + "language", + "maven", + "package" + ], "patterns": [ { "method": "glob", @@ -3114,6 +3361,9 @@ "comment": "JAR-based archives - always active", "package_types": [ "java-archive" + ], + "json_schema_types": [ + "JavaArchive" ] }, { @@ -3131,6 +3381,9 @@ "comment": "ZIP archives require indexed archive support", "package_types": [ "java-archive" + ], + "json_schema_types": [ + "JavaArchive" ] }, { @@ -3166,6 +3419,9 @@ "comment": "TAR archives require unindexed archive support", "package_types": [ "java-archive" + ], + "json_schema_types": [ + "JavaArchive" ] } ], @@ -3256,6 +3512,14 @@ "ecosystem": "java", "name": "java-gradle-lockfile-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "gradle", + "java", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -3311,6 +3575,14 @@ "ecosystem": "java", "name": "java-pom-cataloger", "type": "custom", + "selectors": [ + "declared", + "directory", + "java", + "language", + "maven", + "package" + ], "patterns": [ { "method": "glob", @@ -3365,6 +3637,17 @@ "ecosystem": "java", "name": "java-jvm-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "image", + "installed", + "java", + "jdk", + "jre", + "jvm", + "package" + ], "patterns": [ { "method": "glob", @@ -3423,6 +3706,14 @@ "ecosystem": "java", "name": "graalvm-native-image-cataloger", "type": "custom", + "selectors": [ + "directory", + "image", + "installed", + "java", + "language", + "package" + ], "patterns": [ { "method": "mimetype", @@ -3480,6 +3771,15 @@ "ecosystem": "haskell", "name": "haskell-cataloger", "type": "generic", + "selectors": [ + "cabal", + "declared", + "directory", + "hackage", + "haskell", + "language", + "package" + ], "patterns": [ { "method": "glob", @@ -3633,6 +3933,13 @@ "ecosystem": "homebrew", "name": "homebrew-cataloger", "type": "generic", + "selectors": [ + "directory", + "homebrew", + "image", + "installed", + "package" + ], "patterns": [ { "method": "glob", @@ -3683,6 +3990,15 @@ "ecosystem": "javascript", "name": "javascript-lock-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "javascript", + "language", + "node", + "npm", + "package" + ], "patterns": [ { "method": "glob", @@ -3855,6 +4171,14 @@ "ecosystem": "javascript", "name": "javascript-package-cataloger", "type": "generic", + "selectors": [ + "image", + "installed", + "javascript", + "language", + "node", + "package" + ], "patterns": [ { "method": "glob", @@ -3908,6 +4232,15 @@ "ecosystem": "linux", "name": "linux-kernel-cataloger", "type": "custom", + "selectors": [ + "declared", + "directory", + "image", + "installed", + "kernel", + "linux", + "package" + ], "patterns": [ { "method": "glob", @@ -3975,6 +4308,14 @@ "ecosystem": "lua", "name": "lua-rock-cataloger", "type": "generic", + "selectors": [ + "directory", + "image", + "installed", + "language", + "lua", + "package" + ], "patterns": [ { "method": "glob", @@ -4028,6 +4369,14 @@ "ecosystem": "nix", "name": "nix-cataloger", "type": "custom", + "selectors": [ + "directory", + "image", + "installed", + "language", + "nix", + "package" + ], "patterns": [ { "method": "glob", @@ -4087,6 +4436,11 @@ "ecosystem": "nix", "name": "nix-store-cataloger", "type": "custom", + "selectors": [ + "deprecated", + "package" + ], + "deprecated": true, "patterns": [ { "method": "glob", @@ -4166,6 +4520,14 @@ "ecosystem": "ocaml", "name": "opam-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "language", + "ocaml", + "opam", + "package" + ], "patterns": [ { "method": "glob", @@ -4219,6 +4581,14 @@ "ecosystem": "php", "name": "php-composer-installed-cataloger", "type": "generic", + "selectors": [ + "composer", + "image", + "installed", + "language", + "package", + "php" + ], "patterns": [ { "method": "glob", @@ -4274,6 +4644,14 @@ "ecosystem": "php", "name": "php-composer-lock-cataloger", "type": "generic", + "selectors": [ + "composer", + "declared", + "directory", + "language", + "package", + "php" + ], "patterns": [ { "method": "glob", @@ -4328,6 +4706,15 @@ "ecosystem": "php", "name": "php-interpreter-cataloger", "type": "custom", + "selectors": [ + "binary", + "declared", + "directory", + "image", + "installed", + "package", + "php" + ], "patterns": [ { "method": "glob", @@ -4383,6 +4770,15 @@ "ecosystem": "php", "name": "php-pear-serialized-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "image", + "language", + "package", + "pear", + "php" + ], "patterns": [ { "method": "glob", @@ -4436,6 +4832,11 @@ "ecosystem": "php", "name": "php-pecl-serialized-cataloger", "type": "generic", + "selectors": [ + "deprecated", + "package" + ], + "deprecated": true, "patterns": [ { "method": "glob", @@ -4486,9 +4887,19 @@ ] }, { - "ecosystem": "gentoo", + "ecosystem": "portage", "name": "portage-cataloger", "type": "generic", + "selectors": [ + "directory", + "gentoo", + "image", + "installed", + "linux", + "os", + "package", + "portage" + ], "patterns": [ { "method": "glob", @@ -4548,6 +4959,14 @@ "ecosystem": "python", "name": "python-installed-package-cataloger", "type": "generic", + "selectors": [ + "directory", + "image", + "installed", + "language", + "package", + "python" + ], "patterns": [ { "method": "glob", @@ -4611,6 +5030,13 @@ "ecosystem": "python", "name": "python-package-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "language", + "package", + "python" + ], "patterns": [ { "method": "glob", @@ -4817,7 +5243,9 @@ }, { "name": "dependency.depth", - "default": [] + "default": [ + "direct" + ] }, { "name": "dependency.edges", @@ -4825,7 +5253,9 @@ }, { "name": "dependency.kinds", - "default": [] + "default": [ + "any" + ] }, { "name": "package_manager.files.listing", @@ -4857,6 +5287,14 @@ "ecosystem": "r", "name": "r-package-cataloger", "type": "generic", + "selectors": [ + "directory", + "image", + "installed", + "language", + "package", + "r" + ], "patterns": [ { "method": "glob", @@ -4906,6 +5344,15 @@ "ecosystem": "rpm", "name": "rpm-archive-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "linux", + "os", + "package", + "redhat", + "rpm" + ], "patterns": [ { "method": "glob", @@ -4925,19 +5372,15 @@ }, { "name": "dependency.depth", - "default": [ - "direct" - ] + "default": [] }, { "name": "dependency.edges", - "default": "complete" + "default": "" }, { "name": "dependency.kinds", - "default": [ - "runtime" - ] + "default": [] }, { "name": "package_manager.files.listing", @@ -4965,6 +5408,16 @@ "ecosystem": "rpm", "name": "rpm-db-cataloger", "type": "generic", + "selectors": [ + "directory", + "image", + "installed", + "linux", + "os", + "package", + "redhat", + "rpm" + ], "patterns": [ { "method": "glob", @@ -5072,6 +5525,14 @@ "ecosystem": "ruby", "name": "ruby-gemfile-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "gem", + "language", + "package", + "ruby" + ], "patterns": [ { "method": "glob", @@ -5124,6 +5585,15 @@ "ecosystem": "ruby", "name": "ruby-gemspec-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "gem", + "gemspec", + "language", + "package", + "ruby" + ], "patterns": [ { "method": "glob", @@ -5180,6 +5650,15 @@ "ecosystem": "ruby", "name": "ruby-installed-gemspec-cataloger", "type": "generic", + "selectors": [ + "gem", + "gemspec", + "image", + "installed", + "language", + "package", + "ruby" + ], "patterns": [ { "method": "glob", @@ -5237,6 +5716,10 @@ "ecosystem": "sbom", "name": "sbom-cataloger", "type": "generic", + "selectors": [ + "package", + "sbom" + ], "patterns": [ { "method": "glob", @@ -5296,6 +5779,13 @@ "ecosystem": "snap", "name": "snap-cataloger", "type": "generic", + "selectors": [ + "directory", + "image", + "installed", + "package", + "snap" + ], "patterns": [ { "method": "glob", @@ -5513,6 +6003,14 @@ "ecosystem": "prolog", "name": "swipl-pack-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "language", + "pack", + "package", + "swipl" + ], "patterns": [ { "method": "glob", @@ -5567,6 +6065,12 @@ "ecosystem": "terraform", "name": "terraform-lock-cataloger", "type": "generic", + "selectors": [ + "declared", + "directory", + "package", + "terraform" + ], "patterns": [ { "method": "glob", @@ -5610,7 +6114,10 @@ }, { "name": "package_manager.package_integrity_hash", - "default": true + "default": true, + "evidence": [ + "TerraformLockProviderEntry.Hashes" + ] } ] } @@ -5620,6 +6127,12 @@ "ecosystem": "wordpress", "name": "wordpress-plugins-cataloger", "type": "generic", + "selectors": [ + "directory", + "image", + "package", + "wordpress" + ], "patterns": [ { "method": "glob", diff --git a/data/capabilities/vulnerability-data.yaml b/data/capabilities/vulnerability-data.yaml index bf395ab7..160b157a 100644 --- a/data/capabilities/vulnerability-data.yaml +++ b/data/capabilities/vulnerability-data.yaml @@ -61,6 +61,10 @@ # Supported = true/false # Commentary: Important for RPM/DEB ecosystems where binary packages are built from source packages +#x-ref: +# explanations: +# fix-dates-from-vunnel: 'Fix dates are supplemented by Vunnel observations, not provided directly by a data source.' &fix-dates-from-vunnel +# fix-dates-from-advisory: 'Fix dates match the advisory publication date, or if missing, supplemented by Vunnel observations.' &fix-dates-from-advisory sources: @@ -79,7 +83,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'Enhanced via vunnel fixdater mechanism. Dates are added to the database_specific.anchore.fixes array with date and kind.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -147,7 +150,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Alpine directly. The Alpine SecDB feed does not include fix dates.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -178,7 +180,7 @@ sources: - name: fix.date.source values: - enriched - commentary: 'Fix dates are supplemented by the fixdater tool during Vunnel processing, not provided directly by Alpine SecDB.' + commentary: 'Fix dates are supplemented by Vunnel observations, not provided directly by Alpine SecDB.' # Indicates whether the source provides advisory identifiers for cross-referencing - name: advisory.identifiers @@ -215,7 +217,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Amazon directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -255,7 +256,7 @@ sources: - name: fix.date.source values: - native - commentary: 'Fix availability dates derived from advisory publication date (pubDate from RSS feed) with optional fixdater supplementation.' + commentary: 'Fix availability dates derived from advisory publication date (pubDate from RSS feed) with optional supplementation from Vunnel.' # Indicates whether the source provides advisory identifiers for cross-referencing - name: advisory.identifiers @@ -294,7 +295,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Mariner directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -334,7 +334,7 @@ sources: - name: fix.date.source values: - native - commentary: 'Extracted from OVAL advisory_date field in metadata with fixdater processing.' # TODO: is this accurate? + commentary: 'Extracted from OVAL advisory_date field in optional Vunnel supplementation.' # TODO: is this accurate? # Indicates whether the source provides advisory identifiers for cross-referencing - name: advisory.identifiers @@ -370,7 +370,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Bitnami directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -441,7 +440,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Chainguard directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -510,7 +508,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Chainguard directly. OpenVEX source does not include explicit fix date information.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -581,7 +578,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Debian directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -630,7 +626,6 @@ sources: values: - DSA - DLA - commentary: 'Debian Security Advisory (DSA) and Debian Long Term Support Announcements (DLA) identifiers.' # Indicates whether advisories include modification/update timestamps separate from initial publication - name: advisory.updated_date @@ -659,11 +654,9 @@ sources: # Indicates whether the advisory includes fix version information - name: fix.versions supported: true - commentary: 'ECHO provides fix version information via the fixed_version field in the JSON feed. Empty objects indicate no fix is currently available.' # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by ECHO directly. Fix dates are supplemented by the fixdater tool during Vunnel processing.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -671,57 +664,44 @@ sources: supported: true values: - fixed - - not_fixed - commentary: 'Fix states are inferred during transformation. "fixed" is set when a fix version exists, "not_fixed" when no fix version exists. ECHO does not use the "wont-fix" state.' - # TODO: ... # Indicates whether the advisory discloses the vulnerability regardless of fix availability - # - name: disclosure.affected - # supported: unknown - # commentary: 'Test fixtures show ECHO includes CVEs without fixes, suggesting potential independent disclosure. However, unclear if empty fix versions represent "not yet fixed" or "vulnerability disclosed without fix". Needs verification against live feed.' + - name: disclosure.affected + supported: false # Indicates whether the advisory includes a disclosure date (must be able to describe a date separate from the fix date) - name: disclosure.date supported: false - commentary: 'ECHO source data does not provide disclosure dates. The OSSchema supports Metadata.Issued and Metadata.Updated fields, but the ECHO parser does not populate these from the source feed.' - # TODO: ... # Indicates whether the advisory includes severity categories (aka string severity levels) - # - name: disclosure.severity.categories - # supported: unknown - # commentary: 'The ECHO parser checks for an optional severity field in the source data, suggesting the source MAY provide categorical severity. However, all test fixtures show "Unknown" severity. Needs verification against actual feed to determine if severity categories are ever provided.' + - name: disclosure.severity.categories + supported: false # Indicates if CVSS vectors are provided - name: disclosure.severity.cvss supported: false - commentary: 'ECHO source data does not provide CVSS vectors. The CVSS array is empty for all ECHO test fixtures, and the parser does not extract CVSS information from the feed.' # Indicates whether fix dates are native to the data source or enriched by external tooling - name: fix.date.source values: - enriched - commentary: 'Fix dates are enriched via the fixdater tool during Vunnel processing, not provided natively by ECHO.' # Indicates whether the source provides advisory identifiers for cross-referencing - name: advisory.identifiers supported: false - commentary: 'ECHO does not provide advisory IDs for cross-referencing. Only CVE IDs are tracked.' # Indicates whether advisories include modification/update timestamps separate from initial publication - name: advisory.updated_date supported: false - commentary: 'ECHO does not provide modification timestamps separate from publication dates. The Metadata fields Issued and Updated are not populated by the ECHO parser.' # Indicates whether the source provides version ranges versus point versions only - name: fix.version_ranges values: - point - commentary: 'ECHO provides point versions (specific fixed version numbers like "1.25.2"), not version ranges. The transformer derives constraints from these point versions.' # Indicates whether the source tracks upstream/source packages in addition to binary packages - name: package.upstream_tracking supported: true - commentary: 'The source package is used to track vulnerabilities in addition to binary packages.' github: name: GitHub Security Advisories @@ -737,7 +717,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by GitHub directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -812,7 +791,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Mariner directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -887,7 +865,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by MINIMOS directly. Fix dates are enriched by the fixdater tool during Vunnel processing, which tracks when package versions first appeared in repositories.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -961,7 +938,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'Fix dates are NOT provided by NVD directly. They are enriched via external fixdaters that track when fixes become available in various ecosystems.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -1043,7 +1019,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Oracle directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -1125,7 +1100,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Red Hat directly. The Red Hat Security Data API provides a "public_date" field, but vunnel does not extract it as a fix date.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -1205,7 +1179,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by SUSE directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -1288,7 +1261,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Ubuntu directly.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -1372,7 +1344,6 @@ sources: # Indicates whether the advisory includes a date when the fix was made available - name: fix.date - commentary: 'These are tracked by nightly builds of the vunnel and Grype DB data and not provided by Wolfi directly. The Wolfi security.json feed does not include fix dates.' supported: true # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) @@ -1439,7 +1410,6 @@ sources: # # # Indicates whether the advisory includes a date when the fix was made available # - name: fix.date -# commentary: 'Enhanced via vunnel fixdater mechanism. Dates are added to the database_specific.anchore.fixes array with date and kind (e.g., "advisory", "snapshot", "first-observed").' # supported: true # # # Indicates whether the advisory includes fix state information (e.g., fixed, not fixed, etc.) diff --git a/data/syft/cli/version/output.txt b/data/syft/cli/version/output.txt index 53ff542d..863d9d78 100644 --- a/data/syft/cli/version/output.txt +++ b/data/syft/cli/version/output.txt @@ -1,9 +1,14 @@ -Application: syft -Version: 1.33.0-SNAPSHOT-1510db7c -BuildDate: 2025-10-14T14:06:38Z -GitCommit: 1510db7c4ea279ff41bc5f0dca627ec2c1c200d0 -GitDescription: v1.33.0-35-g1510db7c -Platform: linux/amd64 -GoVersion: go1.24.4 -Compiler: gc -SchemaVersion: 16.0.40 +show version information + +Usage: + syft version [flags] + +Flags: + -h, --help help for version + -o, --output string the format to show the results (allowable: [text json]) (default "text") + +Global Flags: + -c, --config stringArray syft configuration file(s) to use + --profile stringArray configuration profiles to use + -q, --quiet suppress all logging output + -v, --verbose count increase verbosity (-v = info, -vv = debug) diff --git a/hugo.yaml b/hugo.yaml index 5db99e36..c13a80b9 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -52,6 +52,13 @@ params: github_repo: https://github.com/anchore/oss-docs github_project_repo: https://github.com/anchore/oss-docs offlineSearch: true + capabilities_groups: + - id: 'os' + title: 'OS Distro' + - id: 'language' + title: 'Language / Framework' + - id: 'other' + title: 'Other' links: user: - name: OSS Docs home diff --git a/layouts/partials/sidebar-tree.html b/layouts/partials/sidebar-tree.html index 1a77fbc3..6c384b7f 100644 --- a/layouts/partials/sidebar-tree.html +++ b/layouts/partials/sidebar-tree.html @@ -67,11 +67,64 @@ {{- end }} {{- if $withChild }} {{- $ulNr := add $ulNr 1 }} - ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") @@ -678,10 +776,10 @@ def generate_app_config_snippet( html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") @@ -774,81 +872,6 @@ def clean_glob_pattern(pattern: str) -> str: return pattern.removeprefix("**/") -def format_evidence_for_tooltip(evidence: list[str]) -> str: - """ - format evidence field paths for tooltip display. - - Args: - evidence: list of evidence field paths (e.g., ['AlpmDBEntry.Files']) - - Returns: - formatted string for tooltip: - - empty string if no evidence - - single path if one item - - bullet list with line breaks if multiple items - """ - if not evidence: - return "" - - if len(evidence) == 1: - return evidence[0] - - # format as bullet list with line breaks for multiple items - return " ".join(f"• {path}" for path in evidence) - - -def get_svg_icon(icon_type: str) -> str: - """ - get SVG icon HTML for a capability indicator. - - Args: - icon_type: 'check', 'gear', or 'dash' - - Returns: - HTML string with SVG icon - """ - if icon_type not in ["check", "gear", "dash"]: - icon_type = "dash" - return f'' - - -def get_capability_indicator_svg(cap_support: CapabilitySupport | None) -> str: - """ - get the SVG icon for a capability support level. - - Args: - cap_support: CapabilitySupport object or None - - Returns: - HTML string with SVG icon (with data-evidence attribute if evidence exists), or empty string if not supported - """ - if cap_support is None: - return "" - - # determine icon type - if cap_support.conditional: - icon_type = "gear" - elif cap_support.supported: - icon_type = "check" - else: - return "" - - # format evidence for tooltip if present - evidence_attr = "" - if cap_support.evidence: - formatted_evidence = format_evidence_for_tooltip(cap_support.evidence) - if formatted_evidence: - # escape quotes in evidence for HTML attribute - escaped_evidence = formatted_evidence.replace('"', """) - evidence_attr = f' data-evidence="{escaped_evidence}"' - - # wrap SVG in span when evidence exists (SVG elements don't support ::after pseudo-elements) - if evidence_attr: - return f'' - else: - return f'' - - def has_any_dependency_support( capabilities: dict[str, CapabilitySupport], ) -> CapabilitySupport | None: @@ -880,6 +903,7 @@ def has_any_dependency_support( conditional=has_conditional, default_value=None, evidence=[], # aggregated dependency support has no specific evidence + conditions=[], # aggregated dependency support has no specific conditions ) return None @@ -919,7 +943,7 @@ def generate_overview_table( rowspans = _calculate_rowspans_for_overview(sorted_rows) # generate comment - comment = get_generated_comment("scripts/generate_capability_tables.py", "html") + comment = config.get_generated_comment("scripts/generate_capability_tables.py", "html") comment += "\n\n" comment += "\n" @@ -927,23 +951,23 @@ def generate_overview_table( html_lines = [] # table header - single row with simple columns (5 columns total) - html_lines.append('
Configuration Key Configuration KeyDescription Description
{app_key}{app_key}{cleaned_description}{cleaned_description}
') + html_lines.append(f'
') html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") @@ -962,7 +986,7 @@ def generate_overview_table( ) ecosystem_display = get_ecosystem_display_name(row.ecosystem, display_names) html_lines.append( - f' ' + f' ' ) # cataloger column with evidence (no rowspan - each row shows its own) @@ -972,25 +996,27 @@ def generate_overview_table( row.paths, row.mimetypes, row.class_pattern_pairs, + row.deprecated, + row.conditions, ) - html_lines.append(f' ') + html_lines.append(f' ') # license column (SVG indicator) license_cap = row.capabilities.get("license") html_lines.append( - f' ' + f' ' ) # dependency column (aggregated SVG indicator) dependency_cap = has_any_dependency_support(row.capabilities) html_lines.append( - f' ' + f' ' ) # files column (SVG indicator) files_cap = row.capabilities.get("package_manager.files.listing") html_lines.append( - f' ' + f' ' ) html_lines.append(" ") @@ -1041,7 +1067,7 @@ def generate_ecosystem_table( sorted_rows = sorted(ecosystem_rows, key=lambda r: r.cataloger_name) # generate comment - comment = get_generated_comment("scripts/generate_capability_tables.py", "html") + comment = config.get_generated_comment("scripts/generate_capability_tables.py", "html") comment += "\n\n" comment += "\n" @@ -1049,40 +1075,40 @@ def generate_ecosystem_table( html_lines = [] # table header with two-row grouped structure - html_lines.append('
Ecosystem EcosystemCataloger + Evidence Cataloger + EvidenceLicenses LicensesDependencies DependenciesFiles Files
{ecosystem_display}{ecosystem_display}{cataloger_content}{cataloger_content}{get_capability_indicator_svg(license_cap)}{html_table.get_capability_indicator_svg(license_cap)}{get_capability_indicator_svg(dependency_cap)}{html_table.get_capability_indicator_svg(dependency_cap)}{get_capability_indicator_svg(files_cap)}{html_table.get_capability_indicator_svg(files_cap)}
') + html_lines.append(f'
') html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") @@ -1093,51 +1119,58 @@ def generate_ecosystem_table( html_lines.append(" ") # cataloger column with evidence (no rowspan - each row shows its own) - cataloger_content = format_cataloger_with_evidence( - row.cataloger_name, - row.globs, - row.paths, - row.mimetypes, - row.class_pattern_pairs, - ) - html_lines.append(f' ') + # special handling for binary-classifier-cataloger in ecosystem-specific tables + if row.cataloger_name == "binary-classifier-cataloger": + deprecated_pill = ' deprecated' if row.deprecated else '' + cataloger_content = f'
binary-classifier-cataloger{deprecated_pill}
(see table below)
' + else: + cataloger_content = format_cataloger_with_evidence( + row.cataloger_name, + row.globs, + row.paths, + row.mimetypes, + row.class_pattern_pairs, + row.deprecated, + row.conditions, + ) + html_lines.append(f' ') # license column (SVG indicator) license_cap = row.capabilities.get("license") html_lines.append( - f' ' + f' ' ) # dependency columns (individual values) depth_cap = row.capabilities.get("dependency.depth") html_lines.append( - f' ' + f' ' ) edges_cap = row.capabilities.get("dependency.edges") html_lines.append( - f' ' + f' ' ) kinds_cap = row.capabilities.get("dependency.kinds") html_lines.append( - f' ' + f' ' ) # package manager columns (SVG indicators) files_cap = row.capabilities.get("package_manager.files.listing") html_lines.append( - f' ' + f' ' ) digests_cap = row.capabilities.get("package_manager.files.digests") html_lines.append( - f' ' + f' ' ) integrity_cap = row.capabilities.get("package_manager.package_integrity_hash") html_lines.append( - f' ' + f' ' ) html_lines.append(" ") @@ -1155,86 +1188,129 @@ def generate_ecosystem_table( logger.debug(f"Generated {output_file}") -@click.command() -@click.option( - "--update", - is_flag=True, - help="Update the cataloger data cache even if it already exists", -) -@click.option( - "-v", - "--verbose", - count=True, - help="Increase verbosity (use -v for info, -vv for debug)", -) -def main(update: bool, verbose: int) -> None: - """Generate package capability table snippets from Syft cataloger information.""" - logger = setup_logging(verbose, __file__) +def generate_binary_package_details_table( + cataloger_data: dict, output_dir: Path, logger +) -> None: + """ + generate binary package details table showing class-to-package mappings. - # Clean output directory to ensure no stale content - # Note: This script runs first and shares output dir with generate_capability_vulnerability_tables.py - output_dir = paths.capabilities_snippet_dir - if output_dir.exists(): - logger.debug(f"Cleaning output directory: {output_dir}") - shutil.rmtree(output_dir) + creates a table showing detailed information about each pattern in the + binary-classifier-cataloger, including class, criteria, PURL, and CPEs. - # load ecosystem aliases - logger.debug("Loading ecosystem aliases...") - ecosystem_aliases = load_ecosystem_aliases() - if ecosystem_aliases: - logger.debug(f"Loaded {len(ecosystem_aliases)} ecosystem aliases") + Args: + cataloger_data: dict from syft cataloger info + output_dir: output directory for snippets (ecosystem/binary/) + logger: logger instance + """ + # find binary-classifier-cataloger + catalogers = cataloger_data.get("catalogers", []) + binary_cataloger = None + for cataloger in catalogers: + if cataloger.get("name") == "binary-classifier-cataloger": + binary_cataloger = cataloger + break - # load ecosystem display names - logger.debug("Loading ecosystem display names...") - ecosystem_display_names = load_ecosystem_display_names() - if ecosystem_display_names: - logger.debug(f"Loaded {len(ecosystem_display_names)} ecosystem display names") + if not binary_cataloger: + logger.warning("binary-classifier-cataloger not found in cataloger data") + return - # load or generate cataloger data - cataloger_data = load_cataloger_data(update=update) + patterns = binary_cataloger.get("patterns", []) + if not patterns: + logger.warning("No patterns found in binary-classifier-cataloger") + return - # parse catalogers into rows - logger.info("Parsing cataloger capabilities...") - rows = parse_catalogers(cataloger_data, ecosystem_aliases) + # create output directory + binary_dir = output_dir / "binary" + binary_dir.mkdir(parents=True, exist_ok=True) - if not rows: - logger.error("No catalogers found") - sys.exit(1) + output_file = binary_dir / "binary-package-details.md" - logger.info( - f"Found {len(rows)} cataloger patterns across {len({r.ecosystem for r in rows})} ecosystems" - ) + # generate comment + comment = config.get_generated_comment("scripts/generate_capability_tables.py", "html") + comment += "\n\n" + comment += "\n" - # generate tables - logger.info("Generating tables...") + # build HTML lines + html_lines = [] - # generate overview table - generate_overview_table( - rows, - paths.capabilities_snippet_dir / "overview", - ecosystem_display_names, - logger, + # table header text + html_lines.append('
Binary Package Details
') + + # table header + html_lines.append(f'
Cataloger + Evidence Cataloger + EvidenceLicense LicenseDependencies DependenciesPackage Manager Claims Package Manager Claims
Depth DepthEdges EdgesKinds KindsFiles FilesDigests DigestsIntegrity Hash Integrity Hash
{cataloger_content}{cataloger_content}{get_capability_indicator_svg(license_cap)}{html_table.get_capability_indicator_svg(license_cap)}{format_depth_value(depth_cap)}{format_depth_value(depth_cap)}{format_edges_value(edges_cap)}{format_edges_value(edges_cap)}{format_kinds_value(kinds_cap)}{format_kinds_value(kinds_cap)}{get_capability_indicator_svg(files_cap)}{html_table.get_capability_indicator_svg(files_cap)}{get_capability_indicator_svg(digests_cap)}{html_table.get_capability_indicator_svg(digests_cap)}{get_capability_indicator_svg(integrity_cap)}{html_table.get_capability_indicator_svg(integrity_cap)}
') + html_lines.append(" ") + html_lines.append(" ") + html_lines.append( + ' ' + ) + html_lines.append( + ' ' ) + html_lines.append( + ' ' + ) + html_lines.append( + ' ' + ) + html_lines.append(" ") + html_lines.append(" ") + html_lines.append(" ") - # generate individual ecosystem tables - ecosystems = {r.ecosystem for r in rows} - for ecosystem in sorted(ecosystems): - generate_ecosystem_table( - ecosystem, rows, paths.capabilities_snippet_dir / "ecosystem", logger - ) + # sort patterns by class name for consistent output + def get_class_name(pattern): + packages = pattern.get("packages", []) + if packages: + return packages[0].get("class", "") + return "" - # collect and generate app config snippets - logger.info("Generating app config snippets...") - app_configs = collect_app_configs_by_ecosystem(cataloger_data, ecosystem_aliases) - for ecosystem, config_fields in app_configs.items(): - generate_app_config_snippet( - ecosystem, - config_fields, - paths.capabilities_snippet_dir / "ecosystem", - logger, - ) + sorted_patterns = sorted(patterns, key=get_class_name) + + # table body - one row per pattern + for pattern in sorted_patterns: + packages = pattern.get("packages", []) + if not packages: + continue + + pkg = packages[0] # each pattern has exactly one package + class_name = pkg.get("class", "") + purl = pkg.get("purl", "") + cpes = pkg.get("cpes", []) + + # format criteria (glob patterns) + criteria = pattern.get("criteria", []) + if criteria: + criteria_html = ", ".join(f"{clean_glob_pattern(c)}" for c in criteria) + else: + criteria_html = "-" + + # format CPEs + if not cpes: + cpes_html = "-" + elif len(cpes) == 1: + cpes_html = f"{cpes[0]}" + else: + # multiple CPEs - show as separate lines + cpes_html = "
".join(f"{cpe}" for cpe in cpes) + + html_lines.append(" ") + html_lines.append(f' ') + html_lines.append(f' ') + html_lines.append(f' ') + html_lines.append(f' ') + html_lines.append(" ") + + # close table + html_lines.append(" ") + html_lines.append("
ClassCriteriaPURLCPEs
{class_name}{criteria_html}{purl}{cpes_html}
") + + # write file + with open(output_file, "w") as f: + f.write(comment) + for line in html_lines: + f.write(line + "\n") + + logger.debug(f"Generated {output_file}") - logger.info("Generation complete!") if __name__ == "__main__": diff --git a/scripts/generate_capability_vulnerability_tables.py b/scripts/generate_capability_vulnerability_tables.py index 06fa84c3..984a2da0 100644 --- a/scripts/generate_capability_vulnerability_tables.py +++ b/scripts/generate_capability_vulnerability_tables.py @@ -17,40 +17,8 @@ from pathlib import Path import click -from utils.config import get_generated_comment, paths -from utils.data import ( - load_cataloger_data, - load_ecosystem_aliases, - load_os_data, - load_vulnerability_data, -) -from utils.logging import get_logger, setup_logging - -# Header definitions for tooltips -HEADER_DEFINITIONS = { - "operating_system": "The operating system distribution name", - "supported_versions": "Which OS versions have vulnerability data available", - "vunnel_provider": "The vunnel provider that supplies vulnerability data for this OS", - "provider": "The vunnel provider that supplies vulnerability data", - "data_source": "The upstream vulnerability database or security feed", - "disclosures": "Information about when and how vulnerabilities are disclosed", - "fixes": "Information about vulnerability fixes and their availability", - "disclosure_affected": "Whether vulnerabilities are reported even when no fix exists yet", - "disclosure_date": "When the vulnerability was first publicly disclosed (separate from fix availability date)", - "fix_versions": "Which package versions contain fixes for the vulnerability", - "fix_date": "When the fix was made available", - "source_package": "Whether the data source tracks upstream/source packages in addition to binary packages (important for RPM/DEB ecosystems)", - "configuration_key": "The configuration field name used in Grype application configuration", - "description": "Explanation of what the configuration option controls", -} - - -@dataclass -class OSVersion: - """represents an operating system version.""" - - value: str - codename: str | None = None +from utils import config, data, html_table, log +from utils.constants import HEADER_DEFINITIONS, CSSClasses @dataclass @@ -58,7 +26,7 @@ class OS: """represents an operating system with its versions.""" name: str - versions: list[OSVersion] + versions: list[html_table.OSVersion] release_id: str provider: str channel: str | None = None @@ -74,12 +42,116 @@ class DataSource: vunnel_provider: str + +@click.command() +@click.option( + "--update", + is_flag=True, + help="Update the cataloger data cache even if it already exists", +) +@click.option( + "-v", + "--verbose", + count=True, + help="Increase verbosity (use -v for info, -vv for debug)", +) +def main(update: bool, verbose: int) -> None: + """Generate vulnerability data source and OS support tables.""" + logger = log.setup(verbose, __file__) + + # Clean only owned files to avoid deleting artifacts from other scripts + output_dir = config.paths.capabilities_snippet_dir + owned_files = { + "os.md", + "vulnerability.md", + "grype-app-config.md", + } + html_table.clean_owned_files(output_dir, owned_files, logger) + + # load data + logger.info("Loading operating system data...") + os_data = data.load_os_data() + os_list = _convert_os_data_to_objects(os_data) + logger.debug(f"Loaded {len(os_list)} operating systems") + + logger.info("Loading vulnerability data...") + vuln_data = data.load_vulnerability_data() + logger.debug( + f"Loaded {len(vuln_data.get('sources', {}))} data sources and {len(vuln_data.get('ecosystems', {}))} ecosystems" + ) + + logger.debug("Loading ecosystem aliases...") + ecosystem_aliases = data.load_ecosystem_aliases() + if ecosystem_aliases: + logger.debug(f"Loaded {len(ecosystem_aliases)} ecosystem aliases") + + logger.debug("Loading cataloger data...") + cataloger_data = data.load_cataloger_data(update=update) + + logger.info("Extracting ecosystems from catalogers...") + all_ecosystems = extract_ecosystems_from_catalogers( + cataloger_data, ecosystem_aliases + ) + logger.info(f"Found {len(all_ecosystems)} ecosystems from Syft catalogers") + + # generate tables + logger.info("Generating tables...") + + # generate overview OS table + generate_overview_os_table( + os_list, vuln_data, config.paths.capabilities_snippet_dir / "overview" + ) + + # generate tables for each ecosystem + logger.info("Generating ecosystem-specific tables...") + for ecosystem_name in sorted(all_ecosystems): + # skip 'default' - it's a template only + if ecosystem_name == "default": + continue + + # get ecosystem definition (will fall back to default if not defined) + ecosystem_def = get_ecosystem_definition(ecosystem_name, vuln_data) + ecosystem_kind = ecosystem_def.get("kind", "unknown") + + logger.debug(f"Processing {ecosystem_name} (kind={ecosystem_kind})...") + + # for OS ecosystems, generate OS support table + if ecosystem_kind == "os": + generate_os_ecosystem_table( + ecosystem_name, + os_list, + vuln_data, + config.paths.capabilities_snippet_dir / "ecosystem", + ) + generate_os_ecosystem_vulnerability_capabilities_table( + ecosystem_name, + os_list, + vuln_data, + config.paths.capabilities_snippet_dir / "ecosystem", + ) + else: + # for language/other/default ecosystems, generate vulnerability capabilities table + generate_ecosystem_vulnerability_capabilities_table( + ecosystem_name, vuln_data, config.paths.capabilities_snippet_dir / "ecosystem" + ) + + # generate config snippet if ecosystem has configuration + config_fields = ecosystem_def.get("config", []) + if config_fields: + generate_grype_config_snippet( + ecosystem_name, + config_fields, + config.paths.capabilities_snippet_dir / "ecosystem", + ) + + logger.info("Generation complete!") + def _convert_os_data_to_objects(data: list[dict]) -> list[OS]: """ convert OS data from JSON format to OS objects. Args: - data: list of OS dictionaries from load_os_data() + data: list of OS dictionaries from data.load_os_data() Returns: list of OS objects @@ -89,7 +161,7 @@ def _convert_os_data_to_objects(data: list[dict]) -> list[OS]: versions = [] for version_entry in os_entry.get("versions", []): versions.append( - OSVersion( + html_table.OSVersion( value=version_entry.get("value", ""), codename=version_entry.get("codename"), ) @@ -188,199 +260,6 @@ def get_advisory_identifiers(source_info: dict) -> str: return "" -def sort_versions(versions: list[OSVersion]) -> list[OSVersion]: - """ - sort OS versions numerically with special handling for non-numeric versions. - - Args: - versions: list of OSVersion objects - - Returns: - sorted list of OSVersion objects - """ - special_versions = [] - numeric_versions = [] - - for version in versions: - # check if version is special (non-numeric or single word) - if version.value.lower() in ["rolling", "unstable", "edge"]: - special_versions.append(version) - else: - numeric_versions.append(version) - - # sort numeric versions - def version_key(v: OSVersion) -> tuple: - """generate sort key for version.""" - try: - # split on '.' and convert to numbers - parts = v.value.split(".") - # convert each part to int if possible, otherwise keep as string - numeric_parts = [] - for part in parts: - try: - numeric_parts.append(int(part)) - except ValueError: - # if we hit a non-numeric part, keep it as high value string - numeric_parts.append((999999, part)) - return tuple(numeric_parts) - except Exception: - # fallback to string comparison - return (999999, v.value) - - numeric_versions.sort(key=version_key) - - # combine numeric first, then special versions - return numeric_versions + special_versions - - -def summarize_versions(versions: list[OSVersion]) -> list[OSVersion]: - """ - summarize continuous version ranges into condensed format. - - Examples: - [11.1, 11.2, 11.3] -> [11] (if continuous from .1) - [11.2, 11.3, 11.4] -> [11.2+] (starts from .2, not .0 or .1) - [11.0, 11.1, 11.2] -> [11] (has .0) - [3.2, 3.3, ..., 3.22, edge] -> [3.2+, edge] - - Args: - versions: sorted list of OSVersion objects - - Returns: - condensed list of OSVersion objects - """ - if not versions: - return [] - - # separate special versions - special_versions = [] - numeric_versions = [] - - for v in versions: - if v.value.lower() in ["rolling", "unstable", "edge"]: - special_versions.append(v) - else: - numeric_versions.append(v) - - if not numeric_versions: - return special_versions - - # group by major version - from collections import defaultdict - - major_groups = defaultdict(list) - - for v in numeric_versions: - try: - parts = v.value.split(".") - major = parts[0] - major_groups[major].append(v) - except Exception: - # can't parse, keep as-is - major_groups[v.value].append(v) - - result = [] - - # process each major version group - for major in sorted( - major_groups.keys(), key=lambda x: int(x) if x.isdigit() else 999999 - ): - group = major_groups[major] - - if len(group) == 1: - # single version, keep as-is - result.append(group[0]) - continue - - # check if we have version.0 - has_zero = any(v.value == major or v.value == f"{major}.0" for v in group) - - # extract minor versions - minors = [] - for v in group: - parts = v.value.split(".") - if len(parts) == 1: - # just major version (e.g., "11") - minors.append((0, v)) - elif len(parts) == 2: - try: - minor = int(parts[1]) - minors.append((minor, v)) - except ValueError: - # non-numeric minor, keep as-is - result.append(v) - continue - else: - # more complex version, keep as-is - result.append(v) - continue - - # sort by minor version - minors.sort(key=lambda x: x[0]) - - if not minors: - # no valid minors, add all as-is - result.extend(group) - continue - - # check for continuous sequence - min_minor = minors[0][0] - max_minor = minors[-1][0] - - # check if sequence is continuous - expected_minors = set(range(min_minor, max_minor + 1)) - actual_minors = {m[0] for m in minors} - is_continuous = expected_minors == actual_minors - - # decide how to summarize - if has_zero or (min_minor == 1 and is_continuous): - # has .0 or starts from .1 continuously - show just major - # keep codename from highest minor version if present - highest_version = minors[-1][1] - if highest_version.codename: - result.append(OSVersion(value=major, codename=highest_version.codename)) - else: - result.append(OSVersion(value=major)) - elif min_minor > 1 and is_continuous: - # starts from .2+ without .0 or .1 - show "major.minor+" - result.append(OSVersion(value=f"{major}.{min_minor}+")) - else: - # not continuous or has gaps, keep all versions - for _, v in minors: - result.append(v) - - return result + special_versions - - -def format_versions_list(versions: list[OSVersion]) -> str: - """ - format OS versions for display, with codenames in parentheses. - - Versions are sorted numerically and continuous ranges are summarized. - - Args: - versions: list of OSVersion objects - - Returns: - formatted string like "10 (buster), 11 (bullseye), 12 (bookworm)" or "3.2+, edge" - """ - if not versions: - return "-" - - # sort and summarize versions - sorted_versions = sort_versions(versions) - summarized_versions = summarize_versions(sorted_versions) - - formatted = [] - for version in summarized_versions: - if version.codename: - formatted.append(f"{version.value} ({version.codename})") - else: - formatted.append(version.value) - - return ", ".join(formatted) - - def generate_overview_os_table( os_list: list[OS], vuln_data: dict, @@ -415,27 +294,27 @@ def generate_overview_os_table( all_os_names = set(os_by_name.keys()) # generate comment - comment = get_generated_comment("scripts/generate_vulnerability_tables.py", "html") + comment = config.get_generated_comment("scripts/generate_vulnerability_tables.py", "html") comment += "\n\n" # build HTML lines html_lines = [] # table header with CSS classes matching capability tables - html_lines.append('') + html_lines.append(f'
') html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") @@ -463,12 +342,12 @@ def generate_overview_os_table( # handle multiple entries (e.g., RedHat with EUS) if len(os_entries) == 1: # single entry, format versions normally - versions_str = format_versions_list(os_entries[0].versions) + versions_str = html_table.format_versions_list(os_entries[0].versions) else: # multiple entries, combine with
separator version_parts = [] for entry in os_entries: - versions = format_versions_list(entry.versions) + versions = html_table.format_versions_list(entry.versions) if entry.channel: # annotate with channel name (e.g., "EUS: ") version_parts.append(f"{entry.channel.upper()}: {versions}") @@ -476,7 +355,7 @@ def generate_overview_os_table( version_parts.append(versions) versions_str = "
".join(version_parts) - provider_cell = os_entries[0].provider + provider_cell = f"{os_entries[0].provider}" # format data source as link if source_url: @@ -490,10 +369,10 @@ def generate_overview_os_table( data_source_cell = "-" html_lines.append(" ") - html_lines.append(f' ') - html_lines.append(f' ') - html_lines.append(f' ') - html_lines.append(f' ') + html_lines.append(f' ') + html_lines.append(f' ') + html_lines.append(f' ') + html_lines.append(f' ') html_lines.append(" ") # close table @@ -506,7 +385,7 @@ def generate_overview_os_table( for line in html_lines: f.write(line + "\n") - logger = get_logger(__name__) + logger = log.logger(__name__) logger.debug(f"Generated {output_file}") @@ -536,14 +415,14 @@ def generate_os_ecosystem_vulnerability_capabilities_table( os_definitions = vuln_data.get("os", {}) # find OSes that use this ecosystem - # note: 'like' references are already resolved in load_vulnerability_data() + # note: 'like' references are already resolved in data.load_vulnerability_data() os_names = [] for os_name, os_def in os_definitions.items(): if os_def.get("ecosystem") == ecosystem: os_names.append(os_name) if not os_names: - logger = get_logger(__name__) + logger = log.logger(__name__) logger.warning(f"No operating systems defined for ecosystem {ecosystem}") return @@ -579,7 +458,7 @@ def generate_os_ecosystem_vulnerability_capabilities_table( source_keys.append("nvd") if not source_keys: - logger = get_logger(__name__) + logger = log.logger(__name__) logger.warning(f"No sources found for ecosystem {ecosystem}") return @@ -618,7 +497,7 @@ def generate_os_ecosystem_vulnerability_capabilities_table( ] # generate comment - comment = get_generated_comment( + comment = config.get_generated_comment( "scripts/generate_capability_vulnerability_tables.py", "html" ) comment += "\n\n" @@ -628,35 +507,35 @@ def generate_os_ecosystem_vulnerability_capabilities_table( # table header with two-row grouped structure html_lines.append( - '
Operating System Operating SystemSupported Versions Supported VersionsVunnel Provider Vunnel ProviderData Source Data Source
{os_name_cell}{versions_str}{provider_cell}{data_source_cell}{os_name_cell}{versions_str}{provider_cell}{data_source_cell}
' + f'
' ) html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") @@ -683,7 +562,7 @@ def generate_os_ecosystem_vulnerability_capabilities_table( source_cell = f"{source_name}{get_advisory_identifiers(source_info)}" html_lines.append(" ") - html_lines.append(f' ') + html_lines.append(f' ') # add cells for each capability for cap in capabilities_to_include: @@ -702,7 +581,7 @@ def generate_os_ecosystem_vulnerability_capabilities_table( icon_html = "" html_lines.append( - f' ' + f' ' ) html_lines.append(" ") @@ -717,7 +596,7 @@ def generate_os_ecosystem_vulnerability_capabilities_table( for line in html_lines: f.write(line + "\n") - logger = get_logger(__name__) + logger = log.logger(__name__) logger.debug(f"Generated {output_file}") @@ -745,14 +624,14 @@ def generate_os_ecosystem_table( os_definitions = vuln_data.get("os", {}) # find OSes that use this ecosystem - # note: 'like' references are already resolved in load_vulnerability_data() + # note: 'like' references are already resolved in data.load_vulnerability_data() os_names = [] for os_name, os_def in os_definitions.items(): if os_def.get("ecosystem") == ecosystem: os_names.append(os_name) if not os_names: - logger = get_logger(__name__) + logger = log.logger(__name__) logger.warning(f"No operating systems defined for ecosystem {ecosystem}") return @@ -760,27 +639,27 @@ def generate_os_ecosystem_table( sources = vuln_data.get("sources", {}) # generate comment - comment = get_generated_comment("scripts/generate_vulnerability_tables.py", "html") + comment = config.get_generated_comment("scripts/generate_vulnerability_tables.py", "html") comment += "\n\n" # build HTML lines html_lines = [] # table header with CSS classes matching capability tables - html_lines.append('
Data Source Data SourceDisclosures DisclosuresFixes FixesTrack by
Source
Package
Track by
Source
Package
Affected AffectedDate DateVersions VersionsDate Date
{source_cell}{source_cell}{icon_html}{icon_html}
') + html_lines.append(f'
') html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") @@ -809,12 +688,12 @@ def generate_os_ecosystem_table( # handle multiple entries (e.g., RedHat with EUS) if len(os_entries) == 1: # single entry, format versions normally - versions_str = format_versions_list(os_entries[0].versions) + versions_str = html_table.format_versions_list(os_entries[0].versions) else: # multiple entries, combine with
separator version_parts = [] for entry in os_entries: - versions = format_versions_list(entry.versions) + versions = html_table.format_versions_list(entry.versions) if entry.channel: # annotate with channel name (e.g., "EUS: ") version_parts.append(f"{entry.channel.upper()}: {versions}") @@ -822,7 +701,7 @@ def generate_os_ecosystem_table( version_parts.append(versions) versions_str = "
".join(version_parts) - provider_cell = os_entries[0].provider + provider_cell = f"{os_entries[0].provider}" # format data source as link if source_url: @@ -838,7 +717,7 @@ def generate_os_ecosystem_table( # Uses default/stock matcher (NVD with CPEs) os_name_cell = display_name versions_str = "minimal support (CPE-based)" - provider_cell = "nvd" + provider_cell = "nvd" # Get NVD source info for link nvd_source = sources.get("nvd", {}) @@ -857,10 +736,10 @@ def generate_os_ecosystem_table( data_source_cell = "-" html_lines.append(" ") - html_lines.append(f' ') - html_lines.append(f' ') - html_lines.append(f' ') - html_lines.append(f' ') + html_lines.append(f' ') + html_lines.append(f' ') + html_lines.append(f' ') + html_lines.append(f' ') html_lines.append(" ") # close table @@ -873,7 +752,7 @@ def generate_os_ecosystem_table( for line in html_lines: f.write(line + "\n") - logger = get_logger(__name__) + logger = log.logger(__name__) logger.debug(f"Generated {output_file}") @@ -897,7 +776,7 @@ def generate_grype_config_snippet( output_file = ecosystem_dir / "grype-app-config.md" # generate comment - comment = get_generated_comment( + comment = config.get_generated_comment( "scripts/generate_capability_vulnerability_tables.py", "html" ) comment += "\n\n" @@ -906,17 +785,17 @@ def generate_grype_config_snippet( html_lines = [] # table header text - html_lines.append('
Grype Configuration
') + html_lines.append(f'
Grype Configuration
') # table header - html_lines.append('
Operating System Operating SystemSupported Versions Supported VersionsProvider ProviderData Source Data Source
{os_name_cell}{versions_str}{provider_cell}{data_source_cell}{os_name_cell}{versions_str}{provider_cell}{data_source_cell}
') + html_lines.append(f'
') html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") @@ -929,9 +808,9 @@ def generate_grype_config_snippet( html_lines.append(" ") html_lines.append( - f' ' + f' ' ) - html_lines.append(f' ') + html_lines.append(f' ') html_lines.append(" ") # close table @@ -944,7 +823,7 @@ def generate_grype_config_snippet( for line in html_lines: f.write(line + "\n") - logger = get_logger(__name__) + logger = log.logger(__name__) logger.debug(f"Generated {output_file}") @@ -973,14 +852,14 @@ def generate_ecosystem_vulnerability_capabilities_table( ecosystem_def = get_ecosystem_definition(ecosystem, vuln_data) if not ecosystem_def: - logger = get_logger(__name__) + logger = log.logger(__name__) logger.warning(f"No vulnerability data for ecosystem {ecosystem}") return # get source entries (list of dicts with 'name' and optionally 'when' fields) source_entries = ecosystem_def.get("sources", []) if not source_entries: - logger = get_logger(__name__) + logger = log.logger(__name__) logger.warning(f"No sources defined for ecosystem {ecosystem}") return @@ -1023,7 +902,7 @@ def generate_ecosystem_vulnerability_capabilities_table( ] # generate comment - comment = get_generated_comment( + comment = config.get_generated_comment( "scripts/generate_capability_vulnerability_tables.py", "html" ) comment += "\n\n" @@ -1033,35 +912,35 @@ def generate_ecosystem_vulnerability_capabilities_table( # table header with two-row grouped structure html_lines.append( - '
Configuration Key Configuration KeyDescription Description
{field_key}{field_key}{description}{description}
' + f'
' ) html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append( - f' ' + f' ' ) html_lines.append(" ") html_lines.append(" ") @@ -1102,7 +981,7 @@ def generate_ecosystem_vulnerability_capabilities_table( source_cell = source_display html_lines.append(" ") - html_lines.append(f' ') + html_lines.append(f' ') # add cells for each capability for cap in capabilities_to_include: @@ -1121,7 +1000,7 @@ def generate_ecosystem_vulnerability_capabilities_table( icon_html = "" html_lines.append( - f' ' + f' ' ) html_lines.append(" ") @@ -1136,104 +1015,10 @@ def generate_ecosystem_vulnerability_capabilities_table( for line in html_lines: f.write(line + "\n") - logger = get_logger(__name__) + logger = log.logger(__name__) logger.debug(f"Generated {output_file}") -@click.command() -@click.option( - "--update", - is_flag=True, - help="Update the cataloger data cache even if it already exists", -) -@click.option( - "-v", - "--verbose", - count=True, - help="Increase verbosity (use -v for info, -vv for debug)", -) -def main(update: bool, verbose: int) -> None: - """Generate vulnerability data source and OS support tables.""" - logger = setup_logging(verbose, __file__) - - # load data - logger.info("Loading operating system data...") - os_data = load_os_data() - os_list = _convert_os_data_to_objects(os_data) - logger.debug(f"Loaded {len(os_list)} operating systems") - - logger.info("Loading vulnerability data...") - vuln_data = load_vulnerability_data() - logger.debug( - f"Loaded {len(vuln_data.get('sources', {}))} data sources and {len(vuln_data.get('ecosystems', {}))} ecosystems" - ) - - logger.debug("Loading ecosystem aliases...") - ecosystem_aliases = load_ecosystem_aliases() - if ecosystem_aliases: - logger.debug(f"Loaded {len(ecosystem_aliases)} ecosystem aliases") - - logger.debug("Loading cataloger data...") - cataloger_data = load_cataloger_data(update=update) - - logger.info("Extracting ecosystems from catalogers...") - all_ecosystems = extract_ecosystems_from_catalogers( - cataloger_data, ecosystem_aliases - ) - logger.info(f"Found {len(all_ecosystems)} ecosystems from Syft catalogers") - - # generate tables - logger.info("Generating tables...") - - # generate overview OS table - generate_overview_os_table( - os_list, vuln_data, paths.capabilities_snippet_dir / "overview" - ) - - # generate tables for each ecosystem - logger.info("Generating ecosystem-specific tables...") - for ecosystem_name in sorted(all_ecosystems): - # skip 'default' - it's a template only - if ecosystem_name == "default": - continue - - # get ecosystem definition (will fall back to default if not defined) - ecosystem_def = get_ecosystem_definition(ecosystem_name, vuln_data) - ecosystem_kind = ecosystem_def.get("kind", "unknown") - - logger.debug(f"Processing {ecosystem_name} (kind={ecosystem_kind})...") - - # for OS ecosystems, generate OS support table - if ecosystem_kind == "os": - generate_os_ecosystem_table( - ecosystem_name, - os_list, - vuln_data, - paths.capabilities_snippet_dir / "ecosystem", - ) - generate_os_ecosystem_vulnerability_capabilities_table( - ecosystem_name, - os_list, - vuln_data, - paths.capabilities_snippet_dir / "ecosystem", - ) - else: - # for language/other/default ecosystems, generate vulnerability capabilities table - generate_ecosystem_vulnerability_capabilities_table( - ecosystem_name, vuln_data, paths.capabilities_snippet_dir / "ecosystem" - ) - - # generate config snippet if ecosystem has configuration - config_fields = ecosystem_def.get("config", []) - if config_fields: - generate_grype_config_snippet( - ecosystem_name, - config_fields, - paths.capabilities_snippet_dir / "ecosystem", - ) - - logger.info("Generation complete!") - if __name__ == "__main__": main() diff --git a/scripts/generate_format_examples.py b/scripts/generate_format_examples.py index 523e0df1..5522316d 100755 --- a/scripts/generate_format_examples.py +++ b/scripts/generate_format_examples.py @@ -4,16 +4,12 @@ Creates markdown files with code fences for each format. """ -import shutil import sys from pathlib import Path from typing import cast import click -from utils.config import docker_images, get_generated_comment, paths -from utils.logging import setup_logging -from utils.sbom import get_or_generate_sbom -from utils.syft import run_syft_convert_format +from utils import config, log, markdown, output_manager, sbom, syft # Format definitions: (format_name, file_extension, code_fence_language) FORMATS = [ @@ -32,19 +28,19 @@ @click.command() @click.option( "--image", - default=docker_images.busybox_test, - help=f"Container image to scan (default: {docker_images.busybox_test})", + default=config.docker_images.busybox_test, + help=f"Container image to scan (default: {config.docker_images.busybox_test})", ) @click.option( "--syft-image", - default=docker_images.syft, - help=f"Syft container image to use (default: {docker_images.syft})", + default=config.docker_images.syft, + help=f"Syft container image to use (default: {config.docker_images.syft})", ) @click.option( "--output-dir", "-o", - default=str(paths.format_examples_snippet_dir), - help=f"Output directory for format examples (default: {paths.format_examples_snippet_dir})", + default=str(config.paths.format_examples_snippet_dir), + help=f"Output directory for format examples (default: {config.paths.format_examples_snippet_dir})", ) @click.option( "--update", @@ -61,26 +57,23 @@ def main( image: str, syft_image: str, output_dir: str, update: bool, verbose: int ) -> None: """Generate SBOM format examples using Syft.""" - logger = setup_logging(verbose, __file__) + logger = log.setup(verbose, __file__) logger.info(f"Generating format examples for {image} using {syft_image}...") - # Clean output directory to ensure no stale content + # Clean and prepare output directory output_path = Path(output_dir) - if output_path.exists(): - logger.debug(f"Cleaning output directory: {output_path}") - shutil.rmtree(output_path) - output_path.mkdir(parents=True, exist_ok=True) + output_manager.clean_directory(output_path, update=update, logger=logger) # use convention: cache is always sbom-cache subdirectory of template dir # the format examples are in snippets/format/examples, so we need to go up to data/sbom - cache_dir = paths.sbom_data_dir / "format-examples" / "sbom-cache" - cache_dir.mkdir(parents=True, exist_ok=True) + cache_dir = config.paths.sbom_data_dir / "format-examples" / "sbom-cache" + output_manager.ensure_directory(cache_dir) # Generate or retrieve SBOM from cache sbom_file = cast( Path, - get_or_generate_sbom( + sbom.get_or_generate( image=image, cache_dir=cache_dir, syft_image=syft_image, @@ -89,7 +82,18 @@ def main( ) # Generate examples for each format + skipped_count = 0 + generated_count = 0 + for format_name, _, fence_lang in FORMATS: + output_file = output_path / f"{format_name}.md" + + # Check if output needs regeneration + if not output_manager.should_regenerate(output_file, [sbom_file], update=update): + logger.debug(f" ⊚ Skipping {format_name}.md (up-to-date)") + skipped_count += 1 + continue + logger.debug(f"Generating {format_name} example...") try: generate_format_example( @@ -97,16 +101,21 @@ def main( syft_image=syft_image, format_name=format_name, fence_lang=fence_lang, - output_path=output_path / f"{format_name}.md", + output_path=output_file, ) logger.debug(f" ✓ Generated {format_name}.md") + generated_count += 1 except Exception as e: logger.error(f" ✗ Error generating {format_name}: {e}") sys.exit(1) - logger.info( - f"Successfully generated {len(FORMATS)} format examples in {output_path}" - ) + # Log summary + if skipped_count > 0: + logger.info( + f"Format examples: {generated_count} generated, {skipped_count} skipped (up-to-date)" + ) + else: + logger.info(f"Successfully generated {len(FORMATS)} format examples in {output_path}") def generate_format_example( @@ -118,7 +127,7 @@ def generate_format_example( ) -> None: """Generate a single format example and write to markdown file.""" # Use syft convert to generate the output format from cached SBOM - output = run_syft_convert_format( + output = syft.convert_format( sbom_file=sbom_file, output_format=format_name, syft_image=syft_image, @@ -139,18 +148,11 @@ def generate_format_example( def create_markdown_content(fence_lang: str, output: str) -> str: """Create markdown content with code fence.""" # Add auto-generated comment - comment = get_generated_comment("scripts/generate_format_examples.py", "html") + comment = config.get_generated_comment("scripts/generate_format_examples.py", "html") - # Build the code fence opening - if fence_lang: - fence_start = f"```{fence_lang}" - else: - fence_start = "```" + # Use markdown utility for code fence + content = comment + markdown.create_code_fence(output, fence_lang) - content = f"""{comment}{fence_start} -{output} -``` -""" return content diff --git a/scripts/generate_format_versions.py b/scripts/generate_format_versions.py index 82f441c2..4f7dbb48 100755 --- a/scripts/generate_format_versions.py +++ b/scripts/generate_format_versions.py @@ -15,8 +15,53 @@ from pathlib import Path import click -from utils.config import docker_images, get_generated_comment, paths, timeouts -from utils.logging import setup_logging +from utils import config, log + + + +@click.command() +@click.option( + "--update", + is_flag=True, + help="Update the JSON file even if it already exists", +) +@click.option( + "-v", + "--verbose", + count=True, + help="Increase verbosity (use -v for info, -vv for debug)", +) +def main(update: bool, verbose: int) -> None: + """Generate format version information from Syft output.""" + logger = log.setup(verbose, __file__) + + # define output paths from config + json_output = config.paths.format_versions_json + md_output = config.paths.format_versions_snippet + + # check if JSON file already exists + if json_output.exists() and not update: + logger.info(f"Using existing {json_output}") + formats = load_existing_formats(json_output) + if formats is None: + logger.error("Could not load existing JSON file") + sys.exit(1) + else: + # extract format information + logger.info("Extracting format versions from Syft...") + formats = extract_format_versions() + + if not formats: + logger.error("No formats found") + sys.exit(1) + + logger.info(f"Found {len(formats)} formats") + + # save JSON data + save_json_data(formats, json_output, logger) + + # generate markdown snippet + generate_markdown_snippet(formats, md_output, logger) def extract_format_versions(): @@ -28,10 +73,10 @@ def extract_format_versions(): try: # run syft with an invalid format to trigger the error message result = subprocess.run( - ["syft", docker_images.busybox_test, "-o", "fake"], + ["syft", config.docker_images.busybox_test, "-o", "fake"], capture_output=True, text=True, - timeout=timeouts.syft_format_version_check, + timeout=config.timeouts.syft_format_version_check, ) # the format list will be in stderr @@ -83,7 +128,7 @@ def save_json_data(formats, output_path: Path, logger) -> None: output_path.parent.mkdir(parents=True, exist_ok=True) # add auto-generated comment as a special field - comment = get_generated_comment("scripts/generate_format_versions.py", "json") + comment = config.get_generated_comment("scripts/generate_format_versions.py", "json") data = {"_comment": comment, **formats} with open(output_path, "w") as f: @@ -108,7 +153,7 @@ def generate_markdown_snippet(formats, output_path: Path, logger) -> None: return # add auto-generated comment - comment = get_generated_comment("scripts/generate_format_versions.py", "html") + comment = config.get_generated_comment("scripts/generate_format_versions.py", "html") # generate markdown list only lines = [] @@ -144,50 +189,6 @@ def load_existing_formats(json_path: Path): return None -@click.command() -@click.option( - "--update", - is_flag=True, - help="Update the JSON file even if it already exists", -) -@click.option( - "-v", - "--verbose", - count=True, - help="Increase verbosity (use -v for info, -vv for debug)", -) -def main(update: bool, verbose: int) -> None: - """Generate format version information from Syft output.""" - logger = setup_logging(verbose, __file__) - - # define output paths from config - json_output = paths.format_versions_json - md_output = paths.format_versions_snippet - - # check if JSON file already exists - if json_output.exists() and not update: - logger.info(f"Using existing {json_output}") - formats = load_existing_formats(json_output) - if formats is None: - logger.error("Could not load existing JSON file") - sys.exit(1) - else: - # extract format information - logger.info("Extracting format versions from Syft...") - formats = extract_format_versions() - - if not formats: - logger.error("No formats found") - sys.exit(1) - - logger.info(f"Found {len(formats)} formats") - - # save JSON data - save_json_data(formats, json_output, logger) - - # generate markdown snippet - generate_markdown_snippet(formats, md_output, logger) - if __name__ == "__main__": main() diff --git a/scripts/generate_jq_query_examples.py b/scripts/generate_jq_query_examples.py index 156e177b..454536fb 100755 --- a/scripts/generate_jq_query_examples.py +++ b/scripts/generate_jq_query_examples.py @@ -4,7 +4,6 @@ Runs Syft to generate SBOMs, then executes jq queries and creates markdown files. """ -import shutil import subprocess import sys from pathlib import Path @@ -12,26 +11,24 @@ import click import yaml -from utils.config import docker_images, paths, timeouts -from utils.logging import setup_logging -from utils.sbom import get_or_generate_sbom +from utils import config, log, markdown, output_manager, sbom @click.command() @click.option( "--examples-dir", - default=str(paths.jq_query_examples_dir), - help=f"Directory containing YAML example definitions (default: {paths.jq_query_examples_dir})", + default=str(config.paths.jq_query_examples_dir), + help=f"Directory containing YAML example definitions (default: {config.paths.jq_query_examples_dir})", ) @click.option( "--output-dir", - default=str(paths.jq_queries_snippet_dir), - help=f"Output directory for generated examples (default: {paths.jq_queries_snippet_dir})", + default=str(config.paths.jq_queries_snippet_dir), + help=f"Output directory for generated examples (default: {config.paths.jq_queries_snippet_dir})", ) @click.option( "--syft-image", - default=docker_images.syft, - help=f"Syft Docker image to use (default: {docker_images.syft})", + default=config.docker_images.syft, + help=f"Syft Docker image to use (default: {config.docker_images.syft})", ) @click.option( "--update", @@ -52,7 +49,7 @@ def main( verbose: int, ) -> None: """Generate jq query example documentation.""" - logger = setup_logging(verbose, __file__) + logger = log.setup(verbose, __file__) examples_path = Path(examples_dir) output_path = Path(output_dir) @@ -73,22 +70,20 @@ def main( logger.info(f"Found {len(example_files)} example(s) in {examples_path}") logger.debug(f"Using Syft image: {syft_image}") - # Clean output directory to remove stale examples - if output_path.exists(): - logger.debug(f"Cleaning output directory: {output_path}") - shutil.rmtree(output_path) - - # Create output and cache directories - output_path.mkdir(parents=True, exist_ok=True) - cache_dir.mkdir(parents=True, exist_ok=True) + # Clean and prepare directories + output_manager.clean_directory(output_path, update=update, logger=logger) + output_manager.ensure_directory(cache_dir) # Process each example + skipped_count = 0 + generated_count = 0 + for example_file in example_files: example_name = example_file.stem logger.debug(f"Processing: {example_name}") try: - generate_example( + was_generated = generate_example( example_file=example_file, example_name=example_name, output_dir=output_path, @@ -96,12 +91,23 @@ def main( syft_image=syft_image, update=update, ) - logger.debug(f" ✓ Generated {example_name}") + if was_generated: + logger.debug(f" ✓ Generated {example_name}") + generated_count += 1 + else: + logger.debug(f" ⊚ Skipping {example_name} (up-to-date)") + skipped_count += 1 except Exception as e: logger.error(f" ✗ Failed to generate {example_name}: {e}") sys.exit(1) - logger.info(f"All examples generated successfully in {output_path}") + # Log summary + if skipped_count > 0: + logger.info( + f"JQ query examples: {generated_count} generated, {skipped_count} skipped (up-to-date)" + ) + else: + logger.info(f"All examples generated successfully in {output_path}") def generate_example( @@ -111,8 +117,13 @@ def generate_example( cache_dir: Path, syft_image: str, update: bool = False, -) -> None: - """Generate markdown files for a single jq query example.""" +) -> bool: + """ + Generate markdown files for a single jq query example. + + Returns: + True if example was generated, False if skipped (up-to-date) + """ # Load example definition with open(example_file) as f: example = yaml.safe_load(f) @@ -128,13 +139,32 @@ def generate_example( # Create example directory example_dir = output_dir / example_name - example_dir.mkdir(parents=True, exist_ok=True) + output_manager.ensure_directory(example_dir) - # Generate or retrieve SBOM + # Define output files + query_md = example_dir / "query.md" + example_md = example_dir / "example.md" + output_md = example_dir / "output.md" + + # Build list of source files config_file = example_file.parent / config if config else None + cache_key = output_manager.get_cache_key(image, config_file) + sbom_cache = cache_dir / f"{cache_key}.json" + + source_files = [example_file, sbom_cache] + if config_file and config_file.exists(): + source_files.append(config_file) + + # Check if outputs need regeneration + if not output_manager.should_regenerate_multiple([query_md, example_md, output_md], source_files, update): + return False + + # Import sbom utility for SBOM generation + + # Generate or retrieve SBOM sbom_json = cast( str, - get_or_generate_sbom( + sbom.get_or_generate( image=image, cache_dir=cache_dir, syft_image=syft_image, @@ -146,14 +176,14 @@ def generate_example( # Generate query.md - just the jq expression # there is no jq support... python is the closest (see https://gohugo.io/content-management/syntax-highlighting/#languages) - query_md = f"```python\n{query}\n```\n" + query_md = markdown.create_code_fence(query, "python") (example_dir / "query.md").write_text(query_md) # Generate example.md - full copy-pastable command using piped input # Strip comments from query for the example command query_no_comments = strip_comments(query) - example_md = ( - f"```bash\nsyft {image} -o json | \\\n jq '{query_no_comments}'\n```\n" + example_md = markdown.create_code_fence( + f"syft {image} -o json | \\\n jq '{query_no_comments}'", "bash" ) (example_dir / "example.md").write_text(example_md) @@ -162,7 +192,7 @@ def generate_example( config_path = example_file.parent / config if config_path.exists(): config_content = config_path.read_text() - config_md = f"```yaml\n# .syft.yaml\n{config_content}```\n" + config_md = markdown.create_code_fence(f"# .syft.yaml\n{config_content}", "yaml") (example_dir / "config.md").write_text(config_md) # Run jq query and generate output.md @@ -173,12 +203,14 @@ def generate_example( if len(output_lines) > 200: output = "\n".join(output_lines[:200]) + "\n...\n" - # try to detect output format - output_format = detect_output_format(output) + # detect output format + output_format = markdown.detect_format(output) - output_md = f"```{output_format}\n{output}\n```\n" + output_md = markdown.create_code_fence(output, output_format) (example_dir / "output.md").write_text(output_md) + return True + def run_jq_query(sbom_json: str, query: str) -> str: """Execute a jq query against SBOM JSON and return the output.""" @@ -194,7 +226,7 @@ def run_jq_query(sbom_json: str, query: str) -> str: input=sbom_json, capture_output=True, text=True, - timeout=timeouts.jq_query, + timeout=config.timeouts.jq_query, ) if result.returncode != 0: @@ -210,7 +242,7 @@ def run_jq_query(sbom_json: str, query: str) -> str: except subprocess.TimeoutExpired as e: raise RuntimeError( - f"jq command timed out after {timeouts.jq_query} seconds" + f"jq command timed out after {config.timeouts.jq_query} seconds" ) from e except FileNotFoundError as e: raise RuntimeError("jq not found. Please install jq to run this script.") from e @@ -244,23 +276,5 @@ def extract_jq_expression(query: str) -> str: return strip_comments(query).strip() -def detect_output_format(output: str) -> str: - """Detect the output format for syntax highlighting.""" - if output == "(no results)": - return "text" - - # try to parse as JSON (if starts with { or [)... we can't parse it since it might be truncated - if output.startswith("{") or output.startswith("["): - return "json" - - # check if it looks like CSV - lines = output.split("\n") - if len(lines) > 1 and all("," in line for line in lines[:3]): - return "csv" - - # default to text - return "text" - - if __name__ == "__main__": main() diff --git a/scripts/generate_reference_cli_docs.py b/scripts/generate_reference_cli_docs.py index d34cc1b9..44abfc05 100755 --- a/scripts/generate_reference_cli_docs.py +++ b/scripts/generate_reference_cli_docs.py @@ -10,10 +10,7 @@ from pathlib import Path import click -from utils.cache import get_cached_output, save_to_cache -from utils.config import get_generated_comment, paths, reference_weights -from utils.logging import setup_logging -from utils.syft import run_syft +from utils import cache, config, log, markdown, syft, version @click.command() @@ -67,7 +64,7 @@ def main( IMAGE: Container image (e.g., anchore/syft:latest) """ - logger = setup_logging(verbose, __file__) + logger = log.setup(verbose, __file__) # Auto-detect tool and app names if not provided if not tool_name: @@ -89,6 +86,11 @@ def main( if output_dir and not os.path.exists(output_dir): os.makedirs(output_dir, exist_ok=True) + # Check if output is up-to-date + if is_output_up_to_date(output, tool_name, update): + logger.info(f"CLI docs are up-to-date, skipping generation: {output}") + return + # Generate markdown content try: content = generate_markdown_content( @@ -123,39 +125,24 @@ def generate_markdown_content( # Prepare tool name for display tool_display = tool_name.title() - # Generate front matter - weight = reference_weights.get_weight(tool_name, "cli") - content = f"""+++ -title = "{tool_display} Command Line Reference" -linkTitle = "{tool_display} CLI" -weight = {weight} -tags = ['{tool_name.lower()}'] -categories = ['reference'] -url = "docs/reference/{tool_name.lower()}/cli" -+++ - -""" + # Generate front matter using utility + weight = config.reference_weights.get_weight(tool_name, "cli") + content = markdown.generate_front_matter( + title=f"{tool_display} Command Line Reference", + link_title=f"{tool_display} CLI", + weight=weight, + tags=[tool_name.lower()], + categories=["reference"], + url=f"docs/reference/{tool_name.lower()}/cli", + ) # Add auto-generated comment - content += get_generated_comment("scripts/generate_reference_cli_docs.py", "html") + content += config.get_generated_comment("scripts/generate_reference_cli_docs.py", "html") # Add version info block at the top version_info = get_version_info(image, app_name, tool_name, update) - # Extract just the version line for the info block - version_lines = version_info.split("\n") - app_version = "unknown" - for line in version_lines: - if line.startswith("Version:") or line.startswith("version:"): - app_version = line.split(":", 1)[1].strip() - break - elif line.startswith(f"{tool_display}:") or line.startswith(f"{tool_name}:"): - app_version = line.split(":", 1)[1].strip() - break - elif "version" in line.lower() and ":" in line: - parts = line.split(":", 1) - if len(parts) == 2: - app_version = parts[1].strip() - break + # Extract version using utility function + app_version = version.extract_from_output(version_info, tool_name=tool_name) content += f"""{{{{< alert title="Note" >}}}} This documentation was generated with {tool_display} version `{app_version}`. @@ -167,7 +154,7 @@ def generate_markdown_content( main_help = get_command_help( image, [], tool_name, update ) # Empty cmd_parts for main help - content += f"```\n{main_help}\n```\n\n" + content += markdown.create_code_fence(main_help, "") + "\n" # Discover and add all subcommands all_commands, leaf_commands = discover_all_commands( @@ -209,7 +196,7 @@ def generate_markdown_content( content += f"### `{app_name} {cmd_string}`\n\n" if description: content += f"{description}\n\n" - content += f"```\n{command_details}\n```\n\n" + content += markdown.create_code_fence(command_details, "") + "\n" return content @@ -227,10 +214,10 @@ def get_cache_path_for_cli(tool_name: str, cmd_parts: list[str]) -> Path: """ if not cmd_parts: # main help - cache_dir = paths.reference_cache_dir / tool_name / "cli" / "main" + cache_dir = config.paths.reference_cache_dir / tool_name / "cli" / "main" else: # subcommand help - use command path as directory structure - cache_dir = paths.reference_cache_dir / tool_name / "cli" / "/".join(cmd_parts) + cache_dir = config.paths.reference_cache_dir / tool_name / "cli" / "/".join(cmd_parts) return cache_dir / "output.txt" @@ -282,13 +269,13 @@ def get_subcommands(image: str, cmd_parts, tool_name: str, update: bool = False) """Extract subcommands from help output.""" # check cache first cache_path = get_cache_path_for_cli(tool_name, cmd_parts + ["help"]) - cached = get_cached_output(cache_path, update) + cached = cache.get_output(cache_path, update) if cached is not None: lines = cached.split("\n") else: # run command - stdout, stderr, returncode = run_syft( + stdout, stderr, returncode = syft.run( syft_image=image, args=cmd_parts + ["help"], ) @@ -297,7 +284,7 @@ def get_subcommands(image: str, cmd_parts, tool_name: str, update: bool = False) return [] # save to cache - save_to_cache(cache_path, stdout) + cache.save(cache_path, stdout) lines = stdout.split("\n") in_commands_section = False commands = [] @@ -323,20 +310,20 @@ def get_version_info( """Get version information from the app.""" # check cache first cache_path = get_cache_path_for_cli(tool_name, ["version"]) - cached = get_cached_output(cache_path, update) + cached = cache.get_output(cache_path, update) if cached is not None: return cached.strip() # run command - stdout, stderr, returncode = run_syft( + stdout, stderr, returncode = syft.run( syft_image=image, args=["version"], ) if returncode == 0: # save to cache - save_to_cache(cache_path, stdout) + cache.save(cache_path, stdout) return stdout.strip() raise RuntimeError(f"Failed to retrieve version info from the image '{image}'.") @@ -352,7 +339,7 @@ def get_command_help( # check cache first cache_path = get_cache_path_for_cli(tool_name, cmd_parts) - cached = get_cached_output(cache_path, update) + cached = cache.get_output(cache_path, update) if cached is not None: return cached.strip() @@ -367,18 +354,59 @@ def get_command_help( else: full_cmd = cmd_parts + [help_flag] - stdout, stderr, returncode = run_syft( + stdout, stderr, returncode = syft.run( syft_image=image, args=full_cmd, ) if returncode == 0 and stdout.strip(): # save to cache - save_to_cache(cache_path, stdout) + cache.save(cache_path, stdout) return stdout.strip() raise RuntimeError(f"Failed to retrieve help for command: {' '.join(cmd_parts)}") +def is_output_up_to_date(output_path: str, tool_name: str, update: bool) -> bool: + """ + check if output file is up-to-date relative to cache files. + + Args: + output_path: path to output markdown file + tool_name: tool name (e.g., "syft", "grype") + update: if true, always return False to force regeneration + + Returns: + True if output exists and is newer than all cache files + """ + # if updating, always regenerate + if update: + return False + + # check if output exists + output_file = Path(output_path) + if not output_file.exists(): + return False + + # get output modification time + output_mtime = output_file.stat().st_mtime + + # find all cache files for this tool + cache_base = config.paths.reference_cache_dir / tool_name / "cli" + if not cache_base.exists(): + # no cache exists, output is stale + return False + + # check all cache files recursively + for cache_file in cache_base.rglob("output.txt"): + cache_mtime = cache_file.stat().st_mtime + if cache_mtime > output_mtime: + # cache is newer than output, output is stale + return False + + # output is up-to-date + return True + + def split_help_output(help_output: str, is_main_help=False) -> tuple[str, str]: """Split help output into description and command details. diff --git a/scripts/generate_reference_config_docs.py b/scripts/generate_reference_config_docs.py index b153dddd..ea360858 100755 --- a/scripts/generate_reference_config_docs.py +++ b/scripts/generate_reference_config_docs.py @@ -9,10 +9,7 @@ from pathlib import Path import click -from utils.cache import get_cached_output, save_to_cache -from utils.config import get_generated_comment, paths, reference_weights -from utils.logging import setup_logging -from utils.syft import run_syft +from utils import cache, config, log, markdown, syft, version @click.command() @@ -54,7 +51,7 @@ def main( IMAGE: Container image (e.g., anchore/syft:latest) """ - logger = setup_logging(verbose, __file__) + logger = log.setup(verbose, __file__) # Auto-detect tool and app names if not provided if not tool_name: @@ -76,6 +73,11 @@ def main( if output_dir and not os.path.exists(output_dir): os.makedirs(output_dir, exist_ok=True) + # Check if output is up-to-date + if is_output_up_to_date(output, tool_name, update): + logger.info(f"Configuration docs are up-to-date, skipping generation: {output}") + return + # Generate markdown content try: content = generate_markdown_content(image, app_name, tool_name, update) @@ -98,21 +100,19 @@ def generate_markdown_content( # Prepare tool name for display tool_display = tool_name.title() - # Generate front matter - weight = reference_weights.get_weight(tool_name, "config") - content = f"""+++ -title = "{tool_display} Default Configuration" -linkTitle = "{tool_display} Default Config" -weight = {weight} -tags = ['{tool_name.lower()}'] -categories = ['reference'] -url = "docs/reference/{tool_name.lower()}/configuration" -+++ - -""" + # Generate front matter using utility + weight = config.reference_weights.get_weight(tool_name, "config") + content = markdown.generate_front_matter( + title=f"{tool_display} Default Configuration", + link_title=f"{tool_display} Default Config", + weight=weight, + tags=[tool_name.lower()], + categories=["reference"], + url=f"docs/reference/{tool_name.lower()}/configuration", + ) # Add auto-generated comment - content += get_generated_comment( + content += config.get_generated_comment( "scripts/generate_reference_config_docs.py", "html" ) @@ -135,7 +135,7 @@ def generate_markdown_content( config_output = get_config_output(image, tool_name, update) if config_output: - content += f"```yaml\n{config_output}\n```\n\n" + content += markdown.create_code_fence(config_output, "yaml") + "\n" else: raise RuntimeError( f"Failed to retrieve configuration from the image '{image}'." @@ -155,10 +155,50 @@ def get_cache_path(tool_name: str, command_type: str) -> Path: Returns: Path to cache file """ - cache_dir = paths.reference_cache_dir / tool_name / command_type + cache_dir = config.paths.reference_cache_dir / tool_name / command_type return cache_dir / "output.txt" +def is_output_up_to_date(output_path: str, tool_name: str, update: bool) -> bool: + """ + check if output file is up-to-date relative to cache files. + + Args: + output_path: path to output markdown file + tool_name: tool name (e.g., "syft", "grype") + update: if true, always return False to force regeneration + + Returns: + True if output exists and is newer than all cache files + """ + # if updating, always regenerate + if update: + return False + + # check if output exists + output_file = Path(output_path) + if not output_file.exists(): + return False + + # get output modification time + output_mtime = output_file.stat().st_mtime + + # check version cache + version_cache = get_cache_path(tool_name, "version") + if version_cache.exists(): + if version_cache.stat().st_mtime > output_mtime: + return False + + # check config cache + config_cache = get_cache_path(tool_name, "config") + if config_cache.exists(): + if config_cache.stat().st_mtime > output_mtime: + return False + + # output is up-to-date + return True + + def get_config_locations_section(app_name: str, tool_display: str) -> str: """Generate markdown section describing configuration file search locations.""" return f""" @@ -180,29 +220,25 @@ def get_app_version(image: str, tool_name: str, update: bool = False) -> str | N """Get the application version from the image.""" # check cache first cache_path = get_cache_path(tool_name, "version") - cached = get_cached_output(cache_path, update) + cached = cache.get_output(cache_path, update) if cached is not None: - # parse cached output - for line in cached.splitlines(): - if line.startswith("Version:"): - return line.split(":", 1)[1].strip() - return None + # parse cached output using utility function + return version.extract_from_output(cached, tool_name=tool_name) # run command - stdout, stderr, returncode = run_syft( + stdout, stderr, returncode = syft.run( syft_image=image, args=["version"], ) if returncode == 0: # save to cache - save_to_cache(cache_path, stdout) + cache.save(cache_path, stdout) + + # parse output using utility function + return version.extract_from_output(stdout, tool_name=tool_name) - # parse output - for line in stdout.splitlines(): - if line.startswith("Version:"): - return line.split(":", 1)[1].strip() return None @@ -210,20 +246,20 @@ def get_config_output(image: str, tool_name: str, update: bool = False) -> str | """Get configuration output from the app.""" # check cache first cache_path = get_cache_path(tool_name, "config") - cached = get_cached_output(cache_path, update) + cached = cache.get_output(cache_path, update) if cached is not None: return cached.strip() # run command - stdout, stderr, returncode = run_syft( + stdout, stderr, returncode = syft.run( syft_image=image, args=["config"], ) if returncode == 0: # save to cache - save_to_cache(cache_path, stdout) + cache.save(cache_path, stdout) return stdout.strip() return None diff --git a/scripts/generate_reference_syft_json_schema.py b/scripts/generate_reference_syft_json_schema.py index cd7f617b..c201e15c 100644 --- a/scripts/generate_reference_syft_json_schema.py +++ b/scripts/generate_reference_syft_json_schema.py @@ -36,14 +36,76 @@ from typing import Any import click -from utils.config import ( - excluded_schema_types, - get_generated_comment, - min_schema_major_version, - paths, +from utils import config, log +from utils.constants import CSSClasses + + + + +@click.command() +@click.option( + "--schema-dir", + type=click.Path(exists=True, path_type=Path), + default=config.paths.default_schema_dir, + help="Directory containing Syft JSON schema files", +) +@click.option( + "--update", + is_flag=True, + help="Update documentation even if output files already exist", +) +@click.option( + "-v", + "--verbose", + count=True, + help="Increase verbosity (use -v for info, -vv for debug)", ) -from utils.logging import setup_logging +def main(schema_dir: Path, update: bool, verbose: int) -> None: + """Generate JSON schema reference documentation from Syft schema files. + + Processes all schema files in the specified directory, selecting the latest + patch version for each major version >= {config.min_schema_major_version}. + """ + logger = log.setup(verbose, __file__) + + # scan directory for schema files + all_schemas = scan_schema_directory(schema_dir, logger) + + # select schemas to process (latest patch per major version >= min) + selected = select_schemas_to_process(all_schemas, config.min_schema_major_version, logger) + if not selected: + logger.error("No schemas selected for processing") + sys.exit(1) + + # determine highest major version for "latest" badge + highest_major = max(selected.keys()) + logger.info(f"Highest major version: v{highest_major} (will receive 'latest' badge)") + + # process each selected schema + for major, (schema_path, full_version) in sorted(selected.items(), reverse=True): + output_file = config.paths.json_reference_dir / f"{major}.md" + + # check if output already exists + if output_file.exists() and not update: + logger.info( + f"Output file already exists: {output_file} " + f"(use --update to regenerate)" + ) + continue + + # load schema + schema_data = load_json_schema(schema_path, major, logger) + + # determine if this is the latest version + is_latest = (major == highest_major) + + # generate documentation + generate_schema_documentation( + schema_data, full_version, config.paths.json_reference_dir, is_latest, logger + ) + + logger.info("Generation complete!") def parse_schema_filename(filename: str) -> tuple[int, int, int] | None: """ @@ -286,7 +348,7 @@ def load_ecosystem_types_from_catalogers() -> set[str]: cataloger has 'AlpmDbEntry' -> returns 'AlpmDbEntry' cataloger has 'ApkDbEntry' -> returns 'ApkDbEntry' """ - cataloger_data = json.loads(paths.cataloger_cache_file.read_text()) + cataloger_data = json.loads(config.paths.cataloger_cache_file.read_text()) json_schema_types = set() for cataloger in cataloger_data.get("catalogers", []): @@ -619,7 +681,7 @@ def categorize_definitions(schema: dict, logger) -> dict[str, Any]: related types are types ONLY referenced by ecosystem types. core types are everything else (including shared types used by both). - filters out types in excluded_schema_types from all categories. + filters out types in config.excluded_schema_types from all categories. Args: schema: parsed JSON schema dict @@ -666,17 +728,17 @@ def categorize_definitions(schema: dict, logger) -> dict[str, Any]: core_types = [ t for t in (categories["core_only"] + categories["shared"]) - if t != "Document" and t not in excluded_schema_types + if t != "Document" and t not in config.excluded_schema_types ] # filter excluded types from ecosystem types - filtered_ecosystem_types = [t for t in ecosystem_types if t not in excluded_schema_types] + filtered_ecosystem_types = [t for t in ecosystem_types if t not in config.excluded_schema_types] # filter excluded types from ecosystem_related (both keys and values) filtered_ecosystem_related = {} for eco_type, related_types in categories["ecosystem_related"].items(): - if eco_type not in excluded_schema_types: - filtered_related = [t for t in related_types if t not in excluded_schema_types] + if eco_type not in config.excluded_schema_types: + filtered_related = [t for t in related_types if t not in config.excluded_schema_types] if filtered_related: filtered_ecosystem_related[eco_type] = filtered_related @@ -1104,13 +1166,13 @@ def generate_type_section_html( # table header show_descriptions = has_field_descriptions(parsed["fields"]) - html_lines.append('
Data Source Data SourceDisclosures DisclosuresFixes FixesTrack by
Source
Package
Track by
Source
Package
Affected AffectedDate DateVersions VersionsDate Date
{source_cell}{source_cell}{icon_html}{icon_html}
') + html_lines.append(f'
') html_lines.append(" ") html_lines.append(" ") - html_lines.append(' ') - html_lines.append(' ') + html_lines.append(f' ') + html_lines.append(f' ') if show_descriptions: - html_lines.append(' ') + html_lines.append(f' ') html_lines.append(" ") html_lines.append(" ") html_lines.append(" ") @@ -1121,26 +1183,26 @@ def generate_type_section_html( # add required icon outside code block for required fields field_name_html = f'{field["name"]}' if field["required"]: - field_name_html += '' + field_name_html += f'' html_lines.append( - f' ' + f' ' ) # handle special ecosystem types link if field["type"] == "ECOSYSTEM_TYPES_LINK": html_lines.append( - ' ' + f' ' ) else: # linkify type references and wrap in code tags linked_type = linkify_type_string(field["type"], documented_types) html_lines.append( - f' ' + f' ' ) if show_descriptions: html_lines.append( - f' ' + f' ' ) html_lines.append(" ") @@ -1177,13 +1239,13 @@ def generate_type_section_html( # table (same structure as main types) related_show_descriptions = has_field_descriptions(related_parsed["fields"]) - html_lines.append('
Field NameTypeField NameTypeDescriptionDescription
{field_name_html}{field_name_html}see the Ecosystem Specific Types sectionsee the Ecosystem Specific Types section{linked_type}{linked_type}{field["description"]}{field["description"]}
') + html_lines.append(f'
') html_lines.append(" ") html_lines.append(" ") - html_lines.append(' ') - html_lines.append(' ') + html_lines.append(f' ') + html_lines.append(f' ') if related_show_descriptions: - html_lines.append(' ') + html_lines.append(f' ') html_lines.append(" ") html_lines.append(" ") html_lines.append(" ") @@ -1193,19 +1255,19 @@ def generate_type_section_html( # add required icon outside code block for required fields field_name_html = f'{field["name"]}' if field["required"]: - field_name_html += '' + field_name_html += f'' html_lines.append( - f' ' + f' ' ) # linkify type references linked_type = linkify_type_string(field["type"], documented_types) html_lines.append( - f' ' + f' ' ) if related_show_descriptions: html_lines.append( - f' ' + f' ' ) html_lines.append(" ") @@ -1267,7 +1329,7 @@ def generate_schema_documentation( front_matter_lines.append("+++") # generate comment (after front matter) - comment = get_generated_comment("scripts/generate_reference_syft_json_schema.py", "html") + comment = config.get_generated_comment("scripts/generate_reference_syft_json_schema.py", "html") comment += "\n" # generate content sections @@ -1290,13 +1352,13 @@ def generate_schema_documentation( if parsed["fields"]: show_descriptions = has_field_descriptions(parsed["fields"]) - doc_html.append('
Field NameTypeField NameTypeDescriptionDescription
{field_name_html}{field_name_html}{linked_type}{linked_type}{field["description"]}{field["description"]}
') + doc_html.append(f'
') doc_html.append(" ") doc_html.append(" ") - doc_html.append(' ') - doc_html.append(' ') + doc_html.append(f' ') + doc_html.append(f' ') if show_descriptions: - doc_html.append(' ') + doc_html.append(f' ') doc_html.append(" ") doc_html.append(" ") doc_html.append(" ") @@ -1306,19 +1368,19 @@ def generate_schema_documentation( # add required icon outside code block for required fields field_name_html = f'{field["name"]}' if field["required"]: - field_name_html += '' + field_name_html += f'' doc_html.append( - f' ' + f' ' ) # linkify type references linked_type = linkify_type_string(field["type"], documented_types) doc_html.append( - f' ' + f' ' ) if show_descriptions: doc_html.append( - f' ' + f' ' ) doc_html.append(" ") @@ -1359,71 +1421,6 @@ def generate_schema_documentation( logger.info(f"Generated {output_file}") -@click.command() -@click.option( - "--schema-dir", - type=click.Path(exists=True, path_type=Path), - default=paths.default_schema_dir, - help="Directory containing Syft JSON schema files", -) -@click.option( - "--update", - is_flag=True, - help="Update documentation even if output files already exist", -) -@click.option( - "-v", - "--verbose", - count=True, - help="Increase verbosity (use -v for info, -vv for debug)", -) -def main(schema_dir: Path, update: bool, verbose: int) -> None: - """Generate JSON schema reference documentation from Syft schema files. - - Processes all schema files in the specified directory, selecting the latest - patch version for each major version >= {min_schema_major_version}. - """ - logger = setup_logging(verbose, __file__) - - # scan directory for schema files - all_schemas = scan_schema_directory(schema_dir, logger) - - # select schemas to process (latest patch per major version >= min) - selected = select_schemas_to_process(all_schemas, min_schema_major_version, logger) - - if not selected: - logger.error("No schemas selected for processing") - sys.exit(1) - - # determine highest major version for "latest" badge - highest_major = max(selected.keys()) - logger.info(f"Highest major version: v{highest_major} (will receive 'latest' badge)") - - # process each selected schema - for major, (schema_path, full_version) in sorted(selected.items(), reverse=True): - output_file = paths.json_reference_dir / f"{major}.md" - - # check if output already exists - if output_file.exists() and not update: - logger.info( - f"Output file already exists: {output_file} " - f"(use --update to regenerate)" - ) - continue - - # load schema - schema_data = load_json_schema(schema_path, major, logger) - - # determine if this is the latest version - is_latest = (major == highest_major) - - # generate documentation - generate_schema_documentation( - schema_data, full_version, paths.json_reference_dir, is_latest, logger - ) - - logger.info("Generation complete!") - if __name__ == "__main__": main() diff --git a/scripts/generate_template_examples.py b/scripts/generate_template_examples.py index 1291a247..d6b301f9 100755 --- a/scripts/generate_template_examples.py +++ b/scripts/generate_template_examples.py @@ -4,38 +4,34 @@ Runs Syft templates against a test image and creates markdown files. """ -import shutil import sys from pathlib import Path from typing import cast import click -from utils.config import docker_images, paths -from utils.logging import setup_logging -from utils.sbom import get_or_generate_sbom -from utils.syft import run_syft_convert +from utils import config, log, markdown, output_manager, sbom, syft @click.command() @click.option( "--template-dir", - default=str(paths.template_examples_dir), - help=f"Directory containing template files (default: {paths.template_examples_dir})", + default=str(config.paths.template_examples_dir), + help=f"Directory containing template files (default: {config.paths.template_examples_dir})", ) @click.option( "--output-dir", - default=str(paths.templates_snippet_dir), - help=f"Output directory for generated examples (default: {paths.templates_snippet_dir})", + default=str(config.paths.templates_snippet_dir), + help=f"Output directory for generated examples (default: {config.paths.templates_snippet_dir})", ) @click.option( "--image", - default=docker_images.alpine_test, - help=f"Docker image to scan (default: {docker_images.alpine_test})", + default=config.docker_images.alpine_test, + help=f"Docker image to scan (default: {config.docker_images.alpine_test})", ) @click.option( "--syft-image", - default=docker_images.syft, - help=f"Syft Docker image to use (default: {docker_images.syft})", + default=config.docker_images.syft, + help=f"Syft Docker image to use (default: {config.docker_images.syft})", ) @click.option( "--update", @@ -57,7 +53,7 @@ def main( verbose: int, ) -> None: """Generate template example documentation.""" - logger = setup_logging(verbose, __file__) + logger = log.setup(verbose, __file__) template_path = Path(template_dir) output_path = Path(output_dir) @@ -79,22 +75,20 @@ def main( logger.info(f"Scanning image: {image}") logger.debug(f"Using Syft image: {syft_image}") - # Clean output directory to ensure no stale content - if output_path.exists(): - logger.debug(f"Cleaning output directory: {output_path}") - shutil.rmtree(output_path) - - # Create output and cache directories - output_path.mkdir(parents=True, exist_ok=True) - cache_dir.mkdir(parents=True, exist_ok=True) + # Clean and prepare directories + output_manager.clean_directory(output_path, update=update, logger=logger) + output_manager.ensure_directory(cache_dir) # Process each template + skipped_count = 0 + generated_count = 0 + for template_file in template_files: example_name = template_file.stem # filename without extension logger.debug(f"Processing: {example_name}") try: - generate_example( + was_generated = generate_example( template_file=template_file, example_name=example_name, output_dir=output_path, @@ -103,12 +97,23 @@ def main( syft_image=syft_image, update=update, ) - logger.debug(f" ✓ Generated {example_name}") + if was_generated: + logger.debug(f" ✓ Generated {example_name}") + generated_count += 1 + else: + logger.debug(f" ⊚ Skipping {example_name} (up-to-date)") + skipped_count += 1 except Exception as e: logger.error(f" ✗ Failed to generate {example_name}: {e}") sys.exit(1) - logger.info(f"All examples generated successfully in {output_path}") + # Log summary + if skipped_count > 0: + logger.info( + f"Template examples: {generated_count} generated, {skipped_count} skipped (up-to-date)" + ) + else: + logger.info(f"All examples generated successfully in {output_path}") def generate_example( @@ -119,24 +124,37 @@ def generate_example( image: str, syft_image: str, update: bool = False, -) -> None: - """Generate markdown files for a single template example.""" +) -> bool: + """ + Generate markdown files for a single template example. + + Returns: + True if example was generated, False if skipped (up-to-date) + """ # Create example directory example_dir = output_dir / example_name - example_dir.mkdir(parents=True, exist_ok=True) + output_manager.ensure_directory(example_dir) + + # Define output files + template_md = example_dir / "template.md" + output_md = example_dir / "output.md" + + # Check if outputs need regeneration + if not output_manager.should_regenerate_multiple([template_md, output_md], [template_file], update): + return False # Read template content template_content = template_file.read_text() # Generate template.md # see the language support: https://gohugo.io/content-management/syntax-highlighting/#languages - template_md = f"```go-text-template\n{template_content}\n```\n" - (example_dir / "template.md").write_text(template_md) + template_md_content = markdown.create_code_fence(template_content, "go-text-template") + (example_dir / "template.md").write_text(template_md_content) # Generate or retrieve SBOM from cache sbom_file = cast( Path, - get_or_generate_sbom( + sbom.get_or_generate( image=image, cache_dir=cache_dir, syft_image=syft_image, @@ -145,7 +163,7 @@ def generate_example( ) # Use syft convert to apply template to cached SBOM - output = run_syft_convert( + output = syft.convert( sbom_file=sbom_file, template_file=template_file, syft_image=syft_image, @@ -162,8 +180,10 @@ def generate_example( output_format = "text" # Generate output.md - output_md = f"```{output_format}\n{output}\n```\n" - (example_dir / "output.md").write_text(output_md) + output_md_content = markdown.create_code_fence(output, output_format) + (example_dir / "output.md").write_text(output_md_content) + + return True if __name__ == "__main__": diff --git a/scripts/release-to-hugo.py b/scripts/release-to-hugo.py index 2eafce46..7fe00c56 100644 --- a/scripts/release-to-hugo.py +++ b/scripts/release-to-hugo.py @@ -13,7 +13,7 @@ import click import requests -from utils.logging import setup_logging +from utils import log # GitHub API configuration HEADERS = {"Accept": "application/vnd.github.v3+json"} @@ -160,7 +160,7 @@ def main( verbose: int, ) -> None: """Generate Hugo markdown files from GitHub releases with minimal processing.""" - logger = setup_logging(verbose, __file__) + logger = log.setup(verbose, __file__) repo_full = f"anchore/{repo}" diff --git a/scripts/utils/cache.py b/scripts/utils/cache.py index bc88ebc3..9c05a5db 100644 --- a/scripts/utils/cache.py +++ b/scripts/utils/cache.py @@ -9,7 +9,7 @@ from pathlib import Path -def get_cached_output(cache_path: Path, update: bool) -> str | None: +def get_output(cache_path: Path, update: bool) -> str | None: """ get cached output if available and not updating. @@ -22,7 +22,7 @@ def get_cached_output(cache_path: Path, update: bool) -> str | None: Examples: >>> cache_path = Path("cache/syft/cli/main/output.txt") - >>> cached = get_cached_output(cache_path, update=False) + >>> cached = cache.get_output(cache_path, update=False) >>> if cached: ... print("Using cached output") ... else: @@ -40,7 +40,7 @@ def get_cached_output(cache_path: Path, update: bool) -> str | None: return None -def save_to_cache(cache_path: Path, content: str) -> None: +def save(cache_path: Path, content: str) -> None: """ save content to cache file. @@ -52,7 +52,7 @@ def save_to_cache(cache_path: Path, content: str) -> None: Examples: >>> cache_path = Path("cache/syft/version/output.txt") - >>> save_to_cache(cache_path, "Syft version 1.0.0") + >>> cache.save(cache_path, "Syft version 1.0.0") """ # create directory if it doesn't exist cache_path.parent.mkdir(parents=True, exist_ok=True) diff --git a/scripts/utils/cataloger.py b/scripts/utils/cataloger.py index 133fbeda..d3900d80 100644 --- a/scripts/utils/cataloger.py +++ b/scripts/utils/cataloger.py @@ -9,15 +9,14 @@ import json import subprocess -from .config import docker_images, paths, timeouts -from .logging import get_logger +from . import config, log -logger = get_logger(__name__) +logger = log.logger(__name__) def run_syft_cataloger_info( - syft_image: str = docker_images.syft, - timeout: int = timeouts.cataloger_info, + syft_image: str = config.docker_images.syft, + timeout: int = config.timeouts.cataloger_info, ) -> str: """ run 'syft cataloger info' command in Docker and return JSON output. @@ -84,7 +83,7 @@ def get_cataloger_data(skip_cache: bool = False) -> dict: RuntimeError: if data retrieval fails json.JSONDecodeError: if cached or fresh data is invalid JSON """ - cache_file = paths.cataloger_cache_file + cache_file = config.paths.cataloger_cache_file # fast path: return cached data if available and not skipping cache if not skip_cache and cache_file.exists(): diff --git a/scripts/utils/constants.py b/scripts/utils/constants.py new file mode 100644 index 00000000..36c85d22 --- /dev/null +++ b/scripts/utils/constants.py @@ -0,0 +1,164 @@ +""" +constants for HTML generation, output formats, and configuration. + +This module centralizes magic strings used across documentation generation scripts +to improve maintainability, reduce typos, and provide IDE autocomplete support. +""" + +from enum import Enum + + +class CSSClasses(str, Enum): + """CSS class names used in HTML table generation.""" + + # table classes + CAPABILITY_TABLE = "capability-table" + CAPABILITY_TABLE_OVERVIEW = "capability-table-overview" + CAPABILITY_TABLE_ECOSYSTEM = "capability-table-ecosystem" + CAPABILITY_TABLE_OS = "capability-table-os" + CAPABILITY_TABLE_OS_OVERVIEW = "capability-table-os-overview" + CAPABILITY_TABLE_VULNERABILITY = "capability-table-vulnerability-capabilities" + CONFIG_TABLE = "config-table" + SYFT_CONFIG_TABLE = "syft-config-table" + GRYPE_CONFIG_TABLE = "grype-config-table" + BINARY_DETAILS_TABLE = "binary-details-table" + + # column classes - ecosystem/cataloger + COL_ECOSYSTEM = "col-ecosystem" + COL_CATALOGER = "col-cataloger" + + # column classes - capabilities + COL_LICENSE = "col-license" + COL_DEPENDENCY = "col-dependency" + COL_FILES = "col-files" + COL_DEPTH = "col-depth" + COL_EDGES = "col-edges" + COL_KINDS = "col-kinds" + COL_DIGESTS = "col-digests" + COL_INTEGRITY_HASH = "col-integrity-hash" + + # column classes - OS/vulnerability + COL_OS_NAME = "col-os-name" + COL_VERSIONS = "col-versions" + COL_PROVIDER = "col-provider" + COL_DATA_SOURCE = "col-data-source" + COL_DISCLOSURE_AFFECTED = "col-disclosure-affected" + COL_DISCLOSURE_DATE = "col-disclosure-date" + COL_FIX_VERSIONS = "col-fix-versions" + COL_FIX_DATE = "col-fix-date" + COL_PACKAGE_UPSTREAM_TRACKING = "col-package-upstream_tracking" + + # column classes - config + COL_CONFIG_KEY = "col-config-key" + COL_DESCRIPTION = "col-description" + + # column classes - binary details + COL_CLASS = "col-class" + COL_CRITERIA = "col-criteria" + COL_PURL = "col-purl" + COL_CPES = "col-cpes" + + # column classes - JSON schema + COL_FIELD_NAME = "col-field-name" + COL_TYPE = "col-type" + + # table classes - JSON schema + SCHEMA_TABLE = "schema-table" + + # indicator classes + INDICATOR = "indicator" + VALUE = "value" + + # icon and UI classes + CAPABILITY_ICON = "capability-icon" + CAPABILITY_ICON_WRAPPER = "capability-icon-wrapper" + INLINE_ICON = "inline-icon" + HEADER_HELP = "header-help" + REQUIRED_ICON = "required-icon" + + # content classes + CATALOGER_NAME = "cataloger-name" + EVIDENCE_PATTERNS = "evidence-patterns" + CONFIG_TABLE_HEADER = "config-table-header" + DEPRECATED_PILL = "deprecated-pill" + CATALOGER_CONDITION_WRAPPER = "cataloger-condition-wrapper" + CLASS_PATTERN_PILL = "class-pattern-pill" + CLASS_PATTERN_PILLS = "class-pattern-pills" + PILL_CLASS = "pill-class" + PILL_PATTERN = "pill-pattern" + + def __str__(self) -> str: + return self.value + + +class SVGIcons(str, Enum): + """SVG icon identifiers for capability indicators.""" + + CHECK = "icon-check" + GEAR = "icon-gear" + DASH = "icon-dash" + + def __str__(self) -> str: + return self.value + +class OutputFormats(str, Enum): + """Syft output format identifiers.""" + + # SBOM formats + SYFT_JSON = "syft-json" + JSON = "json" + CYCLONEDX_JSON = "cyclonedx-json" + CYCLONEDX_XML = "cyclonedx-xml" + SPDX_JSON = "spdx-json" + SPDX_TAG_VALUE = "spdx-tag-value" + GITHUB_JSON = "github-json" + + # display formats + TABLE = "table" + TEXT = "text" + PURLS = "purls" + + # code fence languages + YAML = "yaml" + CSV = "csv" + XML = "xml" + BASH = "bash" + PYTHON = "python" + GO_TEXT_TEMPLATE = "go-text-template" + MARKDOWN = "markdown" + + def __str__(self) -> str: + return self.value + +# Header definitions for table tooltips +# these are shared across capability and vulnerability tables +HEADER_DEFINITIONS: dict[str, str] = { + # ecosystem/package headers + "ecosystem": "The package manager or programming language ecosystem", + "cataloger": "The Syft cataloger name and file patterns it analyzes to discover packages", + "license": "Whether Syft can detect and catalog license information from package metadata", + "licenses": "Whether Syft can detect and catalog license information from package metadata", + "dependencies": "Whether dependency information can be captured (depth, edges, kinds)", + "depth": "How far into the dependency graph packages are discovered (direct = only explicit dependencies, transitive = all depths)", + "edges": "Whether relationships between packages can be captured (flat = star topology from root, complete = full dependency graph)", + "kinds": "Types of dependencies captured (runtime = required at runtime, dev = development dependencies)", + "package_manager_claims": "Metadata and integrity information explicitly tracked by the package manager about packages and their files", + "files": "Whether Syft can catalog the list of files that are part of a package installation", + "digests": "Whether Syft can capture file checksums (digests/hashes) claimed by the package manager for individual files within a package", + "integrity_hash": "Whether Syft can capture a single package-level hash used by package managers to verify the package itself", + "configuration_key": "The configuration field name used in Syft/Grype application configuration", + "description": "Explanation of what the configuration option controls", + # OS/vulnerability headers + "operating_system": "The operating system distribution name", + "supported_versions": "Which OS versions have vulnerability data available", + "vunnel_provider": "The vunnel provider that supplies vulnerability data for this OS", + "provider": "The vunnel provider that supplies vulnerability data", + "data_source": "The upstream vulnerability database or security feed", + "disclosures": "Information about when and how vulnerabilities are disclosed", + "fixes": "Information about vulnerability fixes and their availability", + "disclosure_affected": "Whether vulnerabilities are reported even when no fix exists yet", + "disclosure_date": "When the vulnerability was first publicly disclosed (separate from fix availability date)", + "fix_versions": "Which package versions contain fixes for the vulnerability", + "fix_date": "When the fix was made available", + "source_package": "Whether the data source tracks upstream/source packages in addition to binary packages (important for RPM/DEB ecosystems)", +} diff --git a/scripts/utils/data.py b/scripts/utils/data.py index ea2969ce..4467cefb 100644 --- a/scripts/utils/data.py +++ b/scripts/utils/data.py @@ -11,11 +11,9 @@ import yaml -from .config import get_generated_comment, paths, timeouts -from .logging import get_logger -from .syft import run_syft +from . import config, log, syft -logger = get_logger(__name__) +logger = log.logger(__name__) def version_to_number(version: str) -> float: @@ -120,7 +118,7 @@ def load_ecosystem_aliases() -> dict[str, str]: >>> aliases = load_ecosystem_aliases() >>> # {'javascript': 'npm', 'typescript': 'npm'} """ - aliases_file = paths.ecosystem_aliases_file + aliases_file = config.paths.ecosystem_aliases_file if not aliases_file.exists(): logger.warning(f"Ecosystem aliases file not found: {aliases_file}") @@ -149,7 +147,7 @@ def load_ecosystem_display_names() -> dict[str, str]: >>> display_names.get('dotnet') '.NET' """ - aliases_file = paths.ecosystem_aliases_file + aliases_file = config.paths.ecosystem_aliases_file if not aliases_file.exists(): logger.warning(f"Ecosystem aliases file not found: {aliases_file}") @@ -178,7 +176,7 @@ def load_cataloger_data(update: bool = False) -> dict: >>> data = load_cataloger_data() >>> catalogers = data.get("catalogers", []) """ - cache_file = paths.cataloger_cache_file + cache_file = config.paths.cataloger_cache_file # check if cache exists and we're not forcing update if cache_file.exists() and not update: @@ -195,9 +193,9 @@ def load_cataloger_data(update: bool = False) -> dict: # generate cataloger data from syft logger.info("Extracting cataloger information from Syft...") try: - stdout, stderr, returncode = run_syft( + stdout, stderr, returncode = syft.run( args=["cataloger", "info", "-o", "json"], - timeout=timeouts.cataloger_info, + timeout=config.timeouts.cataloger_info, ) if returncode != 0: @@ -208,7 +206,7 @@ def load_cataloger_data(update: bool = False) -> dict: # save to cache cache_file.parent.mkdir(parents=True, exist_ok=True) - comment = get_generated_comment("scripts/generate_capability_tables.py", "json") + comment = config.get_generated_comment("scripts/generate_capability_tables.py", "json") cache_data = {"_comment": comment, **data} with open(cache_file, "w") as f: @@ -240,7 +238,7 @@ def load_os_data() -> list[dict]: >>> for os_entry in os_list: ... print(os_entry["name"]) """ - os_file = paths.os_data_file + os_file = config.paths.os_data_file if not os_file.exists(): logger.error(f"OS data file not found: {os_file}") @@ -345,7 +343,7 @@ def load_vulnerability_data() -> dict: >>> sources = vuln_data.get("sources", {}) >>> ecosystems = vuln_data.get("ecosystems", {}) """ - vuln_file = paths.vulnerability_data_file + vuln_file = config.paths.vulnerability_data_file if not vuln_file.exists(): logger.error(f"Vulnerability data file not found: {vuln_file}") diff --git a/scripts/utils/html_table.py b/scripts/utils/html_table.py new file mode 100644 index 00000000..80d41ae9 --- /dev/null +++ b/scripts/utils/html_table.py @@ -0,0 +1,702 @@ +""" +HTML table generation utilities for capability and vulnerability tables. + +This module provides shared functions for generating HTML tables with consistent +formatting, SVG icons, tooltips, and version handling across capability and +vulnerability documentation. +""" + +from dataclasses import dataclass +from pathlib import Path + +from utils.constants import CSSClasses, SVGIcons + + +@dataclass +class OSVersion: + """represents an operating system version.""" + + value: str + codename: str | None = None + + +def sort_versions(versions: list[OSVersion]) -> list[OSVersion]: + """ + sort OS versions numerically with special handling for non-numeric versions. + + special versions like "rolling", "unstable", "edge" are sorted after numeric versions. + numeric versions are sorted by converting version parts to integers when possible. + + Args: + versions: list of OSVersion objects to sort + + Returns: + sorted list of OSVersion objects (numeric first, then special versions) + + Examples: + >>> versions = [OSVersion("edge"), OSVersion("11.2"), OSVersion("11.1")] + >>> sorted_versions = sort_versions(versions) + >>> [v.value for v in sorted_versions] + ['11.1', '11.2', 'edge'] + """ + special_versions = [] + numeric_versions = [] + + for version in versions: + # check if version is special (non-numeric or single word) + if version.value.lower() in ["rolling", "unstable", "edge"]: + special_versions.append(version) + else: + numeric_versions.append(version) + + # sort numeric versions + def version_key(v: OSVersion) -> tuple: + """generate sort key for version.""" + try: + # split on '.' and convert to numbers + parts = v.value.split(".") + # convert each part to int if possible, otherwise keep as string + numeric_parts = [] + for part in parts: + try: + numeric_parts.append(int(part)) + except ValueError: + # if we hit a non-numeric part, keep it as high value string + numeric_parts.append((999999, part)) + return tuple(numeric_parts) + except Exception: + # fallback to string comparison + return (999999, v.value) + + numeric_versions.sort(key=version_key) + + # combine numeric first, then special versions + return numeric_versions + special_versions + + +def summarize_versions(versions: list[OSVersion]) -> list[OSVersion]: + """ + summarize continuous version ranges into condensed format. + + this function groups versions by major version and determines if they can be + summarized based on whether they form a continuous sequence. + + Args: + versions: sorted list of OSVersion objects + + Returns: + condensed list of OSVersion objects + + Examples: + >>> versions = [OSVersion("11.1"), OSVersion("11.2"), OSVersion("11.3")] + >>> result = summarize_versions(versions) + >>> [v.value for v in result] + ['11'] + + >>> versions = [OSVersion("11.2"), OSVersion("11.3"), OSVersion("11.4")] + >>> result = summarize_versions(versions) + >>> [v.value for v in result] + ['11.2+'] + + >>> versions = [OSVersion("3.20"), OSVersion("3.21"), OSVersion("edge")] + >>> result = summarize_versions(versions) + >>> [v.value for v in result] + ['3.20+', 'edge'] + """ + if not versions: + return [] + + # separate special versions + special_versions = [] + numeric_versions = [] + + for v in versions: + if v.value.lower() in ["rolling", "unstable", "edge"]: + special_versions.append(v) + else: + numeric_versions.append(v) + + if not numeric_versions: + return special_versions + + # group by major version + from collections import defaultdict + + major_groups = defaultdict(list) + + for v in numeric_versions: + try: + parts = v.value.split(".") + major = parts[0] + major_groups[major].append(v) + except Exception: + # can't parse, keep as-is + major_groups[v.value].append(v) + + result = [] + + # process each major version group + for major in sorted( + major_groups.keys(), key=lambda x: int(x) if x.isdigit() else 999999 + ): + group = major_groups[major] + + if len(group) == 1: + # single version, keep as-is + result.append(group[0]) + continue + + # check if we have version.0 + has_zero = any(v.value == major or v.value == f"{major}.0" for v in group) + + # extract minor versions + minors = [] + for v in group: + parts = v.value.split(".") + if len(parts) == 1: + # just major version (e.g., "11") + minors.append((0, v)) + elif len(parts) == 2: + try: + minor = int(parts[1]) + minors.append((minor, v)) + except ValueError: + # non-numeric minor, keep as-is + result.append(v) + continue + else: + # more complex version, keep as-is + result.append(v) + continue + + # sort by minor version + minors.sort(key=lambda x: x[0]) + + if not minors: + # no valid minors, add all as-is + result.extend(group) + continue + + # check for continuous sequence + min_minor = minors[0][0] + max_minor = minors[-1][0] + + # check if sequence is continuous + expected_minors = set(range(min_minor, max_minor + 1)) + actual_minors = {m[0] for m in minors} + is_continuous = expected_minors == actual_minors + + # decide how to summarize + if has_zero or (min_minor == 1 and is_continuous): + # has .0 or starts from .1 continuously - show just major + # keep codename from highest minor version if present + highest_version = minors[-1][1] + if highest_version.codename: + result.append(OSVersion(value=major, codename=highest_version.codename)) + else: + result.append(OSVersion(value=major)) + elif min_minor > 1 and is_continuous: + # starts from .2+ without .0 or .1 - show "major.minor+" + result.append(OSVersion(value=f"{major}.{min_minor}+")) + else: + # not continuous or has gaps, keep all versions + for _, v in minors: + result.append(v) + + return result + special_versions + + +def format_versions_list(versions: list[OSVersion]) -> str: + """ + format OS versions for display, with codenames in parentheses. + + versions are sorted numerically and continuous ranges are summarized. + each version is wrapped in tags, and codenames are shown in parentheses. + + Args: + versions: list of OSVersion objects + + Returns: + formatted HTML string for display + + Examples: + >>> versions = [ + ... OSVersion("10", "buster"), + ... OSVersion("11", "bullseye"), + ... OSVersion("12", "bookworm") + ... ] + >>> format_versions_list(versions) + '10 (buster), 11 (bullseye), 12 (bookworm)' + + >>> versions = [OSVersion("3.2"), OSVersion("3.3"), OSVersion("edge")] + >>> format_versions_list(versions) + '3.2+, edge' + """ + if not versions: + return "-" + + # sort and summarize versions + sorted_versions = sort_versions(versions) + summarized_versions = summarize_versions(sorted_versions) + + formatted = [] + for version in summarized_versions: + if version.codename: + formatted.append(f"{version.value} ({version.codename})") + else: + formatted.append(f"{version.value}") + + return ", ".join(formatted) + + +def get_svg_icon(icon_type: str) -> str: + """ + get SVG icon HTML for a capability indicator. + + the SVG sprite definitions are in layouts/partials/hooks/body-end.html + and are automatically included on every page by the Docsy theme. + + Args: + icon_type: 'check', 'gear', or 'dash' + + Returns: + HTML string with SVG icon reference + + Examples: + >>> get_svg_icon('check') + '' + + >>> get_svg_icon('gear') + '' + """ + # map string to enum + icon_map = { + "check": SVGIcons.CHECK, + "gear": SVGIcons.GEAR, + "dash": SVGIcons.DASH, + } + icon = icon_map.get(icon_type, SVGIcons.DASH) + return f'' + + +def format_evidence_for_tooltip(evidence: list[str]) -> str: + """ + format evidence field paths for tooltip display. + + single evidence items are shown as-is, multiple items are formatted as + a bullet list with line breaks using HTML entity. + + Args: + evidence: list of evidence field paths (e.g., ['AlpmDBEntry.Files']) + + Returns: + formatted string for tooltip: + - empty string if no evidence + - single path if one item + - bullet list with line breaks if multiple items + + Examples: + >>> format_evidence_for_tooltip([]) + '' + + >>> format_evidence_for_tooltip(['AlpmDBEntry.Files']) + 'AlpmDBEntry.Files' + + >>> format_evidence_for_tooltip(['Path.A', 'Path.B']) + ' • Path.A • Path.B' + """ + if not evidence: + return "" + + if len(evidence) == 1: + return evidence[0] + + # format as bullet list with line breaks for multiple items + return " ".join(f"• {path}" for path in evidence) + + +def format_conditions_for_tooltip(conditions: list[dict], prefix: str = "Requires") -> str: + """ + format condition requirements for tooltip display. + + extracts configuration key-value pairs from condition objects and formats + them with a prefix. single conditions are shown on one line, multiple + conditions are formatted as a bullet list. + + Args: + conditions: list of condition dicts with 'when' and optionally 'value' fields + e.g., [{"when": {"IncludeUnindexedArchives": true}}] + or [{"when": {"SearchLocalModCacheLicenses": true}, "value": true}] + prefix: prefix text for the condition (default: "Requires") + + Returns: + formatted string for tooltip: + - empty string if no conditions + - single line for one condition: "Requires: ConfigKey = value" + - multi-line for multiple conditions with bullet list + + Examples: + >>> conditions = [{"when": {"IncludeArchives": True}}] + >>> format_conditions_for_tooltip(conditions) + 'Requires: IncludeArchives = true' + + >>> conditions = [ + ... {"when": {"Option1": True}}, + ... {"when": {"Option2": False}} + ... ] + >>> format_conditions_for_tooltip(conditions, "When") + 'When: • Option1 = true • Option2 = false' + """ + if not conditions: + return "" + + # extract all config key-value pairs from conditions + config_pairs = [] + for condition in conditions: + when = condition.get("when", {}) + for config_key, config_value in when.items(): + # format value as lowercase string for boolean values + if isinstance(config_value, bool): + value_str = str(config_value).lower() + else: + value_str = str(config_value) + config_pairs.append((config_key, value_str)) + + if not config_pairs: + return "" + + # format based on number of config pairs + if len(config_pairs) == 1: + config_key, config_value = config_pairs[0] + return f"{prefix}: {config_key} = {config_value}" + + # multiple pairs - use bullet list with line breaks + lines = [f"{prefix}:"] + for config_key, config_value in config_pairs: + lines.append(f"• {config_key} = {config_value}") + return " ".join(lines) + + +def get_capability_indicator_svg( + cap_support, + evidence: list[str] = None, + conditions: list[dict] = None, +) -> str: + """ + get the SVG icon for a capability support level with optional tooltip. + + determines the appropriate icon (check or gear) based on whether the capability + is supported and/or conditional. combines condition and evidence information + into a tooltip if present. + + Args: + cap_support: CapabilitySupport object or None (must have supported, conditional, + evidence, and conditions attributes if not None) + evidence: optional evidence list to override cap_support.evidence + conditions: optional conditions list to override cap_support.conditions + + Returns: + HTML string with SVG icon (with data-tooltip attribute if tooltip exists), + or empty string if not supported + + Examples: + >>> # With supported capability + >>> class CapSupport: + ... supported = True + ... conditional = False + ... evidence = ['Field.Path'] + ... conditions = [] + >>> get_capability_indicator_svg(CapSupport()) + '' + + >>> # With conditional capability + >>> class CapSupport: + ... supported = True + ... conditional = True + ... evidence = [] + ... conditions = [{"when": {"Option": True}}] + >>> get_capability_indicator_svg(CapSupport()) + '' + """ + if cap_support is None: + return "" + + # use provided evidence/conditions or fall back to cap_support attributes + if evidence is None: + evidence = getattr(cap_support, "evidence", []) + if conditions is None: + conditions = getattr(cap_support, "conditions", []) + + # determine icon type + if cap_support.conditional: + icon_type = "gear" + elif cap_support.supported: + icon_type = "check" + else: + return "" + + # format tooltip content - combine conditions and evidence if both exist + tooltip_parts = [] + + # add condition info if present + if conditions: + formatted_condition = format_conditions_for_tooltip(conditions, prefix="When") + if formatted_condition: + tooltip_parts.append(formatted_condition) + + # add evidence info if present + if evidence: + formatted_evidence = format_evidence_for_tooltip(evidence) + if formatted_evidence: + # add "Evidence:" prefix if we also have conditions + if tooltip_parts: + tooltip_parts.append(f"Evidence: {formatted_evidence}") + else: + tooltip_parts.append(formatted_evidence) + + # create data attribute for combined tooltip + tooltip_attr = "" + if tooltip_parts: + # join with double line break for visual separation + combined_tooltip = " ".join(tooltip_parts) + # escape quotes for HTML attribute + escaped_tooltip = combined_tooltip.replace('"', """) + tooltip_attr = f' data-tooltip="{escaped_tooltip}"' + + # wrap SVG in span when tooltip exists (SVG elements don't support ::after pseudo-elements) + icon_enum = SVGIcons.CHECK if icon_type == "check" else SVGIcons.GEAR + if tooltip_attr: + return f'' + else: + return f'' + + +def clean_owned_files(output_dir: Path, owned_files: set[str], logger) -> None: + """ + clean only specified files from output directory. + + removes stale files without deleting artifacts from other scripts. + this is useful when multiple scripts generate files to the same directory + and each script should only clean up its own files. + + Args: + output_dir: root output directory + owned_files: set of filenames this script owns (e.g., {"package.md", "config.md"}) + logger: logger instance for debug output + + Examples: + >>> from pathlib import Path + >>> import logging + >>> logger = logging.getLogger() + >>> output_dir = Path("/tmp/output") + >>> owned_files = {"package.md", "config.md"} + >>> clean_owned_files(output_dir, owned_files, logger) + # Removes only package.md and config.md from output_dir and subdirectories + """ + if not output_dir.exists(): + return + + # walk through the directory tree and remove only owned files + removed_count = 0 + for file_path in output_dir.rglob("*"): + if file_path.is_file() and file_path.name in owned_files: + logger.debug(f"Removing stale file: {file_path}") + file_path.unlink() + removed_count += 1 + + if removed_count > 0: + logger.debug(f"Cleaned up {removed_count} stale file(s)") + + +class TableBuilder: + """ + programmatic HTML table builder for capability and vulnerability tables. + + provides a fluent API for building complex HTML tables with multi-row headers, + cell attributes (class, rowspan, colspan), and automatic HTML generation. + + Examples: + >>> builder = TableBuilder("capability-table") + >>> builder.add_header_row([ + ... {"class": "col-ecosystem", "content": "Ecosystem", "rowspan": 2}, + ... {"class": "col-license", "content": "License", "rowspan": 2} + ... ]) + >>> builder.add_body_row([ + ... {"class": "col-ecosystem", "content": "Python"}, + ... {"class": "col-license", "content": "✅"} + ... ]) + >>> html_lines = builder.build() + """ + + def __init__(self, table_class: str = "capability-table") -> None: + """ + initialize table builder with CSS class. + + Args: + table_class: CSS class name for the table element + """ + self.table_class = table_class + self.header_rows: list[list[dict[str, str | int]]] = [] + self.body_rows: list[list[dict[str, str | int]]] = [] + + def add_header_row(self, cells: list[dict[str, str | int]]) -> "TableBuilder": + """ + add a header row to the table. + + Args: + cells: list of cell definitions, each dict can contain: + - content: cell HTML content (required) + - class: CSS class name (optional) + - rowspan: number of rows to span (optional) + - colspan: number of columns to span (optional) + - tooltip: tooltip text for abbr element (optional) + + Returns: + self for method chaining + + Examples: + >>> builder.add_header_row([ + ... {"content": "Name", "class": "col-name"}, + ... {"content": "Value", "class": "col-value", "rowspan": 2} + ... ]) + """ + self.header_rows.append(cells) + return self + + def add_body_row(self, cells: list[dict[str, str | int]]) -> "TableBuilder": + """ + add a body row to the table. + + Args: + cells: list of cell definitions (same format as add_header_row) + + Returns: + self for method chaining + + Examples: + >>> builder.add_body_row([ + ... {"content": "Python", "class": "col-name"}, + ... {"content": "3.11", "class": "col-value"} + ... ]) + """ + self.body_rows.append(cells) + return self + + def build(self) -> list[str]: + """ + build the complete HTML table. + + Returns: + list of HTML lines for the table + + Examples: + >>> lines = builder.build() + >>> print("\\n".join(lines)) +
Field NameTypeField NameTypeDescriptionDescription
{field_name_html}{field_name_html}{linked_type}{linked_type}{field["description"]}{field["description"]}
+ + + + + + + + + + +
Name
Python
+ """ + lines = [] + + # table opening + lines.append(f'') + + # thead + if self.header_rows: + lines.append(" ") + for row in self.header_rows: + lines.append(" ") + for cell in row: + lines.append(self._format_header_cell(cell)) + lines.append(" ") + lines.append(" ") + + # tbody + if self.body_rows: + lines.append(" ") + for row in self.body_rows: + lines.append(" ") + for cell in row: + lines.append(self._format_body_cell(cell)) + lines.append(" ") + lines.append(" ") + + # table closing + lines.append("
") + + return lines + + def _format_header_cell(self, cell: dict[str, str | int]) -> str: + """ + format a single header cell with attributes. + + Args: + cell: cell definition dict + + Returns: + formatted HTML line + """ + attrs = [] + + # add class + if "class" in cell: + attrs.append(f'class="{cell["class"]}"') + + # add rowspan + if "rowspan" in cell and cell["rowspan"] > 1: + attrs.append(f'rowspan="{cell["rowspan"]}"') + + # add colspan + if "colspan" in cell and cell["colspan"] > 1: + attrs.append(f'colspan="{cell["colspan"]}"') + + # format content with optional tooltip + content = cell.get("content", "") + tooltip = cell.get("tooltip") + + if tooltip: + # wrap content in with tooltip + content = f'{content}' + + # build tag + attr_str = " " + " ".join(attrs) if attrs else "" + return f' {content}' + + def _format_body_cell(self, cell: dict[str, str | int]) -> str: + """ + format a single body cell with attributes. + + Args: + cell: cell definition dict + + Returns: + formatted HTML line + """ + attrs = [] + + # add class + if "class" in cell: + attrs.append(f'class="{cell["class"]}"') + + # add rowspan + if "rowspan" in cell and cell["rowspan"] > 1: + attrs.append(f'rowspan="{cell["rowspan"]}"') + + # add colspan + if "colspan" in cell and cell["colspan"] > 1: + attrs.append(f'colspan="{cell["colspan"]}"') + + content = cell.get("content", "") + + # build tag + attr_str = " " + " ".join(attrs) if attrs else "" + return f' {content}' diff --git a/scripts/utils/logging.py b/scripts/utils/log.py similarity index 89% rename from scripts/utils/logging.py rename to scripts/utils/log.py index 4f9ded1d..c783d8fe 100644 --- a/scripts/utils/logging.py +++ b/scripts/utils/log.py @@ -11,7 +11,7 @@ from rich.logging import RichHandler -def setup_logging(verbosity: int = 0, script_name: str | None = None) -> logging.Logger: +def setup(verbosity: int = 0, script_name: str | None = None) -> logging.Logger: """ configure logging with RichHandler for pretty output. @@ -26,7 +26,7 @@ def setup_logging(verbosity: int = 0, script_name: str | None = None) -> logging >>> # in a script with click >>> @click.option("-v", "--verbose", count=True) >>> def main(verbose: int): - ... logger = setup_logging(verbose, __file__) + ... logger = log.setup(verbose, __file__) ... logger.info("Starting script...") """ # map verbosity count to log level @@ -85,11 +85,11 @@ def setup_logging(verbosity: int = 0, script_name: str | None = None) -> logging return logger -def get_logger(name: str | None = None) -> logging.Logger: +def logger(name: str | None = None) -> logging.Logger: """ get a logger instance for use in utility modules. - this function assumes setup_logging() has already been called + this function assumes setup() has already been called by the main script entrypoint. Args: @@ -100,7 +100,7 @@ def get_logger(name: str | None = None) -> logging.Logger: Examples: >>> # in a utility module - >>> logger = get_logger(__name__) + >>> logger = log.logger(__name__) >>> logger.debug("Processing data...") """ return logging.getLogger(name) diff --git a/scripts/utils/markdown.py b/scripts/utils/markdown.py new file mode 100644 index 00000000..2046a6c7 --- /dev/null +++ b/scripts/utils/markdown.py @@ -0,0 +1,163 @@ +"""Markdown generation utilities for documentation scripts.""" + + +def create_code_fence(content: str, language: str = "") -> str: + """ + Create markdown code fence with optional language specifier. + + Args: + content: Code/text content to wrap in code fence + language: Language for syntax highlighting (empty string for plain text) + + Returns: + Formatted markdown code fence with content + + Examples: + >>> create_code_fence("print('hello')", "python") + "```python\\nprint('hello')\\n```\\n" + + >>> create_code_fence("plain text") + "```\\nplain text\\n```\\n" + """ + fence_start = f"```{language}" if language else "```" + return f"{fence_start}\n{content}\n```\n" + + +def generate_front_matter( + title: str, + link_title: str | None = None, + weight: int | None = None, + tags: list[str] | None = None, + categories: list[str] | None = None, + url: str | None = None, + description: str | None = None, + aliases: list[str] | None = None, + params: dict[str, any] | None = None, +) -> str: + """ + Generate Hugo front matter in TOML format. + + Args: + title: Page title + link_title: Sidebar link title (defaults to title) + weight: Menu ordering weight + tags: List of tags + categories: List of categories + url: Custom URL path + description: Page description for SEO + aliases: List of URL aliases + params: Additional parameters dict + + Returns: + Formatted TOML front matter with +++ delimiters + + Example: + >>> generate_front_matter( + ... title="Syft CLI", + ... link_title="Syft CLI", + ... weight=10, + ... tags=["syft"], + ... categories=["reference"], + ... url="docs/reference/syft/cli" + ... ) + '+++\\ntitle = "Syft CLI"\\nlinkTitle = "Syft CLI"\\nweight = 10\\ntags = [\\'syft\\']\\ncategories = [\\'reference\\']\\nurl = "docs/reference/syft/cli"\\n+++\\n\\n' + """ + lines = ["+++"] + + # required field + lines.append(f'title = "{title}"') + + # optional fields + if link_title is not None: + lines.append(f'linkTitle = "{link_title}"') + + if weight is not None: + lines.append(f"weight = {weight}") + + if tags is not None: + tags_str = ", ".join(f"'{tag}'" for tag in tags) + lines.append(f"tags = [{tags_str}]") + + if categories is not None: + categories_str = ", ".join(f"'{cat}'" for cat in categories) + lines.append(f"categories = [{categories_str}]") + + if url is not None: + lines.append(f'url = "{url}"') + + if description is not None: + lines.append(f'description = "{description}"') + + if aliases is not None: + aliases_str = ", ".join(f'"{alias}"' for alias in aliases) + lines.append(f"aliases = [{aliases_str}]") + + if params is not None: + for key, value in params.items(): + if isinstance(value, str): + lines.append(f'{key} = "{value}"') + elif isinstance(value, bool): + lines.append(f"{key} = {str(value).lower()}") + elif isinstance(value, (int, float)): + lines.append(f"{key} = {value}") + else: + # for complex types, convert to string + lines.append(f'{key} = "{value}"') + + lines.append("+++") + lines.append("") # blank line after front matter + + return "\n".join(lines) + "\n" + + +def detect_format(content: str) -> str: + """ + Detect output format for syntax highlighting. + + Analyzes content to determine the best syntax highlighting language identifier. + + Args: + content: Output content to analyze + + Returns: + Format string: "json", "csv", "text", "yaml", "xml", etc. + + Examples: + >>> markdown.detect_format('{"foo": "bar"}') + 'json' + + >>> markdown.detect_format('name,value\\nfoo,bar') + 'csv' + + >>> markdown.detect_format('plain text output') + 'text' + + >>> markdown.detect_format('(no results)') + 'text' + """ + # handle empty or special cases + if not content or content == "(no results)": + return "text" + + # try to detect JSON (starts with { or [) + # note: we can't parse it since it might be truncated + if content.startswith("{") or content.startswith("["): + return "json" + + # check if it looks like CSV (multiple lines with commas) + lines = content.split("\n") + if len(lines) > 1 and all("," in line for line in lines[:3] if line.strip()): + return "csv" + + # check for YAML indicators + if ":" in content and any( + line.strip().startswith("-") for line in lines if line.strip() + ): + return "yaml" + + # check for XML + if content.strip().startswith(" bool: + """ + check if output file needs regeneration based on source file timestamps. + + compares modification times of output file against all source files to determine + if regeneration is needed. If any source file is newer than the output, or if + the output doesn't exist, regeneration is needed. + + Args: + output_file: path to output file to check + source_files: list of source files that contribute to the output + update: if True, always return True to force regeneration + + Returns: + True if output needs regeneration, False if output is up-to-date + + Examples: + >>> output = Path("output.md") + >>> sources = [Path("input.yaml"), Path("sbom.json")] + >>> if should_regenerate(output, sources, update=False): + ... # regenerate output + ... pass + """ + # always regenerate if --update flag is set + if update: + return True + + # regenerate if output doesn't exist + if not output_file.exists(): + return True + + # get output modification time + output_mtime = output_file.stat().st_mtime + + # check if any source file is newer than output + for source_file in source_files: + if source_file.exists(): + source_mtime = source_file.stat().st_mtime + if source_mtime > output_mtime: + # source is newer, need to regenerate + return True + + # output is up-to-date + return False + + +def should_regenerate_multiple( + output_files: list[Path], + source_files: list[Path], + update: bool = False, +) -> bool: + """ + check if any output files need regeneration based on source file timestamps. + + similar to should_regenerate(), but checks multiple output files. If any output + is missing or stale, regeneration is needed. + + Args: + output_files: list of output files to check + source_files: list of source files that contribute to outputs + update: if True, always return True to force regeneration + + Returns: + True if any output needs regeneration, False if all outputs are up-to-date + + Examples: + >>> outputs = [Path("query.md"), Path("example.md"), Path("output.md")] + >>> sources = [Path("query.yaml"), Path("sbom.json")] + >>> if should_regenerate_multiple(outputs, sources, update=False): + ... # regenerate all outputs + ... pass + """ + # always regenerate if --update flag is set + if update: + return True + + # check if all outputs exist + if not all(output.exists() for output in output_files): + return True + + # get oldest output modification time + output_mtime = min(output.stat().st_mtime for output in output_files) + + # check if any source file is newer than oldest output + for source_file in source_files: + if source_file.exists(): + source_mtime = source_file.stat().st_mtime + if source_mtime > output_mtime: + # source is newer, need to regenerate + return True + + # all outputs are up-to-date + return False + + +def get_cache_key(image: str, config_file: Path | None = None) -> str: + """ + generate a cache key for SBOM caching based on image and optional config. + + converts image name and config file into a filesystem-safe cache key by + replacing special characters. + + Args: + image: container image name (e.g., "alpine:3.9.2", "node:18-alpine") + config_file: optional config file path that affects SBOM generation + + Returns: + cache key string safe for use in filenames + + Examples: + >>> get_cache_key("alpine:3.9.2") + 'alpine_3.9.2' + + >>> get_cache_key("node:18-alpine", Path(".syft.yaml")) + 'node_18-alpine_.syft' + + >>> get_cache_key("anchore/syft:latest") + 'anchore_syft_latest' + """ + # replace special characters with underscores + cache_key = image.replace(":", "_").replace("/", "_") + + # append config file stem if provided + if config_file: + cache_key += f"_{config_file.stem}" + + return cache_key + + +def clean_directory( + output_dir: Path, + update: bool = False, + logger=None, +) -> None: + """ + clean output directory when update flag is set. + + removes and recreates the output directory to ensure a clean slate for + regeneration. Only cleans if update flag is True and directory exists. + + Args: + output_dir: directory to clean + update: if True, perform the cleanup + logger: optional logger for debug output + + Examples: + >>> from pathlib import Path + >>> output_dir = Path("/tmp/output") + >>> output_manager.clean_directory(output_dir, update=True) + # Removes /tmp/output and recreates it + """ + if update and output_dir.exists(): + if logger: + logger.debug(f"Cleaning output directory (--update flag): {output_dir}") + shutil.rmtree(output_dir) + + # ensure directory exists + output_dir.mkdir(parents=True, exist_ok=True) + + +def ensure_directory(path: Path) -> None: + """ + ensure directory exists, creating it and parents if needed. + + Args: + path: directory path to create + + Examples: + >>> ensure_directory(Path("/tmp/nested/dir")) + # Creates /tmp/nested/dir and any missing parent directories + """ + path.mkdir(parents=True, exist_ok=True) diff --git a/scripts/utils/sbom.py b/scripts/utils/sbom.py index d138d028..f651bcc7 100644 --- a/scripts/utils/sbom.py +++ b/scripts/utils/sbom.py @@ -8,14 +8,12 @@ from pathlib import Path -from .config import timeouts -from .logging import get_logger -from .syft import run_syft_scan, run_syft_with_config +from . import config, log, syft -logger = get_logger(__name__) +logger = log.logger(__name__) -def get_or_generate_sbom( +def get_or_generate( image: str, cache_dir: Path, syft_image: str, @@ -80,19 +78,19 @@ def get_or_generate_sbom( logger.debug(f"Generating SBOM for: {image}") if config_file: - sbom_json = run_syft_with_config( + sbom_json = syft.scan_with_config( target_image=image, config_file=config_file, syft_image=syft_image, output_format="syft-json", - timeout=timeouts.syft_scan_with_config, + timeout=config.timeouts.syft_scan_with_config, ) else: - sbom_json = run_syft_scan( + sbom_json = syft.scan( target_image=image, syft_image=syft_image, output_format="syft-json", - timeout=timeouts.syft_scan_default, + timeout=config.timeouts.syft_scan_default, ) # save to cache diff --git a/scripts/utils/syft.py b/scripts/utils/syft.py index 28612a0d..55db85ba 100644 --- a/scripts/utils/syft.py +++ b/scripts/utils/syft.py @@ -12,7 +12,7 @@ from .config import docker_images, timeouts -def run_syft( +def run( syft_image: str = docker_images.syft, args: list[str] | None = None, timeout: int = timeouts.syft_scan_default, @@ -39,13 +39,13 @@ def run_syft( Examples: >>> # Scan an image - >>> stdout, stderr, code = run_syft(args=["alpine:3.9.2", "-o", "json"]) + >>> stdout, stderr, code = syft.run(args=["alpine:3.9.2", "-o", "json"]) >>> >>> # Get version - >>> stdout, stderr, code = run_syft(args=["version"]) + >>> stdout, stderr, code = syft.run(args=["version"]) >>> >>> # Get config - >>> stdout, stderr, code = run_syft(args=["config"]) + >>> stdout, stderr, code = syft.run(args=["config"]) """ docker_cmd = ["docker", "run", "--rm"] @@ -80,7 +80,7 @@ def run_syft( raise -def run_syft_scan( +def scan( target_image: str, syft_image: str = docker_images.syft, output_format: str = "syft-json", @@ -114,7 +114,7 @@ def run_syft_scan( args.extend(extra_args) try: - stdout, stderr, returncode = run_syft( + stdout, stderr, returncode = run( syft_image=syft_image, args=args, timeout=timeout, @@ -133,7 +133,7 @@ def run_syft_scan( raise RuntimeError(f"Failed to run Syft: {e}") from e -def run_syft_with_template( +def scan_with_template( template_file: Path, target_image: str, syft_image: str = docker_images.syft, @@ -163,7 +163,7 @@ def run_syft_with_template( # use template output format with path to mounted template extra_args = ["-t", "/template.tmpl"] - return run_syft_scan( + return scan( target_image=target_image, syft_image=syft_image, output_format="template", @@ -173,7 +173,7 @@ def run_syft_with_template( ) -def run_syft_with_config( +def scan_with_config( target_image: str, config_file: Path, syft_image: str = docker_images.syft, @@ -208,7 +208,7 @@ def run_syft_with_config( # specify config file path extra_args = ["-c", "/config.yaml"] - return run_syft_scan( + return scan( target_image=target_image, syft_image=syft_image, output_format=output_format, @@ -218,7 +218,7 @@ def run_syft_with_config( ) -def run_syft_convert( +def convert( sbom_file: Path, template_file: Path, syft_image: str = docker_images.syft, @@ -259,7 +259,7 @@ def run_syft_convert( args = ["convert", "/sbom.json", "-o", "template", "-t", "/template.tmpl"] try: - stdout, stderr, returncode = run_syft( + stdout, stderr, returncode = run( syft_image=syft_image, args=args, timeout=timeout, @@ -279,7 +279,7 @@ def run_syft_convert( raise RuntimeError(f"Failed to run Syft convert: {e}") from e -def run_syft_convert_format( +def convert_format( sbom_file: Path, output_format: str, syft_image: str = docker_images.syft, @@ -316,7 +316,7 @@ def run_syft_convert_format( args = ["convert", "/sbom.json", "-o", output_format] try: - stdout, stderr, returncode = run_syft( + stdout, stderr, returncode = run( syft_image=syft_image, args=args, timeout=timeout, @@ -337,7 +337,7 @@ def run_syft_convert_format( raise RuntimeError(f"Failed to run Syft convert: {e}") from e -def run_syft_with_format( +def scan_with_format( target_image: str, syft_image: str = docker_images.syft, output_format: str = "json", @@ -370,7 +370,7 @@ def run_syft_with_format( if file_metadata_selection: env_vars["SYFT_FILE_METADATA_SELECTION"] = file_metadata_selection - return run_syft_scan( + return scan( target_image=target_image, syft_image=syft_image, output_format=output_format, diff --git a/scripts/utils/version.py b/scripts/utils/version.py new file mode 100644 index 00000000..2fde4821 --- /dev/null +++ b/scripts/utils/version.py @@ -0,0 +1,302 @@ +#!/usr/bin/env python3 +""" +Version handling utilities for extracting and parsing version strings. + +Provides utilities for: +- Extracting version information from command output +- Parsing semantic version strings +- Comparing and sorting versions +""" + +import re +from dataclasses import dataclass + + +def extract_from_output( + output: str, + patterns: list[str] | None = None, + tool_name: str | None = None, +) -> str: + """ + extract version string from command output. + + Tries multiple patterns to find version information: + 1. "Version: X.Y.Z" format (case-insensitive) + 2. "ToolName: X.Y.Z" format (if tool_name provided) + 3. Lines containing "version" and a colon + 4. Custom regex patterns + + Args: + output: command output text + patterns: optional custom regex patterns to try first + tool_name: tool name to look for (e.g., "Syft", "Grype") + + Returns: + version string or "unknown" if not found + + Examples: + >>> version.extract_from_output("Version: 1.2.3\\nBuild: xyz") + '1.2.3' + + >>> version.extract_from_output("Syft: v1.0.0\\nOther: info", tool_name="Syft") + 'v1.0.0' + + >>> version.extract_from_output("application version: 2.0.0") + '2.0.0' + """ + if not output: + return "unknown" + + lines = output.strip().split("\n") + + # Try custom patterns first if provided + if patterns: + for pattern in patterns: + for line in lines: + match = re.search(pattern, line) + if match: + # Return first capture group if present, otherwise full match + return match.group(1) if match.groups() else match.group(0) + + # Try standard "Version:" pattern (case-insensitive) + for line in lines: + if line.lower().startswith("version:"): + version = line.split(":", 1)[1].strip() + if version: + return version + + # Try tool-specific pattern if tool_name provided + if tool_name: + tool_display = tool_name.title() + for line in lines: + # Try both original case and title case + for name_variant in [tool_name, tool_display]: + if line.startswith(f"{name_variant}:"): + version = line.split(":", 1)[1].strip() + if version: + return version + + # Try any line containing "version" and a colon + for line in lines: + if "version" in line.lower() and ":" in line: + parts = line.split(":", 1) + if len(parts) == 2: + version = parts[1].strip() + if version: + return version + + # If nothing found, return unknown + return "unknown" + + +@dataclass +class Version: + """Parsed semantic version.""" + + major: int + minor: int + patch: int + prerelease: str | None = None + + @classmethod + def parse(cls, version_str: str) -> "Version": + """ + parse version string into components. + + Handles: + - Standard semver: "1.2.3" + - With 'v' prefix: "v1.2.3" + - With prerelease: "1.2.3-beta.1" + + Args: + version_str: version string to parse + + Returns: + Version object + + Raises: + ValueError: if version string is invalid + + Examples: + >>> Version.parse("1.2.3") + Version(major=1, minor=2, patch=3, prerelease=None) + + >>> Version.parse("v2.0.0-beta.1") + Version(major=2, minor=0, patch=0, prerelease='beta.1') + """ + # Remove leading 'v' if present + clean_version = version_str.strip() + if clean_version.startswith("v"): + clean_version = clean_version[1:] + + # Split on '-' to separate prerelease + parts = clean_version.split("-", 1) + version_parts = parts[0] + prerelease = parts[1] if len(parts) > 1 else None + + # Parse major.minor.patch + version_components = version_parts.split(".") + if len(version_components) < 3: + raise ValueError( + f"Invalid version string: {version_str} (expected format: X.Y.Z)" + ) + + try: + major = int(version_components[0]) + minor = int(version_components[1]) + patch = int(version_components[2]) + except ValueError as e: + raise ValueError(f"Invalid version string: {version_str}") from e + + return cls(major=major, minor=minor, patch=patch, prerelease=prerelease) + + def __lt__(self, other: "Version") -> bool: + """ + compare versions for sorting. + + Versions are compared by major, minor, patch in order. + Prerelease versions are considered less than release versions. + """ + if not isinstance(other, Version): + return NotImplemented + + # Compare major.minor.patch + if self.major != other.major: + return self.major < other.major + if self.minor != other.minor: + return self.minor < other.minor + if self.patch != other.patch: + return self.patch < other.patch + + # If versions are equal, check prerelease + # No prerelease (release) is greater than prerelease + if self.prerelease is None and other.prerelease is None: + return False + if self.prerelease is None: + return False # Release > prerelease + if other.prerelease is None: + return True # Prerelease < release + + # Both have prerelease, compare lexically + return self.prerelease < other.prerelease + + def __eq__(self, other: object) -> bool: + """Check if versions are equal.""" + if not isinstance(other, Version): + return NotImplemented + return ( + self.major == other.major + and self.minor == other.minor + and self.patch == other.patch + and self.prerelease == other.prerelease + ) + + def __str__(self) -> str: + """ + format as version string. + + Returns: + version string in format "X.Y.Z" or "X.Y.Z-prerelease" + + Examples: + >>> str(Version(1, 2, 3)) + '1.2.3' + + >>> str(Version(2, 0, 0, 'beta.1')) + '2.0.0-beta.1' + """ + version = f"{self.major}.{self.minor}.{self.patch}" + if self.prerelease: + version += f"-{self.prerelease}" + return version + + +def parse(version_str: str) -> Version: + """ + parse semantic version string into components. + + convenience wrapper around Version.parse(). + + Args: + version_str: version string to parse + + Returns: + Version object + + Raises: + ValueError: if version string is invalid + + Examples: + >>> version.parse("1.2.3") + Version(major=1, minor=2, patch=3, prerelease=None) + + >>> version.parse("v2.0.0-beta.1") + Version(major=2, minor=0, patch=0, prerelease='beta.1') + """ + return Version.parse(version_str) + + +def compare(v1: str, v2: str) -> int: + """ + compare two version strings. + + Args: + v1: first version string + v2: second version string + + Returns: + -1 if v1 < v2, 0 if equal, 1 if v1 > v2 + + Raises: + ValueError: if either version string is invalid + + Examples: + >>> version.compare("1.2.3", "1.2.4") + -1 + + >>> version.compare("2.0.0", "1.9.9") + 1 + + >>> version.compare("1.0.0", "1.0.0") + 0 + """ + version1 = parse(v1) + version2 = parse(v2) + + if version1 < version2: + return -1 + elif version1 == version2: + return 0 + else: + return 1 + + +def sort_strings(versions: list[str], reverse: bool = False) -> list[str]: + """ + sort version strings numerically. + + Args: + versions: list of version strings + reverse: sort descending if True (default: False for ascending) + + Returns: + sorted list of version strings + + Raises: + ValueError: if any version string is invalid + + Examples: + >>> version.sort_strings(["1.2.3", "1.0.0", "2.0.0"]) + ['1.0.0', '1.2.3', '2.0.0'] + + >>> version.sort_strings(["1.2.3", "1.0.0", "2.0.0"], reverse=True) + ['2.0.0', '1.2.3', '1.0.0'] + """ + # Parse all versions + parsed_versions = [(v, parse(v)) for v in versions] + + # Sort by parsed version + sorted_versions = sorted(parsed_versions, key=lambda x: x[1], reverse=reverse) + + # Return original strings + return [v[0] for v in sorted_versions] diff --git a/tasks.d/generate.yaml b/tasks.d/generate.yaml index 88f9fc13..74f7d816 100644 --- a/tasks.d/generate.yaml +++ b/tasks.d/generate.yaml @@ -3,7 +3,7 @@ version: '3' vars: SYFT_CLI_CMD: "uv run ./scripts/generate_reference_cli_docs.py anchore/syft:latest --output ./content/docs/reference/syft/cli.md --tool-name syft" SYFT_CONFIG_CMD: "uv run ./scripts/generate_reference_config_docs.py anchore/syft:latest --output ./content/docs/reference/syft/config.md --tool-name syft" - SYFT_JSON_SCHEMA_CMD: "uv run ./scripts/generate_reference_syft_json_schema.py --latest" + SYFT_JSON_SCHEMA_CMD: "uv run ./scripts/generate_reference_syft_json_schema.py" GRYPE_CLI_CMD: "uv run ./scripts/generate_reference_cli_docs.py anchore/grype:latest --output ./content/docs/reference/grype/cli.md --tool-name grype" GRYPE_CONFIG_CMD: "uv run ./scripts/generate_reference_config_docs.py anchore/grype:latest --output ./content/docs/reference/grype/config.md --tool-name grype" FORMAT_EXAMPLES_CMD: "uv run ./scripts/generate_format_examples.py" From f0de881b0c3fcdee96ee3d13c3851a2648d9577f Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Wed, 29 Oct 2025 15:47:32 -0400 Subject: [PATCH 2/2] fix linting Signed-off-by: Alex Goodman --- content/_index.html | 6 +- .../snippets/ecosystem/alpm/os.md | 1 - .../snippets/ecosystem/alpm/package.md | 1 - .../snippets/ecosystem/alpm/vulnerability.md | 1 - .../capabilities/snippets/ecosystem/apk/os.md | 1 - .../snippets/ecosystem/apk/package.md | 1 - .../snippets/ecosystem/apk/vulnerability.md | 1 - .../binary/binary-package-details.md | 1 - .../ecosystem/binary/grype-app-config.md | 1 - .../snippets/ecosystem/binary/package.md | 1 - .../ecosystem/binary/vulnerability.md | 1 - .../snippets/ecosystem/bitnami/package.md | 1 - .../ecosystem/bitnami/vulnerability.md | 1 - .../ecosystem/c++/grype-app-config.md | 1 - .../snippets/ecosystem/c++/package.md | 1 - .../snippets/ecosystem/c++/vulnerability.md | 1 - .../ecosystem/conda/grype-app-config.md | 1 - .../snippets/ecosystem/conda/package.md | 1 - .../snippets/ecosystem/conda/vulnerability.md | 1 - .../ecosystem/dart/grype-app-config.md | 1 - .../snippets/ecosystem/dart/package.md | 1 - .../snippets/ecosystem/dart/vulnerability.md | 1 - .../ecosystem/dotnet/grype-app-config.md | 1 - .../snippets/ecosystem/dotnet/package.md | 1 - .../ecosystem/dotnet/syft-app-config.md | 1 - .../ecosystem/dotnet/vulnerability.md | 1 - .../snippets/ecosystem/dpkg/os.md | 1 - .../snippets/ecosystem/dpkg/package.md | 1 - .../snippets/ecosystem/dpkg/vulnerability.md | 1 - .../ecosystem/elixir/grype-app-config.md | 1 - .../snippets/ecosystem/elixir/package.md | 1 - .../ecosystem/elixir/vulnerability.md | 1 - .../ecosystem/erlang/grype-app-config.md | 1 - .../snippets/ecosystem/erlang/package.md | 1 - .../ecosystem/erlang/vulnerability.md | 1 - .../ecosystem/github-actions/package.md | 1 - .../ecosystem/github-actions/vulnerability.md | 1 - .../snippets/ecosystem/go/grype-app-config.md | 1 - .../snippets/ecosystem/go/package.md | 1 - .../snippets/ecosystem/go/syft-app-config.md | 1 - .../snippets/ecosystem/go/vulnerability.md | 1 - .../ecosystem/haskell/grype-app-config.md | 1 - .../snippets/ecosystem/haskell/package.md | 1 - .../ecosystem/haskell/vulnerability.md | 1 - .../ecosystem/homebrew/grype-app-config.md | 1 - .../snippets/ecosystem/homebrew/package.md | 1 - .../ecosystem/homebrew/vulnerability.md | 1 - .../ecosystem/java/grype-app-config.md | 1 - .../snippets/ecosystem/java/package.md | 1 - .../ecosystem/java/syft-app-config.md | 1 - .../snippets/ecosystem/java/vulnerability.md | 1 - .../ecosystem/javascript/grype-app-config.md | 1 - .../snippets/ecosystem/javascript/package.md | 1 - .../ecosystem/javascript/syft-app-config.md | 1 - .../ecosystem/javascript/vulnerability.md | 1 - .../ecosystem/linux/grype-app-config.md | 1 - .../snippets/ecosystem/linux/package.md | 1 - .../ecosystem/linux/syft-app-config.md | 1 - .../snippets/ecosystem/linux/vulnerability.md | 1 - .../ecosystem/lua/grype-app-config.md | 1 - .../snippets/ecosystem/lua/package.md | 1 - .../snippets/ecosystem/lua/vulnerability.md | 1 - .../ecosystem/nix/grype-app-config.md | 1 - .../snippets/ecosystem/nix/package.md | 1 - .../snippets/ecosystem/nix/syft-app-config.md | 1 - .../snippets/ecosystem/nix/vulnerability.md | 1 - .../ecosystem/ocaml/grype-app-config.md | 1 - .../snippets/ecosystem/ocaml/package.md | 1 - .../snippets/ecosystem/ocaml/vulnerability.md | 1 - .../ecosystem/php/grype-app-config.md | 1 - .../snippets/ecosystem/php/package.md | 1 - .../snippets/ecosystem/php/vulnerability.md | 1 - .../snippets/ecosystem/portage/os.md | 1 - .../snippets/ecosystem/portage/package.md | 1 - .../ecosystem/portage/vulnerability.md | 1 - .../ecosystem/prolog/grype-app-config.md | 1 - .../snippets/ecosystem/prolog/package.md | 1 - .../ecosystem/prolog/vulnerability.md | 1 - .../ecosystem/python/grype-app-config.md | 1 - .../snippets/ecosystem/python/package.md | 1 - .../ecosystem/python/syft-app-config.md | 1 - .../ecosystem/python/vulnerability.md | 1 - .../snippets/ecosystem/r/grype-app-config.md | 1 - .../snippets/ecosystem/r/package.md | 1 - .../snippets/ecosystem/r/vulnerability.md | 1 - .../capabilities/snippets/ecosystem/rpm/os.md | 1 - .../snippets/ecosystem/rpm/package.md | 1 - .../snippets/ecosystem/rpm/vulnerability.md | 1 - .../ecosystem/ruby/grype-app-config.md | 1 - .../snippets/ecosystem/ruby/package.md | 1 - .../snippets/ecosystem/ruby/vulnerability.md | 1 - .../ecosystem/rust/grype-app-config.md | 1 - .../snippets/ecosystem/rust/package.md | 1 - .../snippets/ecosystem/rust/vulnerability.md | 1 - .../ecosystem/sbom/grype-app-config.md | 1 - .../snippets/ecosystem/sbom/package.md | 1 - .../snippets/ecosystem/sbom/vulnerability.md | 1 - .../ecosystem/snap/grype-app-config.md | 1 - .../snippets/ecosystem/snap/package.md | 1 - .../snippets/ecosystem/snap/vulnerability.md | 1 - .../ecosystem/swift/grype-app-config.md | 1 - .../snippets/ecosystem/swift/package.md | 1 - .../snippets/ecosystem/swift/vulnerability.md | 1 - .../ecosystem/terraform/grype-app-config.md | 1 - .../snippets/ecosystem/terraform/package.md | 1 - .../ecosystem/terraform/vulnerability.md | 1 - .../ecosystem/wordpress/grype-app-config.md | 1 - .../snippets/ecosystem/wordpress/package.md | 1 - .../ecosystem/wordpress/vulnerability.md | 1 - .../docs/capabilities/snippets/overview/os.md | 1 - .../capabilities/snippets/overview/package.md | 1 - scripts/generate_capability_package_tables.py | 72 ++++++--- ...enerate_capability_vulnerability_tables.py | 81 +++++++--- scripts/generate_format_examples.py | 12 +- scripts/generate_format_versions.py | 10 +- scripts/generate_jq_query_examples.py | 8 +- scripts/generate_reference_cli_docs.py | 8 +- .../generate_reference_syft_json_schema.py | 147 ++++++++++++------ scripts/generate_template_examples.py | 8 +- scripts/utils/constants.py | 2 + scripts/utils/data.py | 4 +- scripts/utils/html_table.py | 20 +-- scripts/utils/markdown.py | 4 +- 123 files changed, 262 insertions(+), 230 deletions(-) diff --git a/content/_index.html b/content/_index.html index eaadf702..b748bdc0 100644 --- a/content/_index.html +++ b/content/_index.html @@ -45,7 +45,7 @@

Syft

Get Started - Releases + Releases @@ -66,7 +66,7 @@

Grype

Get Started - Releases + Releases @@ -90,7 +90,7 @@

Grant

Get Started - Releases + Releases diff --git a/content/docs/capabilities/snippets/ecosystem/alpm/os.md b/content/docs/capabilities/snippets/ecosystem/alpm/os.md index 33d5176f..8437a7ad 100644 --- a/content/docs/capabilities/snippets/ecosystem/alpm/os.md +++ b/content/docs/capabilities/snippets/ecosystem/alpm/os.md @@ -1,6 +1,5 @@ - diff --git a/content/docs/capabilities/snippets/ecosystem/alpm/package.md b/content/docs/capabilities/snippets/ecosystem/alpm/package.md index 9433d945..a8d72686 100644 --- a/content/docs/capabilities/snippets/ecosystem/alpm/package.md +++ b/content/docs/capabilities/snippets/ecosystem/alpm/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/alpm/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/alpm/vulnerability.md index a616d352..7fcea091 100644 --- a/content/docs/capabilities/snippets/ecosystem/alpm/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/alpm/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/apk/os.md b/content/docs/capabilities/snippets/ecosystem/apk/os.md index 4735323a..e1e4d7c9 100644 --- a/content/docs/capabilities/snippets/ecosystem/apk/os.md +++ b/content/docs/capabilities/snippets/ecosystem/apk/os.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/apk/package.md b/content/docs/capabilities/snippets/ecosystem/apk/package.md index b980042b..ad3e5811 100644 --- a/content/docs/capabilities/snippets/ecosystem/apk/package.md +++ b/content/docs/capabilities/snippets/ecosystem/apk/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/apk/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/apk/vulnerability.md index 5af9f97f..8803bf15 100644 --- a/content/docs/capabilities/snippets/ecosystem/apk/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/apk/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/binary/binary-package-details.md b/content/docs/capabilities/snippets/ecosystem/binary/binary-package-details.md index 84b0d894..ae3a5228 100644 --- a/content/docs/capabilities/snippets/ecosystem/binary/binary-package-details.md +++ b/content/docs/capabilities/snippets/ecosystem/binary/binary-package-details.md @@ -1,6 +1,5 @@ -
Binary Package Details
diff --git a/content/docs/capabilities/snippets/ecosystem/binary/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/binary/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/binary/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/binary/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/binary/package.md b/content/docs/capabilities/snippets/ecosystem/binary/package.md index 5a8367d1..7d376db1 100644 --- a/content/docs/capabilities/snippets/ecosystem/binary/package.md +++ b/content/docs/capabilities/snippets/ecosystem/binary/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/binary/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/binary/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/binary/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/binary/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/bitnami/package.md b/content/docs/capabilities/snippets/ecosystem/bitnami/package.md index 9042695e..bebda391 100644 --- a/content/docs/capabilities/snippets/ecosystem/bitnami/package.md +++ b/content/docs/capabilities/snippets/ecosystem/bitnami/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/bitnami/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/bitnami/vulnerability.md index 8cab8f96..2663fa6c 100644 --- a/content/docs/capabilities/snippets/ecosystem/bitnami/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/bitnami/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/c++/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/c++/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/c++/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/c++/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/c++/package.md b/content/docs/capabilities/snippets/ecosystem/c++/package.md index 4e924c55..4772fc80 100644 --- a/content/docs/capabilities/snippets/ecosystem/c++/package.md +++ b/content/docs/capabilities/snippets/ecosystem/c++/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/c++/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/c++/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/c++/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/c++/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/conda/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/conda/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/conda/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/conda/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/conda/package.md b/content/docs/capabilities/snippets/ecosystem/conda/package.md index dfd2dc81..5de0af4c 100644 --- a/content/docs/capabilities/snippets/ecosystem/conda/package.md +++ b/content/docs/capabilities/snippets/ecosystem/conda/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/conda/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/conda/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/conda/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/conda/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/dart/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/dart/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/dart/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/dart/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/dart/package.md b/content/docs/capabilities/snippets/ecosystem/dart/package.md index a83b8aec..9139fcd4 100644 --- a/content/docs/capabilities/snippets/ecosystem/dart/package.md +++ b/content/docs/capabilities/snippets/ecosystem/dart/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/dart/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/dart/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/dart/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/dart/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/dotnet/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/dotnet/grype-app-config.md index e9f37980..697879c0 100644 --- a/content/docs/capabilities/snippets/ecosystem/dotnet/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/dotnet/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/dotnet/package.md b/content/docs/capabilities/snippets/ecosystem/dotnet/package.md index d3aac589..52ac04b5 100644 --- a/content/docs/capabilities/snippets/ecosystem/dotnet/package.md +++ b/content/docs/capabilities/snippets/ecosystem/dotnet/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/dotnet/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/dotnet/syft-app-config.md index 3ba95eb4..58988c2f 100644 --- a/content/docs/capabilities/snippets/ecosystem/dotnet/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/dotnet/syft-app-config.md @@ -1,6 +1,5 @@ -
Syft Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/dotnet/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/dotnet/vulnerability.md index 3efca18f..5ca1bef4 100644 --- a/content/docs/capabilities/snippets/ecosystem/dotnet/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/dotnet/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/dpkg/os.md b/content/docs/capabilities/snippets/ecosystem/dpkg/os.md index a2d2d64e..65e2af8f 100644 --- a/content/docs/capabilities/snippets/ecosystem/dpkg/os.md +++ b/content/docs/capabilities/snippets/ecosystem/dpkg/os.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/dpkg/package.md b/content/docs/capabilities/snippets/ecosystem/dpkg/package.md index c4d661d7..cea50e99 100644 --- a/content/docs/capabilities/snippets/ecosystem/dpkg/package.md +++ b/content/docs/capabilities/snippets/ecosystem/dpkg/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/dpkg/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/dpkg/vulnerability.md index d4cf31a4..d3297e1d 100644 --- a/content/docs/capabilities/snippets/ecosystem/dpkg/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/dpkg/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/elixir/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/elixir/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/elixir/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/elixir/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/elixir/package.md b/content/docs/capabilities/snippets/ecosystem/elixir/package.md index fab38d61..c43071ba 100644 --- a/content/docs/capabilities/snippets/ecosystem/elixir/package.md +++ b/content/docs/capabilities/snippets/ecosystem/elixir/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/elixir/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/elixir/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/elixir/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/elixir/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/erlang/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/erlang/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/erlang/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/erlang/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/erlang/package.md b/content/docs/capabilities/snippets/ecosystem/erlang/package.md index 734ebc8d..d9756a80 100644 --- a/content/docs/capabilities/snippets/ecosystem/erlang/package.md +++ b/content/docs/capabilities/snippets/ecosystem/erlang/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/erlang/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/erlang/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/erlang/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/erlang/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/github-actions/package.md b/content/docs/capabilities/snippets/ecosystem/github-actions/package.md index 78cb0ea5..5ec5f727 100644 --- a/content/docs/capabilities/snippets/ecosystem/github-actions/package.md +++ b/content/docs/capabilities/snippets/ecosystem/github-actions/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/github-actions/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/github-actions/vulnerability.md index 1882f8cd..7c747a3c 100644 --- a/content/docs/capabilities/snippets/ecosystem/github-actions/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/github-actions/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/go/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/go/grype-app-config.md index 8c977595..56e338a7 100644 --- a/content/docs/capabilities/snippets/ecosystem/go/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/go/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/go/package.md b/content/docs/capabilities/snippets/ecosystem/go/package.md index 45dd3003..d83862aa 100644 --- a/content/docs/capabilities/snippets/ecosystem/go/package.md +++ b/content/docs/capabilities/snippets/ecosystem/go/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/go/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/go/syft-app-config.md index 931dca57..0ef8e28b 100644 --- a/content/docs/capabilities/snippets/ecosystem/go/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/go/syft-app-config.md @@ -1,6 +1,5 @@ -
Syft Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/go/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/go/vulnerability.md index 3efca18f..5ca1bef4 100644 --- a/content/docs/capabilities/snippets/ecosystem/go/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/go/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/haskell/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/haskell/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/haskell/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/haskell/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/haskell/package.md b/content/docs/capabilities/snippets/ecosystem/haskell/package.md index d6805dd2..e9f476cc 100644 --- a/content/docs/capabilities/snippets/ecosystem/haskell/package.md +++ b/content/docs/capabilities/snippets/ecosystem/haskell/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/haskell/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/haskell/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/haskell/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/haskell/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/homebrew/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/homebrew/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/homebrew/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/homebrew/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/homebrew/package.md b/content/docs/capabilities/snippets/ecosystem/homebrew/package.md index 39cf88fe..5ed593a2 100644 --- a/content/docs/capabilities/snippets/ecosystem/homebrew/package.md +++ b/content/docs/capabilities/snippets/ecosystem/homebrew/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/homebrew/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/homebrew/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/homebrew/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/homebrew/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/java/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/java/grype-app-config.md index 17af43d8..bfb2b528 100644 --- a/content/docs/capabilities/snippets/ecosystem/java/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/java/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/java/package.md b/content/docs/capabilities/snippets/ecosystem/java/package.md index 277e013b..33b0cf60 100644 --- a/content/docs/capabilities/snippets/ecosystem/java/package.md +++ b/content/docs/capabilities/snippets/ecosystem/java/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/java/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/java/syft-app-config.md index a9461f0f..ee28ff4f 100644 --- a/content/docs/capabilities/snippets/ecosystem/java/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/java/syft-app-config.md @@ -1,6 +1,5 @@ -
Syft Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/java/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/java/vulnerability.md index 3efca18f..5ca1bef4 100644 --- a/content/docs/capabilities/snippets/ecosystem/java/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/java/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/javascript/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/javascript/grype-app-config.md index 18c7fadd..ba77ed80 100644 --- a/content/docs/capabilities/snippets/ecosystem/javascript/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/javascript/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/javascript/package.md b/content/docs/capabilities/snippets/ecosystem/javascript/package.md index e7e2353c..2922c94a 100644 --- a/content/docs/capabilities/snippets/ecosystem/javascript/package.md +++ b/content/docs/capabilities/snippets/ecosystem/javascript/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/javascript/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/javascript/syft-app-config.md index 117c4776..4daf11e8 100644 --- a/content/docs/capabilities/snippets/ecosystem/javascript/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/javascript/syft-app-config.md @@ -1,6 +1,5 @@ -
Syft Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/javascript/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/javascript/vulnerability.md index 3efca18f..5ca1bef4 100644 --- a/content/docs/capabilities/snippets/ecosystem/javascript/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/javascript/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/linux/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/linux/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/linux/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/linux/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/linux/package.md b/content/docs/capabilities/snippets/ecosystem/linux/package.md index 11aa9a7c..219743b4 100644 --- a/content/docs/capabilities/snippets/ecosystem/linux/package.md +++ b/content/docs/capabilities/snippets/ecosystem/linux/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/linux/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/linux/syft-app-config.md index 1d0585f1..3443eb26 100644 --- a/content/docs/capabilities/snippets/ecosystem/linux/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/linux/syft-app-config.md @@ -1,6 +1,5 @@ -
Syft Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/linux/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/linux/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/linux/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/linux/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/lua/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/lua/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/lua/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/lua/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/lua/package.md b/content/docs/capabilities/snippets/ecosystem/lua/package.md index 62573cfc..4b4fff91 100644 --- a/content/docs/capabilities/snippets/ecosystem/lua/package.md +++ b/content/docs/capabilities/snippets/ecosystem/lua/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/lua/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/lua/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/lua/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/lua/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/nix/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/nix/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/nix/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/nix/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/nix/package.md b/content/docs/capabilities/snippets/ecosystem/nix/package.md index 524426f1..47c0e182 100644 --- a/content/docs/capabilities/snippets/ecosystem/nix/package.md +++ b/content/docs/capabilities/snippets/ecosystem/nix/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/nix/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/nix/syft-app-config.md index b3a1d3bd..6e47e00b 100644 --- a/content/docs/capabilities/snippets/ecosystem/nix/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/nix/syft-app-config.md @@ -1,6 +1,5 @@ -
Syft Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/nix/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/nix/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/nix/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/nix/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/ocaml/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/ocaml/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/ocaml/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/ocaml/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/ocaml/package.md b/content/docs/capabilities/snippets/ecosystem/ocaml/package.md index 025f701a..46ce235d 100644 --- a/content/docs/capabilities/snippets/ecosystem/ocaml/package.md +++ b/content/docs/capabilities/snippets/ecosystem/ocaml/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/ocaml/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/ocaml/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/ocaml/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/ocaml/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/php/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/php/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/php/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/php/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/php/package.md b/content/docs/capabilities/snippets/ecosystem/php/package.md index 4d7c0de1..6605460c 100644 --- a/content/docs/capabilities/snippets/ecosystem/php/package.md +++ b/content/docs/capabilities/snippets/ecosystem/php/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/php/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/php/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/php/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/php/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/portage/os.md b/content/docs/capabilities/snippets/ecosystem/portage/os.md index 82b5f778..95251f20 100644 --- a/content/docs/capabilities/snippets/ecosystem/portage/os.md +++ b/content/docs/capabilities/snippets/ecosystem/portage/os.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/portage/package.md b/content/docs/capabilities/snippets/ecosystem/portage/package.md index 5f359d04..a24e2024 100644 --- a/content/docs/capabilities/snippets/ecosystem/portage/package.md +++ b/content/docs/capabilities/snippets/ecosystem/portage/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/portage/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/portage/vulnerability.md index a616d352..7fcea091 100644 --- a/content/docs/capabilities/snippets/ecosystem/portage/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/portage/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/prolog/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/prolog/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/prolog/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/prolog/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/prolog/package.md b/content/docs/capabilities/snippets/ecosystem/prolog/package.md index 4facf524..f6c381f6 100644 --- a/content/docs/capabilities/snippets/ecosystem/prolog/package.md +++ b/content/docs/capabilities/snippets/ecosystem/prolog/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/prolog/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/prolog/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/prolog/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/prolog/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/python/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/python/grype-app-config.md index 2301e809..11ce8504 100644 --- a/content/docs/capabilities/snippets/ecosystem/python/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/python/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/python/package.md b/content/docs/capabilities/snippets/ecosystem/python/package.md index 7711ed5f..9499ee8b 100644 --- a/content/docs/capabilities/snippets/ecosystem/python/package.md +++ b/content/docs/capabilities/snippets/ecosystem/python/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/python/syft-app-config.md b/content/docs/capabilities/snippets/ecosystem/python/syft-app-config.md index 7d9e4b40..c16ae476 100644 --- a/content/docs/capabilities/snippets/ecosystem/python/syft-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/python/syft-app-config.md @@ -1,6 +1,5 @@ -
Syft Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/python/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/python/vulnerability.md index 3efca18f..5ca1bef4 100644 --- a/content/docs/capabilities/snippets/ecosystem/python/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/python/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/r/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/r/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/r/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/r/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/r/package.md b/content/docs/capabilities/snippets/ecosystem/r/package.md index b18d45fc..af62fb7b 100644 --- a/content/docs/capabilities/snippets/ecosystem/r/package.md +++ b/content/docs/capabilities/snippets/ecosystem/r/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/r/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/r/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/r/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/r/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/rpm/os.md b/content/docs/capabilities/snippets/ecosystem/rpm/os.md index 7ffe0e77..b4660f2b 100644 --- a/content/docs/capabilities/snippets/ecosystem/rpm/os.md +++ b/content/docs/capabilities/snippets/ecosystem/rpm/os.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/rpm/package.md b/content/docs/capabilities/snippets/ecosystem/rpm/package.md index 32db8744..a91ae8ad 100644 --- a/content/docs/capabilities/snippets/ecosystem/rpm/package.md +++ b/content/docs/capabilities/snippets/ecosystem/rpm/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/rpm/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/rpm/vulnerability.md index 25d4dea0..24d0e222 100644 --- a/content/docs/capabilities/snippets/ecosystem/rpm/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/rpm/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/ruby/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/ruby/grype-app-config.md index 5e66123b..eb75729e 100644 --- a/content/docs/capabilities/snippets/ecosystem/ruby/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/ruby/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/ruby/package.md b/content/docs/capabilities/snippets/ecosystem/ruby/package.md index 32bc491f..c94c1670 100644 --- a/content/docs/capabilities/snippets/ecosystem/ruby/package.md +++ b/content/docs/capabilities/snippets/ecosystem/ruby/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/ruby/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/ruby/vulnerability.md index 3efca18f..5ca1bef4 100644 --- a/content/docs/capabilities/snippets/ecosystem/ruby/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/ruby/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/rust/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/rust/grype-app-config.md index 3fb3d874..a4c34339 100644 --- a/content/docs/capabilities/snippets/ecosystem/rust/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/rust/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/rust/package.md b/content/docs/capabilities/snippets/ecosystem/rust/package.md index 30a3d6e1..2d9e56e0 100644 --- a/content/docs/capabilities/snippets/ecosystem/rust/package.md +++ b/content/docs/capabilities/snippets/ecosystem/rust/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/rust/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/rust/vulnerability.md index 3efca18f..5ca1bef4 100644 --- a/content/docs/capabilities/snippets/ecosystem/rust/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/rust/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/sbom/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/sbom/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/sbom/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/sbom/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/sbom/package.md b/content/docs/capabilities/snippets/ecosystem/sbom/package.md index 4841d175..ac25d3a5 100644 --- a/content/docs/capabilities/snippets/ecosystem/sbom/package.md +++ b/content/docs/capabilities/snippets/ecosystem/sbom/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/sbom/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/sbom/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/sbom/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/sbom/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/snap/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/snap/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/snap/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/snap/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/snap/package.md b/content/docs/capabilities/snippets/ecosystem/snap/package.md index fa802ad6..39b36af1 100644 --- a/content/docs/capabilities/snippets/ecosystem/snap/package.md +++ b/content/docs/capabilities/snippets/ecosystem/snap/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/snap/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/snap/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/snap/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/snap/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/swift/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/swift/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/swift/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/swift/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/swift/package.md b/content/docs/capabilities/snippets/ecosystem/swift/package.md index 71667262..062321bb 100644 --- a/content/docs/capabilities/snippets/ecosystem/swift/package.md +++ b/content/docs/capabilities/snippets/ecosystem/swift/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/swift/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/swift/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/swift/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/swift/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/terraform/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/terraform/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/terraform/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/terraform/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/terraform/package.md b/content/docs/capabilities/snippets/ecosystem/terraform/package.md index 9464cd10..a214299a 100644 --- a/content/docs/capabilities/snippets/ecosystem/terraform/package.md +++ b/content/docs/capabilities/snippets/ecosystem/terraform/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/terraform/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/terraform/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/terraform/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/terraform/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/wordpress/grype-app-config.md b/content/docs/capabilities/snippets/ecosystem/wordpress/grype-app-config.md index 3a71cc0f..58049660 100644 --- a/content/docs/capabilities/snippets/ecosystem/wordpress/grype-app-config.md +++ b/content/docs/capabilities/snippets/ecosystem/wordpress/grype-app-config.md @@ -1,6 +1,5 @@ -
Grype Configuration
diff --git a/content/docs/capabilities/snippets/ecosystem/wordpress/package.md b/content/docs/capabilities/snippets/ecosystem/wordpress/package.md index fd7e43fb..99f50c11 100644 --- a/content/docs/capabilities/snippets/ecosystem/wordpress/package.md +++ b/content/docs/capabilities/snippets/ecosystem/wordpress/package.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/ecosystem/wordpress/vulnerability.md b/content/docs/capabilities/snippets/ecosystem/wordpress/vulnerability.md index b276db76..85f3fcc9 100644 --- a/content/docs/capabilities/snippets/ecosystem/wordpress/vulnerability.md +++ b/content/docs/capabilities/snippets/ecosystem/wordpress/vulnerability.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/overview/os.md b/content/docs/capabilities/snippets/overview/os.md index f8077ffa..832e1d92 100644 --- a/content/docs/capabilities/snippets/overview/os.md +++ b/content/docs/capabilities/snippets/overview/os.md @@ -1,6 +1,5 @@ -
diff --git a/content/docs/capabilities/snippets/overview/package.md b/content/docs/capabilities/snippets/overview/package.md index 42b38712..210ff338 100644 --- a/content/docs/capabilities/snippets/overview/package.md +++ b/content/docs/capabilities/snippets/overview/package.md @@ -1,6 +1,5 @@ -
diff --git a/scripts/generate_capability_package_tables.py b/scripts/generate_capability_package_tables.py index b9572c4d..1c517aad 100755 --- a/scripts/generate_capability_package_tables.py +++ b/scripts/generate_capability_package_tables.py @@ -73,7 +73,6 @@ class CatalogerRow: conditions: list[dict] | None = None - @click.command() @click.option( "--update", @@ -135,7 +134,7 @@ def main(update: bool, verbose: int) -> None: config.paths.capabilities_snippet_dir / "overview", ecosystem_display_names, logger, - ) + ) # generate individual ecosystem tables ecosystems = {r.ecosystem for r in rows} @@ -151,7 +150,7 @@ def main(update: bool, verbose: int) -> None: cataloger_data, config.paths.capabilities_snippet_dir / "ecosystem", logger, - ) + ) # collect and generate app config snippets logger.info("Generating app config snippets...") @@ -162,7 +161,7 @@ def main(update: bool, verbose: int) -> None: config_fields, config.paths.capabilities_snippet_dir / "ecosystem", logger, - ) + ) logger.info("Generation complete!") @@ -532,12 +531,16 @@ def format_cataloger_with_evidence( # use exact cataloger name (keep -cataloger suffix) # build combined cell content - cataloger name in div, not code # add deprecated pill inline if cataloger is deprecated - deprecated_pill = ' deprecated' if deprecated else '' + deprecated_pill = ( + ' deprecated' if deprecated else "" + ) # add conditional gear icon inline if pattern has conditions - condition_icon = '' + condition_icon = "" if conditions: - formatted_condition = html_table.format_conditions_for_tooltip(conditions, prefix="Requires") + formatted_condition = html_table.format_conditions_for_tooltip( + conditions, prefix="Requires" + ) if formatted_condition: escaped_condition = formatted_condition.replace('"', """) condition_icon = f' ' @@ -741,7 +744,9 @@ def generate_app_config_snippet( output_file = ecosystem_dir / "syft-app-config.md" # generate comment - comment = config.get_generated_comment("scripts/generate_capability_tables.py", "html") + comment = config.get_generated_comment( + "scripts/generate_capability_tables.py", "html" + ) comment += "\n\n" comment += "\n" @@ -943,7 +948,9 @@ def generate_overview_table( rowspans = _calculate_rowspans_for_overview(sorted_rows) # generate comment - comment = config.get_generated_comment("scripts/generate_capability_tables.py", "html") + comment = config.get_generated_comment( + "scripts/generate_capability_tables.py", "html" + ) comment += "\n\n" comment += "\n" @@ -951,7 +958,9 @@ def generate_overview_table( html_lines = [] # table header - single row with simple columns (5 columns total) - html_lines.append(f'
') + html_lines.append( + f'
' + ) html_lines.append(" ") html_lines.append(" ") html_lines.append( @@ -999,7 +1008,9 @@ def generate_overview_table( row.deprecated, row.conditions, ) - html_lines.append(f' ') + html_lines.append( + f' ' + ) # license column (SVG indicator) license_cap = row.capabilities.get("license") @@ -1067,7 +1078,9 @@ def generate_ecosystem_table( sorted_rows = sorted(ecosystem_rows, key=lambda r: r.cataloger_name) # generate comment - comment = config.get_generated_comment("scripts/generate_capability_tables.py", "html") + comment = config.get_generated_comment( + "scripts/generate_capability_tables.py", "html" + ) comment += "\n\n" comment += "\n" @@ -1075,7 +1088,9 @@ def generate_ecosystem_table( html_lines = [] # table header with two-row grouped structure - html_lines.append(f'
{cataloger_content}{cataloger_content}
') + html_lines.append( + f'
' + ) html_lines.append(" ") html_lines.append(" ") html_lines.append( @@ -1121,7 +1136,11 @@ def generate_ecosystem_table( # cataloger column with evidence (no rowspan - each row shows its own) # special handling for binary-classifier-cataloger in ecosystem-specific tables if row.cataloger_name == "binary-classifier-cataloger": - deprecated_pill = ' deprecated' if row.deprecated else '' + deprecated_pill = ( + ' deprecated' + if row.deprecated + else "" + ) cataloger_content = f'
binary-classifier-cataloger{deprecated_pill}
(see table below)
' else: cataloger_content = format_cataloger_with_evidence( @@ -1133,7 +1152,9 @@ def generate_ecosystem_table( row.deprecated, row.conditions, ) - html_lines.append(f' ') + html_lines.append( + f' ' + ) # license column (SVG indicator) license_cap = row.capabilities.get("license") @@ -1226,7 +1247,9 @@ def generate_binary_package_details_table( output_file = binary_dir / "binary-package-details.md" # generate comment - comment = config.get_generated_comment("scripts/generate_capability_tables.py", "html") + comment = config.get_generated_comment( + "scripts/generate_capability_tables.py", "html" + ) comment += "\n\n" comment += "\n" @@ -1237,7 +1260,9 @@ def generate_binary_package_details_table( html_lines.append('
Binary Package Details
') # table header - html_lines.append(f'
{cataloger_content}{cataloger_content}
') + html_lines.append( + f'
' + ) html_lines.append(" ") html_lines.append(" ") html_lines.append( @@ -1279,7 +1304,9 @@ def get_class_name(pattern): # format criteria (glob patterns) criteria = pattern.get("criteria", []) if criteria: - criteria_html = ", ".join(f"{clean_glob_pattern(c)}" for c in criteria) + criteria_html = ", ".join( + f"{clean_glob_pattern(c)}" for c in criteria + ) else: criteria_html = "-" @@ -1294,8 +1321,12 @@ def get_class_name(pattern): html_lines.append(" ") html_lines.append(f' ') - html_lines.append(f' ') - html_lines.append(f' ') + html_lines.append( + f' ' + ) + html_lines.append( + f' ' + ) html_lines.append(f' ') html_lines.append(" ") @@ -1312,6 +1343,5 @@ def get_class_name(pattern): logger.debug(f"Generated {output_file}") - if __name__ == "__main__": main() diff --git a/scripts/generate_capability_vulnerability_tables.py b/scripts/generate_capability_vulnerability_tables.py index 984a2da0..a74a9292 100644 --- a/scripts/generate_capability_vulnerability_tables.py +++ b/scripts/generate_capability_vulnerability_tables.py @@ -42,7 +42,6 @@ class DataSource: vunnel_provider: str - @click.command() @click.option( "--update", @@ -122,17 +121,19 @@ def main(update: bool, verbose: int) -> None: os_list, vuln_data, config.paths.capabilities_snippet_dir / "ecosystem", - ) + ) generate_os_ecosystem_vulnerability_capabilities_table( ecosystem_name, os_list, vuln_data, config.paths.capabilities_snippet_dir / "ecosystem", - ) + ) else: # for language/other/default ecosystems, generate vulnerability capabilities table generate_ecosystem_vulnerability_capabilities_table( - ecosystem_name, vuln_data, config.paths.capabilities_snippet_dir / "ecosystem" + ecosystem_name, + vuln_data, + config.paths.capabilities_snippet_dir / "ecosystem", ) # generate config snippet if ecosystem has configuration @@ -142,10 +143,11 @@ def main(update: bool, verbose: int) -> None: ecosystem_name, config_fields, config.paths.capabilities_snippet_dir / "ecosystem", - ) + ) logger.info("Generation complete!") + def _convert_os_data_to_objects(data: list[dict]) -> list[OS]: """ convert OS data from JSON format to OS objects. @@ -294,14 +296,18 @@ def generate_overview_os_table( all_os_names = set(os_by_name.keys()) # generate comment - comment = config.get_generated_comment("scripts/generate_vulnerability_tables.py", "html") + comment = config.get_generated_comment( + "scripts/generate_vulnerability_tables.py", "html" + ) comment += "\n\n" # build HTML lines html_lines = [] # table header with CSS classes matching capability tables - html_lines.append(f'
{class_name}{criteria_html}{purl}{criteria_html}{purl}{cpes_html}
') + html_lines.append( + f'
' + ) html_lines.append(" ") html_lines.append(" ") html_lines.append( @@ -369,10 +375,18 @@ def generate_overview_os_table( data_source_cell = "-" html_lines.append(" ") - html_lines.append(f' ') - html_lines.append(f' ') - html_lines.append(f' ') - html_lines.append(f' ') + html_lines.append( + f' ' + ) + html_lines.append( + f' ' + ) + html_lines.append( + f' ' + ) + html_lines.append( + f' ' + ) html_lines.append(" ") # close table @@ -562,7 +576,9 @@ def generate_os_ecosystem_vulnerability_capabilities_table( source_cell = f"{source_name}{get_advisory_identifiers(source_info)}" html_lines.append(" ") - html_lines.append(f' ') + html_lines.append( + f' ' + ) # add cells for each capability for cap in capabilities_to_include: @@ -639,14 +655,18 @@ def generate_os_ecosystem_table( sources = vuln_data.get("sources", {}) # generate comment - comment = config.get_generated_comment("scripts/generate_vulnerability_tables.py", "html") + comment = config.get_generated_comment( + "scripts/generate_vulnerability_tables.py", "html" + ) comment += "\n\n" # build HTML lines html_lines = [] # table header with CSS classes matching capability tables - html_lines.append(f'
{os_name_cell}{versions_str}{provider_cell}{data_source_cell}{os_name_cell}{versions_str}{provider_cell}{data_source_cell}
{source_cell}{source_cell}
') + html_lines.append( + f'
' + ) html_lines.append(" ") html_lines.append(" ") html_lines.append( @@ -736,10 +756,18 @@ def generate_os_ecosystem_table( data_source_cell = "-" html_lines.append(" ") - html_lines.append(f' ') - html_lines.append(f' ') - html_lines.append(f' ') - html_lines.append(f' ') + html_lines.append( + f' ' + ) + html_lines.append( + f' ' + ) + html_lines.append( + f' ' + ) + html_lines.append( + f' ' + ) html_lines.append(" ") # close table @@ -785,10 +813,14 @@ def generate_grype_config_snippet( html_lines = [] # table header text - html_lines.append(f'
Grype Configuration
') + html_lines.append( + f'
Grype Configuration
' + ) # table header - html_lines.append(f'
{os_name_cell}{versions_str}{provider_cell}{data_source_cell}{os_name_cell}{versions_str}{provider_cell}{data_source_cell}
') + html_lines.append( + f'
' + ) html_lines.append(" ") html_lines.append(" ") html_lines.append( @@ -810,7 +842,9 @@ def generate_grype_config_snippet( html_lines.append( f' ' ) - html_lines.append(f' ') + html_lines.append( + f' ' + ) html_lines.append(" ") # close table @@ -981,7 +1015,9 @@ def generate_ecosystem_vulnerability_capabilities_table( source_cell = source_display html_lines.append(" ") - html_lines.append(f' ') + html_lines.append( + f' ' + ) # add cells for each capability for cap in capabilities_to_include: @@ -1019,6 +1055,5 @@ def generate_ecosystem_vulnerability_capabilities_table( logger.debug(f"Generated {output_file}") - if __name__ == "__main__": main() diff --git a/scripts/generate_format_examples.py b/scripts/generate_format_examples.py index 5522316d..6102c9d7 100755 --- a/scripts/generate_format_examples.py +++ b/scripts/generate_format_examples.py @@ -89,7 +89,9 @@ def main( output_file = output_path / f"{format_name}.md" # Check if output needs regeneration - if not output_manager.should_regenerate(output_file, [sbom_file], update=update): + if not output_manager.should_regenerate( + output_file, [sbom_file], update=update + ): logger.debug(f" ⊚ Skipping {format_name}.md (up-to-date)") skipped_count += 1 continue @@ -115,7 +117,9 @@ def main( f"Format examples: {generated_count} generated, {skipped_count} skipped (up-to-date)" ) else: - logger.info(f"Successfully generated {len(FORMATS)} format examples in {output_path}") + logger.info( + f"Successfully generated {len(FORMATS)} format examples in {output_path}" + ) def generate_format_example( @@ -148,7 +152,9 @@ def generate_format_example( def create_markdown_content(fence_lang: str, output: str) -> str: """Create markdown content with code fence.""" # Add auto-generated comment - comment = config.get_generated_comment("scripts/generate_format_examples.py", "html") + comment = config.get_generated_comment( + "scripts/generate_format_examples.py", "html" + ) # Use markdown utility for code fence content = comment + markdown.create_code_fence(output, fence_lang) diff --git a/scripts/generate_format_versions.py b/scripts/generate_format_versions.py index 4f7dbb48..f7507728 100755 --- a/scripts/generate_format_versions.py +++ b/scripts/generate_format_versions.py @@ -18,7 +18,6 @@ from utils import config, log - @click.command() @click.option( "--update", @@ -128,7 +127,9 @@ def save_json_data(formats, output_path: Path, logger) -> None: output_path.parent.mkdir(parents=True, exist_ok=True) # add auto-generated comment as a special field - comment = config.get_generated_comment("scripts/generate_format_versions.py", "json") + comment = config.get_generated_comment( + "scripts/generate_format_versions.py", "json" + ) data = {"_comment": comment, **formats} with open(output_path, "w") as f: @@ -153,7 +154,9 @@ def generate_markdown_snippet(formats, output_path: Path, logger) -> None: return # add auto-generated comment - comment = config.get_generated_comment("scripts/generate_format_versions.py", "html") + comment = config.get_generated_comment( + "scripts/generate_format_versions.py", "html" + ) # generate markdown list only lines = [] @@ -189,6 +192,5 @@ def load_existing_formats(json_path: Path): return None - if __name__ == "__main__": main() diff --git a/scripts/generate_jq_query_examples.py b/scripts/generate_jq_query_examples.py index 454536fb..159169d2 100755 --- a/scripts/generate_jq_query_examples.py +++ b/scripts/generate_jq_query_examples.py @@ -156,7 +156,9 @@ def generate_example( source_files.append(config_file) # Check if outputs need regeneration - if not output_manager.should_regenerate_multiple([query_md, example_md, output_md], source_files, update): + if not output_manager.should_regenerate_multiple( + [query_md, example_md, output_md], source_files, update + ): return False # Import sbom utility for SBOM generation @@ -192,7 +194,9 @@ def generate_example( config_path = example_file.parent / config if config_path.exists(): config_content = config_path.read_text() - config_md = markdown.create_code_fence(f"# .syft.yaml\n{config_content}", "yaml") + config_md = markdown.create_code_fence( + f"# .syft.yaml\n{config_content}", "yaml" + ) (example_dir / "config.md").write_text(config_md) # Run jq query and generate output.md diff --git a/scripts/generate_reference_cli_docs.py b/scripts/generate_reference_cli_docs.py index 44abfc05..49a02d5a 100755 --- a/scripts/generate_reference_cli_docs.py +++ b/scripts/generate_reference_cli_docs.py @@ -137,7 +137,9 @@ def generate_markdown_content( ) # Add auto-generated comment - content += config.get_generated_comment("scripts/generate_reference_cli_docs.py", "html") + content += config.get_generated_comment( + "scripts/generate_reference_cli_docs.py", "html" + ) # Add version info block at the top version_info = get_version_info(image, app_name, tool_name, update) @@ -217,7 +219,9 @@ def get_cache_path_for_cli(tool_name: str, cmd_parts: list[str]) -> Path: cache_dir = config.paths.reference_cache_dir / tool_name / "cli" / "main" else: # subcommand help - use command path as directory structure - cache_dir = config.paths.reference_cache_dir / tool_name / "cli" / "/".join(cmd_parts) + cache_dir = ( + config.paths.reference_cache_dir / tool_name / "cli" / "/".join(cmd_parts) + ) return cache_dir / "output.txt" diff --git a/scripts/generate_reference_syft_json_schema.py b/scripts/generate_reference_syft_json_schema.py index c201e15c..a7466ead 100644 --- a/scripts/generate_reference_syft_json_schema.py +++ b/scripts/generate_reference_syft_json_schema.py @@ -40,8 +40,6 @@ from utils.constants import CSSClasses - - @click.command() @click.option( "--schema-dir", @@ -72,7 +70,9 @@ def main(schema_dir: Path, update: bool, verbose: int) -> None: all_schemas = scan_schema_directory(schema_dir, logger) # select schemas to process (latest patch per major version >= min) - selected = select_schemas_to_process(all_schemas, config.min_schema_major_version, logger) + selected = select_schemas_to_process( + all_schemas, config.min_schema_major_version, logger + ) if not selected: logger.error("No schemas selected for processing") @@ -80,7 +80,9 @@ def main(schema_dir: Path, update: bool, verbose: int) -> None: # determine highest major version for "latest" badge highest_major = max(selected.keys()) - logger.info(f"Highest major version: v{highest_major} (will receive 'latest' badge)") + logger.info( + f"Highest major version: v{highest_major} (will receive 'latest' badge)" + ) # process each selected schema for major, (schema_path, full_version) in sorted(selected.items(), reverse=True): @@ -98,15 +100,20 @@ def main(schema_dir: Path, update: bool, verbose: int) -> None: schema_data = load_json_schema(schema_path, major, logger) # determine if this is the latest version - is_latest = (major == highest_major) + is_latest = major == highest_major # generate documentation generate_schema_documentation( - schema_data, full_version, config.paths.json_reference_dir, is_latest, logger + schema_data, + full_version, + config.paths.json_reference_dir, + is_latest, + logger, ) logger.info("Generation complete!") + def parse_schema_filename(filename: str) -> tuple[int, int, int] | None: """ parse schema filename to extract version numbers. @@ -168,7 +175,9 @@ def scan_schema_directory( continue schemas.append((file_path, version)) - logger.debug(f"Found schema {file_path.name}: v{version[0]}.{version[1]}.{version[2]}") + logger.debug( + f"Found schema {file_path.name}: v{version[0]}.{version[1]}.{version[2]}" + ) if not schemas: logger.error(f"No valid schema files found in {dir_path}") @@ -445,7 +454,9 @@ def _categorize_using_cataloger_data( """ # load ecosystem types from cataloger metadata cataloger_ecosystem_types = load_ecosystem_types_from_catalogers() - logger.debug(f"Loaded {len(cataloger_ecosystem_types)} json_schema_types from cataloger data") + logger.debug( + f"Loaded {len(cataloger_ecosystem_types)} json_schema_types from cataloger data" + ) # match cataloger types against schema types (case-insensitive) # cataloger has: AlpmDbEntry, schema has: AlpmDbEntry @@ -460,14 +471,20 @@ def _categorize_using_cataloger_data( schema_type_name = schema_type_names_lower[cataloger_type_lower] ecosystem_types.add(schema_type_name) matched_count += 1 - logger.debug(f" Matched cataloger type '{cataloger_type}' to schema type '{schema_type_name}'") + logger.debug( + f" Matched cataloger type '{cataloger_type}' to schema type '{schema_type_name}'" + ) - logger.debug(f"Matched {matched_count}/{len(cataloger_ecosystem_types)} cataloger types to schema types") + logger.debug( + f"Matched {matched_count}/{len(cataloger_ecosystem_types)} cataloger types to schema types" + ) logger.debug(f"Final ecosystem types count: {len(ecosystem_types)}") # find all types referenced by each ecosystem type ecosystem_refs = {} - ecosystem_related_types = set() # types that are referenced by ecosystems and share prefix + ecosystem_related_types = ( + set() + ) # types that are referenced by ecosystems and share prefix for eco_type in ecosystem_types: if eco_type not in all_defs: @@ -495,11 +512,15 @@ def _categorize_using_cataloger_data( if ref_prefix == eco_prefix: # shares prefix, so it's also an ecosystem type ecosystem_related_types.add(ref_type) - logger.debug(f" Type '{ref_type}' shares prefix '{ref_prefix}' with '{eco_type}' → ecosystem type") + logger.debug( + f" Type '{ref_type}' shares prefix '{ref_prefix}' with '{eco_type}' → ecosystem type" + ) # add prefix-matched types to ecosystem_types ecosystem_types.update(ecosystem_related_types) - logger.debug(f"Added {len(ecosystem_related_types)} prefix-matched types to ecosystem types") + logger.debug( + f"Added {len(ecosystem_related_types)} prefix-matched types to ecosystem types" + ) # truly_core_types = everything that's not an ecosystem type or Document truly_core_types = set() @@ -509,7 +530,9 @@ def _categorize_using_cataloger_data( if type_name not in ecosystem_types: truly_core_types.add(type_name) - logger.debug(f"Total ecosystem types (including prefix-matched): {len(ecosystem_types)}") + logger.debug( + f"Total ecosystem types (including prefix-matched): {len(ecosystem_types)}" + ) logger.debug(f"Total truly_core_types: {len(truly_core_types)}") logger.debug(f"Ecosystem types sample: {sorted(ecosystem_types)[:10]}...") logger.debug(f"Core types sample: {sorted(truly_core_types)[:10]}...") @@ -549,9 +572,7 @@ def _build_categorization_from_core_types( ecosystem_related = {} for eco_type, refs in ecosystem_refs.items(): # filter out truly core types from ecosystem-related types - ecosystem_specific_refs = [ - ref for ref in refs if ref not in truly_core_types - ] + ecosystem_specific_refs = [ref for ref in refs if ref not in truly_core_types] if ecosystem_specific_refs: ecosystem_related[eco_type] = sorted(ecosystem_specific_refs) @@ -559,7 +580,9 @@ def _build_categorization_from_core_types( sample_ecosystems = list(ecosystem_related.keys())[:3] for eco_type in sample_ecosystems: related = ecosystem_related.get(eco_type, []) - logger.debug(f"Ecosystem {eco_type} has {len(related)} related types: {related[:5]}...") + logger.debug( + f"Ecosystem {eco_type} has {len(related)} related types: {related[:5]}..." + ) # core types include truly core types AND types not referenced by any ecosystem all_ecosystem_specific_refs = set() @@ -662,8 +685,8 @@ def compute_type_categories( } """ # use data-driven categorization from cataloger metadata - truly_core_types, cataloger_ecosystem_types, ecosystem_refs = _categorize_using_cataloger_data( - all_defs, ecosystem_types, logger + truly_core_types, cataloger_ecosystem_types, ecosystem_refs = ( + _categorize_using_cataloger_data(all_defs, ecosystem_types, logger) ) # build categorization structure from core types @@ -732,13 +755,17 @@ def categorize_definitions(schema: dict, logger) -> dict[str, Any]: ] # filter excluded types from ecosystem types - filtered_ecosystem_types = [t for t in ecosystem_types if t not in config.excluded_schema_types] + filtered_ecosystem_types = [ + t for t in ecosystem_types if t not in config.excluded_schema_types + ] # filter excluded types from ecosystem_related (both keys and values) filtered_ecosystem_related = {} for eco_type, related_types in categories["ecosystem_related"].items(): if eco_type not in config.excluded_schema_types: - filtered_related = [t for t in related_types if t not in config.excluded_schema_types] + filtered_related = [ + t for t in related_types if t not in config.excluded_schema_types + ] if filtered_related: filtered_ecosystem_related[eco_type] = filtered_related @@ -852,12 +879,16 @@ def expand_type_reference(type_spec: Any, all_defs: dict) -> str: options = type_spec["anyOf"] # filter out null types for cleaner display non_null_options = [ - opt for opt in options if not (isinstance(opt, dict) and opt.get("type") == "null") + opt + for opt in options + if not (isinstance(opt, dict) and opt.get("type") == "null") ] if len(non_null_options) == 1: return expand_type_reference(non_null_options[0], all_defs) elif non_null_options: - option_types = [expand_type_reference(opt, all_defs) for opt in non_null_options] + option_types = [ + expand_type_reference(opt, all_defs) for opt in non_null_options + ] return " | ".join(option_types) # handle oneOf unions @@ -1010,11 +1041,12 @@ def shorten_type_string(type_str: str) -> str: # apply replacements as whole-word substitutions # use word boundaries to avoid replacing parts of custom type names import re + result = type_str for long_name, short_name in replacements.items(): # match whole word (not part of another word) # negative lookbehind/lookahead to ensure not part of a type name - pattern = r'\b' + re.escape(long_name) + r'\b' + pattern = r"\b" + re.escape(long_name) + r"\b" result = re.sub(pattern, short_name, result) return result @@ -1042,15 +1074,15 @@ def should_replace_field_with_link( any_of = field_spec.get("anyOf", []) # if there are many options (more than just null), this is the ecosystem union non_null_options = [ - opt for opt in any_of if not (isinstance(opt, dict) and opt.get("type") == "null") + opt + for opt in any_of + if not (isinstance(opt, dict) and opt.get("type") == "null") ] return len(non_null_options) > 5 # arbitrary threshold return False -def parse_definition( - def_name: str, def_schema: dict, all_defs: dict -) -> dict[str, Any]: +def parse_definition(def_name: str, def_schema: dict, all_defs: dict) -> dict[str, Any]: """ parse a schema definition to extract structured information. @@ -1067,7 +1099,9 @@ def parse_definition( """ result = { "name": def_name, - "description": clean_type_description(def_name, def_schema.get("description", "")), + "description": clean_type_description( + def_name, def_schema.get("description", "") + ), "fields": [], } @@ -1142,7 +1176,7 @@ def generate_type_section_html( # generate markdown h2 header with custom anchor ID anchor_id = section_title.lower().replace(" ", "-") - html_lines.append(f'## {section_title} {{#{anchor_id}}}\n') + html_lines.append(f"## {section_title} {{#{anchor_id}}}\n") for type_name in type_names: type_def = all_defs.get(type_name) @@ -1157,11 +1191,11 @@ def generate_type_section_html( continue # type heading with anchor (markdown h3) - html_lines.append(f'### `{type_name}` {{#{type_name.lower()}}}\n') + html_lines.append(f"### `{type_name}` {{#{type_name.lower()}}}\n") # type description (if exists) if parsed["description"]: - html_lines.append(f'

{parsed["description"]}

\n') + html_lines.append(f"

{parsed['description']}

\n") # table header show_descriptions = has_field_descriptions(parsed["fields"]) @@ -1169,10 +1203,14 @@ def generate_type_section_html( html_lines.append(f'
{field_key}{description}{description}
{source_cell}{source_cell}
') html_lines.append(" ") html_lines.append(" ") - html_lines.append(f' ') + html_lines.append( + f' ' + ) html_lines.append(f' ') if show_descriptions: - html_lines.append(f' ') + html_lines.append( + f' ' + ) html_lines.append(" ") html_lines.append(" ") html_lines.append(" ") @@ -1181,7 +1219,7 @@ def generate_type_section_html( for field in parsed["fields"]: html_lines.append(" ") # add required icon outside code block for required fields - field_name_html = f'{field["name"]}' + field_name_html = f"{field['name']}" if field["required"]: field_name_html += f'' html_lines.append( @@ -1229,23 +1267,29 @@ def generate_type_section_html( # related type heading with markdown h4 html_lines.append( - f'#### `{related_type_name}` {{#{related_type_name.lower()}}}\n' + f"#### `{related_type_name}` {{#{related_type_name.lower()}}}\n" ) # type description (if exists) if related_parsed["description"]: - html_lines.append(f'

{related_parsed["description"]}

\n') + html_lines.append(f"

{related_parsed['description']}

\n") # table (same structure as main types) - related_show_descriptions = has_field_descriptions(related_parsed["fields"]) + related_show_descriptions = has_field_descriptions( + related_parsed["fields"] + ) html_lines.append(f'
Field NameField NameTypeDescriptionDescription
') html_lines.append(" ") html_lines.append(" ") - html_lines.append(f' ') + html_lines.append( + f' ' + ) html_lines.append(f' ') if related_show_descriptions: - html_lines.append(f' ') + html_lines.append( + f' ' + ) html_lines.append(" ") html_lines.append(" ") html_lines.append(" ") @@ -1253,7 +1297,7 @@ def generate_type_section_html( for field in related_parsed["fields"]: html_lines.append(" ") # add required icon outside code block for required fields - field_name_html = f'{field["name"]}' + field_name_html = f"{field['name']}" if field["required"]: field_name_html += f'' html_lines.append( @@ -1329,7 +1373,9 @@ def generate_schema_documentation( front_matter_lines.append("+++") # generate comment (after front matter) - comment = config.get_generated_comment("scripts/generate_reference_syft_json_schema.py", "html") + comment = config.get_generated_comment( + "scripts/generate_reference_syft_json_schema.py", "html" + ) comment += "\n" # generate content sections @@ -1337,7 +1383,7 @@ def generate_schema_documentation( # document section (single type, no h3 to avoid redundant "Document" heading) doc_html = [] - doc_html.append('## Document {#document}\n') + doc_html.append("## Document {#document}\n") # get and parse Document definition doc_def = all_defs.get("Document") @@ -1346,7 +1392,7 @@ def generate_schema_documentation( # type description (if exists) if parsed["description"]: - doc_html.append(f'

{parsed["description"]}

\n') + doc_html.append(f"

{parsed['description']}

\n") # generate table (same structure as in generate_type_section_html) if parsed["fields"]: @@ -1355,10 +1401,14 @@ def generate_schema_documentation( doc_html.append(f'
Field NameField NameTypeDescriptionDescription
') doc_html.append(" ") doc_html.append(" ") - doc_html.append(f' ') + doc_html.append( + f' ' + ) doc_html.append(f' ') if show_descriptions: - doc_html.append(f' ') + doc_html.append( + f' ' + ) doc_html.append(" ") doc_html.append(" ") doc_html.append(" ") @@ -1366,7 +1416,7 @@ def generate_schema_documentation( for field in parsed["fields"]: doc_html.append(" ") # add required icon outside code block for required fields - field_name_html = f'{field["name"]}' + field_name_html = f"{field['name']}" if field["required"]: field_name_html += f'' doc_html.append( @@ -1421,6 +1471,5 @@ def generate_schema_documentation( logger.info(f"Generated {output_file}") - if __name__ == "__main__": main() diff --git a/scripts/generate_template_examples.py b/scripts/generate_template_examples.py index d6b301f9..3e797e9e 100755 --- a/scripts/generate_template_examples.py +++ b/scripts/generate_template_examples.py @@ -140,7 +140,9 @@ def generate_example( output_md = example_dir / "output.md" # Check if outputs need regeneration - if not output_manager.should_regenerate_multiple([template_md, output_md], [template_file], update): + if not output_manager.should_regenerate_multiple( + [template_md, output_md], [template_file], update + ): return False # Read template content @@ -148,7 +150,9 @@ def generate_example( # Generate template.md # see the language support: https://gohugo.io/content-management/syntax-highlighting/#languages - template_md_content = markdown.create_code_fence(template_content, "go-text-template") + template_md_content = markdown.create_code_fence( + template_content, "go-text-template" + ) (example_dir / "template.md").write_text(template_md_content) # Generate or retrieve SBOM from cache diff --git a/scripts/utils/constants.py b/scripts/utils/constants.py index 36c85d22..ce28f211 100644 --- a/scripts/utils/constants.py +++ b/scripts/utils/constants.py @@ -101,6 +101,7 @@ class SVGIcons(str, Enum): def __str__(self) -> str: return self.value + class OutputFormats(str, Enum): """Syft output format identifiers.""" @@ -130,6 +131,7 @@ class OutputFormats(str, Enum): def __str__(self) -> str: return self.value + # Header definitions for table tooltips # these are shared across capability and vulnerability tables HEADER_DEFINITIONS: dict[str, str] = { diff --git a/scripts/utils/data.py b/scripts/utils/data.py index 4467cefb..383878c9 100644 --- a/scripts/utils/data.py +++ b/scripts/utils/data.py @@ -206,7 +206,9 @@ def load_cataloger_data(update: bool = False) -> dict: # save to cache cache_file.parent.mkdir(parents=True, exist_ok=True) - comment = config.get_generated_comment("scripts/generate_capability_tables.py", "json") + comment = config.get_generated_comment( + "scripts/generate_capability_tables.py", "json" + ) cache_data = {"_comment": comment, **data} with open(cache_file, "w") as f: diff --git a/scripts/utils/html_table.py b/scripts/utils/html_table.py index 80d41ae9..adab433b 100644 --- a/scripts/utils/html_table.py +++ b/scripts/utils/html_table.py @@ -315,7 +315,9 @@ def format_evidence_for_tooltip(evidence: list[str]) -> str: return " ".join(f"• {path}" for path in evidence) -def format_conditions_for_tooltip(conditions: list[dict], prefix: str = "Requires") -> str: +def format_conditions_for_tooltip( + conditions: list[dict], prefix: str = "Requires" +) -> str: """ format condition requirements for tooltip display. @@ -379,8 +381,8 @@ def format_conditions_for_tooltip(conditions: list[dict], prefix: str = "Require def get_capability_indicator_svg( cap_support, - evidence: list[str] = None, - conditions: list[dict] = None, + evidence: list[str] | None = None, + conditions: list[dict] | None = None, ) -> str: """ get the SVG icon for a capability support level with optional tooltip. @@ -652,11 +654,11 @@ def _format_header_cell(self, cell: dict[str, str | int]) -> str: attrs.append(f'class="{cell["class"]}"') # add rowspan - if "rowspan" in cell and cell["rowspan"] > 1: + if "rowspan" in cell and int(cell["rowspan"]) > 1: attrs.append(f'rowspan="{cell["rowspan"]}"') # add colspan - if "colspan" in cell and cell["colspan"] > 1: + if "colspan" in cell and int(cell["colspan"]) > 1: attrs.append(f'colspan="{cell["colspan"]}"') # format content with optional tooltip @@ -669,7 +671,7 @@ def _format_header_cell(self, cell: dict[str, str | int]) -> str: # build tag attr_str = " " + " ".join(attrs) if attrs else "" - return f' {content}' + return f" {content}" def _format_body_cell(self, cell: dict[str, str | int]) -> str: """ @@ -688,15 +690,15 @@ def _format_body_cell(self, cell: dict[str, str | int]) -> str: attrs.append(f'class="{cell["class"]}"') # add rowspan - if "rowspan" in cell and cell["rowspan"] > 1: + if "rowspan" in cell and int(cell["rowspan"]) > 1: attrs.append(f'rowspan="{cell["rowspan"]}"') # add colspan - if "colspan" in cell and cell["colspan"] > 1: + if "colspan" in cell and int(cell["colspan"]) > 1: attrs.append(f'colspan="{cell["colspan"]}"') content = cell.get("content", "") # build tag attr_str = " " + " ".join(attrs) if attrs else "" - return f' {content}' + return f" {content}" diff --git a/scripts/utils/markdown.py b/scripts/utils/markdown.py index 2046a6c7..f7891a3b 100644 --- a/scripts/utils/markdown.py +++ b/scripts/utils/markdown.py @@ -1,5 +1,7 @@ """Markdown generation utilities for documentation scripts.""" +from typing import Any + def create_code_fence(content: str, language: str = "") -> str: """ @@ -32,7 +34,7 @@ def generate_front_matter( url: str | None = None, description: str | None = None, aliases: list[str] | None = None, - params: dict[str, any] | None = None, + params: dict[str, Any] | None = None, ) -> str: """ Generate Hugo front matter in TOML format.
Field NameField NameTypeDescriptionDescription