Compare commits

...
67 Commits
Author SHA1 Message Date
Keith Zantow c33a51d3d8 chore: restore ci-check.sh script (#3218)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-09-10 15:19:05 -04:00
Laurent Goderre dbc4238f63 Add haskell binaries cataloger (#3078)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
2024-09-10 10:58:20 -04:00
anchore-actions-token-generator[bot]andwagoodman fce14fd537 chore(deps): update CPE dictionary index (#3206)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com>
2024-09-10 10:36:50 -04:00
dependabot[bot] 98bd4e99b6 chore(deps): bump golang.org/x/net from 0.28.0 to 0.29.0 (#3203)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.28.0 to 0.29.0.
- [Commits](https://github.com/golang/net/compare/v0.28.0...v0.29.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-10 10:35:43 -04:00
Laurent Goderre 9c2799e379 Add the Ocaml ecosystem (#3112)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
2024-09-10 10:35:18 -04:00
dependabot[bot] dafc6ad034 chore(deps): bump github.com/charmbracelet/bubbles from 0.19.0 to 0.20.0 (#3209)
Bumps [github.com/charmbracelet/bubbles](https://github.com/charmbracelet/bubbles) from 0.19.0 to 0.20.0.
- [Release notes](https://github.com/charmbracelet/bubbles/releases)
- [Changelog](https://github.com/charmbracelet/bubbles/blob/master/.goreleaser.yml)
- [Commits](https://github.com/charmbracelet/bubbles/compare/v0.19.0...v0.20.0)

---
updated-dependencies:
- dependency-name: github.com/charmbracelet/bubbles
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 16:28:01 -04:00
dependabot[bot] 16f89840fd chore(deps): bump modernc.org/sqlite from 1.32.0 to 1.33.0 (#3210)
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.32.0 to 1.33.0.
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.32.0...v1.33.0)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 16:27:52 -04:00
dependabot[bot] 2475f7f696 chore(deps): bump github.com/docker/docker (#3211)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 27.2.0+incompatible to 27.2.1+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v27.2.0...v27.2.1)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 16:27:43 -04:00
dependabot[bot] f735a428eb chore(deps): bump github.com/dave/jennifer from 1.7.0 to 1.7.1 (#3212)
Bumps [github.com/dave/jennifer](https://github.com/dave/jennifer) from 1.7.0 to 1.7.1.
- [Commits](https://github.com/dave/jennifer/compare/v1.7.0...v1.7.1)

---
updated-dependencies:
- dependency-name: github.com/dave/jennifer
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-09 16:27:33 -04:00
Alex Goodman ba7bf6b85e dont cleanup cache in forks (#3214)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-09-09 20:27:21 +00:00
Alex Goodman b153b1d594 less verbose java logging when non-fatal issues arise (#3208)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-09-09 15:27:59 +00:00
Alex Goodman 0a3f513f92 Slim down docker cache size (#3190)
* slim down docker cache size

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* remove old centos images

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* troubleshoot test failure

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix wget version ref

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* refactor caching mechanisms

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add cache cleanup steps

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* simplify deleting cache

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix first clone issue

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* add tool dep

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-09-09 11:15:13 -04:00
dependabot[bot] deabd4115a chore(deps): bump peter-evans/create-pull-request from 7.0.0 to 7.0.1 (#3196)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/4320041ed380b20e97d388d56a7fb4f9b8c20e79...8867c4aba1b742c39f8d0ba35429c2dfa4b6cb20)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-05 15:06:23 -04:00
dependabot[bot] ff0bae67bd chore(deps): bump golang.org/x/mod from 0.20.0 to 0.21.0 (#3197)
Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.20.0 to 0.21.0.
- [Commits](https://github.com/golang/mod/compare/v0.20.0...v0.21.0)

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-05 15:05:15 -04:00
witchcraze a343825685 fix: haproxy classifier for versions with -dev suffix (#3180)
Signed-off-by: witchcraze <witchcraze@gmail.com>
2024-09-05 14:52:19 -04:00
dependabot[bot] 7c96a10cbe chore(deps): bump github.com/Masterminds/sprig/v3 from 3.2.3 to 3.3.0 (#3177)
Bumps [github.com/Masterminds/sprig/v3](https://github.com/Masterminds/sprig) from 3.2.3 to 3.3.0.
- [Release notes](https://github.com/Masterminds/sprig/releases)
- [Changelog](https://github.com/Masterminds/sprig/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Masterminds/sprig/compare/v3.2.3...v3.3.0)

---
updated-dependencies:
- dependency-name: github.com/Masterminds/sprig/v3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-03 12:22:43 -04:00
anchore-actions-token-generator[bot]andwagoodman 8c690d000d chore(deps): update CPE dictionary index (#3183)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com>
2024-09-03 12:22:30 -04:00
dependabot[bot] 8ade391658 chore(deps): bump actions/upload-artifact from 4.3.6 to 4.4.0 (#3184)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.6 to 4.4.0.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/834a144ee995460fba8ed112a2fc961b36a5ec5a...50769540e7f4bd5e21e526ee35c689e35e0d6874)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-03 12:22:16 -04:00
dependabot[bot] e299a95120 chore(deps): bump peter-evans/create-pull-request from 6.1.0 to 7.0.0 (#3187)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.1.0 to 7.0.0.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/c5a7806660adbe173f04e3e038b0ccdcd758773c...4320041ed380b20e97d388d56a7fb4f9b8c20e79)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-03 12:22:07 -04:00
Mikail f2caf45695 fix: properly decode SPDX license expressions in CycloneDX format (#3175)
Signed-off-by: Mikail Kocak <mikail-gh@pm.me>
2024-08-29 11:05:43 -04:00
dependabot[bot] 731fc77641 chore(deps): bump github.com/docker/docker (#3168) 2024-08-29 14:16:50 +00:00
dependabot[bot] 3499d92c6d chore(deps): bump github.com/charmbracelet/bubbletea (#3171) 2024-08-29 14:16:43 +00:00
dependabot[bot] 19d2735aff chore(deps): bump github/codeql-action from 3.26.5 to 3.26.6 (#3173) 2024-08-29 14:16:34 +00:00
Keith Zantow 11d77b4a94 fix: cycles resolving relative path parent poms with parent-defined variables (#3170)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-08-28 15:12:13 -04:00
Weston Steimel 2c25f81b68 fix: improve generated cpes for binaries with existing classifiers (#3169)
The existing syft binary classifiers already specify any known CPEs for
the defined binary; however, sometimes these end up getting suppressed
(such as when there are ELF notes extracted) and the CPE generator ends
up being used instead.  This adds enough detail to at least ensure the
correct ones get appended to the generation list for the currently
covered classifiers.

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-08-28 16:46:35 +01:00
GGMU 04e3371cce fix: add log time of task (#3105)
Signed-off-by: tomersein <tomersein@gmail.com>
2024-08-28 11:04:26 -04:00
Weston Steimel 5ab43bafec fix: improve known CPEs and set NVD as source for all current binary classifiers (#3167)
Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-08-27 17:36:34 +01:00
Alex Goodman e9a8c27be1 respond to authoratative CPEs from catalogers (#3166)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-08-27 10:26:35 -04:00
Alex Goodman 4ee6c179f8 set cataloger names within package cataloger task (#3165)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-08-27 09:23:43 -04:00
Weston Steimel 99be365f62 fix: use official CPE for curl binary cataloger (#3164)
The official CPE for curl is `cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*`

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-08-27 14:03:19 +01:00
anchore-actions-token-generator[bot]andspiffcs cf9bb13f2b chore(deps): update tools to latest versions (#3160)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-08-26 10:07:59 -04:00
anchore-actions-token-generator[bot]andwagoodman 0cd6185716 chore(deps): update CPE dictionary index (#3161)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com>
2024-08-26 10:07:44 -04:00
dependabot[bot] 6549ec9831 chore(deps): bump github/codeql-action from 3.26.4 to 3.26.5 (#3162)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.4 to 3.26.5.
- [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/f0f3afee809481da311ca3a6ff1ff51d81dbeb24...2c779ab0d087cd7fe7b826087247c2c81f27bfa6)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-26 10:07:18 -04:00
Alex Goodman b6b5c8e308 fix ELF package correlations (#3151) 2024-08-26 08:44:39 -04:00
anchore-actions-token-generator[bot] dad253785e chore(deps): update tools to latest versions (#3144) 2024-08-23 14:42:12 -04:00
KrysGor cff9d494df feat: detect curl binaries (#3146) 2024-08-23 14:41:08 -04:00
dependabot[bot] 9ab3de1819 chore(deps): bump anchore/sbom-action from 0.17.1 to 0.17.2 (#3155)
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.17.1 to 0.17.2.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/ab9d16d4b419c9d1a02df5213fa0ebe965ca5a57...61119d458adab75f756bc0b9e4bde25725f86a7a)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 13:52:58 -04:00
dependabot[bot] 6f0230879a chore(deps): bump github/codeql-action from 3.26.3 to 3.26.4 (#3154)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.3 to 3.26.4.
- [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/883d8588e56d1753a8a58c1c86e88976f0c23449...f0f3afee809481da311ca3a6ff1ff51d81dbeb24)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 13:52:48 -04:00
anchore-actions-token-generator[bot]andkzantow 691f34ce27 chore(deps): update stereoscope to e6d086e8bef5fab4fcfbd60c9a759c4cb229decf (#3152)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: kzantow <3009477+kzantow@users.noreply.github.com>
2024-08-22 13:52:34 -04:00
dependabot[bot] ac977246c9 chore(deps): bump github.com/charmbracelet/bubbles from 0.18.0 to 0.19.0 (#3148)
Bumps [github.com/charmbracelet/bubbles](https://github.com/charmbracelet/bubbles) from 0.18.0 to 0.19.0.
- [Release notes](https://github.com/charmbracelet/bubbles/releases)
- [Changelog](https://github.com/charmbracelet/bubbles/blob/master/.goreleaser.yml)
- [Commits](https://github.com/charmbracelet/bubbles/compare/v0.18.0...v0.19.0)

---
updated-dependencies:
- dependency-name: github.com/charmbracelet/bubbles
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 13:52:06 -04:00
dependabot[bot] 78d48b4209 chore(deps): bump github.com/charmbracelet/lipgloss (#3147)
Bumps [github.com/charmbracelet/lipgloss](https://github.com/charmbracelet/lipgloss) from 0.12.1 to 0.13.0.
- [Release notes](https://github.com/charmbracelet/lipgloss/releases)
- [Changelog](https://github.com/charmbracelet/lipgloss/blob/master/.goreleaser.yml)
- [Commits](https://github.com/charmbracelet/lipgloss/compare/v0.12.1...v0.13.0)

---
updated-dependencies:
- dependency-name: github.com/charmbracelet/lipgloss
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 13:51:57 -04:00
dependabot[bot] bd80eeafac chore(deps): bump github.com/anchore/stereoscope (#3153)
Bumps [github.com/anchore/stereoscope](https://github.com/anchore/stereoscope) from 0.0.3-0.20240725180315-50ce3be7aa1f to 0.0.3.
- [Release notes](https://github.com/anchore/stereoscope/releases)
- [Changelog](https://github.com/anchore/stereoscope/blob/main/.goreleaser.yaml)
- [Commits](https://github.com/anchore/stereoscope/commits/v0.0.3)

---
updated-dependencies:
- dependency-name: github.com/anchore/stereoscope
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-22 13:51:50 -04:00
Keith Zantow 73b9d5aa42 fix: mysql 8.0.3x binary detection (#3142)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-08-21 09:48:28 -04:00
dependabot[bot] f786233e97 chore(deps): bump github/codeql-action from 3.26.2 to 3.26.3 (#3139)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.2 to 3.26.3.
- [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/429e1977040da7a23b6822b13c129cd1ba93dbb2...883d8588e56d1753a8a58c1c86e88976f0c23449)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-20 23:04:58 +00:00
Keith Zantow 95b4a88256 fix: logging for remote network calls (#3140)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-08-20 11:45:33 -04:00
anchore-actions-token-generator[bot]andwagoodman 511cc9c2d5 chore(deps): update CPE dictionary index (#3135)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com>
2024-08-19 12:49:43 -04:00
dependabot[bot] 360983f75b chore(deps): bump github.com/charmbracelet/bubbletea (#3137)
Bumps [github.com/charmbracelet/bubbletea](https://github.com/charmbracelet/bubbletea) from 0.26.6 to 0.27.0.
- [Release notes](https://github.com/charmbracelet/bubbletea/releases)
- [Changelog](https://github.com/charmbracelet/bubbletea/blob/master/.goreleaser.yml)
- [Commits](https://github.com/charmbracelet/bubbletea/compare/v0.26.6...v0.27.0)

---
updated-dependencies:
- dependency-name: github.com/charmbracelet/bubbletea
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-19 12:48:24 -04:00
anchore-actions-token-generator[bot]andspiffcs 4b7ae0ed3b chore(deps): update tools to latest versions (#3121)
* chore(deps): update tools to latest versions

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore: update code to reflect new linter settings for error messages

Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>

---------

Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-08-16 17:56:36 +00:00
dependabot[bot] 4ff60ee837 chore(deps): bump github.com/docker/docker (#3123)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 27.1.1+incompatible to 27.1.2+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v27.1.1...v27.1.2)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-15 13:50:51 -04:00
dependabot[bot] 965000dcbb chore(deps): bump anchore/sbom-action from 0.17.0 to 0.17.1 (#3124)
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.17.0 to 0.17.1.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/d94f46e13c6c62f59525ac9a1e147a99dc0b9bf5...ab9d16d4b419c9d1a02df5213fa0ebe965ca5a57)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-15 13:16:47 -04:00
dependabot[bot] a447884084 chore(deps): bump github/codeql-action from 3.26.0 to 3.26.2 (#3129)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.0 to 3.26.2.
- [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/eb055d739abdc2e8de2e5f4ba1a8b246daa779aa...429e1977040da7a23b6822b13c129cd1ba93dbb2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-15 13:16:39 -04:00
Lucas Rodriguez cd3b828905 fix: add nil check to CycloneDX toBomProperties (#3119)
Signed-off-by: Lucas Rodriguez <lucas.rodriguez9616@gmail.com>
2024-08-13 16:02:15 -04:00
Lukas Voetmand 3161e1847e fix: read CycloneDX BOM components from metadata (#3092)
Signed-off-by: dervoeti <lukas.voetmand@stackable.tech>
2024-08-12 16:37:23 -04:00
Weston Steimel df1e5b57fe fix: improve groupid extraction for Jenkins plugins (#2815)
* fix: improve groupid extraction for Jenkins plugins

Consider the `Group-Id` java manifest property as this is typically set
for Jenkins plugins if there is no pom file

Signed-off-by: Weston Steimel <commits@weston.slmail.me>

* test: update java purl integration test image

Signed-off-by: Weston Steimel <commits@weston.slmail.me>

---------

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-08-12 13:01:44 -04:00
d2b33f1acb chore(deps): update CPE dictionary index (#3116)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com>
Co-authored-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
2024-08-12 16:57:47 +00:00
GGMU 91cf066db6 support .kar files (#3113)
* add kar

Signed-off-by: tomersein <tomersein@gmail.com>
2024-08-12 12:10:03 -04:00
luozexuan c19cf626ab chore: fix some comments (#3114)
Signed-off-by: luozexuan <fetchcode@139.com>
2024-08-12 12:08:04 -04:00
Keith Zantow cf85450e08 chore: fix failing python relationship test (#3117)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-08-12 12:07:47 -04:00
Alan Pope 49d4e32241 update-slack-to-discourse (#3111)
Signed-off-by: Alan Pope <alan@popey.com>
2024-08-12 11:49:10 +01:00
Weston Steimel 19cc664cf8 test: increase java purl generation test coverage (#3110)
ensures correct package url generation for more java packages now that
syft has more deterministic results per https://github.com/anchore/syft/pull/3085

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-08-09 10:14:10 +00:00
dependabot[bot] 64a9ecbf7a chore(deps): bump modernc.org/sqlite from 1.31.1 to 1.32.0 (#3106)
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.31.1 to 1.32.0.
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.31.1...v1.32.0)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-08 15:49:45 -04:00
dependabot[bot] 6267d69930 chore(deps): bump sigstore/cosign-installer from 3.5.0 to 3.6.0 (#3107)
Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.5.0 to 3.6.0.
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/v3.5.0...v3.6.0)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-08 15:49:37 -04:00
anchore-actions-token-generator[bot]andspiffcs 1fb47d908e chore(deps): update tools to latest versions (#3099)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-08-07 14:26:05 -04:00
dependabot[bot] 2339743c8c chore(deps): bump github/codeql-action from 3.25.15 to 3.26.0 (#3101)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.15 to 3.26.0.
- [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/afb54ba388a7dca6ecae48f608c4ff05ff4cc77a...eb055d739abdc2e8de2e5f4ba1a8b246daa779aa)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-07 14:25:52 -04:00
dependabot[bot] 9031592649 chore(deps): bump actions/upload-artifact from 4.3.5 to 4.3.6 (#3102)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.5 to 4.3.6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/89ef406dd8d7e03cfd12d9e0a4a378f454709029...834a144ee995460fba8ed112a2fc961b36a5ec5a)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-07 14:25:44 -04:00
dependabot[bot] 47d192d79b chore(deps): bump github.com/google/go-containerregistry (#3103)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.20.1 to 0.20.2.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Changelog](https://github.com/google/go-containerregistry/blob/main/.goreleaser.yml)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.20.1...v0.20.2)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-07 14:25:36 -04:00
dependabot[bot] 040b683da8 chore(deps): bump golang.org/x/net from 0.27.0 to 0.28.0 (#3104)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.27.0 to 0.28.0.
- [Commits](https://github.com/golang/net/compare/v0.27.0...v0.28.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-07 14:25:28 -04:00
183 changed files with 6529 additions and 1071 deletions
+21 -5
View File
@@ -26,7 +26,7 @@ tools:
# used for linting
- name: golangci-lint
version:
want: v1.59.1
want: v1.60.3
method: github-release
with:
repo: golangci/golangci-lint
@@ -34,7 +34,7 @@ tools:
# used for showing the changelog at release
- name: glow
version:
want: v1.5.1
want: v2.0.0
method: github-release
with:
repo: charmbracelet/glow
@@ -42,7 +42,7 @@ tools:
# used for signing the checksums file at release
- name: cosign
version:
want: v2.3.0
want: v2.4.0
method: github-release
with:
repo: sigstore/cosign
@@ -58,7 +58,7 @@ tools:
# used to release all artifacts
- name: goreleaser
version:
want: v2.1.0
want: v2.2.0
method: github-release
with:
repo: goreleaser/goreleaser
@@ -111,7 +111,23 @@ tools:
# used for triggering a release
- name: gh
version:
want: v2.54.0
want: v2.55.0
method: github-release
with:
repo: cli/cli
# used to upload test fixture cache
- name: oras
version:
want: v1.2.0
method: github-release
with:
repo: oras-project/oras
# used to upload test fixture cache
- name: yq
version:
want: v4.44.3
method: github-release
with:
repo: mikefarah/yq
+3 -3
View File
@@ -1,6 +1,6 @@
contact_links:
- name: Join the Slack community 💬
# link to our community Slack registration page
url: https://anchore.com/slack
- name: Join our Discourse community 💬
# link to our community Discourse site
url: https://anchore.com/discourse
about: 'Come chat with us! Ask for help, join our software development efforts, or just give us feedback!'
+14 -9
View File
@@ -13,16 +13,15 @@ inputs:
cache-key-prefix:
description: "Prefix all cache keys with this value"
required: true
default: "1ac8281053"
compute-fingerprints:
description: "Compute test fixture fingerprints"
default: "181053ac82"
download-test-fixture-cache:
description: "Download test fixture cache from OCI and github actions"
required: true
default: "true"
default: "false"
bootstrap-apt-packages:
description: "Space delimited list of tools to install via apt"
default: "libxml2-utils"
runs:
using: "composite"
steps:
@@ -54,8 +53,14 @@ runs:
run: |
DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y ${{ inputs.bootstrap-apt-packages }}
- name: Create all cache fingerprints
if: inputs.compute-fingerprints == 'true'
shell: bash
run: make fingerprints
- name: Restore ORAS cache from github actions
if: inputs.download-test-fixture-cache == 'true'
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
with:
path: ${{ github.workspace }}/.tmp/oras-cache
key: ${{ inputs.cache-key-prefix }}-oras-cache
- name: Download test fixture cache
if: inputs.download-test-fixture-cache == 'true'
shell: bash
run: make download-test-fixture-cache
Executable → Regular
View File
+135
View File
@@ -0,0 +1,135 @@
#!/usr/bin/env python3
from __future__ import annotations
import os
import glob
import sys
import json
import hashlib
IGNORED_PREFIXES = []
def find_fingerprints_and_check_dirs(base_dir):
all_fingerprints = set(glob.glob(os.path.join(base_dir, '**', 'test*', '**', '*.fingerprint'), recursive=True))
all_fingerprints = {os.path.relpath(fp) for fp in all_fingerprints
if not any(fp.startswith(prefix) for prefix in IGNORED_PREFIXES)}
if not all_fingerprints:
show("No .fingerprint files or cache directories found.")
exit(1)
missing_content = []
valid_paths = set()
fingerprint_contents = []
for fingerprint in all_fingerprints:
path = fingerprint.replace('.fingerprint', '')
if not os.path.exists(path):
missing_content.append(path)
continue
if not os.path.isdir(path):
valid_paths.add(path)
continue
if os.listdir(path):
valid_paths.add(path)
else:
missing_content.append(path)
with open(fingerprint, 'r') as f:
content = f.read().strip()
fingerprint_contents.append((fingerprint, content))
return sorted(valid_paths), missing_content, fingerprint_contents
def parse_fingerprint_contents(fingerprint_content):
input_map = {}
for line in fingerprint_content.splitlines():
digest, path = line.split()
input_map[path] = digest
return input_map
def calculate_sha256(fingerprint_contents):
sorted_fingerprint_contents = sorted(fingerprint_contents, key=lambda x: x[0])
concatenated_contents = ''.join(content for _, content in sorted_fingerprint_contents)
sha256_hash = hashlib.sha256(concatenated_contents.encode()).hexdigest()
return sha256_hash
def calculate_file_sha256(file_path):
sha256_hash = hashlib.sha256()
with open(file_path, 'rb') as f:
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
def show(*s: str):
print(*s, file=sys.stderr)
def main(file_path: str | None):
base_dir = '.'
valid_paths, missing_content, fingerprint_contents = find_fingerprints_and_check_dirs(base_dir)
if missing_content:
show("The following paths are missing or have no content, but have corresponding .fingerprint files:")
for path in sorted(missing_content):
show(f"- {path}")
show("Please ensure these paths exist and have content if they are directories.")
exit(1)
sha256_hash = calculate_sha256(fingerprint_contents)
paths_with_digests = []
for path in sorted(valid_paths):
fingerprint_file = f"{path}.fingerprint"
try:
if os.path.exists(fingerprint_file):
file_digest = calculate_file_sha256(fingerprint_file)
# Parse the fingerprint file to get the digest/path tuples
with open(fingerprint_file, 'r') as f:
fingerprint_content = f.read().strip()
input_map = parse_fingerprint_contents(fingerprint_content)
paths_with_digests.append({
"path": path,
"digest": file_digest,
"input": input_map
})
except Exception as e:
show(f"Error processing {fingerprint_file}: {e}")
raise e
output = {
"digest": sha256_hash,
"paths": paths_with_digests
}
content = json.dumps(output, indent=2, sort_keys=True)
if file_path:
with open(file_path, 'w') as f:
f.write(content)
print(content)
if __name__ == "__main__":
file_path = None
if len(sys.argv) > 1:
file_path = sys.argv[1]
main(file_path)
+70
View File
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
import os
import subprocess
import hashlib
BOLD = '\033[1m'
YELLOW = '\033[0;33m'
RESET = '\033[0m'
def print_message(message):
print(f"{YELLOW}{message}{RESET}")
def sha256sum(filepath):
h = hashlib.sha256()
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(4096), b""):
h.update(chunk)
return h.hexdigest()
def is_git_tracked_or_untracked(directory):
"""Returns a sorted list of files in the directory that are tracked or not ignored by Git."""
result = subprocess.run(
["git", "ls-files", "--cached", "--others", "--exclude-standard"],
cwd=directory,
stdout=subprocess.PIPE,
text=True
)
return sorted(result.stdout.strip().splitlines())
def find_test_fixture_dirs_with_images(base_dir):
"""Find directories that contain 'test-fixtures' and at least one 'image-*' directory."""
for root, dirs, files in os.walk(base_dir):
if 'test-fixtures' in root:
image_dirs = [d for d in dirs if d.startswith('image-')]
if image_dirs:
yield os.path.realpath(root)
def generate_fingerprints():
print_message("creating fingerprint files for docker fixtures...")
for test_fixture_dir in find_test_fixture_dirs_with_images('.'):
cache_fingerprint_path = os.path.join(test_fixture_dir, 'cache.fingerprint')
with open(cache_fingerprint_path, 'w') as fingerprint_file:
for image_dir in find_image_dirs(test_fixture_dir):
for file in is_git_tracked_or_untracked(image_dir):
file_path = os.path.join(image_dir, file)
checksum = sha256sum(file_path)
path_from_fixture_dir = os.path.relpath(file_path, test_fixture_dir)
fingerprint_file.write(f"{checksum} {path_from_fixture_dir}\n")
def find_image_dirs(test_fixture_dir):
"""Find all 'image-*' directories inside a given test-fixture directory."""
result = []
for root, dirs, files in os.walk(test_fixture_dir):
for dir_name in dirs:
if dir_name.startswith('image-'):
result.append(os.path.join(root, dir_name))
return sorted(result)
if __name__ == "__main__":
generate_fingerprints()
Regular → Executable
+2
View File
@@ -1,3 +1,5 @@
#!/usr/bin/env python3
from __future__ import annotations
import sys
Regular → Executable
+2
View File
@@ -1,3 +1,5 @@
#!/usr/bin/env python3
import unittest
from unittest.mock import patch
import subprocess
+1 -1
View File
@@ -39,7 +39,7 @@ jobs:
OUTPUT="${OUTPUT//$'\r'/'%0D'}" # URL encode all '\r' characters
echo "result=$OUTPUT" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@89ef406dd8d7e03cfd12d9e0a4a378f454709029 # v4.3.5
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
with:
name: benchmark-test-results
path: test/results/**/*
+3 -3
View File
@@ -45,7 +45,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15
uses: github/codeql-action/init@4dd16135b69a43b6c8efb853346f8437d92d3c93 #v3.26.6
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -56,7 +56,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@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15
uses: github/codeql-action/autobuild@4dd16135b69a43b6c8efb853346f8437d92d3c93 #v3.26.6
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -70,4 +70,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15
uses: github/codeql-action/analyze@4dd16135b69a43b6c8efb853346f8437d92d3c93 #v3.26.6
+1 -1
View File
@@ -1,4 +1,4 @@
name: "Release"
name: "Release: version file"
on:
+1 -1
View File
@@ -148,7 +148,7 @@ jobs:
# for updating brew formula in anchore/homebrew-syft
GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }}
- uses: anchore/sbom-action@d94f46e13c6c62f59525ac9a1e147a99dc0b9bf5 #v0.17.0
- uses: anchore/sbom-action@61119d458adab75f756bc0b9e4bde25725f86a7a #v0.17.2
continue-on-error: true
with:
artifact-name: sbom.spdx.json
@@ -0,0 +1,39 @@
name: "Test fixture cache: publish"
on:
workflow_dispatch:
schedule:
# run nightly at 4AM UTC
- cron: "0 4 * * *"
permissions:
contents: read
jobs:
Publish:
name: "Publish test fixture image cache"
# we use this runner to get enough storage space for docker images and fixture cache
runs-on: ubuntu-22.04-4core-16gb
permissions:
packages: write
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
# we want to rebuild the cache with no previous state
download-test-fixture-cache: false
- name: Run all tests
run: make test
env:
# we want to rebuild the cache with no previous state
DOWNLOAD_TEST_FIXTURE_CACHE: "false"
- name: Login to GitHub Container Registry (ORAS)
run: echo "${{ secrets.GITHUB_TOKEN }}" | .tool/oras login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Publish test fixture cache
run: make upload-test-fixture-cache
+1 -2
View File
@@ -19,7 +19,6 @@ jobs:
uses: ./.github/actions/bootstrap
with:
bootstrap-apt-packages: ""
compute-fingerprints: "false"
go-dependencies: false
- name: "Update tool versions"
@@ -50,7 +49,7 @@ jobs:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c #v6.1.0
- uses: peter-evans/create-pull-request@8867c4aba1b742c39f8d0ba35429c2dfa4b6cb20 #v7.0.1
with:
signoff: true
delete-branch: true
@@ -33,7 +33,7 @@ jobs:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c #v6.1.0
- uses: peter-evans/create-pull-request@8867c4aba1b742c39f8d0ba35429c2dfa4b6cb20 #v7.0.1
with:
signoff: true
delete-branch: true
@@ -44,7 +44,7 @@ jobs:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c #v6.1.0
- uses: peter-evans/create-pull-request@8867c4aba1b742c39f8d0ba35429c2dfa4b6cb20 #v7.0.1
with:
signoff: true
delete-branch: true
+27 -68
View File
@@ -35,48 +35,8 @@ jobs:
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Restore file executable test-fixture cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/file/cataloger/executable/test-fixtures/elf/bin
key: ${{ runner.os }}-unit-file-executable-elf-cache-${{ hashFiles( 'syft/file/cataloger/executable/test-fixtures/elf/cache.fingerprint' ) }}
- name: Restore file executable shared-info test-fixture cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/file/cataloger/executable/test-fixtures/shared-info/bin
key: ${{ runner.os }}-unit-file-executable-shared-info-cache-${{ hashFiles( 'syft/file/cataloger/executable/test-fixtures/shared-info/cache.fingerprint' ) }}
- name: Restore Java test-fixture cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/java/test-fixtures/java-builds/packages
key: ${{ runner.os }}-unit-java-cache-${{ hashFiles( 'syft/pkg/cataloger/java/test-fixtures/java-builds/cache.fingerprint' ) }}
- name: Restore RPM test-fixture cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/redhat/test-fixtures/rpms
key: ${{ runner.os }}-unit-rpm-cache-${{ hashFiles( 'syft/pkg/cataloger/redhat/test-fixtures/rpms.fingerprint' ) }}
- name: Restore go binary test-fixture cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/golang/test-fixtures/archs/binaries
key: ${{ runner.os }}-unit-go-binaries-cache-${{ hashFiles( 'syft/pkg/cataloger/golang/test-fixtures/archs/binaries.fingerprint' ) }}
- name: Restore binary cataloger test-fixture cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/binary/test-fixtures/classifiers/bin
key: ${{ runner.os }}-unit-binary-cataloger-cache-${{ hashFiles( 'syft/pkg/cataloger/binary/test-fixtures/cache.fingerprint' ) }}
- name: Restore Kernel test-fixture cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/kernel/test-fixtures/cache
key: ${{ runner.os }}-unit-kernel-cache-${{ hashFiles( 'syft/pkg/cataloger/kernel/test-fixtures/cache.fingerprint' ) }}
download-test-fixture-cache: true
- name: Run unit tests
run: make unit
@@ -91,16 +51,12 @@ jobs:
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
download-test-fixture-cache: true
- name: Validate syft output against the CycloneDX schema
run: make validate-cyclonedx-schema
- name: Restore integration test cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: ${{ github.workspace }}/cmd/syft/internal/test/integration/test-fixtures/cache
key: ${{ runner.os }}-integration-test-cache-${{ hashFiles('/cmd/syft/internal/test/integration/test-fixtures/cache.fingerprint') }}
- name: Run integration tests
run: make integration
@@ -143,6 +99,8 @@ jobs:
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
download-test-fixture-cache: true
- name: Download snapshot build
id: snapshot-cache
@@ -162,13 +120,6 @@ jobs:
- name: Run comparison tests (Linux)
run: make compare-linux
- name: Restore install.sh test image cache
id: install-test-image-cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: ${{ github.workspace }}/test/install/cache
key: ${{ runner.os }}-install-test-image-cache-${{ hashFiles('test/install/cache.fingerprint') }}
- name: Load test image cache
if: steps.install-test-image-cache.outputs.cache-hit == 'true'
run: make install-test-cache-load
@@ -188,7 +139,7 @@ jobs:
runs-on: macos-latest
steps:
- name: Install Cosign
uses: sigstore/cosign-installer@v3.5.0
uses: sigstore/cosign-installer@v3.6.0
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
@@ -196,8 +147,8 @@ jobs:
uses: ./.github/actions/bootstrap
with:
bootstrap-apt-packages: ""
compute-fingerprints: "false"
go-dependencies: false
download-test-fixture-cache: true
- name: Download snapshot build
id: snapshot-cache
@@ -214,13 +165,6 @@ jobs:
if: steps.snapshot-cache.outputs.cache-hit != 'true'
run: echo "unable to download snapshots from previous job" && false
- name: Restore docker image cache for compare testing
id: mac-compare-testing-cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: image.tar
key: ${{ runner.os }}-${{ hashFiles('test/compare/mac.sh') }}
- name: Run comparison tests (Mac)
run: make compare-mac
@@ -238,12 +182,8 @@ jobs:
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Restore CLI test-fixture cache
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: ${{ github.workspace }}/test/cli/test-fixtures/cache
key: ${{ runner.os }}-cli-test-cache-${{ hashFiles('test/cli/test-fixtures/cache.fingerprint') }}
download-test-fixture-cache: true
- name: Download snapshot build
id: snapshot-cache
@@ -262,3 +202,22 @@ jobs:
- name: Run CLI Tests (Linux)
run: make cli
Cleanup-Cache:
name: "Cleanup snapshot cache"
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-20.04
permissions:
actions: write
needs:
- Acceptance-Linux
- Acceptance-Mac
- Cli-Linux
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
- name: Delete snapshot cache
run: gh cache delete "snapshot-build-${{ github.run_id }}"
env:
GH_TOKEN: ${{ github.token }}
+2 -2
View File
@@ -12,10 +12,10 @@ linters:
enable:
- asciicheck
- bodyclose
- copyloopvar
- dogsled
- dupl
- errcheck
- exportloopref
- funlen
- gocognit
- goconst
@@ -30,6 +30,7 @@ linters:
- ineffassign
- misspell
- nakedret
- nolintlint
- revive
- staticcheck
- stylecheck
@@ -80,7 +81,6 @@ run:
# - lll # without a way to specify per-line exception cases, this is not usable
# - maligned # this is an excellent linter, but tricky to optimize and we are not sensitive to memory layout optimizations
# - nestif
# - nolintlint # as of go1.19 this conflicts with the behavior of gofmt, which is a deal-breaker (lint-fix will still fail when running lint)
# - prealloc # following this rule isn't consistently a good idea, as it sometimes forces unnecessary allocations that result in less idiomatic code
# - rowserrcheck # not in a repo with sql, so this is not useful
# - scopelint # deprecated
+2 -2
View File
@@ -83,7 +83,7 @@ Syft's core library is implemented in the `syft` package and subpackages, where
- the `syft` package contains a single function that can take a `source.Source` object and catalog it, producing an `sbom.SBOM` object
- the `syft/format` package contains the ability to encode and decode SBOMs to and from different SBOM formats (such as SPDX and CycloneDX)
The `cmd` pacakge at the highest level execution flow wires up [`spf13/cobra`](https://github.com/spf13/cobra) commands for execution in the main application:
The `cmd` package at the highest level execution flow wires up [`spf13/cobra`](https://github.com/spf13/cobra) commands for execution in the main application:
```mermaid
sequenceDiagram
participant main as cmd/syft/main
@@ -212,7 +212,7 @@ Finally, here is an example of where the package construction is done within the
- [The APK package constructor itself](https://github.com/anchore/syft/tree/v0.70.0/syft/pkg/cataloger/apkdb/package.go#L12-L27)
Interested in building a new cataloger? Checkout the [list of issues with the `new-cataloger` label](https://github.com/anchore/syft/issues?q=is%3Aopen+is%3Aissue+label%3Anew-cataloger+no%3Aassignee)!
If you have questions about implementing a cataloger feel free to file an issue or reach out to us [on slack](https://anchore.com/slack)!
If you have questions about implementing a cataloger feel free to file an issue or reach out to us [on discourse](https://anchore.com/discourse)!
#### Searching for files
+2 -2
View File
@@ -25,8 +25,8 @@ ci-bootstrap-go:
# this is a bootstrapping catch-all, where if the target doesn't exist, we'll ensure the tools are installed and then try again
%:
make $(TASK)
$(TASK) $@
@make --silent $(TASK)
@$(TASK) $@
## Shim targets #################################
+1 -1
View File
@@ -12,7 +12,7 @@
&nbsp;<a href="https://github.com/anchore/syft/releases/latest" target="_blank"><img alt="GitHub release" src="https://img.shields.io/github/release/anchore/syft.svg"></a>&nbsp;
&nbsp;<a href="https://github.com/anchore/syft" target="_blank"><img alt="GitHub go.mod Go version" src="https://img.shields.io/github/go-mod/go-version/anchore/syft.svg"></a>&nbsp;
&nbsp;<a href="" target="_blank"><img alt="License: Apache-2.0" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a>&nbsp;
&nbsp;<a href="https://anchore.com/slack" target="_blank"><img alt="Slack" src="https://img.shields.io/badge/Slack-Join-blue?logo=slack"></a>&nbsp;
&nbsp;<a href="https://anchore.com/discourse" target="_blank"><img alt="Join our Discourse" src="https://img.shields.io/badge/Discourse-Join-blue?logo=discourse"/></a>&nbsp;
</p>
![syft-demo](https://user-images.githubusercontent.com/590471/90277200-2a253000-de33-11ea-893f-32c219eea11a.gif)
+212 -53
View File
@@ -4,9 +4,19 @@ vars:
OWNER: anchore
PROJECT: syft
CACHE_IMAGE: ghcr.io/{{ .OWNER }}/{{ .PROJECT }}/test-fixture-cache:latest
# static file dirs
TOOL_DIR: .tool
TMP_DIR: .tmp
ORAS_CACHE: "{{ .TMP_DIR }}/oras-cache"
CACHE_PATHS_FILE: "{{ .TMP_DIR }}/cache_paths.json"
LAST_CACHE_PULL_FILE: "{{ .TMP_DIR }}/last_cache_paths.json"
# TOOLS
ORAS: "{{ .TOOL_DIR }}/oras"
YQ: "{{ .TOOL_DIR }}/yq"
TASK: "{{ .TOOL_DIR }}/task"
# used for changelog generation
CHANGELOG: CHANGELOG.md
@@ -33,6 +43,9 @@ vars:
COMPARE_DIR: ./test/compare
COMPARE_TEST_IMAGE: centos:8.2.2004
env:
GNUMAKEFLAGS: '--no-print-directory'
tasks:
## High-level tasks #################################
@@ -65,6 +78,7 @@ tasks:
- task: benchmark
- task: test-utils
- task: cli
- task: check-docker-cache
## Bootstrap tasks #################################
@@ -212,10 +226,6 @@ tasks:
# that the cache being restored with the correct binary will be rebuilt since the timestamps
# and local checksums will not line up.
deps: [tools, snapshot]
sources:
- "{{ .SNAPSHOT_BIN }}"
- ./test/cli/**
- ./**/*.go
cmds:
- cmd: "echo 'testing binary: {{ .SNAPSHOT_BIN }}'"
silent: true
@@ -229,18 +239,14 @@ tasks:
test-utils:
desc: Run tests for pipeline utils
sources:
- .github/scripts/labeler*.py
cmds:
- cmd: python .github/scripts/labeler_test.py
- cmd: .github/scripts/labeler_test.py
## Benchmark test targets #################################
benchmark:
deps: [tmpdir]
sources:
- ./**/*.go
generates:
- "{{ .TMP_DIR }}/benchmark-main.txt"
cmds:
@@ -253,8 +259,6 @@ tasks:
show-benchstat:
deps: [benchmark, tmpdir]
sources:
- "{{ .TMP_DIR }}/benchstat.txt"
cmds:
- cmd: "cat {{ .TMP_DIR }}/benchstat.txt"
silent: true
@@ -263,56 +267,188 @@ tasks:
## Test-fixture-related targets #################################
fingerprints:
desc: Generate test fixture fingerprints
desc: Generate fingerprints for all non-docker test fixture
silent: true
# this will look for `test-fixtures/Makefile` and invoke the `fingerprint` target to calculate all cache input fingerprint files
generates:
- cmd/syft/internal/test/integration/test-fixtures/cache.fingerprint
- syft/file/cataloger/executable/test-fixtures/elf/cache.fingerprint
- syft/file/cataloger/executable/test-fixtures/shared-info/cache.fingerprint
- syft/pkg/cataloger/binary/test-fixtures/cache.fingerprint
- syft/pkg/cataloger/java/test-fixtures/java-builds/cache.fingerprint
- syft/pkg/cataloger/golang/test-fixtures/archs/binaries.fingerprint
- syft/pkg/cataloger/redhat/test-fixtures/rpms.fingerprint
- syft/pkg/cataloger/kernel/test-fixtures/cache.fingerprint
- '**/test-fixtures/**/*.fingerprint'
- test/install/cache.fingerprint
- test/cli/test-fixtures/cache.fingerprint
cmds:
# for EXECUTABLE unit test fixtures
- "cd syft/file/cataloger/executable/test-fixtures/elf && make cache.fingerprint"
- "cd syft/file/cataloger/executable/test-fixtures/shared-info && make cache.fingerprint"
# for IMAGE integration test fixtures
- "cd cmd/syft/internal/test/integration/test-fixtures && make cache.fingerprint"
# for BINARY unit test fixtures
- "cd syft/pkg/cataloger/binary/test-fixtures && make cache.fingerprint"
# for JAVA BUILD unit test fixtures
- "cd syft/pkg/cataloger/java/test-fixtures/java-builds && make cache.fingerprint"
# for GO BINARY unit test fixtures
- "cd syft/pkg/cataloger/golang/test-fixtures/archs && make binaries.fingerprint"
# for RPM unit test fixtures
- "cd syft/pkg/cataloger/redhat/test-fixtures && make rpms.fingerprint"
# for Kernel unit test fixtures
- "cd syft/pkg/cataloger/kernel/test-fixtures && make cache.fingerprint"
# for INSTALL test fixtures
- "cd test/install && make cache.fingerprint"
# for CLI test fixtures
- "cd test/cli/test-fixtures && make cache.fingerprint"
- |
BOLD='\033[1m'
YELLOW='\033[0;33m'
RESET='\033[0m'
fixtures:
desc: Generate test fixtures
echo -e "${YELLOW}creating fingerprint files for non-docker fixtures...${RESET}"
for dir in $(find . -type d -name 'test-fixtures'); do
if [ -f "$dir/Makefile" ]; then
# for debugging...
#echo -e "${YELLOW}• calculating fingerprints in $dir... ${RESET}"
(make -C "$dir" fingerprint)
fi
done
# for debugging...
# echo -e "generated all fixture fingerprints"
- .github/scripts/fingerprint_docker_fixtures.py
- |
# if DOWNLOAD_TEST_FIXTURE_CACHE is set to 'false', then we don't need to calculate the fingerprint for the cache
if [ "$DOWNLOAD_TEST_FIXTURE_CACHE" = "false" ]; then
exit 0
fi
.github/scripts/find_cache_paths.py {{ .CACHE_PATHS_FILE }} > /dev/null
refresh-fixtures:
desc: Clear and fetch all test fixture cache
aliases:
- fixtures
silent: true
deps:
- tools
cmds:
- "cd syft/file/cataloger/executable/test-fixtures/elf && make"
- "cd syft/file/cataloger/executable/test-fixtures/shared-info && make"
- "cd syft/pkg/cataloger/java/test-fixtures/java-builds && make"
- "cd syft/pkg/cataloger/redhat/test-fixtures && make"
- "cd syft/pkg/cataloger/binary/test-fixtures && make"
- |
BOLD='\033[1m'
PURPLE='\033[0;35m'
RESET='\033[0m'
# if DOWNLOAD_TEST_FIXTURE_CACHE is set to 'false', then skip the cache download and always build
if [ "$DOWNLOAD_TEST_FIXTURE_CACHE" = "false" ]; then
echo -e "${BOLD}${PURPLE}skipping cache download, rebuilding cache...${RESET}"
{{ .TASK }} build-fixtures
exit 0
fi
LATEST_FINGERPRINT=$(docker manifest inspect {{ .CACHE_IMAGE }} | {{ .YQ }} -r '.annotations.fingerprint')
echo "latest cache: $LATEST_FINGERPRINT"
if [ -f {{ .LAST_CACHE_PULL_FILE }} ]; then
LAST_PULL_FINGERPRINT=$(cat {{ .LAST_CACHE_PULL_FILE }} | {{ .YQ }} -r '.digest')
else
echo -e "${BOLD}${PURPLE}empty cache, downloading cache...${RESET}"
{{ .TASK }} download-test-fixture-cache
exit 0
fi
{{ .TASK }} fingerprints
WANT_FINGERPRINT=$(cat {{ .CACHE_PATHS_FILE }} | {{ .YQ }} -r '.digest')
echo "desired cache: $WANT_FINGERPRINT"
echo "last pulled cache: $LAST_PULL_FINGERPRINT"
# if we already have the latest cache, skip the refresh
if [ "$LAST_PULL_FINGERPRINT" = "$WANT_FINGERPRINT" ]; then
echo -e "${BOLD}${PURPLE}already have the latest cache (skipping cache download)${RESET}"
exit 0
fi
# at this point we only refresh the cache if we want the same cache that is currently available.
# we don't by default refresh the cache if the cache if it is simply different from what we have,
# because we may be working on a code change that doesn't require a cache refresh (but could trigger one,
# which would be annoying to deal with in a development workflow).
if [ "$LATEST_FINGERPRINT" = "$WANT_FINGERPRINT" ]; then
echo -e "${BOLD}${PURPLE}found newer cache! downloading cache...${RESET}"
{{ .TASK }} download-test-fixture-cache
else
echo -e "${BOLD}${PURPLE}found different cache, but isn't clear if it's newer (skipping cache download and manually building)${RESET}"
{{ .YQ }} eval '.paths[] | "\(.digest) \(.path)"' {{ .LAST_CACHE_PULL_FILE }} > .tmp/last_cache_lines
{{ .YQ }} eval '.paths[] | "\(.digest) \(.path)"' {{ .CACHE_PATHS_FILE }} > .tmp/cache_lines
diff .tmp/last_cache_lines .tmp/cache_lines || true
echo -e "${BOLD}${PURPLE}diff with more context...${RESET}"
diff -U10000 {{ .LAST_CACHE_PULL_FILE }} {{ .CACHE_PATHS_FILE }} || true
echo -e "${BOLD}${PURPLE}detected changes to input material, manually building fixtures...${RESET}"
{{ .TASK }} build-fixtures
fi
build-fixtures:
desc: Generate all non-docker test fixtures
silent: true
# this will look for `test-fixtures/Makefile` and invoke the `fixtures` target to generate any and all test fixtures
cmds:
- |
BOLD='\033[1m'
YELLOW='\033[0;33m'
RESET='\033[0m'
# Use a for loop with command substitution to avoid subshell issues
for dir in $(find . -type d -name 'test-fixtures'); do
if [ -f "$dir/Makefile" ]; then
echo -e "${YELLOW}${BOLD}generating fixtures in $dir${RESET}"
(make -C "$dir" fixtures)
fi
done
echo -e "${BOLD}generated all fixtures${RESET}"
download-test-fixture-cache:
desc: Download test fixture cache from ghcr.io
deps: [tools, clean-cache]
vars:
CACHE_DIGEST:
sh: docker manifest inspect {{ .CACHE_IMAGE }} | {{ .YQ }} -r '.annotations.fingerprint'
cmds:
- silent: true
cmd: |
# if oras cache is > 4 GB, delete it
if [ -d {{ .ORAS_CACHE }} ]; then
total_size=$(du -c {{ .ORAS_CACHE }} | grep total | awk '{print $1}')
if [ "$total_size" -gt 4194304 ]; then
echo 'deleting oras cache'
rm -rf {{ .ORAS_CACHE }}
fi
fi
- "ORAS_CACHE={{ .ORAS_CACHE }} {{ .ORAS }} pull {{ .CACHE_IMAGE }}"
- "cp {{ .CACHE_PATHS_FILE }} {{ .LAST_CACHE_PULL_FILE }}"
upload-test-fixture-cache:
desc: Upload the test fixture cache to ghcr.io
deps: [tools, fingerprints]
silent: true
cmd: |
set -eu
oras_command="{{ .ORAS }} push {{ .CACHE_IMAGE }}"
paths=$(cat {{ .CACHE_PATHS_FILE }} | {{ .YQ }} -r '.paths[].path')
for path in $paths; do
oras_command+=" $path"
done
oras_command+=" {{ .CACHE_PATHS_FILE }}"
oras_command+=" --annotation org.opencontainers.image.source=https://github.com/{{ .OWNER }}/{{ .PROJECT }}"
oras_command+=" --annotation fingerprint=$(cat {{ .CACHE_PATHS_FILE }} | {{ .YQ }} -r '.digest')"
echo "Executing: $oras_command"
eval $oras_command
show-test-image-cache:
silent: true
cmds:
- "echo '\nDocker daemon cache:'"
- "echo 'Docker daemon cache:'"
- "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}:{{`{{.Tag}}`}}' | grep stereoscope-fixture- | sort"
- "echo '\nTar cache:'"
- 'find . -type f -wholename "**/test-fixtures/snapshot/*" | sort'
- 'find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" | sort'
check-docker-cache:
desc: Ensure docker caches aren't using too much disk space
silent: true
cmd: |
total_size=$(find . | grep cache | grep tar | xargs du -c | grep total | awk '{print $1}')
find . | grep cache | grep tar | xargs du
echo "total $total_size KB"
if [ "$total_size" -gt 1048576 ]; then
echo 'docker cache is larger than 1GB'
exit 1
fi
## install.sh testing targets #################################
@@ -489,8 +625,31 @@ tasks:
- "rm -rf {{ .SNAPSHOT_DIR }}"
- "rm -rf {{ .TMP_DIR }}/goreleaser.yaml"
clean-cache:
desc: Remove all docker cache and local image tar cache
clean-docker-cache:
desc: Remove all docker cache tars and images from the daemon
cmds:
- 'find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" -delete'
- "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}' | grep stereoscope-fixture- | awk '{print $$1}' | uniq | xargs -r docker rmi --force"
- find . -type d -wholename "**/test-fixtures/cache" | xargs rm -rf
- docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}' | grep stereoscope-fixture- | awk '{print $1}' | uniq | xargs -r docker rmi --force
clean-oras-cache:
desc: Remove all cache for oras commands
cmd: rm -rf {{ .ORAS_CACHE }}
clean-cache:
desc: Remove all image docker tar cache, images from the docker daemon, and ephemeral test fixtures
cmds:
- task: clean-docker-cache
- |
BOLD='\033[1m'
YELLOW='\033[0;33m'
RESET='\033[0m'
# Use a for loop with command substitution to avoid subshell issues
for dir in $(find . -type d -name 'test-fixtures'); do
if [ -f "$dir/Makefile" ]; then
echo -e "${YELLOW}${BOLD}deleting ephemeral test fixtures in $dir${RESET}"
(make -C "$dir" clean)
fi
done
echo -e "${BOLD}Deleted all ephemeral test fixtures${RESET}"
- rm -f {{ .LAST_CACHE_PULL_FILE }} {{ .CACHE_PATHS_FILE }}
+1 -2
View File
@@ -93,14 +93,13 @@ func defaultAttestOutputOptions() options.Output {
string(spdxtagvalue.ID),
},
Outputs: []string{syftjson.ID.String()},
OutputFile: options.OutputFile{ // nolint:staticcheck
OutputFile: options.OutputFile{ //nolint:staticcheck
Enabled: false, // explicitly not allowed
},
Format: options.DefaultFormat(),
}
}
//nolint:funlen
func runAttest(ctx context.Context, id clio.Identification, opts *attestOptions, userInput string) error {
// TODO: what other validation here besides binary name?
if !commandExists(cosignBinName) {
-1
View File
@@ -28,7 +28,6 @@ type ConvertOptions struct {
options.UpdateCheck `yaml:",inline" mapstructure:",squash"`
}
//nolint:dupl
func Convert(app clio.Application) *cobra.Command {
id := app.ID()
+4 -5
View File
@@ -80,7 +80,6 @@ func defaultScanOptions() *scanOptions {
}
}
//nolint:dupl
func Scan(app clio.Application) *cobra.Command {
id := app.ID()
@@ -161,7 +160,7 @@ func validateArgs(cmd *cobra.Command, args []string, error string) error {
if err := cmd.Help(); err != nil {
return fmt.Errorf("unable to display help: %w", err)
}
return fmt.Errorf(error)
return fmt.Errorf("%v", error)
}
return cobra.MaximumNArgs(1)(cmd, args)
@@ -396,13 +395,13 @@ func getExplanation(expErr task.ErrInvalidExpression) string {
if errors.Is(err, task.ErrNamesNotAllowed) {
if expErr.Operation == task.SubSelectOperation {
return "However, " + err.Error() + ".\nIt seems like you are intending to add a cataloger in addition to the default set." // nolint:goconst
return "However, " + err.Error() + ".\nIt seems like you are intending to add a cataloger in addition to the default set."
}
return "However, " + err.Error() + "." // nolint:goconst
return "However, " + err.Error() + "."
}
if errors.Is(err, task.ErrTagsNotAllowed) {
return "However, " + err.Error() + ".\nAdding groups of catalogers may result in surprising behavior (create inaccurate SBOMs)." // nolint:goconst
return "However, " + err.Error() + ".\nAdding groups of catalogers may result in surprising behavior (create inaccurate SBOMs)."
}
if errors.Is(err, task.ErrAllNotAllowed) {
+1 -1
View File
@@ -50,7 +50,7 @@ if false, uses the syft-json output for templating (which follows the syft JSON
Note: long term support for this option is not guaranteed (it may change or break at any time)`)
prettyDescription := `include space indention and newlines
prettyDescription := `include space indentation and newlines
note: inherits default value from 'format.pretty' or 'false' if parent is unset`
descriptions.Add(&o.SyftJSON.Pretty, prettyDescription)
descriptions.Add(&o.SPDXJSON.Pretty, prettyDescription)
@@ -0,0 +1 @@
results
@@ -7,7 +7,7 @@ import (
)
func Test_AllLayersIncludesSquashed(t *testing.T) {
// This is a verification test for issue #894 (https://github.com/anchore/syft/issues/894)
// This is a verification test for issue grype/#894 (https://github.com/anchore/grype/issues/894)
allLayers, _ := catalogFixtureImage(t, "image-suse-all-layers", source.AllLayersScope)
squashed, _ := catalogFixtureImage(t, "image-suse-all-layers", source.SquashedScope)
@@ -410,6 +410,14 @@ var dirOnlyTestCases = []testCase{
"octo-org/this-repo/.github/workflows/workflow-1.yml": "172239021f7ba04fe7327647b213799853a9eb89",
},
},
{
name: "find opam package",
pkgType: pkg.OpamPkg,
pkgLanguage: pkg.OCaml,
pkgInfo: map[string]string{
"ocaml-base-compiler": "4.14.0",
},
},
}
var commonTestCases = []testCase{
@@ -52,6 +52,7 @@ func TestPkgCoverageImage(t *testing.T) {
definedLanguages.Remove(pkg.Dart.String())
definedLanguages.Remove(pkg.Swift.String())
definedLanguages.Remove(pkg.Swipl.String())
definedLanguages.Remove(pkg.OCaml.String())
definedLanguages.Remove(pkg.CPP.String())
definedLanguages.Remove(pkg.Haskell.String())
definedLanguages.Remove(pkg.Elixir.String())
@@ -78,6 +79,7 @@ func TestPkgCoverageImage(t *testing.T) {
definedPkgs.Remove(string(pkg.LinuxKernelModulePkg))
definedPkgs.Remove(string(pkg.SwiftPkg))
definedPkgs.Remove(string(pkg.SwiplPackPkg))
definedPkgs.Remove(string(pkg.OpamPkg))
definedPkgs.Remove(string(pkg.GithubActionPkg))
definedPkgs.Remove(string(pkg.GithubActionWorkflowPkg))
@@ -2,7 +2,9 @@ package integration
import (
"bytes"
"regexp"
"os"
"path/filepath"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
@@ -12,8 +14,6 @@ import (
"github.com/anchore/syft/cmd/syft/internal/options"
"github.com/anchore/syft/syft/format"
"github.com/anchore/syft/syft/format/cyclonedxjson"
"github.com/anchore/syft/syft/format/cyclonedxxml"
"github.com/anchore/syft/syft/format/syftjson"
"github.com/anchore/syft/syft/source"
)
@@ -43,26 +43,27 @@ func TestEncodeDecodeEncodeCycleComparison(t *testing.T) {
},
json: true,
},
{
name: cyclonedxjson.ID.String(),
redactor: func(in []byte) []byte {
// unstable values
in = regexp.MustCompile(`"(timestamp|serialNumber|bom-ref|ref)":\s*"(\n|[^"])+"`).ReplaceAll(in, []byte(`"$1": "redacted"`))
in = regexp.MustCompile(`"(dependsOn)":\s*\[(?:\s|[^]])+]`).ReplaceAll(in, []byte(`"$1": []`))
return in
},
json: true,
},
{
name: cyclonedxxml.ID.String(),
redactor: func(in []byte) []byte {
// unstable values
in = regexp.MustCompile(`(serialNumber|bom-ref|ref)="[^"]+"`).ReplaceAll(in, []byte{})
in = regexp.MustCompile(`<timestamp>[^<]+</timestamp>`).ReplaceAll(in, []byte{})
return in
},
},
// TODO: ignoring the `ref` field though does create stable results to compare, but the SBOM is fundamentally gutted and not worth comparing (find a better redaction or compare method)
//{
// name: cyclonedxjson.ID.String(),
// redactor: func(in []byte) []byte {
// // unstable values
// in = regexp.MustCompile(`"(timestamp|serialNumber|bom-ref|ref)":\s*"(\n|[^"])+"`).ReplaceAll(in, []byte(`"$1": "redacted"`))
// in = regexp.MustCompile(`"(dependsOn)":\s*\[(?:\s|[^]])+]`).ReplaceAll(in, []byte(`"$1": []`))
// return in
// },
// json: true,
//},
//{
// name: cyclonedxxml.ID.String(),
// redactor: func(in []byte) []byte {
// // unstable values
// in = regexp.MustCompile(`(serialNumber|bom-ref|ref)="[^"]+"`).ReplaceAll(in, []byte{})
// in = regexp.MustCompile(`<timestamp>[^<]+</timestamp>`).ReplaceAll(in, []byte{})
//
// return in
// },
//},
}
opts := options.DefaultOutput()
@@ -112,6 +113,21 @@ func TestEncodeDecodeEncodeCycleComparison(t *testing.T) {
diffs := dmp.DiffMain(string(by1), string(by2), true)
t.Errorf("diff: %s", dmp.DiffPrettyText(diffs))
}
// write raw IMAGE@NAME-start and IMAGE@NAME-finish to files within the results dir
// ... this is helpful for debugging
require.NoError(t, os.MkdirAll("results", 0700))
suffix := "sbom"
switch {
case strings.Contains(test.name, "json"):
suffix = "json"
case strings.Contains(test.name, "xml"):
suffix = "xml"
}
require.NoError(t, os.WriteFile(filepath.Join("results", image+"@"+test.name+"-start."+suffix), by1, 0600))
require.NoError(t, os.WriteFile(filepath.Join("results", image+"@"+test.name+"-finish."+suffix), by2, 0600))
}
})
}
@@ -35,8 +35,8 @@ func TestGolangCompilerDetection(t *testing.T) {
for _, pkg := range packages {
foundCompilerVersions[pkg.Version] = struct{}{}
foundPURL[pkg.PURL] = struct{}{}
for _, cpe := range pkg.CPEs {
foundCPE[cpe] = struct{}{}
for _, c := range pkg.CPEs {
foundCPE[c] = struct{}{}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,3 @@
//go:build !arm64
package integration
import (
@@ -7,7 +5,6 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/source"
@@ -22,41 +19,39 @@ func TestPackageDeduplication(t *testing.T) {
}{
{
scope: source.AllLayersScope,
packageCount: 172, // without deduplication this would be 618
packageCount: 178, // without deduplication this would be ~600
instanceCount: map[string]int{
"basesystem": 1,
"wget": 1,
"curl": 2, // upgraded in the image
"vsftpd": 1,
"httpd": 1, // rpm, - we exclude binary
"basesystem": 1,
"wget": 1,
"curl-minimal": 2, // upgraded in the image
"vsftpd": 1,
"httpd": 1, // rpm, - we exclude binary
},
locationCount: map[string]int{
"basesystem-10.0-7.el7.centos": 4,
"curl-7.29.0-59.el7": 1, // from base image
"curl-7.29.0-59.el7_9.1": 3, // upgrade
"wget-1.14-18.el7_6.1": 3,
"vsftpd-3.0.2-29.el7_9": 2,
"httpd-2.4.6-97.el7.centos.5": 1,
// "httpd-2.4.6": 1, // binary
"basesystem-11-13.el9": 5, // in all layers
"curl-minimal-7.76.1-26.el9_3.2.0.1": 2, // base + wget layer
"curl-minimal-7.76.1-29.el9_4.1": 3, // curl upgrade layer + all above layers
"wget-1.21.1-8.el9_4": 4, // wget + all above layers
"vsftpd-3.0.5-5.el9": 2, // vsftpd + all above layers
"httpd-2.4.57-11.el9_4.1": 1, // last layer
},
},
{
scope: source.SquashedScope,
packageCount: 170,
packageCount: 172,
instanceCount: map[string]int{
"basesystem": 1,
"wget": 1,
"curl": 1, // upgraded, but the most recent
"vsftpd": 1,
"httpd": 1, // rpm, binary is now excluded by overlap
"basesystem": 1,
"wget": 1,
"curl-minimal": 1, // upgraded, but the most recent
"vsftpd": 1,
"httpd": 1, // rpm, binary is now excluded by overlap
},
locationCount: map[string]int{
"basesystem-10.0-7.el7.centos": 1,
"curl-7.29.0-59.el7_9.1": 1, // upgrade
"wget-1.14-18.el7_6.1": 1,
"vsftpd-3.0.2-29.el7_9": 1,
"httpd-2.4.6-97.el7.centos.5": 1,
// "httpd-2.4.6": 1, // binary (excluded)
"basesystem-11-13.el9": 1,
"curl-minimal-7.76.1-29.el9_4.1": 1, // upgrade
"wget-1.21.1-8.el9_4": 1,
"vsftpd-3.0.5-5.el9": 1,
"httpd-2.4.57-11.el9_4.1": 1,
},
},
}
@@ -75,20 +70,21 @@ func TestPackageDeduplication(t *testing.T) {
pkgs := sbom.Artifacts.Packages.PackagesByName(name)
// with multiple packages with the same name, something is wrong (or this is the wrong fixture)
require.Len(t, pkgs, expectedInstanceCount)
if assert.Len(t, pkgs, expectedInstanceCount, "unexpected package count for %s", name) {
for _, p := range pkgs {
nameVersion := fmt.Sprintf("%s-%s", name, p.Version)
expectedLocationCount, ok := tt.locationCount[nameVersion]
if !ok {
t.Errorf("missing name-version: %s", nameVersion)
continue
}
for _, p := range pkgs {
nameVersion := fmt.Sprintf("%s-%s", name, p.Version)
expectedLocationCount, ok := tt.locationCount[nameVersion]
if !ok {
t.Fatalf("missing name-version: %s", nameVersion)
// we should see merged locations (assumption, there was 1 location for each package)
assert.Len(t, p.Locations.ToSlice(), expectedLocationCount, "unexpected location count for %s", nameVersion)
// all paths should match
assert.Len(t, p.Locations.CoordinateSet().Paths(), 1, "unexpected location count for %s", nameVersion)
}
// we should see merged locations (assumption, there was 1 location for each package)
assert.Len(t, p.Locations.ToSlice(), expectedLocationCount)
// all paths should match
assert.Len(t, p.Locations.CoordinateSet().Paths(), 1)
}
}
@@ -0,0 +1,25 @@
package integration
import (
"reflect"
"testing"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/source"
)
func TestSbomMetadataComponent(t *testing.T) {
sbom, _ := catalogFixtureImage(t, "image-sbom-metadata-component", source.SquashedScope, "+sbom-cataloger")
expectedPkgs := []string{"first-subcomponent", "main-component"}
foundPkgs := []string{}
for sbomPkg := range sbom.Artifacts.Packages.Enumerate(pkg.JavaPkg) {
foundPkgs = append(foundPkgs, sbomPkg.Name)
}
// check if both the package in `.metadata.component` and the one in `.components` were found
if !reflect.DeepEqual(expectedPkgs, foundPkgs) {
t.Errorf("expected packages %v, got %v", expectedPkgs, foundPkgs)
}
}
@@ -1,6 +1,21 @@
# change these if you want CI to not use previous stored cache
INTEGRATION_CACHE_BUSTER := "894d8ca"
FINGERPRINT_FILE := cache.fingerprint
.PHONY: cache.fingerprint
cache.fingerprint:
find image-* -type f -exec md5sum {} + | awk '{print $1}' | sort | tee /dev/stderr | md5sum | tee cache.fingerprint && echo "$(INTEGRATION_CACHE_BUSTER)" >> cache.fingerprint
.DEFAULT_GOAL := fixtures
# requirement 1: 'fixtures' goal to generate any and all test fixtures
fixtures:
@echo "nothing to do"
# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted
fingerprint: $(FINGERPRINT_FILE)
# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint
.PHONY: $(FINGERPRINT_FILE)
$(FINGERPRINT_FILE):
@find image-* -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE)
@#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}'
# requirement 4: 'clean' goal to remove all generated test fixtures
.PHONY: clean
clean:
rm -f $(FINGERPRINT_FILE)
@@ -1 +1,6 @@
FROM golang:1.18.10-alpine
FROM --platform=linux/amd64 golang:1.18.10-alpine
FROM scratch
# we don't need the entire golang toolchain, just a single binary with the stdlib baked in
COPY --from=0 /usr/local/go/bin/gofmt bin/gofmt
@@ -1,4 +1,4 @@
FROM jenkins/jenkins:2.346.3-slim-jdk17@sha256:028fbbd9112c60ed086f5197fcba71992317864d27644e5949cf9c52ff4b65f0
FROM jenkins/jenkins:2.346.3-slim-jdk17@sha256:028fbbd9112c60ed086f5197fcba71992317864d27644e5949cf9c52ff4b65f0 AS base
USER root
@@ -12,7 +12,7 @@ RUN apt-get update 2>&1 > /dev/null && apt-get install -y less zip 2>&1 > /dev/n
RUN unzip ../jenkins.war 2>&1 > /dev/null
RUN rm -f ./META-INF/MANIFEST.MF
RUN rm -rf ./META-INF/MANIFEST.MF ./WEB-INF ./jsbundles ./scripts ./css
WORKDIR /usr/share/jenkins
@@ -21,3 +21,7 @@ RUN rm -rf jenkins.war
RUN cd ./tmp && zip -r ../jenkins.war . && cd ..
RUN rm -rf ./tmp
FROM scratch
COPY --from=base /usr/share/jenkins/jenkins.war /jenkins.war
@@ -1,7 +1,15 @@
FROM alpine:3.18.3@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a
FROM alpine:3.18.3@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a AS base
RUN wget https://repo1.maven.org/maven2/org/jvnet/hudson/main/hudson-war/2.2.1/hudson-war-2.2.1.war
RUN mv hudson-war-2.2.1.war hudson.war
# let's make this image a little smaller as to not take up so much disk space
# we'll only keep the jar metadata files (pom data + manifest) and throw away the rest
RUN apk add --no-cache python3 py3-pip
COPY extract.py /extract.py
RUN python extract.py
FROM scratch
COPY --from=base /slim /
@@ -0,0 +1,69 @@
import os
import zipfile
import io
ARCHIVE_EXTENSIONS = ('.jar', '.war', '.ear', '.hpi', '.war', '.sar', '.nar', '.par')
METADATA_FILES = ('pom.xml', 'pom.properties', 'MANIFEST.MF')
def slim_archive(archive, output_dir, base_path="", archive_name=""):
"""
extracts metadata files from the archive and creates a slim JAR file
containing only these files. handles nested JARs by preserving them.
"""
slim_buffer = io.BytesIO()
with zipfile.ZipFile(archive, 'r') as zip_file:
with zipfile.ZipFile(slim_buffer, 'w', zipfile.ZIP_DEFLATED) as slim_zip:
for file_name in zip_file.namelist():
# check for metadata files or nested JARs
if file_name.endswith(METADATA_FILES):
# add metadata files directly to the slimmed archive
file_data = zip_file.read(file_name)
slim_zip.writestr(file_name, file_data)
elif file_name.endswith(ARCHIVE_EXTENSIONS):
# if it's a nested archive, recursively slim it
nested_archive = io.BytesIO(zip_file.read(file_name))
nested_slim_buffer = io.BytesIO()
slim_archive(
nested_archive,
nested_slim_buffer,
base_path=os.path.join(base_path, os.path.dirname(file_name)),
archive_name=os.path.basename(file_name)
)
# add the slimmed nested archive back to the parent archive
nested_slim_buffer.seek(0)
slim_zip.writestr(file_name, nested_slim_buffer.read())
# write out the slimmed JAR to the output directory if output_dir is a directory
if isinstance(output_dir, str):
output_path = os.path.join(output_dir, base_path, archive_name)
os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, 'wb') as f:
slim_buffer.seek(0)
f.write(slim_buffer.read())
else:
# if output_dir is a BytesIO buffer (for nested archives), just write to it
output_dir.seek(0)
output_dir.write(slim_buffer.getvalue())
def walk_directory_and_slim_jars(base_dir, output_dir):
"""
recursively walks through a directory tree looking for .jar, .war, .ear,
.hpi files and slims them down by keeping only metadata files.
"""
for dirpath, _, filenames in os.walk(base_dir):
for filename in filenames:
if filename.endswith(ARCHIVE_EXTENSIONS):
archive_path = os.path.join(dirpath, filename)
print(f"Processing {archive_path}")
slim_archive(archive_path, output_dir, os.path.relpath(dirpath, base_dir), filename)
# a helper script for slimming down JAR files by keeping only metadata files but still keeping the jar packaging,
# including nested JARs! Useful for testing purposes.
if __name__ == "__main__":
BASE_DIR = "."
OUTPUT_DIR = "./slim"
os.makedirs(OUTPUT_DIR, exist_ok=True)
walk_directory_and_slim_jars(BASE_DIR, OUTPUT_DIR)
@@ -1,4 +1,4 @@
FROM alpine@sha256:d9a7354e3845ea8466bb00b22224d9116b183e594527fb5b6c3d30bc01a20378
FROM alpine@sha256:d9a7354e3845ea8466bb00b22224d9116b183e594527fb5b6c3d30bc01a20378 AS base
# we keep these unpinned so that if alpine
# changes our integration tests can adapt
@@ -6,3 +6,8 @@ RUN apk add --no-cache \
tzdata \
vim \
alpine-sdk
# we don't need the installed bins for this test, only the APK installed metadata
FROM scratch
COPY --from=base /lib/apk/db/installed /lib/apk/db/installed
@@ -1 +1,8 @@
FROM mcr.microsoft.com/cbl-mariner/distroless/base:2.0.202205275@sha256:f550c5428df17b145851ad75983aca6d613ad4b51ca7983b2a83e67d0ac91a5d
FROM mcr.microsoft.com/cbl-mariner/distroless/base:2.0.202205275@sha256:f550c5428df17b145851ad75983aca6d613ad4b51ca7983b2a83e67d0ac91a5d AS base
# let's shoot for smaller test fixtures
FROM scratch
COPY --from=base /var/lib/rpmmanifest/container-manifest-2 /var/lib/rpmmanifest/container-manifest-2
COPY --from=base /usr/bin/gencat /usr/bin/gencat
COPY --from=base /usr/bin/openssl /usr/bin/openssl
@@ -1,3 +1,8 @@
FROM ubuntu:20.04@sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba
FROM ubuntu:20.04@sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba AS base
# this covers rpm-python
RUN apt-get update && apt-get install -y python-pil=6.2.1-3
# let's save some space...
FROM scratch
COPY --from=base /var/lib/dpkg/status /var/lib/dpkg/status
@@ -1 +1,5 @@
FROM photon:5.0-20230729@sha256:4cf2a1ce0a3f4625f13a0becb6b9bccfdb014c565be6e9a2ec4c4aad1ff8a5d9
FROM photon:5.0-20230729@sha256:4cf2a1ce0a3f4625f13a0becb6b9bccfdb014c565be6e9a2ec4c4aad1ff8a5d9 AS base
FROM scratch
COPY --from=base /usr/lib/sysimage/rpm /usr/lib/sysimage/rpm
@@ -0,0 +1,93 @@
opam-version: "2.0"
synopsis: "Official release 4.14.0"
maintainer: [
"David Allsopp <david@tarides.com>"
"Florian Angeletti <florian.angeletti@inria.fr>"
]
authors: "Xavier Leroy and many contributors"
license: "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception"
homepage: "https://ocaml.org"
bug-reports: "https://github.com/ocaml/opam-repository/issues"
depends: [
"ocaml" {= "4.14.0" & post}
"base-unix" {post}
"base-bigarray" {post}
"base-threads" {post}
"host-arch-arm32" {arch = "arm32" & post}
"host-arch-arm64" {arch = "arm64" & post}
"host-arch-ppc64" {arch = "ppc64" & post}
"host-arch-riscv64" {arch = "riscv64" & post}
"host-arch-s390x" {arch = "s390x" & post}
"host-arch-x86_32" {os != "win32" & arch = "x86_32" & post}
"host-arch-x86_64" {os != "win32" & arch = "x86_64" & post}
"host-arch-unknown"
{os != "win32" & arch != "arm32" & arch != "arm64" & arch != "ppc64" &
arch != "riscv64" &
arch != "s390x" &
arch != "x86_32" &
arch != "x86_64" &
post}
(("arch-x86_64" {os = "win32" & arch = "x86_64"} &
(("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) |
"system-msvc")) |
("arch-x86_32" {os = "win32"} &
(("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) |
"system-msvc")) |
"host-system-other" {os != "win32" & post})
"ocaml-options-vanilla" {post}
"flexdll" {>= "0.36" & os = "win32"}
]
conflict-class: "ocaml-core-compiler"
flags: compiler
setenv: CAML_LD_LIBRARY_PATH = "%{lib}%/stublibs"
build: [
[
"./configure"
"--host=x86_64-pc-windows"
{system-msvc:installed & arch-x86_64:installed}
"--host=x86_64-w64-mingw32"
{os-distribution = "cygwin" & system-mingw:installed &
arch-x86_64:installed}
"--host=i686-pc-windows" {system-msvc:installed & arch-x86_32:installed}
"--host=i686-w64-mingw32"
{os-distribution = "cygwin" & system-mingw:installed &
arch-x86_32:installed}
"--prefix=%{prefix}%"
"--docdir=%{doc}%/ocaml"
"--with-flexdll=%{flexdll:share}%" {os = "win32" & flexdll:installed}
"-C"
"CC=cc" {os = "openbsd" | os = "macos"}
"ASPP=cc -c" {os = "openbsd" | os = "macos"}
]
[make "-j%{jobs}%"]
]
install: [make "install"]
build-env: MSYS2_ARG_CONV_EXCL = "*"
post-messages: [
"""\
A failure in the middle of the build may be caused by build parallelism
(enabled by default).
Please file a bug report at https://github.com/ocaml/opam-repository/issues"""
{failure & jobs > "1"}
"""\
You can try installing again including --jobs=1
to force a sequential build instead."""
{failure & jobs > "1" & opam-version >= "2.0.5"}
]
dev-repo: "git+https://github.com/ocaml/ocaml#4.14"
url {
src: "https://github.com/ocaml/ocaml/archive/4.14.0.tar.gz"
checksum:
"sha256=39f44260382f28d1054c5f9d8bf4753cb7ad64027da792f7938344544da155e8"
}
extra-source "ocaml-base-compiler.install" {
src:
"https://raw.githubusercontent.com/ocaml/opam-source-archives/main/patches/ocaml-base-compiler/ocaml-base-compiler.install"
checksum: [
"sha256=79f2a1a5044a91350a0eb6ce12e261a72a2855c094c425cddf3860e58c486678"
"md5=3e969b841df1f51ca448e6e6295cb451"
]
}
x-env-path-rewrite: [
[CAML_LD_LIBRARY_PATH (";" {os = "win32"} ":" {os != "win32"}) "target"]
]
@@ -0,0 +1,2 @@
FROM scratch
COPY test.cdx.json /
@@ -0,0 +1,32 @@
{
"bomFormat" : "CycloneDX",
"specVersion" : "1.5",
"serialNumber" : "urn:uuid:dc807d4b-0415-35ab-ba61-49b5d39bc2d9",
"version" : 1,
"metadata" : {
"component" : {
"name" : "main-component",
"version" : "1.2.3",
"purl" : "pkg:maven/org.example/main-component@1.2.3",
"type" : "library",
"bom-ref" : "pkg:maven/org.example/main-component@1.2.3"
}
},
"components" : [
{
"name" : "first-subcomponent",
"version" : "2.3.4",
"purl" : "pkg:maven/org.example/first-subcomponent@2.3.4",
"type" : "library",
"bom-ref" : "pkg:maven/org.example/first-subcomponent@2.3.4"
}
],
"dependencies" : [
{
"ref" : "pkg:maven/org.example/main-component-assembly@1.2.3",
"dependsOn" : [
"pkg:maven/org.example/first-subcomponent@2.3.4"
]
}
]
}
@@ -1 +1,6 @@
FROM fedora:35@sha256:36af84ba69e21c9ef86a0424a090674c433b2b80c2462e57503886f1d823abe8
FROM fedora:35@sha256:36af84ba69e21c9ef86a0424a090674c433b2b80c2462e57503886f1d823abe8 AS base
# lets save some space
FROM scratch
COPY --from=base /var/lib/rpm /var/lib/rpm
@@ -1,2 +1,11 @@
FROM registry.suse.com/suse/sle15:15.3.17.20.20@sha256:fd657ecbab5ca564d6933e887f6ae8542a9398e6a4b399f352ce10c3a24afc64
FROM registry.suse.com/suse/sle15:15.3.17.20.20@sha256:fd657ecbab5ca564d6933e887f6ae8542a9398e6a4b399f352ce10c3a24afc64 AS base
RUN zypper in -y wget
# let's save some space... we really just need an image that has an RPM DB that is linked across layers
FROM --platform=linux/amd64 busybox:1.36.1
# setup a link /var/lib/rpm -> ../../usr/lib/sysimage/rpm
RUN mkdir -p /var/lib && ln -s ../../usr/lib/sysimage/rpm /var/lib/rpm
# copy the RPM DB from the SUSE image
COPY --from=base /usr/lib/sysimage/rpm/Packages.db /usr/lib/sysimage/rpm/Packages.db
@@ -1 +1,18 @@
FROM anchore/test_images:java-1abc58f@sha256:3add9f90e9ed35739cc99b7830767e09eec921052e2412adf4491648c741f066
FROM docker.io/anchore/test_images:java-88948cc@sha256:dea0e6c24636937f53bdc997d9960c2a18966d1e38bcd8ebd0c395d4e169b806 AS base
# not covered in testing...
RUN rm /packages/gradle-7.1.1-bin.zip
RUN apk add --no-cache python3 py3-pip
COPY extract.py /extract.py
WORKDIR /
# let's make this image a little smaller as to not take up so much disk space
# we'll only keep the jar metadata files (pom data + manifest) and throw away the rest
RUN python extract.py
FROM scratch
COPY --from=base /slim/packages /packages
@@ -0,0 +1,69 @@
import os
import zipfile
import io
ARCHIVE_EXTENSIONS = ('.jar', '.war', '.ear', '.hpi', '.war', '.sar', '.nar', '.par')
METADATA_FILES = ('pom.xml', 'pom.properties', 'MANIFEST.MF')
def slim_archive(archive, output_dir, base_path="", archive_name=""):
"""
extracts metadata files from the archive and creates a slim JAR file
containing only these files. handles nested JARs by preserving them.
"""
slim_buffer = io.BytesIO()
with zipfile.ZipFile(archive, 'r') as zip_file:
with zipfile.ZipFile(slim_buffer, 'w', zipfile.ZIP_DEFLATED) as slim_zip:
for file_name in zip_file.namelist():
# check for metadata files or nested JARs
if file_name.endswith(METADATA_FILES):
# add metadata files directly to the slimmed archive
file_data = zip_file.read(file_name)
slim_zip.writestr(file_name, file_data)
elif file_name.endswith(ARCHIVE_EXTENSIONS):
# if it's a nested archive, recursively slim it
nested_archive = io.BytesIO(zip_file.read(file_name))
nested_slim_buffer = io.BytesIO()
slim_archive(
nested_archive,
nested_slim_buffer,
base_path=os.path.join(base_path, os.path.dirname(file_name)),
archive_name=os.path.basename(file_name)
)
# add the slimmed nested archive back to the parent archive
nested_slim_buffer.seek(0)
slim_zip.writestr(file_name, nested_slim_buffer.read())
# write out the slimmed JAR to the output directory if output_dir is a directory
if isinstance(output_dir, str):
output_path = os.path.join(output_dir, base_path, archive_name)
os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, 'wb') as f:
slim_buffer.seek(0)
f.write(slim_buffer.read())
else:
# if output_dir is a BytesIO buffer (for nested archives), just write to it
output_dir.seek(0)
output_dir.write(slim_buffer.getvalue())
def walk_directory_and_slim_jars(base_dir, output_dir):
"""
recursively walks through a directory tree looking for .jar, .war, .ear,
.hpi files and slims them down by keeping only metadata files.
"""
for dirpath, _, filenames in os.walk(base_dir):
for filename in filenames:
if filename.endswith(ARCHIVE_EXTENSIONS):
archive_path = os.path.join(dirpath, filename)
print(f"Processing {archive_path}")
slim_archive(archive_path, output_dir, os.path.relpath(dirpath, base_dir), filename)
# a helper script for slimming down JAR files by keeping only metadata files but still keeping the jar packaging,
# including nested JARs! Useful for testing purposes.
if __name__ == "__main__":
BASE_DIR = "."
OUTPUT_DIR = "./slim"
os.makedirs(OUTPUT_DIR, exist_ok=True)
walk_directory_and_slim_jars(BASE_DIR, OUTPUT_DIR)
@@ -1,6 +1,27 @@
FROM centos:7.9.2009@sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4
FROM --platform=linux/amd64 rockylinux:9.3.20231119@sha256:d644d203142cd5b54ad2a83a203e1dee68af2229f8fe32f52a30c6e1d3c3a9e0 AS base
# modifying the RPM DB multiple times will result in duplicate packages when using all-layers (if there was no de-dup logic)
# curl is tricky, it already exists in the image and is being upgraded
RUN yum install -y wget-1.14-18.el7_6.1 curl-7.29.0-59.el7_9.1
RUN yum install -y vsftpd-3.0.2-29.el7_9
RUN yum install -y httpd-2.4.6-97.el7.centos.5
# but... we want to make the test image as small as possible, so we are making the changes in stages and then
# copying the RPM DB from each stage to a final stage in separate layers. This will result in a much smaller image.
FROM base AS stage1
RUN dnf install -y wget
FROM stage1 AS stage2
RUN dnf update -y curl-minimal
FROM stage2 AS stage3
RUN dnf install -y vsftpd
FROM stage3 AS stage4
RUN dnf install -y httpd
FROM scratch
COPY --from=base /var/lib/rpm /var/lib/rpm
COPY --from=stage1 /var/lib/rpm /var/lib/rpm
COPY --from=stage2 /var/lib/rpm /var/lib/rpm
COPY --from=stage3 /var/lib/rpm /var/lib/rpm
COPY --from=stage4 /var/lib/rpm /var/lib/rpm
+27 -30
View File
@@ -5,7 +5,7 @@ go 1.22.0
require (
github.com/CycloneDX/cyclonedx-go v0.9.0
github.com/Masterminds/semver v1.5.0
github.com/Masterminds/sprig/v3 v3.2.3
github.com/Masterminds/sprig/v3 v3.3.0
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/acobaugh/osrelease v0.1.0
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9
@@ -17,19 +17,19 @@ 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.20240507183024-848e011fc24f
github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f
github.com/anchore/stereoscope v0.0.3
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
// we are hinting brotli to latest due to warning when installing archiver v3:
// go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
github.com/bmatcuk/doublestar/v4 v4.6.1
github.com/charmbracelet/bubbles v0.18.0
github.com/charmbracelet/bubbletea v0.26.6
github.com/charmbracelet/lipgloss v0.12.1
github.com/dave/jennifer v1.7.0
github.com/charmbracelet/bubbles v0.20.0
github.com/charmbracelet/bubbletea v1.1.0
github.com/charmbracelet/lipgloss v0.13.0
github.com/dave/jennifer v1.7.1
github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da
github.com/distribution/reference v0.6.0
github.com/docker/docker v27.1.1+incompatible
github.com/docker/docker v27.2.1+incompatible
github.com/dustin/go-humanize v1.0.1
github.com/elliotchance/phpserialize v1.4.0
github.com/facebookincubator/nvdtools v0.1.5
@@ -39,7 +39,7 @@ require (
github.com/go-git/go-git/v5 v5.12.0
github.com/go-test/deep v1.1.1
github.com/google/go-cmp v0.6.0
github.com/google/go-containerregistry v0.20.1
github.com/google/go-containerregistry v0.20.2
github.com/google/licensecheck v0.3.1
github.com/google/uuid v1.6.0
github.com/gookit/color v1.5.4
@@ -78,28 +78,29 @@ require (
github.com/xeipuuv/gojsonschema v1.2.0
github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1
go.uber.org/goleak v1.3.0
golang.org/x/mod v0.20.0
golang.org/x/net v0.27.0
golang.org/x/mod v0.21.0
golang.org/x/net v0.29.0
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.31.1
modernc.org/sqlite v1.33.0
)
require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
require (
github.com/BurntSushi/toml v1.4.0
github.com/OneOfOne/xxhash v1.2.8
github.com/adrg/xdg v0.5.0
github.com/magiconair/properties v1.8.7
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678
)
require (
dario.cat/mergo v1.0.0 // indirect
dario.cat/mergo v1.0.1 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Masterminds/semver/v3 v3.3.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.4 // indirect
github.com/ProtonMail/go-crypto v1.0.0 // indirect
@@ -110,10 +111,8 @@ require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/becheran/wildmatch-go v1.0.0 // indirect
github.com/charmbracelet/harmonica v0.2.0 // indirect
github.com/charmbracelet/x/ansi v0.1.4 // indirect
github.com/charmbracelet/x/input v0.1.0 // indirect
github.com/charmbracelet/x/term v0.1.1 // indirect
github.com/charmbracelet/x/windows v0.1.0 // indirect
github.com/charmbracelet/x/ansi v0.2.3 // indirect
github.com/charmbracelet/x/term v0.2.0 // indirect
github.com/cloudflare/circl v1.3.8 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/containerd/containerd v1.7.11 // indirect
@@ -125,7 +124,7 @@ require (
github.com/containerd/typeurl/v2 v2.1.1 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/docker/cli v27.0.3+incompatible // indirect
github.com/docker/cli v27.1.1+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
@@ -153,9 +152,8 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect
github.com/imdario/mergo v0.3.15 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
@@ -169,7 +167,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
@@ -179,7 +177,6 @@ require (
github.com/moby/sys/signal v0.7.0 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/nwaples/rardecode v1.1.0 // indirect
@@ -199,13 +196,13 @@ require (
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect
github.com/sahilm/fuzzy v0.1.1 // indirect
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
@@ -230,11 +227,11 @@ require (
go.opentelemetry.io/otel/trace v1.19.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/term v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
+54 -79
View File
@@ -45,8 +45,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
@@ -69,16 +69,18 @@ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJ
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
@@ -113,8 +115,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.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA=
github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f h1:xuBvotcht1Ns8IdaC4UuYV1U8MFln9c5ELeo5bzDEO8=
github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f/go.mod h1:DcQdMes8SwpFli3rDH0v+Vd9qU9Jariq7JSHNJV5X/A=
github.com/anchore/stereoscope v0.0.3 h1:JRPHySy8S6P+Ff3IDiQ29ap1i8/laUQxDk9K1eFh/2U=
github.com/anchore/stereoscope v0.0.3/go.mod h1:5DJheGPjVRsSqegTB24Zi6SCHnYQnA519yeIG+RG+I4=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
@@ -155,22 +157,18 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqpzOLN2zq1s=
github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk=
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c=
github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs=
github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8=
github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM=
github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ=
github.com/charmbracelet/x/input v0.1.0/go.mod h1:ZZwaBxPF7IG8gWWzPUVqHEtWhc1+HXJPNuerJGRGZ28=
github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI=
github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw=
github.com/charmbracelet/x/windows v0.1.0 h1:gTaxdvzDM5oMa/I2ZNF7wN78X/atWemG9Wph7Ika2k4=
github.com/charmbracelet/x/windows v0.1.0/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ=
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY=
github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -215,8 +213,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/dave/jennifer v1.7.0 h1:uRbSBH9UTS64yXbh4FrMHfgfY762RD+C7bUPKODpSJE=
github.com/dave/jennifer v1.7.0/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo=
github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -227,12 +225,12 @@ github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da/go.mod h1:B3tI9iGHi4i
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlSN5BLDioCQ=
github.com/docker/cli v27.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE=
github.com/docker/cli v27.1.1+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 v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
@@ -384,8 +382,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.20.1 h1:eTgx9QNYugV4DN5mz4U8hiAGTi1ybXn0TPi4Smd8du0=
github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo=
github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/licensecheck v0.3.1 h1:QoxgoDkaeC4nFrtGN1jV7IPmDCHFNIVh54e5hSt6sPs=
github.com/google/licensecheck v0.3.1/go.mod h1:ORkR35t/JjW+emNKtfJDII0zlciG9JgbT7SmsohlHmY=
@@ -411,7 +409,6 @@ github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8I
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -463,8 +460,8 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk=
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
@@ -473,9 +470,6 @@ github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@@ -552,9 +546,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 h1:P8UmIzZMYDR+NGImiFvErt6VWfIRPuGM+vyjiEdkmIw=
github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@@ -564,7 +557,6 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@@ -577,7 +569,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
@@ -603,8 +594,6 @@ github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -673,7 +662,6 @@ github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe
github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@@ -692,8 +680,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y=
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo=
@@ -711,8 +699,8 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -733,10 +721,9 @@ github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY52
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
@@ -875,11 +862,10 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -920,8 +906,8 @@ 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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
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=
@@ -968,8 +954,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
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=
@@ -1000,8 +986,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1081,15 +1067,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1102,8 +1088,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1344,7 +1330,6 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -1359,14 +1344,8 @@ 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.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y=
modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s=
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
@@ -1375,12 +1354,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs=
modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA=
modernc.org/sqlite v1.33.0 h1:WWkA/T2G17okiLGgKAj4/RMIvgyMT19yQ038160IeYk=
modernc.org/sqlite v1.33.0/go.mod h1:9uQ9hF/pCZoYZK73D/ud5Z7cIRIILSZI8NdIemVMTX8=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
+1 -1
View File
@@ -1,6 +1,6 @@
# Caching
All caches are created from a global `manager`. By defaut this is a `bypassedCache`, which performs no caching.
All caches are created from a global `manager`. By default this is a `bypassedCache`, which performs no caching.
One benefit of this is that tests don't need to worry about caching causing issues unless they explicitly need
to test the cache and can opt-in using the `cache.TestCache(t)` helper.
+1 -1
View File
@@ -34,7 +34,7 @@ func (r *errorResolver[T]) Resolve(key string, resolver resolverFunc[T]) (T, err
return v.Value, err
}
if v.Error != "" {
return v.Value, fmt.Errorf(v.Error)
return v.Value, fmt.Errorf("failed to resolve cache: %s", v.Error)
}
return v.Value, nil
}
+1 -1
View File
@@ -3,5 +3,5 @@ package internal
const (
// JSONSchemaVersion is the current schema version output by the JSON encoder
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
JSONSchemaVersion = "16.0.15"
JSONSchemaVersion = "16.0.16"
)
+10 -6
View File
@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io"
"math"
"os"
)
@@ -52,9 +53,14 @@ func OpenZip(filepath string) (*ZipReadCloser, error) {
return nil, fmt.Errorf("unable to seek to beginning of archive: %w", err)
}
size := fi.Size() - int64(offset)
if offset > math.MaxInt64 {
return nil, fmt.Errorf("archive start offset too large: %v", offset)
}
offset64 := int64(offset) //nolint:gosec // lint bug, checked above: https://github.com/securego/gosec/issues/1187
r, err := zip.NewReader(io.NewSectionReader(f, int64(offset), size), size)
size := fi.Size() - offset64
r, err := zip.NewReader(io.NewSectionReader(f, offset64, size), size)
if err != nil {
return nil, fmt.Errorf("unable to open ZipReadCloser @ %q: %w", filepath, err)
}
@@ -95,8 +101,6 @@ type directoryEnd struct {
}
// note: this is derived from readDirectoryEnd within the archive/zip package
//
//nolint:gocognit
func findArchiveStartOffset(r io.ReaderAt, size int64) (startOfArchive uint64, err error) {
// look for directoryEndSignature in the last 1k, then in the last 65k
var buf []byte
@@ -150,7 +154,7 @@ func findArchiveStartOffset(r io.ReaderAt, size int64) (startOfArchive uint64, e
startOfArchive = uint64(directoryEndOffset) - d.directorySize - d.directoryOffset
// Make sure directoryOffset points to somewhere in our file.
if o := int64(d.directoryOffset); o < 0 || o >= size {
if d.directoryOffset >= uint64(size) {
return 0, zip.ErrFormat
}
return startOfArchive, nil
@@ -179,7 +183,7 @@ func findDirectory64End(r io.ReaderAt, directoryEndOffset int64) (int64, error)
if b.uint32() != 1 { // total number of disks
return -1, nil // the file is not a valid zip64-file
}
return int64(p), nil
return int64(p), nil //nolint:gosec
}
// readDirectory64End reads the zip64 directory end and updates the
@@ -36,8 +36,7 @@ func generateRelationships(resolver file.Resolver, accessor sbomsync.Accessor, i
newRelationships.Add(r)
}
}
for _, parentPkg := range s.Artifacts.Packages.Sorted(pkg.BinaryPkg) {
for _, parentPkg := range allElfPackages(s) {
for _, evidentLocation := range parentPkg.Locations.ToSlice() {
if evidentLocation.Annotations[pkg.EvidenceAnnotationKey] != pkg.PrimaryEvidenceAnnotation {
continue
@@ -101,7 +100,7 @@ func onlyPrimaryEvidenceLocations(p pkg.Package) []file.Location {
func allElfPackages(s *sbom.SBOM) []pkg.Package {
var elfPkgs []pkg.Package
for _, p := range s.Artifacts.Packages.Sorted(pkg.BinaryPkg) {
for _, p := range s.Artifacts.Packages.Sorted() {
if !isElfPackage(p) {
continue
}
@@ -50,6 +50,22 @@ func TestPackagesToRemove(t *testing.T) {
}
glibCBinaryELFPackage.SetID()
glibCBinaryELFPackageAsRPM := pkg.Package{
Name: "glibc",
Locations: file.NewLocationSet(
file.NewLocation(glibcCoordinate.RealPath).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
),
Type: pkg.RpmPkg, // note: the elf package claims it is a RPM, not binary
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
Type: "rpm",
Vendor: "syft",
System: "syftsys",
SourceRepo: "https://github.com/someone/somewhere.git",
Commit: "5534c38d0ffef9a3f83154f0b7a7fb6ab0ab6dbb",
},
}
glibCBinaryELFPackageAsRPM.SetID()
glibCBinaryClassifierPackage := pkg.Package{
Name: "glibc",
Locations: file.NewLocationSet(
@@ -83,9 +99,15 @@ func TestPackagesToRemove(t *testing.T) {
want: []artifact.ID{glibCBinaryELFPackage.ID()},
},
{
name: "remove no packages when there is a single binary package",
name: "keep packages that are overlapping rpm --> binary when the binary self identifies as an RPM",
resolver: file.NewMockResolverForPaths(glibcCoordinate.RealPath),
accessor: newAccessor([]pkg.Package{glibCBinaryELFPackage}, map[file.Coordinates]file.Executable{}, nil),
accessor: newAccessor([]pkg.Package{glibCPackage, glibCBinaryELFPackageAsRPM}, map[file.Coordinates]file.Executable{}, nil),
want: []artifact.ID{},
},
{
name: "remove no packages when there is a single binary package (or self identifying RPM)",
resolver: file.NewMockResolverForPaths(glibcCoordinate.RealPath),
accessor: newAccessor([]pkg.Package{glibCBinaryELFPackage, glibCBinaryELFPackageAsRPM}, map[file.Coordinates]file.Executable{}, nil),
want: []artifact.ID{},
},
{
@@ -173,9 +195,9 @@ func TestNewDependencyRelationships(t *testing.T) {
file.NewLocation(parallelLibCoordinate.RealPath).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
),
Language: "",
Type: pkg.BinaryPkg,
Type: pkg.RpmPkg,
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
Type: "testfixture",
Type: "rpm",
Vendor: "syft",
System: "syftsys",
SourceRepo: "https://github.com/someone/somewhere.git",
+13 -2
View File
@@ -1,9 +1,9 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at 2024-05-23 08:47:23.204981 -0400 EDT m=+0.050881068
// This file was generated by robots at 2024-08-20 11:33:49.349625 -0400 EDT m=+0.383911876
// using data from https://spdx.org/licenses/licenses.json
package spdxlicense
const Version = "3.24.0"
const Version = "3.25.0"
var licenseIDs = map[string]string{
"0bsd": "0BSD",
@@ -501,6 +501,8 @@ var licenseIDs = map[string]string{
"dldezero2.0": "DL-DE-ZERO-2.0",
"dldezero2.0.0": "DL-DE-ZERO-2.0",
"doc": "DOC",
"docbookschema": "DocBook-Schema",
"docbookxml": "DocBook-XML",
"dotseqn": "Dotseqn",
"drl1": "DRL-1.0",
"drl1.0": "DRL-1.0",
@@ -714,6 +716,7 @@ var licenseIDs = map[string]string{
"gutmann": "Gutmann",
"haskellreport": "HaskellReport",
"hdparm": "hdparm",
"hidapi": "HIDAPI",
"hippocratic2": "Hippocratic-2.1",
"hippocratic2.1": "Hippocratic-2.1",
"hippocratic2.1.0": "Hippocratic-2.1",
@@ -740,6 +743,7 @@ var licenseIDs = map[string]string{
"hpndmarkuskuhn": "HPND-Markus-Kuhn",
"hpndmerchantabilityvariant": "HPND-merchantability-variant",
"hpndmitdisclaimer": "HPND-MIT-disclaimer",
"hpndnetrek": "HPND-Netrek",
"hpndpbmplus": "HPND-Pbmplus",
"hpndsellmitdisclaimerxserver": "HPND-sell-MIT-disclaimer-xserver",
"hpndsellregexpr": "HPND-sell-regexpr",
@@ -1165,6 +1169,7 @@ var licenseIDs = map[string]string{
"rsamd": "RSA-MD",
"rscpl": "RSCPL",
"ruby": "Ruby",
"rubypty": "Ruby-pty",
"saxpath": "Saxpath",
"saxpd": "SAX-PD",
"saxpd2": "SAX-PD-2.0",
@@ -1265,6 +1270,9 @@ var licenseIDs = map[string]string{
"tuberlin2": "TU-Berlin-2.0",
"tuberlin2.0": "TU-Berlin-2.0",
"tuberlin2.0.0": "TU-Berlin-2.0",
"ubuntufont1": "Ubuntu-font-1.0",
"ubuntufont1.0": "Ubuntu-font-1.0",
"ubuntufont1.0.0": "Ubuntu-font-1.0",
"ucar": "UCAR",
"ucl1": "UCL-1.0",
"ucl1.0": "UCL-1.0",
@@ -1315,8 +1323,11 @@ var licenseIDs = map[string]string{
"x11.0": "X11",
"x11.0.0": "X11",
"x11.0.0distributemodificationsvariant": "X11-distribute-modifications-variant",
"x11.0.0swapped": "X11-swapped",
"x11.0distributemodificationsvariant": "X11-distribute-modifications-variant",
"x11.0swapped": "X11-swapped",
"x11distributemodificationsvariant": "X11-distribute-modifications-variant",
"x11swapped": "X11-swapped",
"xdebug1": "Xdebug-1.03",
"xdebug1.03": "Xdebug-1.03",
"xdebug1.03.0": "Xdebug-1.03",
+6 -1
View File
@@ -5,9 +5,11 @@ import (
"fmt"
"runtime/debug"
"sync"
"time"
"github.com/hashicorp/go-multierror"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/sbomsync"
"github.com/anchore/syft/syft/event/monitor"
"github.com/anchore/syft/syft/file"
@@ -68,5 +70,8 @@ func runTaskSafely(ctx context.Context, t Task, resolver file.Resolver, s sbomsy
}
}()
return t.Execute(ctx, resolver, s)
start := time.Now()
res := t.Execute(ctx, resolver, s)
log.WithFields("task", t.Name(), "elapsed", time.Since(start)).Info("task completed")
return res
}
+22 -10
View File
@@ -15,10 +15,11 @@ import (
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/cataloging"
"github.com/anchore/syft/syft/cataloging/pkgcataloging"
"github.com/anchore/syft/syft/cpe"
"github.com/anchore/syft/syft/event/monitor"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/common/cpe"
cpeutils "github.com/anchore/syft/syft/pkg/cataloger/common/cpe"
)
type packageTaskFactory func(cfg CatalogingFactoryConfig) Task
@@ -81,9 +82,7 @@ func (f PackageTaskFactories) Tasks(cfg CatalogingFactoryConfig) ([]Task, error)
}
// NewPackageTask creates a Task function for a generic pkg.Cataloger, honoring the common configuration options.
//
//nolint:funlen
func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string) Task {
func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string) Task { //nolint: funlen
fn := func(ctx context.Context, resolver file.Resolver, sbom sbomsync.Builder) error {
catalogerName := c.Name()
log.WithFields("name", catalogerName).Trace("starting package cataloger")
@@ -102,21 +101,25 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string
pkgs, relationships, err := c.Catalog(ctx, resolver)
if err != nil {
return fmt.Errorf("unable to catalog packages with %q: %w", c.Name(), err)
return fmt.Errorf("unable to catalog packages with %q: %w", catalogerName, err)
}
log.WithFields("cataloger", c.Name()).Debugf("discovered %d packages", len(pkgs))
log.WithFields("cataloger", catalogerName).Debugf("discovered %d packages", len(pkgs))
for i, p := range pkgs {
if cfg.DataGenerationConfig.GenerateCPEs {
if p.FoundBy == "" {
p.FoundBy = catalogerName
}
if cfg.DataGenerationConfig.GenerateCPEs && !hasAuthoritativeCPE(p.CPEs) {
// generate CPEs (note: this is excluded from package ID, so is safe to mutate)
// we might have binary classified CPE already with the package so we want to append here
dictionaryCPEs, ok := cpe.DictionaryFind(p)
dictionaryCPEs, ok := cpeutils.DictionaryFind(p)
if ok {
log.Tracef("used CPE dictionary to find CPEs for %s package %q: %s", p.Type, p.Name, dictionaryCPEs)
p.CPEs = append(p.CPEs, dictionaryCPEs...)
} else {
p.CPEs = append(p.CPEs, cpe.Generate(p)...)
p.CPEs = append(p.CPEs, cpeutils.Generate(p)...)
}
}
@@ -145,7 +148,7 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string
t.Add(int64(len(pkgs)))
t.SetCompleted()
log.WithFields("name", c.Name()).Trace("package cataloger completed")
log.WithFields("name", catalogerName).Trace("package cataloger completed")
return nil
}
@@ -154,6 +157,15 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string
return NewTask(c.Name(), fn, tags...)
}
func hasAuthoritativeCPE(cpes []cpe.CPE) bool {
for _, c := range cpes {
if c.Source != cpe.GeneratedSource {
return true
}
}
return false
}
func prettyName(s string) string {
if s == "" {
return ""
@@ -0,0 +1,55 @@
package task
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/cpe"
)
func Test_hasAuthoritativeCPE(t *testing.T) {
tests := []struct {
name string
cpes []cpe.CPE
want bool
}{
{
name: "no cpes",
cpes: []cpe.CPE{},
want: false,
},
{
name: "no authoritative cpes",
cpes: []cpe.CPE{
{
Source: cpe.GeneratedSource,
},
},
want: false,
},
{
name: "has declared (authoritative) cpe",
cpes: []cpe.CPE{
{
Source: cpe.DeclaredSource,
},
},
want: true,
},
{
name: "has lookup (authoritative) cpe",
cpes: []cpe.CPE{
{
Source: cpe.NVDDictionaryLookupSource,
},
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, hasAuthoritativeCPE(tt.cpes))
})
}
}
+2
View File
@@ -21,6 +21,7 @@ import (
"github.com/anchore/syft/syft/pkg/cataloger/kernel"
"github.com/anchore/syft/syft/pkg/cataloger/lua"
"github.com/anchore/syft/syft/pkg/cataloger/nix"
"github.com/anchore/syft/syft/pkg/cataloger/ocaml"
"github.com/anchore/syft/syft/pkg/cataloger/php"
"github.com/anchore/syft/syft/pkg/cataloger/python"
"github.com/anchore/syft/syft/pkg/cataloger/r"
@@ -95,6 +96,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories {
newSimplePackageTaskFactory(swift.NewCocoapodsCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "cocoapods"),
newSimplePackageTaskFactory(swift.NewSwiftPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "spm"),
newSimplePackageTaskFactory(swipl.NewSwiplPackCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swipl", "pack"),
newSimplePackageTaskFactory(ocaml.NewOpamPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "ocaml", "opam"),
// language-specific package for both image and directory scans (but not necessarily declared) ////////////////////////////////////////
newSimplePackageTaskFactory(dotnet.NewDotnetPortableExecutableCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "dotnet", "c#", "binary"),
File diff suppressed because it is too large Load Diff
+48 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "anchore.io/schema/syft/json/16.0.15/document",
"$id": "anchore.io/schema/syft/json/16.0.16/document",
"$ref": "#/$defs/Document",
"$defs": {
"AlpmDbEntry": {
@@ -1436,6 +1436,50 @@
"files"
]
},
"OpamPackage": {
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"licenses": {
"items": {
"type": "string"
},
"type": "array"
},
"url": {
"type": "string"
},
"checksum": {
"items": {
"type": "string"
},
"type": "array"
},
"homepage": {
"type": "string"
},
"dependencies": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object",
"required": [
"name",
"version",
"licenses",
"url",
"checksum",
"homepage",
"dependencies"
]
},
"Package": {
"properties": {
"id": {
@@ -1563,6 +1607,9 @@
{
"$ref": "#/$defs/NixStoreEntry"
},
{
"$ref": "#/$defs/OpamPackage"
},
{
"$ref": "#/$defs/PhpComposerInstalledEntry"
},
+1 -1
View File
@@ -175,7 +175,7 @@ func hasElfDynTag(f *elf.File, tag elf.DynTag) bool {
t = elf.DynTag(f.ByteOrder.Uint32(d[0:4]))
d = d[8:]
case elf.ELFCLASS64:
t = elf.DynTag(f.ByteOrder.Uint64(d[0:8]))
t = elf.DynTag(f.ByteOrder.Uint64(d[0:8])) //nolint:gosec
d = d[16:]
}
if t == tag {
@@ -0,0 +1,15 @@
.DEFAULT_GOAL := default
default:
@for dir in $(shell find . -mindepth 1 -maxdepth 1 -type d); do \
if [ -f "$$dir/Makefile" ]; then \
$(MAKE) -C $$dir; \
fi; \
done
%:
@for dir in $(shell find . -mindepth 1 -maxdepth 1 -type d); do \
if [ -f "$$dir/Makefile" ]; then \
$(MAKE) -C $$dir $@; \
fi; \
done
@@ -1,8 +1,19 @@
BIN=./bin
TOOL_IMAGE=localhost/syft-bin-build-tools:latest
VERIFY_FILE=actual_verify
FINGERPRINT_FILE=$(BIN).fingerprint
all: build verify
ifndef BIN
$(error BIN is not set)
endif
.DEFAULT_GOAL := fixtures
# requirement 1: 'fixtures' goal to generate any and all test fixtures
fixtures: build verify
# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted
fingerprint: $(FINGERPRINT_FILE)
tools-check:
@sha256sum -c Dockerfile.sha256 || (echo "Tools Dockerfile has changed" && exit 1)
@@ -25,10 +36,14 @@ verify: tools
debug:
docker run -i --rm -v $(shell pwd):/mount -w /mount/project $(TOOL_IMAGE) bash
cache.fingerprint:
@find project Dockerfile Makefile -type f -exec md5sum {} + | awk '{print $1}' | sort | tee cache.fingerprint
# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint
.PHONY: $(FINGERPRINT_FILE)
$(FINGERPRINT_FILE):
@find project Dockerfile Makefile -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE)
@#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}'
# requirement 4: 'clean' goal to remove all generated test fixtures
clean:
rm -f $(BIN)/*
rm -rf $(BIN) Dockerfile.sha256 $(VERIFY_FILE) $(FINGERPRINT_FILE)
.PHONY: build verify debug build-image build-bins clean dockerfile-check cache.fingerprint
.PHONY: tools tools-check build verify debug clean
@@ -1,8 +1,20 @@
BIN=./bin
TOOL_IMAGE=localhost/syft-shared-info-build-tools:latest
VERIFY_FILE=actual_verify
FINGERPRINT_FILE=$(BIN).fingerprint
ifndef BIN
$(error BIN is not set)
endif
.DEFAULT_GOAL := fixtures
# requirement 1: 'fixtures' goal to generate any and all test fixtures
fixtures: build
# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted
fingerprint: $(FINGERPRINT_FILE)
all: build
tools-check:
@sha256sum -c Dockerfile.sha256 || (echo "Tools Dockerfile has changed" && exit 1)
@@ -10,16 +22,20 @@ tools:
@(docker inspect $(TOOL_IMAGE) > /dev/null && make tools-check) || (docker build -t $(TOOL_IMAGE) . && sha256sum Dockerfile > Dockerfile.sha256)
build: tools
mkdir -p $(BIN)
@mkdir -p $(BIN)
docker run --platform linux/amd64 -i -v $(shell pwd):/mount -w /mount/project $(TOOL_IMAGE) make
debug:
docker run --platform linux/amd64 -i --rm -v $(shell pwd):/mount -w /mount/project $(TOOL_IMAGE) bash
cache.fingerprint:
@find project Dockerfile Makefile -type f -exec md5sum {} + | awk '{print $1}' | sort | tee cache.fingerprint
# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint
.PHONY: $(FINGERPRINT_FILE)
$(FINGERPRINT_FILE):
@find project Dockerfile Makefile -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE)
@#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}'
# requirement 4: 'clean' goal to remove all generated test fixtures
clean:
rm -f $(BIN)/*
rm -rf $(BIN) Dockerfile.sha256 $(VERIFY_FILE) $(FINGERPRINT_FILE)
.PHONY: build verify debug build-image build-bins clean dockerfile-check cache.fingerprint
.PHONY: tools tools-check build debug clean
@@ -211,6 +211,12 @@ func toBomProperties(srcMetadata source.Description) *[]cyclonedx.Property {
metadata, ok := srcMetadata.Metadata.(source.ImageMetadata)
if ok {
props := helpers.EncodeProperties(metadata.Labels, "syft:image:labels")
// return nil if props is nil to avoid creating a pointer to a nil slice,
// which results in a null JSON value that does not comply with the CycloneDX schema.
// https://github.com/anchore/grype/issues/1759
if props == nil {
return nil
}
return &props
}
return nil
@@ -236,6 +236,53 @@ func Test_toBomDescriptor(t *testing.T) {
}
}
func Test_toBomProperties(t *testing.T) {
tests := []struct {
name string
srcMetadata source.Description
props *[]cyclonedx.Property
}{
{
name: "ImageMetadata without labels",
srcMetadata: source.Description{
Metadata: source.ImageMetadata{
Labels: map[string]string{},
},
},
props: nil,
},
{
name: "ImageMetadata with labels",
srcMetadata: source.Description{
Metadata: source.ImageMetadata{
Labels: map[string]string{
"label1": "value1",
"label2": "value2",
},
},
},
props: &[]cyclonedx.Property{
{Name: "syft:image:labels:label1", Value: "value1"},
{Name: "syft:image:labels:label2", Value: "value2"},
},
},
{
name: "not ImageMetadata",
srcMetadata: source.Description{
Metadata: source.FileMetadata{},
},
props: nil,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
props := toBomProperties(test.srcMetadata)
require.Equal(t, test.props, props)
})
}
}
func Test_toOsComponent(t *testing.T) {
tests := []struct {
name string
@@ -505,6 +505,14 @@ func toPackageChecksums(p pkg.Package) ([]spdx.Checksum, bool) {
Algorithm: spdx.ChecksumAlgorithm(algo),
Value: hexStr,
})
case pkg.OpamPackage:
for _, checksum := range meta.Checksums {
parts := strings.Split(checksum, "=")
checksums = append(checksums, spdx.Checksum{
Algorithm: spdx.ChecksumAlgorithm(strings.ToUpper(parts[0])),
Value: parts[1],
})
}
}
return checksums, filesAnalyzed
}
@@ -335,6 +335,31 @@ func Test_toPackageChecksums(t *testing.T) {
},
filesAnalyzed: false,
},
{
name: "Opam Package",
pkg: pkg.Package{
Name: "test",
Version: "1.0.0",
Language: pkg.Go,
Metadata: pkg.OpamPackage{
Checksums: []string{
"sha256=f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c",
"sha512=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b",
},
},
},
expected: []spdx.Checksum{
{
Algorithm: "SHA256",
Value: "f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c",
},
{
Algorithm: "SHA512",
Value: "05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b",
},
},
filesAnalyzed: false,
},
{
name: "Package with no metadata type",
pkg: pkg.Package{
@@ -124,7 +124,7 @@ func decodePackageMetadata(vals map[string]string, c *cyclonedx.Component, typeN
if metadataType == nil {
return nil
}
metaPtrTyp := reflect.PtrTo(metadataType)
metaPtrTyp := reflect.PointerTo(metadataType)
metaPtr := Decode(metaPtrTyp, vals, "syft:metadata", CycloneDXFields)
// Map all explicit metadata properties
@@ -39,12 +39,23 @@ func ToSyftModel(bom *cyclonedx.BOM) (*sbom.SBOM, error) {
}
func collectBomPackages(bom *cyclonedx.BOM, s *sbom.SBOM, idMap map[string]interface{}) error {
if bom.Components == nil {
componentsPresent := false
if bom.Components != nil {
for i := range *bom.Components {
collectPackages(&(*bom.Components)[i], s, idMap)
}
componentsPresent = true
}
if bom.Metadata != nil && bom.Metadata.Component != nil {
collectPackages(bom.Metadata.Component, s, idMap)
componentsPresent = true
}
if !componentsPresent {
return fmt.Errorf("no components are defined in the CycloneDX BOM")
}
for i := range *bom.Components {
collectPackages(&(*bom.Components)[i], s, idMap)
}
return nil
}
@@ -54,17 +54,14 @@ func decodeLicenses(c *cyclonedx.Component) []pkg.License {
}
for _, l := range *c.Licenses {
if l.License == nil {
continue
}
// these fields are mutually exclusive in the spec
switch {
case l.License.ID != "":
case l.License != nil && l.License.ID != "":
licenses = append(licenses, pkg.NewLicenseFromURLs(l.License.ID, l.License.URL))
case l.License.Name != "":
case l.License != nil && l.License.Name != "":
licenses = append(licenses, pkg.NewLicenseFromURLs(l.License.Name, l.License.URL))
case l.Expression != "":
licenses = append(licenses, pkg.NewLicenseFromURLs(l.Expression, l.License.URL))
licenses = append(licenses, pkg.NewLicense(l.Expression))
default:
}
}
@@ -72,7 +69,6 @@ func decodeLicenses(c *cyclonedx.Component) []pkg.License {
return licenses
}
// nolint:funlen
func separateLicenses(p pkg.Package) (spdx, other cyclonedx.Licenses, expressions []string) {
ex := make([]string, 0)
spdxc := cyclonedx.Licenses{}
@@ -254,7 +254,8 @@ func TestDecodeLicenses(t *testing.T) {
input: &cyclonedx.Component{
Licenses: &cyclonedx.Licenses{
{
License: &cyclonedx.License{},
// CycloneDX specification doesn't allow to provide License if Expression is provided
License: nil,
Expression: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0",
},
},
@@ -264,7 +265,6 @@ func TestDecodeLicenses(t *testing.T) {
Value: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0",
SPDXExpression: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0",
Type: license.Declared,
URLs: []string{},
},
},
},
@@ -165,7 +165,7 @@ func Decode(typ reflect.Type, values map[string]string, prefix string, fn FieldN
isSlice := false
if typ.Kind() == reflect.Slice {
typ = reflect.PtrTo(typ)
typ = reflect.PointerTo(typ)
isSlice = true
}
@@ -26,6 +26,8 @@ func DownloadLocation(p pkg.Package) string {
return NoneIfEmpty(metadata.Dist.URL)
case pkg.PhpComposerInstalledEntry:
return NoneIfEmpty(metadata.Dist.URL)
case pkg.OpamPackage:
return NoneIfEmpty(metadata.URL)
}
}
return NOASSERTION
@@ -34,7 +34,7 @@ const (
//
// Available options are: <omit>, NOASSERTION, Person: <person>, Organization: <org>
// return values are: <type>, <value>
func Originator(p pkg.Package) (typ string, author string) { // nolint: funlen
func Originator(p pkg.Package) (typ string, author string) { //nolint: funlen
if !hasMetadata(p) {
return typ, author
}
@@ -41,6 +41,7 @@ func Test_OriginatorSupplier(t *testing.T) {
pkg.RustCargoLockEntry{},
pkg.SwiftPackageManagerResolvedEntry{},
pkg.SwiplPackEntry{},
pkg.OpamPackage{},
pkg.YarnLockEntry{},
)
tests := []struct {
@@ -350,6 +351,14 @@ func Test_OriginatorSupplier(t *testing.T) {
originator: "Person: auth (auth@auth.gov)",
supplier: "Person: me (me@auth.com)",
},
{
name: "from ocaml opam",
input: pkg.Package{
Metadata: pkg.OpamPackage{},
},
originator: "",
supplier: "",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
@@ -64,6 +64,8 @@ func SourceInfo(p pkg.Package) string {
answer = "acquired package info from resolved Swift package manifest"
case pkg.SwiplPackPkg:
answer = "acquired package info from SWI Prolo pack package file"
case pkg.OpamPkg:
answer = "acquired package info from OCaml opam package file"
case pkg.GithubActionPkg, pkg.GithubActionWorkflowPkg:
answer = "acquired package info from GitHub Actions workflow file or composite action file"
case pkg.WordpressPluginPkg:
@@ -271,6 +271,14 @@ func Test_SourceInfo(t *testing.T) {
"acquired package info from SWI Prolo pack package file",
},
},
{
input: pkg.Package{
Type: pkg.OpamPkg,
},
expected: []string{
"acquired package info from OCaml opam package file",
},
},
{
input: pkg.Package{
Type: pkg.GithubActionPkg,
+1 -1
View File
@@ -146,7 +146,7 @@ func safeFileModeConvert(val int) (fs.FileMode, error) {
if err != nil {
return 0, err
}
return os.FileMode(mode), nil
return os.FileMode(mode), nil //nolint:gosec
}
func toSyftLicenses(m []model.License) (p []pkg.License) {
@@ -1,4 +0,0 @@
# Note: changes to this file will result in updating several test values. Consider making a new image fixture instead of editing this one.
FROM scratch
ADD file-1.txt /somefile-1.txt
ADD file-2.txt /somefile-2.txt
@@ -1 +0,0 @@
this file has contents
@@ -1 +0,0 @@
file-2 contents!
@@ -1,11 +1,11 @@
[Image]
Layer: 0
Digest: sha256:fb6beecb75b39f4bb813dbf177e501edd5ddb3e69bb45cedeb78c676ee1b7a59
Digest: sha256:100d5a55f9032faead28b7427fa3e650e4f0158f86ea89d06e1489df00cb8c6f
Size: 22
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
Layer: 1
Digest: sha256:319b588ce64253a87b533c8ed01cf0025e0eac98e7b516e12532957e1244fdec
Digest: sha256:000fb9200890d3a19138478b20023023c0dce1c54352007c2863716780f049eb
Size: 16
MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip
@@ -120,7 +120,8 @@ func (r *ContainerImageAllLayers) FilesByPath(paths ...string) ([]file.Location,
}
// FilesByGlob returns all file.References that match the given path glob pattern from any layer in the image.
// nolint:gocognit
//
//nolint:gocognit
func (r *ContainerImageAllLayers) FilesByGlob(patterns ...string) ([]file.Location, error) {
uniqueFileIDs := stereoscopeFile.NewFileReferenceSet()
uniqueLocations := make([]file.Location, 0)
@@ -79,7 +79,8 @@ func (r *ContainerImageSquash) FilesByPath(paths ...string) ([]file.Location, er
}
// FilesByGlob returns all file.References that match the given path glob pattern within the squashed representation of the image.
// nolint:gocognit
//
//nolint:gocognit
func (r *ContainerImageSquash) FilesByGlob(patterns ...string) ([]file.Location, error) {
uniqueFileIDs := stereoscopeFile.NewFileReferenceSet()
uniqueLocations := make([]file.Location, 0)
@@ -78,7 +78,8 @@ func findMetadataDefinitionNames(paths ...string) ([]string, error) {
// note: 35 is a point-in-time gut check. This number could be updated if new metadata definitions are added, but is not required.
// it is really intended to catch any major issues with the generation process that would generate, say, 0 definitions.
if len(strNames) < 35 {
return nil, fmt.Errorf("not enough metadata definitions found (discovered: " + fmt.Sprintf("%d", len(strNames)) + ")")
msg := fmt.Sprintf("not enough metadata definitions found (discovered %d)", len(strNames))
return nil, fmt.Errorf("%v", msg)
}
return strNames, nil
@@ -34,6 +34,7 @@ func AllTypes() []any {
pkg.NixStoreEntry{},
pkg.NpmPackage{},
pkg.NpmPackageLockEntry{},
pkg.OpamPackage{},
pkg.PhpComposerInstalledEntry{},
pkg.PhpComposerLockEntry{},
pkg.PhpPeclEntry{},
+1
View File
@@ -103,6 +103,7 @@ var jsonTypes = makeJSONTypes(
jsonNamesWithoutLookup(pkg.RpmArchive{}, "rpm-archive", "RpmMetadata"), // the legacy value is split into two types, where the other is preferred
jsonNames(pkg.SwiftPackageManagerResolvedEntry{}, "swift-package-manager-lock-entry", "SwiftPackageManagerMetadata"),
jsonNames(pkg.SwiplPackEntry{}, "swiplpack-package"),
jsonNames(pkg.OpamPackage{}, "opam-package"),
jsonNames(pkg.RustCargoLockEntry{}, "rust-cargo-lock-entry", "RustCargoPackageMetadata"),
jsonNamesWithoutLookup(pkg.RustBinaryAuditEntry{}, "rust-cargo-audit-entry", "RustCargoPackageMetadata"), // the legacy value is split into two types, where the other is preferred
jsonNames(pkg.WordpressPluginEntry{}, "wordpress-plugin-entry", "WordpressMetadata"),
@@ -68,7 +68,8 @@ func findMetadataDefinitionNames(paths ...string) ([]string, error) {
// note: 3 is a point-in-time gut check. This number could be updated if new metadata definitions are added, but is not required.
// it is really intended to catch any major issues with the generation process that would generate, say, 0 definitions.
if len(strNames) < 3 {
return nil, fmt.Errorf("not enough metadata definitions found (discovered: " + fmt.Sprintf("%d", len(strNames)) + ")")
msg := fmt.Sprintf("not enough metadata definitions found (discovered %d)", len(strNames))
return nil, fmt.Errorf("%v", msg)
}
return strNames, nil
+1 -1
View File
@@ -34,7 +34,7 @@ type parsedData struct {
// parseApkDB parses packages from a given APK "installed" flat-file DB. For more
// information on specific fields, see https://wiki.alpinelinux.org/wiki/Apk_spec.
//
//nolint:funlen,gocognit
//nolint:funlen
func parseApkDB(_ context.Context, resolver file.Resolver, env *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
scanner := bufio.NewScanner(reader)
+6 -3
View File
@@ -196,7 +196,6 @@ func matchExcluding(matcher EvidenceMatcher, contentPatternsToExclude ...string)
}
}
//nolint:gocognit
func sharedLibraryLookup(sharedLibraryPattern string, sharedLibraryMatcher EvidenceMatcher) EvidenceMatcher {
pat := regexp.MustCompile(sharedLibraryPattern)
return func(classifier Classifier, context matcherContext) (packages []pkg.Package, _ error) {
@@ -275,9 +274,13 @@ func getContents(context matcherContext) ([]byte, error) {
// singleCPE returns a []cpe.CPE with Source: Generated based on the cpe string or panics if the
// cpe string cannot be parsed into valid CPE Attributes
func singleCPE(cpeString string) []cpe.CPE {
func singleCPE(cpeString string, source ...cpe.Source) []cpe.CPE {
src := cpe.GeneratedSource
if len(source) > 0 {
src = source[0]
}
return []cpe.CPE{
cpe.Must(cpeString, cpe.GeneratedSource),
cpe.Must(cpeString, src),
}
}
@@ -116,6 +116,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Metadata: metadata("mysql-binary"),
},
},
{
logicalFixture: "mysql/8.0.37/linux-amd64",
expected: pkg.Package{
Name: "mysql",
Version: "8.0.37",
Type: "binary",
PURL: "pkg:generic/mysql@8.0.37",
Locations: locations("mysql"),
Metadata: metadata("mysql-binary"),
},
},
{
logicalFixture: "percona-server/8.0.35/linux-amd64",
expected: pkg.Package{
@@ -348,7 +359,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Metadata: metadata("haproxy-binary"),
},
},
{
logicalFixture: "haproxy/3.1-dev0/linux-amd64",
expected: pkg.Package{
Name: "haproxy",
Version: "3.1-dev0",
Type: "binary",
PURL: "pkg:generic/haproxy@3.1-dev0",
Locations: locations("haproxy"),
Metadata: metadata("haproxy-binary"),
},
},
{
logicalFixture: "helm/3.11.1/linux-amd64",
expected: pkg.Package{
@@ -940,6 +961,28 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Metadata: metadata("swipl-binary"),
},
},
{
logicalFixture: "haskell-ghc/9.6.5/linux-amd64",
expected: pkg.Package{
Name: "haskell/ghc",
Version: "9.6.5",
Type: "binary",
PURL: "pkg:generic/haskell/ghc@9.6.5",
Locations: locations("ghc-9.6.5"),
Metadata: metadata("haskell-ghc-binary"),
},
},
{
logicalFixture: "haskell-cabal/3.10.3.0/linux-amd64",
expected: pkg.Package{
Name: "haskell/cabal",
Version: "3.10.3.0",
Type: "binary",
PURL: "pkg:generic/haskell/cabal@3.10.3.0",
Locations: locations("cabal"),
Metadata: metadata("haskell-cabal-binary"),
},
},
{
logicalFixture: "nginx/1.25.1/linux-amd64",
expected: pkg.Package{
+102 -53
View File
@@ -23,8 +23,8 @@ func DefaultClassifiers() []Classifier {
Package: "python",
PURL: mustPURL("pkg:generic/python@version"),
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
},
{
@@ -34,8 +34,8 @@ func DefaultClassifiers() []Classifier {
Package: "python",
PURL: mustPURL("pkg:generic/python@version"),
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
},
{
@@ -53,7 +53,7 @@ func DefaultClassifiers() []Classifier {
`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)\x00`),
Package: "go",
PURL: mustPURL("pkg:generic/go@version"),
CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "julia-binary",
@@ -62,7 +62,7 @@ func DefaultClassifiers() []Classifier {
`(?m)__init__\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00verify`),
Package: "julia",
PURL: mustPURL("pkg:generic/julia@version"),
CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "helm",
@@ -71,7 +71,7 @@ func DefaultClassifiers() []Classifier {
`(?m)\x00v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`),
Package: "helm",
PURL: mustPURL("pkg:golang/helm.sh/helm@version"),
CPEs: singleCPE("cpe:2.3:a:helm:helm:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:helm:helm:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "redis-binary",
@@ -82,7 +82,10 @@ func DefaultClassifiers() []Classifier {
),
Package: "redis",
PURL: mustPURL("pkg:generic/redis@version"),
CPEs: singleCPE("cpe:2.3:a:redislabs:redis:*:*:*:*:*:*:*:*"),
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:redislabs:redis:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
cpe.Must("cpe:2.3:a:redis:redis:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
},
{
Class: "java-binary-openjdk",
@@ -103,7 +106,7 @@ func DefaultClassifiers() []Classifier {
Package: "java/jre",
PURL: mustPURL("pkg:generic/java/jre@version"),
// TODO the updates might need to be part of the CPE Attributes, like: 1.8.0:update152
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "java-binary-ibm",
@@ -113,7 +116,7 @@ func DefaultClassifiers() []Classifier {
`(?m)\x00java\x00(?P<release>[0-9]+[.0-9]+)\x00{4}(?P<version>[0-9]+[-._a-zA-Z0-9]+)\x00`),
Package: "java/jre",
PURL: mustPURL("pkg:generic/java/jre@version"),
CPEs: singleCPE("cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "java-binary-oracle",
@@ -127,7 +130,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "java/jre",
PURL: mustPURL("pkg:generic/java/jre@version"),
CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "java-binary-graalvm",
@@ -136,7 +139,7 @@ func DefaultClassifiers() []Classifier {
`(?m)\x00(?P<version>[0-9]+[.0-9]+[.0-9]+\+[0-9]+-jvmci-[0-9]+[.0-9]+-b[0-9]+)\x00`),
Package: "java/graalvm",
PURL: mustPURL("pkg:generic/java/graalvm@version"),
CPEs: singleCPE("cpe:2.3:a:oracle:graalvm:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:oracle:graalvm:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "java-binary-jdk",
@@ -145,7 +148,7 @@ func DefaultClassifiers() []Classifier {
`(?m)\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\+[0-9]+)?([-._a-zA-Z0-9]+)?)\x00`),
Package: "java/jdk",
PURL: mustPURL("pkg:generic/java/jdk@version"),
CPEs: singleCPE("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "nodejs-binary",
@@ -154,7 +157,7 @@ func DefaultClassifiers() []Classifier {
`(?m)node\.js\/v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
Package: "node",
PURL: mustPURL("pkg:generic/node@version"),
CPEs: singleCPE("cpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "go-binary-hint",
@@ -163,6 +166,7 @@ func DefaultClassifiers() []Classifier {
`(?m)go(?P<version>[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)`),
Package: "go",
PURL: mustPURL("pkg:generic/go@version"),
CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "busybox-binary",
@@ -171,7 +175,7 @@ func DefaultClassifiers() []Classifier {
`(?m)BusyBox\s+v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
Package: "busybox",
PURL: mustPURL("pkg:generic/busybox@version"),
CPEs: singleCPE("cpe:2.3:a:busybox:busybox:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:busybox:busybox:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "util-linux-binary",
@@ -180,18 +184,18 @@ func DefaultClassifiers() []Classifier {
`\x00util-linux\s(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`),
Package: "util-linux",
PURL: mustPURL("pkg:generic/util-linux@version"),
CPEs: singleCPE("cpe:2.3:a:kernel:util-linux:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:kernel:util-linux:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "haproxy-binary",
FileGlob: "**/haproxy",
EvidenceMatcher: evidenceMatchers(
FileContentsVersionMatcher(`(?m)HA-Proxy version (?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
FileContentsVersionMatcher(`(?m)(?P<version>[0-9]+\.[0-9]+\.[0-9]+)-[0-9a-zA-Z]{7}.+HAProxy version`),
FileContentsVersionMatcher(`(?m)HA-Proxy version (?P<version>[0-9]+\.[0-9]+(\.|-dev)[0-9]+)`),
FileContentsVersionMatcher(`(?m)(?P<version>[0-9]+\.[0-9]+(\.|-dev)[0-9]+)-[0-9a-zA-Z]{7}.+HAProxy version`),
),
Package: "haproxy",
PURL: mustPURL("pkg:generic/haproxy@version"),
CPEs: singleCPE("cpe:2.3:a:haproxy:haproxy:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:haproxy:haproxy:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "perl-binary",
@@ -200,7 +204,7 @@ func DefaultClassifiers() []Classifier {
`(?m)\/usr\/local\/lib\/perl\d\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
Package: "perl",
PURL: mustPURL("pkg:generic/perl@version"),
CPEs: singleCPE("cpe:2.3:a:perl:perl:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:perl:perl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "php-cli-binary",
@@ -210,7 +214,7 @@ func DefaultClassifiers() []Classifier {
`(?m)X-Powered-By: PHP\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)`),
Package: "php-cli",
PURL: mustPURL("pkg:generic/php-cli@version"),
CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "php-fpm-binary",
@@ -219,7 +223,7 @@ func DefaultClassifiers() []Classifier {
`(?m)X-Powered-By: PHP\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)`),
Package: "php-fpm",
PURL: mustPURL("pkg:generic/php-fpm@version"),
CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "php-apache-binary",
@@ -228,7 +232,7 @@ func DefaultClassifiers() []Classifier {
`(?m)X-Powered-By: PHP\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)`),
Package: "libphp",
PURL: mustPURL("pkg:generic/php@version"),
CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "php-composer-binary",
@@ -237,7 +241,7 @@ func DefaultClassifiers() []Classifier {
`(?m)'pretty_version'\s*=>\s*'(?P<version>[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)'`),
Package: "composer",
PURL: mustPURL("pkg:generic/composer@version"),
CPEs: singleCPE("cpe:2.3:a:getcomposer:composer:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:getcomposer:composer:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "httpd-binary",
@@ -246,7 +250,7 @@ func DefaultClassifiers() []Classifier {
`(?m)Apache\/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
Package: "httpd",
PURL: mustPURL("pkg:generic/httpd@version"),
CPEs: singleCPE("cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "memcached-binary",
@@ -255,7 +259,7 @@ func DefaultClassifiers() []Classifier {
`(?m)memcached\s(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
Package: "memcached",
PURL: mustPURL("pkg:generic/memcached@version"),
CPEs: singleCPE("cpe:2.3:a:memcached:memcached:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:memcached:memcached:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "traefik-binary",
@@ -267,7 +271,7 @@ func DefaultClassifiers() []Classifier {
`(?m)(\x00|\x{FFFD})?v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`),
Package: "traefik",
PURL: mustPURL("pkg:generic/traefik@version"),
CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "arangodb-binary",
@@ -276,7 +280,7 @@ func DefaultClassifiers() []Classifier {
`(?m)\x00*(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?)\s\[linux\]`),
Package: "arangodb",
PURL: mustPURL("pkg:generic/arangodb@version"),
CPEs: singleCPE("cpe:2.3:a:arangodb:arangodb:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:arangodb:arangodb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "postgresql-binary",
@@ -289,16 +293,20 @@ func DefaultClassifiers() []Classifier {
`(?m)(\x00|\?)PostgreSQL (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
Package: "postgresql",
PURL: mustPURL("pkg:generic/postgresql@version"),
CPEs: singleCPE("cpe:2.3:a:postgresql:postgresql:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:postgresql:postgresql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "mysql-binary",
FileGlob: "**/mysql",
EvidenceMatcher: FileContentsVersionMatcher(
`(?m).*/mysql-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
EvidenceMatcher: evidenceMatchers(
// shutdown[NUL]8.0.37[NUL][NUL][NUL][NUL][NUL]mysql_real_esc
FileContentsVersionMatcher(`\x00(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)\x00+mysql`),
// /export/home/pb2/build/sb_0-26781090-1516292385.58/release/mysql-8.0.4-rc/mysys_ssl/my_default.cc
FileContentsVersionMatcher(`(?m).*/mysql-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
),
Package: "mysql",
PURL: mustPURL("pkg:generic/mysql@version"),
CPEs: singleCPE("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "mysql-binary",
@@ -308,8 +316,8 @@ func DefaultClassifiers() []Classifier {
Package: "percona-server",
PURL: mustPURL("pkg:generic/percona-server@version"),
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
},
{
@@ -320,9 +328,9 @@ func DefaultClassifiers() []Classifier {
Package: "percona-xtradb-cluster",
PURL: mustPURL("pkg:generic/percona-xtradb-cluster@version"),
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:percona:xtradb_cluster:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
cpe.Must("cpe:2.3:a:percona:xtradb_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
},
{
@@ -332,7 +340,7 @@ func DefaultClassifiers() []Classifier {
`(?m).*/percona-xtrabackup-(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
Package: "percona-xtrabackup",
PURL: mustPURL("pkg:generic/percona-xtrabackup@version"),
CPEs: singleCPE("cpe:2.3:a:percona:xtrabackup:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:percona:xtrabackup:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "mariadb-binary",
@@ -342,6 +350,7 @@ func DefaultClassifiers() []Classifier {
`(?m)(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)-MariaDB`),
Package: "mariadb",
PURL: mustPURL("pkg:generic/mariadb@version"),
CPEs: singleCPE("cpe:2.3:a:mariadb:mariadb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "rust-standard-library-linux",
@@ -351,7 +360,7 @@ func DefaultClassifiers() []Classifier {
`(?m)(\x00)clang LLVM \(rustc version (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`),
Package: "rust",
PURL: mustPURL("pkg:generic/rust@version"),
CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "rust-standard-library-macos",
@@ -361,7 +370,7 @@ func DefaultClassifiers() []Classifier {
`(?m)c (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`),
Package: "rust",
PURL: mustPURL("pkg:generic/rust@version"),
CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "ruby-binary",
@@ -375,7 +384,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "ruby",
PURL: mustPURL("pkg:generic/ruby@version"),
CPEs: singleCPE("cpe:2.3:a:ruby-lang:ruby:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:ruby-lang:ruby:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "erlang-binary",
@@ -392,7 +401,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "erlang",
PURL: mustPURL("pkg:generic/erlang@version"),
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "erlang-alpine-binary",
@@ -409,7 +418,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "erlang",
PURL: mustPURL("pkg:generic/erlang@version"),
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "erlang-library",
@@ -426,7 +435,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "erlang",
PURL: mustPURL("pkg:generic/erlang@version"),
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "swipl-binary",
@@ -436,7 +445,37 @@ func DefaultClassifiers() []Classifier {
),
Package: "swipl",
PURL: mustPURL("pkg:generic/swipl@version"),
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "haskell-ghc-binary",
FileGlob: "**/ghc*",
EvidenceMatcher: FileContentsVersionMatcher(
`(?m)\x00GHC (?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00`,
),
Package: "haskell/ghc",
PURL: mustPURL("pkg:generic/haskell/ghc@version"),
CPEs: singleCPE("cpe:2.3:a:haskell:ghc:*:*:*:*:*:*:*:*"),
},
{
Class: "haskell-cabal-binary",
FileGlob: "**/cabal",
EvidenceMatcher: FileContentsVersionMatcher(
`(?m)\x00Cabal-(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)-`,
),
Package: "haskell/cabal",
PURL: mustPURL("pkg:generic/haskell/cabal@version"),
CPEs: singleCPE("cpe:2.3:a:haskell:cabal:*:*:*:*:*:*:*:*"),
},
{
Class: "haskell-stack-binary",
FileGlob: "**/stack",
EvidenceMatcher: FileContentsVersionMatcher(
`(?m)Version\s*(?P<version>[0-9]+\.[0-9]+\.[0-9]+),\s*Git`,
),
Package: "haskell/stack",
PURL: mustPURL("pkg:generic/haskell/stack@version"),
CPEs: singleCPE("cpe:2.3:a:haskell:stack:*:*:*:*:*:*:*:*"),
},
{
Class: "consul-binary",
@@ -447,7 +486,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "consul",
PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"),
CPEs: singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "nginx-binary",
@@ -460,8 +499,8 @@ func DefaultClassifiers() []Classifier {
Package: "nginx",
PURL: mustPURL("pkg:generic/nginx@version"),
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:nginx:nginx:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
cpe.Must("cpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
cpe.Must("cpe:2.3:a:nginx:nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
},
{
@@ -476,7 +515,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "bash",
PURL: mustPURL("pkg:generic/bash@version"),
CPEs: singleCPE("cpe:2.3:a:gnu:bash:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:gnu:bash:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "openssl-binary",
@@ -488,7 +527,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "openssl",
PURL: mustPURL("pkg:generic/openssl@version"),
CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "gcc-binary",
@@ -499,7 +538,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "gcc",
PURL: mustPURL("pkg:generic/gcc@version"),
CPEs: singleCPE("cpe:2.3:a:gnu:gcc:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:gnu:gcc:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "fluent-bit-binary",
@@ -512,7 +551,7 @@ func DefaultClassifiers() []Classifier {
),
Package: "fluent-bit",
PURL: mustPURL("pkg:github/fluent/fluent-bit@version"),
CPEs: singleCPE("cpe:2.3:a:treasuredata:fluent_bit:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:treasuredata:fluent_bit:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "wordpress-cli-binary",
@@ -523,7 +562,17 @@ func DefaultClassifiers() []Classifier {
),
Package: "wp-cli",
PURL: mustPURL("pkg:generic/wp-cli@version"),
CPEs: singleCPE("cpe:2.3:a:wp-cli:wp-cli:*:*:*:*:*:*:*:*"),
CPEs: singleCPE("cpe:2.3:a:wp-cli:wp-cli:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
{
Class: "curl-binary",
FileGlob: "**/curl",
EvidenceMatcher: FileContentsVersionMatcher(
`curl/(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
),
Package: "curl",
PURL: mustPURL("pkg:generic/curl@version"),
CPEs: singleCPE("cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
},
}
}

Some files were not shown because too many files have changed in this diff Show More