Compare commits

...
12 Commits
Author SHA1 Message Date
anchore-actions-token-generator[bot]andspiffcs 8d836fb8b0 chore(deps): update tools to latest versions (#4577)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2026-01-27 15:18:18 -05:00
Christopher Angelo Phillips 9a250a4b4b fix: update mixed case dependencies in python to be normalized (#4573)
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
2026-01-27 15:16:32 -05:00
anchore-actions-token-generator[bot]andwillmurphyscode e8b4527bfb chore(deps): update anchore dependencies (#4575)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: willmurphyscode <12529630+willmurphyscode@users.noreply.github.com>
2026-01-27 10:14:26 +00:00
anchore-actions-token-generator[bot]andspiffcs d0bb042d74 chore(deps): update tools to latest versions (#4570)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2026-01-26 12:25:31 -05:00
Keith Zantow c65d023668 feat: detect Debian version from /etc/debian_version (#4569)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2026-01-23 17:52:21 -05:00
Keith Zantow 836f358cd4 fix: correctly report supporting evidence for binary packages (#4558)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2026-01-23 13:01:12 -05:00
dependabot[bot] 27b1219e98 chore(deps): bump the actions-minor-patch group across 2 directories with 3 updates (#4568)
Bumps the actions-minor-patch group with 3 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [actions/setup-go](https://github.com/actions/setup-go) and [github/codeql-action](https://github.com/github/codeql-action).
Bumps the actions-minor-patch group with 1 update in the /.github/actions/bootstrap directory: [actions/setup-go](https://github.com/actions/setup-go).


Updates `actions/checkout` from 6.0.1 to 6.0.2
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/8e8c483db84b4bee98b60c0593521ed34d9990e8...de0fac2e4500dabe0009e67214ff5f5447ce83dd)

Updates `actions/setup-go` from 6.1.0 to 6.2.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/4dc6199c7b1a012772edbd06daecab0f50c9053c...7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5)

Updates `github/codeql-action` from 4.31.9 to 4.31.10
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/5d4e8d1aca955e8d8589aabd499c5cae939e33c7...cdefb33c0f6224e58673d9004f47f7cb3e328b89)

Updates `actions/setup-go` from 6.1.0 to 6.2.0
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/4dc6199c7b1a012772edbd06daecab0f50c9053c...7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-minor-patch
- dependency-name: actions/setup-go
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor-patch
- dependency-name: github/codeql-action
  dependency-version: 4.31.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions-minor-patch
- dependency-name: actions/setup-go
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-23 10:37:23 -05:00
dependabot[bot] c0e0058c86 chore(deps): bump the go-minor-patch group with 6 updates (#4567)
Bumps the go-minor-patch group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [github.com/github/go-spdx/v2](https://github.com/github/go-spdx) | `2.3.5` | `2.3.6` |
| [github.com/go-viper/mapstructure/v2](https://github.com/go-viper/mapstructure) | `2.4.0` | `2.5.0` |
| [golang.org/x/mod](https://github.com/golang/mod) | `0.31.0` | `0.32.0` |
| [golang.org/x/net](https://github.com/golang/net) | `0.48.0` | `0.49.0` |
| [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) | `1.43.0` | `1.44.1` |
| [golang.org/x/tools](https://github.com/golang/tools) | `0.40.0` | `0.41.0` |


Updates `github.com/github/go-spdx/v2` from 2.3.5 to 2.3.6
- [Release notes](https://github.com/github/go-spdx/releases)
- [Commits](https://github.com/github/go-spdx/compare/v2.3.5...v2.3.6)

Updates `github.com/go-viper/mapstructure/v2` from 2.4.0 to 2.5.0
- [Release notes](https://github.com/go-viper/mapstructure/releases)
- [Changelog](https://github.com/go-viper/mapstructure/blob/main/CHANGELOG.md)
- [Commits](https://github.com/go-viper/mapstructure/compare/v2.4.0...v2.5.0)

Updates `golang.org/x/mod` from 0.31.0 to 0.32.0
- [Commits](https://github.com/golang/mod/compare/v0.31.0...v0.32.0)

Updates `golang.org/x/net` from 0.48.0 to 0.49.0
- [Commits](https://github.com/golang/net/compare/v0.48.0...v0.49.0)

Updates `modernc.org/sqlite` from 1.43.0 to 1.44.1
- [Changelog](https://gitlab.com/cznic/sqlite/blob/master/CHANGELOG.md)
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.43.0...v1.44.1)

Updates `golang.org/x/tools` from 0.40.0 to 0.41.0
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.40.0...v0.41.0)

---
updated-dependencies:
- dependency-name: github.com/github/go-spdx/v2
  dependency-version: 2.3.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-minor-patch
- dependency-name: github.com/go-viper/mapstructure/v2
  dependency-version: 2.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-minor-patch
- dependency-name: golang.org/x/mod
  dependency-version: 0.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-minor-patch
- dependency-name: golang.org/x/net
  dependency-version: 0.49.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-minor-patch
- dependency-name: modernc.org/sqlite
  dependency-version: 1.44.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-minor-patch
- dependency-name: golang.org/x/tools
  dependency-version: 0.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: go-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-23 10:37:10 -05:00
anchore-actions-token-generator[bot]andspiffcs a9fabb6c0f chore(deps): update tools to latest versions (#4565)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2026-01-22 13:04:45 -05:00
dependabot[bot] 7954324417 chore(deps): bump github.com/spdx/tools-golang (#4557)
Bumps the go-minor-patch group with 1 update in the / directory: [github.com/spdx/tools-golang](https://github.com/spdx/tools-golang).


Updates `github.com/spdx/tools-golang` from 0.5.6 to 0.5.7
- [Release notes](https://github.com/spdx/tools-golang/releases)
- [Changelog](https://github.com/spdx/tools-golang/blob/main/RELEASE-NOTES.md)
- [Commits](https://github.com/spdx/tools-golang/compare/v0.5.6...v0.5.7)

---
updated-dependencies:
- dependency-name: github.com/spdx/tools-golang
  dependency-version: 0.5.7
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: go-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-16 13:04:13 -05:00
Will Murphy 3e563d90d5 ci: enable zizmor to fail PRs (#4556)
* ci: enable zizmor to fail PRs

Enable zizmor (gh actions yaml linter) to fail builds in PRs. Fix any
outstanding linting errors found by this tool.

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>

* fix outdated version comments

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>

---------

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>
2026-01-16 10:49:00 -05:00
Will Murphy 5987f46353 Chore new slack action (#4553)
* chore: new slack action

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>

* TEMP: exit 1 to test slack notify

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>

* new slack integration everywhere

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>

---------

Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>
2026-01-16 11:26:40 +00:00
38 changed files with 558 additions and 147 deletions
+2 -2
View File
@@ -90,7 +90,7 @@ tools:
# used for running all local and CI tasks
- name: task
version:
want: v3.46.4
want: v3.48.0
method: github-release
with:
repo: go-task/task
@@ -98,7 +98,7 @@ tools:
# used for triggering a release
- name: gh
version:
want: v2.85.0
want: v2.86.0
method: github-release
with:
repo: cli/cli
+1 -1
View File
@@ -29,7 +29,7 @@ runs:
using: "composite"
steps:
# note: go mod and build is automatically cached on default with v4+
- uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0
- uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6.2.0
if: inputs.go-version != ''
with:
go-version: ${{ inputs.go-version }}
+4
View File
@@ -15,6 +15,8 @@ updates:
- package-ecosystem: gomod
directory: "/"
cooldown:
default-days: 7
schedule:
interval: "weekly"
day: "friday"
@@ -34,6 +36,8 @@ updates:
directories:
- "/"
- "/.github/actions/bootstrap"
cooldown:
default-days: 7
schedule:
interval: "weekly"
day: "friday"
+5 -5
View File
@@ -36,18 +36,18 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Install Go
uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c #v6.1.0
uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 #v6.2.0
with:
go-version-file: go.mod
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 #v3.29.5
uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -58,7 +58,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 #v3.29.5
uses: github/codeql-action/autobuild@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -72,4 +72,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 #v3.29.5
uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
issues: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
+18 -8
View File
@@ -24,7 +24,7 @@ jobs:
if: ${{ github.event.inputs.phase == 'all' }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -141,7 +141,7 @@ jobs:
# required for goreleaser signs section with cosign
id-token: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
fetch-depth: 0
persist-credentials: true
@@ -192,14 +192,24 @@ jobs:
file: go.mod
artifact-name: sbom.spdx.json
- uses: 8398a7/action-slack@77eaa4f1c608a7d68b38af4e3f739dcd8cba273e #v3.19.0
- name: Notify Slack of new release
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a #v2.1.1
continue-on-error: true
with:
status: ${{ job.status }}
fields: repo,workflow,action,eventName
text: "A new Syft release has been published: https://github.com/anchore/syft/releases/tag/${{ github.event.inputs.version }}"
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
webhook: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
text: "A new Syft release has been published: https://github.com/anchore/syft/releases/tag/${{ github.event.inputs.version }}"
blocks:
- type: section
text:
type: mrkdwn
text: |
*A new Syft release has been published* :rocket:
• Release: <https://github.com/anchore/syft/releases/tag/${{ github.event.inputs.version }}|${{ github.event.inputs.version }}>
• Repo: `${{ github.repository }}`
• Workflow: `${{ github.workflow }}`
• Event: `${{ github.event_name }}`
if: ${{ success() }}
release-install-script:
@@ -22,7 +22,7 @@ jobs:
permissions:
packages: write
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository_owner == 'anchore' # only run for main repo (not forks)
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
+1 -1
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'anchore/syft' # only run for main repo
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -19,7 +19,7 @@ jobs:
packages: write
if: github.repository == 'anchore/syft' # only run for main repo
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -64,11 +64,21 @@ jobs:
Update CPE dictionary index based on the latest available CPE dictionary
token: ${{ steps.generate-token.outputs.token }}
- uses: 8398a7/action-slack@77eaa4f1c608a7d68b38af4e3f739dcd8cba273e #v3.19.0
- name: Notify Slack on failure
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a #v2.1.1
with:
status: ${{ job.status }}
fields: workflow,eventName,job
text: Syft CPE dictionary index update failed
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
webhook: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
text: "Syft CPE dictionary index update failed"
blocks:
- type: section
text:
type: mrkdwn
text: |
*Syft CPE dictionary index update failed*
• Workflow: `${{ github.workflow }}`
• Event: `${{ github.event_name }}`
• Job Status: `${{ job.status }}`
• <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run>
if: ${{ failure() && env.SLACK_NOTIFICATIONS == 'true' }}
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'anchore/syft' # only run for main repo
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -44,11 +44,21 @@ jobs:
Update SPDX license list based on the latest available list from spdx.org
token: ${{ steps.generate-token.outputs.token }}
- uses: 8398a7/action-slack@77eaa4f1c608a7d68b38af4e3f739dcd8cba273e #v3.19.0
- name: Notify Slack on failure
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a #v2.1.1
with:
status: ${{ job.status }}
fields: workflow,eventName,job
text: Syft SPDX license list update failed
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
webhook: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
text: "Syft SPDX license list update failed"
blocks:
- type: section
text:
type: mrkdwn
text: |
*Syft SPDX license list update failed*
• Workflow: `${{ github.workflow }}`
• Event: `${{ github.event_name }}`
• Job Status: `${{ job.status }}`
• <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run>
if: ${{ failure() && env.SLACK_NOTIFICATIONS == 'true' }}
@@ -23,13 +23,14 @@ jobs:
contents: read
security-events: write # for uploading SARIF results
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: "Run zizmor"
uses: zizmorcore/zizmor-action@e639db99335bc9038abc0e066dfcd72e23d26fb4 # v0.3.0
with:
config-file: .github/zizmor.yml
sarif-upload: true
config: .github/zizmor.yml
# Disable SARIF upload so the step is a simple pass/fail gate
advanced-security: false
inputs: .github
+7 -7
View File
@@ -26,7 +26,7 @@ jobs:
# tmpfs: faster io-intensive workflows
runs-on: &test-runner "runs-on=${{ github.run_id }}/cpu=4+8/ram=32+128/family=r5+r6+r7+r8+m4+m5+m6+m7+m8/spot=price-capacity-optimized/extras=s3-cache+tmpfs"
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -46,7 +46,7 @@ jobs:
name: "Unit tests"
runs-on: *test-runner
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -63,7 +63,7 @@ jobs:
name: "Integration tests"
runs-on: *test-runner
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -90,7 +90,7 @@ jobs:
# required for magic-cache from runs-on to function with artifact upload/download (see https://runs-on.com/caching/magic-cache/#actionsupload-artifact-compatibility)
- uses: runs-on/action@cd2b598b0515d39d78c38a02d529db87d2196d1e # v2.0.3
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -121,7 +121,7 @@ jobs:
# required for magic-cache from runs-on to function with artifact upload/download (see https://runs-on.com/caching/magic-cache/#actionsupload-artifact-compatibility)
- uses: runs-on/action@cd2b598b0515d39d78c38a02d529db87d2196d1e # v2.0.3
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -163,7 +163,7 @@ jobs:
- name: Install Cosign
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
@@ -198,7 +198,7 @@ jobs:
# required for magic-cache from runs-on to function with artifact upload/download (see https://runs-on.com/caching/magic-cache/#actionsupload-artifact-compatibility)
- uses: runs-on/action@cd2b598b0515d39d78c38a02d529db87d2196d1e # v2.0.3
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
+4 -4
View File
@@ -1,9 +1,9 @@
rules:
unpinned-uses:
ignore:
# Allow unpinned uses of trusted internal anchore/workflows actions
- update-anchore-dependencies.yml
config:
policies:
# anchore/workflows is an internal repository; using @main is acceptable
anchore/*: any
dangerous-triggers:
ignore:
# Safe use of pull_request_target - only runs trusted scripts from base repo,
+12 -12
View File
@@ -23,7 +23,7 @@ require (
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b
github.com/anchore/packageurl-go v0.1.1-0.20250220190351-d62adb6e1115
github.com/anchore/stereoscope v0.1.18
github.com/anchore/stereoscope v0.1.19
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
github.com/aquasecurity/go-pep440-version v0.0.1
github.com/bitnami/go-version v0.0.0-20250131085805-b1f57a8634ef
@@ -39,12 +39,12 @@ require (
github.com/dustin/go-humanize v1.0.1
github.com/elliotchance/phpserialize v1.4.0
github.com/facebookincubator/nvdtools v0.1.5
github.com/github/go-spdx/v2 v2.3.5
github.com/github/go-spdx/v2 v2.3.6
github.com/gkampitakis/go-snaps v0.5.19
github.com/go-git/go-billy/v5 v5.7.0
github.com/go-git/go-git/v5 v5.16.4
github.com/go-test/deep v1.1.1
github.com/go-viper/mapstructure/v2 v2.4.0
github.com/go-viper/mapstructure/v2 v2.5.0
github.com/gohugoio/hashstructure v0.6.0
github.com/google/go-cmp v0.7.0
github.com/google/go-containerregistry v0.20.7
@@ -76,7 +76,7 @@ require (
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e
github.com/sergi/go-diff v1.4.0
github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb
github.com/spdx/tools-golang v0.5.6
github.com/spdx/tools-golang v0.5.7
github.com/spf13/afero v1.15.0
github.com/spf13/cobra v1.10.2
github.com/stretchr/testify v1.11.1
@@ -88,10 +88,10 @@ require (
github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1
go.uber.org/goleak v1.3.0
go.yaml.in/yaml/v3 v3.0.4
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
golang.org/x/mod v0.31.0
golang.org/x/net v0.48.0
modernc.org/sqlite v1.43.0
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546
golang.org/x/mod v0.32.0
golang.org/x/net v0.49.0
modernc.org/sqlite v1.44.1
)
require (
@@ -139,7 +139,7 @@ require (
github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/cyphar/filepath-securejoin v0.6.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/cli v29.1.4+incompatible // indirect
github.com/docker/cli v29.1.5+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker v28.5.2+incompatible // indirect
github.com/docker/docker-credential-helpers v0.9.4 // indirect
@@ -199,7 +199,7 @@ require (
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/ncruces/go-strftime v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runtime-spec v1.3.0 // indirect
github.com/opencontainers/selinux v1.13.1 // indirect
@@ -258,7 +258,7 @@ require (
golang.org/x/term v0.39.0 // indirect
golang.org/x/text v0.33.0 // indirect
golang.org/x/time v0.14.0
golang.org/x/tools v0.40.0
golang.org/x/tools v0.41.0
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
google.golang.org/api v0.256.0 // indirect
google.golang.org/genproto v0.0.0-20250922171735-9219d122eba9 // indirect
@@ -268,7 +268,7 @@ require (
google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1
modernc.org/libc v1.66.10 // indirect
modernc.org/libc v1.67.6 // indirect
modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect
)
+30 -28
View File
@@ -152,8 +152,8 @@ github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZV
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=
github.com/anchore/packageurl-go v0.1.1-0.20250220190351-d62adb6e1115 h1:ZyRCmiEjnoGJZ1+Ah0ZZ/mKKqNhGcUZBl0s7PTTDzvY=
github.com/anchore/packageurl-go v0.1.1-0.20250220190351-d62adb6e1115/go.mod h1:KoYIv7tdP5+CC9VGkeZV4/vGCKsY55VvoG+5dadg4YI=
github.com/anchore/stereoscope v0.1.18 h1:Mj34pRtxwfdFJkYKtKjiO9Xn7qs0RTCi59ofRYTSCEU=
github.com/anchore/stereoscope v0.1.18/go.mod h1:y8P4BURfBj0DVRly9cPHsSuZdI/AsZs3ee/x/HusEe4=
github.com/anchore/stereoscope v0.1.19 h1:1G5LVmRN1Sz6qNezpVAEeN7QfWwCE9zw9TJK1ZGnkvw=
github.com/anchore/stereoscope v0.1.19/go.mod h1:+laNHlk05xA2YqgEzq8mxkFzclL3NRdeNIsiQQVeZZ4=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
@@ -351,8 +351,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c=
github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0=
github.com/docker/cli v29.1.4+incompatible h1:AI8fwZhqsAsrqZnVv9h6lbexeW/LzNTasf6A4vcNN8M=
github.com/docker/cli v29.1.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v29.1.5+incompatible h1:GckbANUt3j+lsnQ6eCcQd70mNSOismSHWt8vk2AX8ao=
github.com/docker/cli v29.1.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
@@ -420,8 +420,8 @@ github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/github/go-spdx/v2 v2.3.5 h1:rtRQmzDSq2sU/F2oTIvNQQ+6oInq7yxex5npgY//bJQ=
github.com/github/go-spdx/v2 v2.3.5/go.mod h1:VziiWwQ/hoGS++2ifYyr/za0Ng9rlgMS+c4U7zckrDs=
github.com/github/go-spdx/v2 v2.3.6 h1:9flm625VmmTlWXi0YH5W9V8FdMfulvxalHdYnUfoqxc=
github.com/github/go-spdx/v2 v2.3.6/go.mod h1:/5rwgS0txhGtRdUZwc02bTglzg6HK3FfuEbECKlK2Sg=
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
github.com/gkampitakis/go-snaps v0.5.19 h1:hUJlCQOpTt1M+kSisMwioDWZDWpDtdAvUhvWCx1YGW0=
@@ -458,8 +458,8 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
@@ -772,8 +772,8 @@ github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIf
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/nix-community/go-nix v0.0.0-20250101154619-4bdde671e0a1 h1:kpt9ZfKcm+EDG4s40hMwE//d5SBgDjUOrITReV2u4aA=
github.com/nix-community/go-nix v0.0.0-20250101154619-4bdde671e0a1/go.mod h1:qgCw4bBKZX8qMgGeEZzGFVT3notl42dBjNqO2jut0M0=
github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE=
@@ -898,8 +898,8 @@ github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIK
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb h1:bLo8hvc8XFm9J47r690TUKBzcjSWdJDxmjXJZ+/f92U=
github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM=
github.com/spdx/tools-golang v0.5.6 h1:HUwSJWxyAR7vBstEeZ1+guD6Jcl4TVsKyTBUwT0RjTQ=
github.com/spdx/tools-golang v0.5.6/go.mod h1:jg7w0LOpoNAw6OxKEzCoqPC2GCTj45LyTlVmXubDsYw=
github.com/spdx/tools-golang v0.5.7 h1:+sWcKGnhwp3vLdMqPcLdA6QK679vd86cK9hQWH3AwCg=
github.com/spdx/tools-golang v0.5.7/go.mod h1:jg7w0LOpoNAw6OxKEzCoqPC2GCTj45LyTlVmXubDsYw=
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
@@ -1079,8 +1079,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -1108,8 +1108,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1154,8 +1154,8 @@ golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1342,8 +1342,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1537,18 +1537,20 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
modernc.org/cc/v4 v4.26.5 h1:xM3bX7Mve6G8K8b+T11ReenJOT+BmVqQj0FY5T4+5Y4=
modernc.org/cc/v4 v4.26.5/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A=
modernc.org/ccgo/v4 v4.28.1/go.mod h1:uD+4RnfrVgE6ec9NGguUNdhqzNIeeomeXf6CL0GTE5Q=
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.30.1 h1:4r4U1J6Fhj98NKfSjnPUN7Ze2c6MnAdL0hWw6+LrJpc=
modernc.org/ccgo/v4 v4.30.1/go.mod h1:bIOeI1JL54Utlxn+LwrFyjCx2n2RDiYEaJVSrgdrRfM=
modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=
modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.1 h1:k8T3gkXWY9sEiytKhcgyiZ2L0DTyCQ/nvX+LoCljoRE=
modernc.org/gc/v3 v3.1.1/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.66.10 h1:yZkb3YeLx4oynyR+iUsXsybsX4Ubx7MQlSYEw4yj59A=
modernc.org/libc v1.66.10/go.mod h1:8vGSEwvoUoltr4dlywvHqjtAqHBaw0j1jI7iFBTAr2I=
modernc.org/libc v1.67.6 h1:eVOQvpModVLKOdT+LvBPjdQqfrZq+pC39BygcT+E7OI=
modernc.org/libc v1.67.6/go.mod h1:JAhxUVlolfYDErnwiqaLvUqc8nfb2r6S6slAgZOnaiE=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
@@ -1557,8 +1559,8 @@ modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.43.0 h1:8YqiFx3G1VhHTXO2Q00bl1Wz9KhS9Q5okwfp9Y97VnA=
modernc.org/sqlite v1.43.0/go.mod h1:+VkC6v3pLOAE0A0uVucQEcbVW0I5nHCeDaBf+DpsQT8=
modernc.org/sqlite v1.44.1 h1:qybx/rNpfQipX/t47OxbHmkkJuv2JWifCMH8SVUiDas=
modernc.org/sqlite v1.44.1/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
+9
View File
@@ -54,6 +54,12 @@ var identityFiles = []parseEntry{
// /////////////////////////////////////////////////////////////////////////////////////////////////////
}
// after a parser function returns a Release, it may have incomplete information; supplementers can be used to
// fill in missing details based on other files present in the filesystem
var supplementers = []func(file.Resolver, *Release){
supplementDebianVersion,
}
// IdentifyRelease parses distro-specific files to discover and raise linux distribution release details.
func IdentifyRelease(resolver file.Resolver) *Release {
logger := log.Nested("operation", "identify-release")
@@ -67,6 +73,9 @@ func IdentifyRelease(resolver file.Resolver) *Release {
for _, location := range locations {
release := tryParseReleaseInfo(resolver, location, logger, entry)
if release != nil {
for _, supplementer := range supplementers {
supplementer(resolver, release)
}
return release
}
}
+15 -1
View File
@@ -74,7 +74,7 @@ func TestIdentifyRelease(t *testing.T) {
},
},
{
fixture: "test-fixtures/os/debian",
fixture: "test-fixtures/os/debian/from-os-release",
release: &Release{
PrettyName: "Debian GNU/Linux 8 (jessie)",
Name: "Debian GNU/Linux",
@@ -87,6 +87,20 @@ func TestIdentifyRelease(t *testing.T) {
BugReportURL: "https://bugs.debian.org/",
},
},
{
fixture: "test-fixtures/os/debian/from-debian_version",
release: &Release{
PrettyName: "Distroless",
Name: "Debian GNU/Linux",
ID: "debian",
IDLike: nil,
Version: "10.8",
VersionID: "10.8",
HomeURL: "https://github.com/GoogleContainerTools/distroless",
SupportURL: "https://github.com/GoogleContainerTools/distroless/blob/master/README.md",
BugReportURL: "https://github.com/GoogleContainerTools/distroless/issues/new",
},
},
{
fixture: "test-fixtures/os/fedora",
release: &Release{
+51
View File
@@ -0,0 +1,51 @@
package linux
import (
"io"
"regexp"
"strings"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/file"
)
func supplementDebianVersion(resolver file.Resolver, release *Release) {
// we're only looking for version information for debian when none is present in /etc/os-release
if release.Version != "" || release.VersionID != "" || !strings.EqualFold(release.ID, "debian") {
return
}
// if we have a debian release with no version, look for a debian_version
locations, err := resolver.FilesByGlob("/etc/debian_version")
if err != nil {
log.Debugf("error reading /etc/debian_version: %v", err)
return
}
for _, location := range locations {
version := readDebianVersionFile(resolver, location)
if version != "" {
release.Version = version
release.VersionID = version
return // keep the first result
}
}
}
func readDebianVersionFile(resolver file.Resolver, location file.Location) string {
rdr, err := resolver.FileContentsByLocation(location)
if err != nil {
log.Debugf("error getting contents for %s: %v", location.RealPath, err)
return ""
}
defer internal.CloseAndLogError(rdr, location.RealPath)
contents, err := io.ReadAll(rdr)
if err != nil {
log.Debugf("error reading %s: %v", location.RealPath, err)
return ""
}
version := strings.TrimSpace(string(contents))
if regexp.MustCompile(`^\d+(?:\.\d+)?$`).MatchString(version) {
return version
}
return ""
}
@@ -0,0 +1,6 @@
PRETTY_NAME="Distroless"
NAME="Debian GNU/Linux"
ID="debian"
HOME_URL="https://github.com/GoogleContainerTools/distroless"
SUPPORT_URL="https://github.com/GoogleContainerTools/distroless/blob/master/README.md"
BUG_REPORT_URL="https://github.com/GoogleContainerTools/distroless/issues/new"
@@ -109,16 +109,6 @@ catalogers:
cpes:
- cpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*
type: BinaryPkg
- method: glob
criteria:
- '**/VERSION*'
packages:
- class: go-binary-hint
name: go
purl: pkg:generic/go
cpes:
- cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*
type: BinaryPkg
- method: glob
criteria:
- '**/busybox'
@@ -64,6 +64,10 @@ func (c cataloger) Catalog(_ context.Context, resolver file.Resolver) ([]pkg.Pac
var relationships []artifact.Relationship
var errs error
// we do not run these classifiers in parallel currently because: when determining primary vs. supporting evidence,
// we take preference to the classifier that was defined first, if we modify this to run in parallel,
// we need to retain this behavior by giving precedence to the classifier defined first in the c.classifiers list;
// if this is ever made parallel, we will need to account for this to have deterministic behavior
for _, cls := range c.classifiers {
log.WithFields("classifier", cls.Class).Trace("cataloging binaries")
newPkgs, err := catalog(resolver, cls)
@@ -101,8 +105,26 @@ func mergePackages(target *pkg.Package, extra *pkg.Package) {
if extra.Type != pkg.BinaryPkg && target.Type == pkg.BinaryPkg {
target.Type = extra.Type
}
// add the locations
target.Locations.Add(extra.Locations.ToSlice()...)
addedEvidence := false
// when merging locations together, we need to maintain primary vs. supporting evidence -
// if we are merging two packages together that have overlapping evidence, e.g. libpython
// which are found by 2 different classifiers, we want to deduplicate evidence for the same
// locations when merging so libpython is not considered primary evidence. This allows cases
// where we find python binary with version info coming from libpython to deduplicate the libpython
// entries, but also surface results for libpython separately as primary evidence when there is
// no python binary referencing it
for _, location := range extra.Locations.ToSlice() {
// if we already have the same location, don't include duplicates
if target.Locations.Contains(location) {
continue
}
addedEvidence = true
target.Locations.Add(location)
}
// only include the additional metadata if we added evidence, as it was likely duplicated e.g. libpython
if !addedEvidence {
return
}
// update the metadata to indicate which classifiers were used
meta, _ := target.Metadata.(pkg.BinarySignature)
if m, ok := extra.Metadata.(pkg.BinarySignature); ok {
@@ -6,6 +6,7 @@ import (
"flag"
"fmt"
"io"
"slices"
"strings"
"testing"
@@ -547,6 +548,7 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
},
},
{
// no python binary, but we find libpython, which is surfaced as primary evidence
logicalFixture: "python-shared-lib/3.7.4/linux-amd64",
expected: pkg.Package{
Name: "python",
@@ -556,7 +558,6 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Metadata: metadata("python-binary-lib"),
},
},
{
// note: dynamic (non-snippet) test case
logicalFixture: "python-slim-shared-libs/3.11/linux-amd64",
@@ -569,7 +570,6 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Matches: []pkg.ClassifierMatch{
match("python-binary", "python3.11"),
match("python-binary", "libpython3.11.so.1.0"),
match("python-binary-lib", "libpython3.11.so.1.0"),
},
},
},
@@ -586,7 +586,6 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Matches: []pkg.ClassifierMatch{
match("python-binary", "python3.9"),
match("python-binary", "libpython3.9.so.1.0"),
match("python-binary-lib", "libpython3.9.so.1.0"),
},
},
},
@@ -618,7 +617,6 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Matches: []pkg.ClassifierMatch{
match("python-binary", "python3.4"),
match("python-binary", "libpython3.4m.so.1.0"),
match("python-binary-lib", "libpython3.4m.so.1.0"),
},
},
},
@@ -734,8 +732,8 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Name: "go",
Version: "1.15",
PURL: "pkg:generic/go@1.15",
Locations: locations("VERSION"),
Metadata: metadata("go-binary-hint"),
Locations: locations("bin/go", "VERSION"),
Metadata: metadata("go-binary"),
},
},
{
@@ -745,8 +743,8 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Name: "go",
Version: "1.25-d524e1e",
PURL: "pkg:generic/go@1.25-d524e1e",
Locations: locations("VERSION.cache"),
Metadata: metadata("go-binary-hint"),
Locations: locations("bin/go", "VERSION.cache"),
Metadata: metadata("go-binary"),
},
},
{
@@ -1823,17 +1821,6 @@ func Test_Cataloger_DefaultClassifiers_PositiveCases_Image(t *testing.T) {
require.NoError(t, err)
for _, p := range packages {
expectedLocations := test.expected.Locations.ToSlice()
gotLocations := p.Locations.ToSlice()
require.Len(t, gotLocations, len(expectedLocations))
for i, expectedLocation := range expectedLocations {
gotLocation := gotLocations[i]
if expectedLocation.RealPath != gotLocation.RealPath {
t.Fatalf("locations do not match; expected: %v got: %v", expectedLocations, gotLocations)
}
}
assertPackagesAreEqual(t, test.expected, p)
}
})
@@ -2023,12 +2010,13 @@ func assertPackagesAreEqual(t *testing.T, expected pkg.Package, p pkg.Package) {
gotLocations := p.Locations.ToSlice()
if len(expectedLocations) != len(gotLocations) {
failMessages = append(failMessages, "locations are not equal length")
failMessages = append(failMessages, fmt.Sprintf("locations are not equal: %v != %v", expectedLocations, gotLocations))
} else {
for i, expectedLocation := range expectedLocations {
gotLocation := gotLocations[i]
if expectedLocation.RealPath != gotLocation.RealPath {
failMessages = append(failMessages, fmt.Sprintf("locations do not match; expected: %v got: %v", expectedLocation.RealPath, gotLocation.RealPath))
for _, expectedLocation := range expectedLocations {
if !slices.ContainsFunc(gotLocations, func(gotLocation file.Location) bool {
return gotLocation.RealPath == expectedLocation.RealPath
}) {
failMessages = append(failMessages, fmt.Sprintf("location not found; expected: %v in set: %v", expectedLocation.RealPath, gotLocations))
}
}
}
+8 -11
View File
@@ -71,8 +71,14 @@ func DefaultClassifiers() []binutils.Classifier {
{
Class: "go-binary",
FileGlob: "**/go",
EvidenceMatcher: m.FileContentsVersionMatcher(
`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)\x00`),
EvidenceMatcher: binutils.MatchAny(
m.FileContentsVersionMatcher(
`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)\x00`),
binutils.SupportingEvidenceMatcher("../VERSION*",
m.FileContentsVersionMatcher(
`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+|-[_0-9a-z]+)?)\s`),
),
),
Package: "go",
PURL: mustPURL("pkg:generic/go@version"),
CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
@@ -142,15 +148,6 @@ func DefaultClassifiers() []binutils.Classifier {
PURL: mustPURL("pkg:generic/node@version"),
CPEs: singleCPE("cpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "go-binary-hint",
FileGlob: "**/VERSION*",
EvidenceMatcher: m.FileContentsVersionMatcher(
`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?(-[0-9a-f]{7})?)`),
Package: "go",
PURL: mustPURL("pkg:generic/go@version"),
CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "busybox-binary",
FileGlob: "**/busybox",
@@ -1 +1 @@
go1.15-beta2
go1.15 Fri 2003
@@ -0,0 +1 @@
no version in this binary
@@ -0,0 +1 @@
no version in this binary
@@ -10,7 +10,7 @@ import (
)
func Test_BranchingMatcher(t *testing.T) {
matchingTest := FileContentsVersionMatcher("", `my-verison:(?<version>\d+\.\d+)`)
matchingTest := FileContentsVersionMatcher("", `my-version:(?<version>\d+\.\d+)`)
notMatchingTest := MatchPath("**/not-version*")
tests := []struct {
@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"maps"
"path"
"regexp"
"strconv"
"strings"
@@ -273,9 +274,7 @@ func SharedLibraryLookup(sharedLibraryPattern string, sharedLibraryMatcher Evide
}
for _, p := range pkgs {
// set the source binary as the first location
locationSet := file.NewLocationSet(context.Location)
locationSet.Add(p.Locations.ToSlice()...)
p.Locations = locationSet
makePrimaryLocation(&p, context.Location)
meta, _ := p.Metadata.(pkg.BinarySignature)
p.Metadata = pkg.BinarySignature{
Matches: append([]pkg.ClassifierMatch{
@@ -309,6 +308,28 @@ func MatchPath(path string) EvidenceMatcher {
}
}
// SupportingEvidenceMatcher defines an evidence matcher that searches for secondary evidence with path globs
// relative to a primary file, for example: a VERSION file in the same or a parent directory to another binary
func SupportingEvidenceMatcher(relativePathGlob string, evidenceMatcher EvidenceMatcher) EvidenceMatcher {
return func(classifier Classifier, context MatcherContext) ([]pkg.Package, error) {
f := path.Dir(context.Location.RealPath)
f = path.Join(f, relativePathGlob)
f = path.Clean(f)
// this would ideally be RelativeFileByPath but with a glob search:
relativeFiles, err := context.Resolver.FilesByGlob(f)
if err != nil {
return nil, err
}
for _, relativeFile := range relativeFiles {
evidence, err := collectSupportingEvidence(classifier, context, relativeFile, evidenceMatcher)
if evidence != nil || err != nil {
return evidence, err
}
}
return nil, nil
}
}
func getReader(context MatcherContext) (unionreader.UnionReader, error) {
if context.GetReader != nil {
return context.GetReader(context)
@@ -368,3 +389,43 @@ func sharedLibraries(context MatcherContext) ([]string, error) {
return nil, nil
}
func makePrimaryLocation(p *pkg.Package, primaryLocation file.Location) {
locationSet := file.NewLocationSet(primaryLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation))
for _, l := range p.Locations.ToSlice() {
if locationSet.Contains(l) { // no need for duplicate locations
continue
}
locationSet.Add(l.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation))
}
p.Locations = locationSet
}
func collectSupportingEvidence(classifier Classifier, context MatcherContext, relativeFile file.Location, evidenceMatcher EvidenceMatcher) ([]pkg.Package, error) {
rdr, err := context.Resolver.FileContentsByLocation(relativeFile)
if err != nil {
return nil, err
}
defer internal.CloseAndLogError(rdr, relativeFile.Path())
ur, err := unionreader.GetUnionReader(rdr)
if err != nil {
return nil, err
}
newContext := MatcherContext{
Resolver: context.Resolver,
Location: relativeFile,
GetReader: func(_ MatcherContext) (unionreader.UnionReader, error) {
return ur, nil
},
}
packages, err := evidenceMatcher(classifier, newContext)
if err != nil {
return nil, err
}
for i := range packages {
p := &(packages[i])
// relative files are supporting evidence, like a VERSION file near a go binary, mark the results as supporting
makePrimaryLocation(p, context.Location)
}
return packages, nil
}
@@ -12,6 +12,8 @@ import (
"github.com/anchore/syft/syft/cpe"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/internal/unionreader"
"github.com/anchore/syft/syft/source"
"github.com/anchore/syft/syft/source/directorysource"
)
func Test_ClassifierCPEs(t *testing.T) {
@@ -27,7 +29,7 @@ func Test_ClassifierCPEs(t *testing.T) {
classifier: Classifier{
Package: "some-app",
FileGlob: "**/version.txt",
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)my-verison:(?P<version>[0-9.]+)`),
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)my-version:(?P<version>[0-9.]+)`),
CPEs: []cpe.CPE{},
},
cpes: nil,
@@ -38,7 +40,7 @@ func Test_ClassifierCPEs(t *testing.T) {
classifier: Classifier{
Package: "some-app",
FileGlob: "**/version.txt",
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)my-verison:(?P<version>[0-9.]+)`),
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)my-version:(?P<version>[0-9.]+)`),
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:some:app:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
},
@@ -53,7 +55,7 @@ func Test_ClassifierCPEs(t *testing.T) {
classifier: Classifier{
Package: "some-app",
FileGlob: "**/version.txt",
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)my-verison:(?P<version>[0-9.]+)`),
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)my-version:(?P<version>[0-9.]+)`),
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:some:app:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:some:apps:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
@@ -183,3 +185,61 @@ func TestFileContentsVersionMatcher(t *testing.T) {
})
}
}
func Test_SupportingEvidenceMatcher(t *testing.T) {
tests := []struct {
name string
classifier Classifier
expected string
}{
{
name: "simple version string regexp",
classifier: Classifier{
FileGlob: "**/some-binary",
EvidenceMatcher: SupportingEvidenceMatcher("../version.txt",
FileContentsVersionMatcher("cataloger-name", `(?m)my-version:(?P<version>[0-9.]+)`)),
Package: "some-binary",
},
expected: "1.8",
},
{
name: "not matching version string regexp",
classifier: Classifier{
FileGlob: "**/some-binary",
EvidenceMatcher: SupportingEvidenceMatcher("../version.txt",
FileContentsVersionMatcher("cataloger-name", `(?m)my-version:(?P<version>abdd)`)),
Package: "some-binary",
},
expected: "",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s, err := directorysource.NewFromPath("test-fixtures")
require.NoError(t, err)
r, err := s.FileResolver(source.AllLayersScope)
require.NoError(t, err)
results, err := r.FilesByGlob(tt.classifier.FileGlob)
require.NoError(t, err)
for _, result := range results {
got, err := tt.classifier.EvidenceMatcher(tt.classifier, MatcherContext{
Resolver: r,
Location: result,
GetReader: func(ctx MatcherContext) (unionreader.UnionReader, error) {
return getReader(ctx)
},
})
require.NoError(t, err)
if tt.expected != "" {
require.NotEmpty(t, got)
require.Equal(t, tt.expected, got[0].Version)
} else {
require.Empty(t, got)
}
}
})
}
}
@@ -0,0 +1 @@
a binary
@@ -1 +1 @@
my-verison:1.8
my-version:1.8
@@ -635,6 +635,7 @@ func Test_PackageCataloger_Relationships(t *testing.T) {
"jinja2 @ 3.1.4 (.) [dependency-of] fastapi @ 0.111.0 (.)",
"jinja2 @ 3.1.4 (.) [dependency-of] starlette @ 0.37.2 (.)",
"markdown-it-py @ 3.0.0 (.) [dependency-of] rich @ 13.7.1 (.)",
"markupsafe @ 2.1.5 (.) [dependency-of] jinja2 @ 3.1.4 (.)", // MarkupSafe (mixed case) -> markupsafe
"mdurl @ 0.1.2 (.) [dependency-of] markdown-it-py @ 3.0.0 (.)",
"orjson @ 3.10.3 (.) [dependency-of] fastapi @ 0.111.0 (.)",
"pydantic @ 2.7.1 (.) [dependency-of] fastapi @ 0.111.0 (.)",
+4 -2
View File
@@ -74,8 +74,10 @@ func isDependencyForExtra(dep pkg.PythonPoetryLockDependencyEntry) bool {
}
func packageRef(name, extra string) string {
cleanExtra := strings.TrimSpace(extra)
cleanName := strings.TrimSpace(name)
// normalize both package name and extra to ensure case-insensitive matching per Python packaging spec
// https://packaging.python.org/en/latest/specifications/name-normalization/
cleanName := normalize(strings.TrimSpace(name))
cleanExtra := normalize(strings.TrimSpace(extra))
if cleanExtra == "" {
return cleanName
}
@@ -181,6 +181,30 @@ func Test_poetryLockDependencySpecifier(t *testing.T) {
},
},
},
{
name: "dependency names with mixed case should be normalized",
p: pkg.Package{
Name: "dj-rest-auth",
Metadata: pkg.PythonPoetryLockEntry{
Dependencies: []pkg.PythonPoetryLockDependencyEntry{
{
Name: "Django", // note: capital D
Version: ">=4.2,<6.0",
},
{
Name: "djangorestframework",
Version: ">=3.13.0",
},
},
},
},
want: dependency.Specification{
ProvidesRequires: dependency.ProvidesRequires{
Provides: []string{"dj-rest-auth"},
Requires: []string{"django", "djangorestframework"}, // "Django" should be normalized to "django"
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -195,6 +219,38 @@ func Test_poetryLockDependencySpecifier_againstPoetryLock(t *testing.T) {
fixture string
want []dependency.Specification
}{
{
name: "case-insensitive dependency resolution",
fixture: "test-fixtures/poetry/case-sensitivity/poetry.lock",
want: []dependency.Specification{
// packages are in the order they appear in the lock file
{
ProvidesRequires: dependency.ProvidesRequires{
Provides: []string{"django"},
Requires: []string{"asgiref", "sqlparse"},
},
},
{
ProvidesRequires: dependency.ProvidesRequires{
Provides: []string{"djangorestframework"},
Requires: []string{"django"},
},
},
{
// dj-rest-auth depends on Django (capital D) which should resolve to django
ProvidesRequires: dependency.ProvidesRequires{
Provides: []string{"dj-rest-auth"},
Requires: []string{"django", "djangorestframework"}, // Django normalized to django
},
Variants: []dependency.ProvidesRequires{
{
Provides: []string{"dj-rest-auth[with-social]"},
Requires: []string{"django-allauth"},
},
},
},
},
},
{
name: "simple dependencies with extras",
fixture: "test-fixtures/poetry/simple-deps/poetry.lock",
@@ -276,6 +332,64 @@ func Test_poetryLockDependencySpecifier_againstPoetryLock(t *testing.T) {
}
}
// Test_packageRef verifies that package references are normalized according to
// the Python Packaging specification for names and extras:
// https://packaging.python.org/en/latest/specifications/name-normalization/
func Test_packageRef(t *testing.T) {
tests := []struct {
name string
pkg string
extra string
want string
}{
{
name: "simple package name",
pkg: "requests",
want: "requests",
},
{
name: "package with extra",
pkg: "requests",
extra: "security",
want: "requests[security]",
},
{
name: "package name with mixed case",
pkg: "Django",
want: "django",
},
{
name: "package name with underscores",
pkg: "some_package",
want: "some-package",
},
{
name: "package name with mixed case and extra",
pkg: "Django",
extra: "argon2",
want: "django[argon2]",
},
{
name: "extra with mixed case",
pkg: "package",
extra: "Security",
want: "package[security]",
},
{
name: "both with mixed case and separators",
pkg: "Some_Package",
extra: "Dev_Extra",
want: "some-package[dev-extra]",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := packageRef(tt.pkg, tt.extra)
assert.Equal(t, tt.want, got)
})
}
}
func Test_extractPackageName(t *testing.T) {
tests := []struct {
name string
@@ -0,0 +1,55 @@
# This file is automatically @generated by Poetry and should not be edited manually.
[[package]]
name = "django"
version = "5.2.6"
description = "A high-level Python web framework"
optional = false
python-versions = ">=3.10"
groups = ["main"]
files = [
{file = "Django-5.2.6-py3-none-any.whl", hash = "sha256:example1"},
{file = "django-5.2.6.tar.gz", hash = "sha256:example2"},
]
[package.dependencies]
asgiref = ">=3.8.1,<4"
sqlparse = ">=0.3.1"
[[package]]
name = "djangorestframework"
version = "3.16.1"
description = "Web APIs for Django, made easy."
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "djangorestframework-3.16.1-py3-none-any.whl", hash = "sha256:example3"},
{file = "djangorestframework-3.16.1.tar.gz", hash = "sha256:example4"},
]
[package.dependencies]
django = ">=4.2"
[[package]]
name = "dj-rest-auth"
version = "7.0.1"
description = "Authentication and Registration in Django Rest Framework"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "dj-rest-auth-7.0.1.tar.gz", hash = "sha256:3f8c744cbcf05355ff4bcbef0c8a63645da38e29a0fdef3c3332d4aced52fb90"},
]
[package.dependencies]
Django = ">=4.2,<6.0"
djangorestframework = ">=3.13.0"
[package.extras]
with-social = ["django-allauth[socialaccount] (>=64.0.0)"]
[metadata]
lock-version = "2.1"
python-versions = "^3.10"
content-hash = "example"