mirror of
https://github.com/anchore/syft.git
synced 2026-10-28 13:02:27 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49736e7c4a | ||
|
|
7a9e1e06da | ||
|
|
7b92913a00 | ||
|
|
594b309cdf | ||
|
|
8c6a2bcbb6 | ||
|
|
d4d311155f | ||
|
|
118f564cf3 | ||
|
|
b59c902996 | ||
|
|
fad9340051 | ||
|
|
3820cba0cd | ||
|
|
5af72b6663 | ||
|
|
801b21bb37 |
+3
-3
@@ -26,7 +26,7 @@ tools:
|
||||
# used for linting
|
||||
- name: golangci-lint
|
||||
version:
|
||||
want: v2.3.0
|
||||
want: v2.3.1
|
||||
method: github-release
|
||||
with:
|
||||
repo: golangci/golangci-lint
|
||||
@@ -58,7 +58,7 @@ tools:
|
||||
# used to release all artifacts
|
||||
- name: goreleaser
|
||||
version:
|
||||
want: v2.11.1
|
||||
want: v2.11.2
|
||||
method: github-release
|
||||
with:
|
||||
repo: goreleaser/goreleaser
|
||||
@@ -98,7 +98,7 @@ tools:
|
||||
# used for triggering a release
|
||||
- name: gh
|
||||
version:
|
||||
want: v2.76.1
|
||||
want: v2.76.2
|
||||
method: github-release
|
||||
with:
|
||||
repo: cli/cli
|
||||
|
||||
@@ -37,7 +37,7 @@ runs:
|
||||
- name: Restore tool cache
|
||||
if: inputs.tools == 'true'
|
||||
id: tool-cache
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tool
|
||||
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('.binny.yaml') }}
|
||||
@@ -63,7 +63,7 @@ runs:
|
||||
|
||||
- name: Restore ORAS cache from github actions
|
||||
if: inputs.download-test-fixture-cache == 'true'
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/oras-cache
|
||||
key: ${{ inputs.cache-key-prefix }}-oras-cache
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@4e828ff8d448a8a6e532957b1811f387a63867e8 #v3.29.4
|
||||
uses: github/codeql-action/init@76621b61decf072c1cee8dd1ce2d2a82d33c17ed #v3.29.5
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@4e828ff8d448a8a6e532957b1811f387a63867e8 #v3.29.4
|
||||
uses: github/codeql-action/autobuild@76621b61decf072c1cee8dd1ce2d2a82d33c17ed #v3.29.5
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -72,4 +72,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@4e828ff8d448a8a6e532957b1811f387a63867e8 #v3.29.4
|
||||
uses: github/codeql-action/analyze@76621b61decf072c1cee8dd1ce2d2a82d33c17ed #v3.29.5
|
||||
|
||||
@@ -125,13 +125,13 @@ jobs:
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 #v3.4.0
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0
|
||||
with:
|
||||
username: ${{ secrets.ANCHOREOSSWRITE_DH_USERNAME }}
|
||||
password: ${{ secrets.ANCHOREOSSWRITE_DH_PAT }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 #v3.4.0
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
# why not use actions/upload-artifact? It is very slow (3 minutes to upload ~600MB of data, vs 10 seconds with this approach).
|
||||
# see https://github.com/actions/upload-artifact/issues/199 for more info
|
||||
- name: Upload snapshot artifacts
|
||||
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
# we need to preserve the snapshot data itself as well as the task data that confirms if the
|
||||
# snapshot build is stale or not. Otherwise the downstream jobs will attempt to rebuild the snapshot
|
||||
@@ -118,7 +118,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -175,7 +175,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -225,7 +225,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -262,7 +262,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
|
||||
@@ -89,8 +89,8 @@ require (
|
||||
github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1
|
||||
go.uber.org/goleak v1.3.0
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
|
||||
golang.org/x/mod v0.26.0
|
||||
golang.org/x/net v0.42.0
|
||||
golang.org/x/mod v0.27.0
|
||||
golang.org/x/net v0.43.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
modernc.org/sqlite v1.38.2
|
||||
)
|
||||
@@ -268,14 +268,14 @@ require (
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/crypto v0.40.0 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/term v0.33.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/time v0.7.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // indirect
|
||||
golang.org/x/tools v0.35.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/api v0.203.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect
|
||||
|
||||
@@ -1643,8 +1643,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -1707,8 +1707,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
||||
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
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=
|
||||
@@ -1777,8 +1777,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
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=
|
||||
@@ -1936,8 +1936,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
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=
|
||||
@@ -1952,8 +1952,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
|
||||
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
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=
|
||||
@@ -1974,8 +1974,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
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=
|
||||
@@ -2050,8 +2050,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -75,6 +75,12 @@ func (c cataloger) Catalog(_ context.Context, resolver file.Resolver) ([]pkg.Pac
|
||||
newPackages:
|
||||
for i := range newPkgs {
|
||||
newPkg := &newPkgs[i]
|
||||
purlType := pkg.TypeFromPURL(newPkg.PURL)
|
||||
// for certain results, such as hashicorp vault we are returning a golang PURL, so we can use Golang package type,
|
||||
// despite not having the known metadata, this should result in downstream grype matching to use the golang matcher
|
||||
if purlType != pkg.UnknownPkg {
|
||||
newPkg.Type = purlType
|
||||
}
|
||||
for j := range packages {
|
||||
p := &packages[j]
|
||||
// consolidate identical packages found in different locations or by different classifiers
|
||||
@@ -92,6 +98,9 @@ func (c cataloger) Catalog(_ context.Context, resolver file.Resolver) ([]pkg.Pac
|
||||
|
||||
// mergePackages merges information from the extra package into the target package
|
||||
func mergePackages(target *pkg.Package, extra *pkg.Package) {
|
||||
if extra.Type != pkg.BinaryPkg && target.Type == pkg.BinaryPkg {
|
||||
target.Type = extra.Type
|
||||
}
|
||||
// add the locations
|
||||
target.Locations.Add(extra.Locations.ToSlice()...)
|
||||
// update the metadata to indicate which classifiers were used
|
||||
|
||||
@@ -1007,6 +1007,28 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("consul-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "vault/1.20.2/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "github.com/hashicorp/vault",
|
||||
Version: "1.20.2",
|
||||
Type: "golang",
|
||||
PURL: "pkg:golang/github.com/hashicorp/vault@1.20.2",
|
||||
Locations: locations("vault"),
|
||||
Metadata: metadata("hashicorp-vault-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "vault/1.19.4/linux-arm64",
|
||||
expected: pkg.Package{
|
||||
Name: "github.com/hashicorp/vault",
|
||||
Version: "1.19.4",
|
||||
Type: "golang",
|
||||
PURL: "pkg:golang/github.com/hashicorp/vault@1.19.4",
|
||||
Locations: locations("vault"),
|
||||
Metadata: metadata("hashicorp-vault-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "erlang/25.3.2.6/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
|
||||
@@ -448,6 +448,16 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "hashicorp-vault-binary",
|
||||
FileGlob: "**/vault",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
// revoke1.18.0
|
||||
`(?m)revoke(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
Package: "github.com/hashicorp/vault",
|
||||
PURL: mustPURL("pkg:golang/github.com/hashicorp/vault@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:hashicorp:vault:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "nginx-binary",
|
||||
FileGlob: "**/nginx",
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
name: vault
|
||||
offset: 191891817
|
||||
length: 420
|
||||
snippetSha256: fd8eb7979e1e7bbc254f2f7a26f6a70ecb479cc4f50c804f3b0789bc0e229097
|
||||
fileSha256: a4754a343e619adef87a1d7e1368a0709ba29802fefbe8d70105c11085becd43
|
||||
|
||||
### byte snippet to follow ###
|
||||
ctstreamPragma</a>.
|
||||
:httpssocks Locked%s.logCT_LOGLOCAL0@level[INFO][WARN]env:///v1/%sDELETEcreateErrorserrorsclient/data/lookupactualAcceptregionawskmsocikmspkcs11%s%s%scloud:%s.%s:revoke1.19.4)(nil))(%#v) {...}frenchCommonArabicBrahmiCarianChakmaCopticGothicHangulHatranHebrewKaithiKhojkiLepchaLycianLydianRejangSyriacTai_LeTangsaTangutTeluguThaanaWanchoYezidiHyphen\u%04x\U%08xgetentpasswd390625%s
|
||||
%s
|
||||
%q: %wnumber\uff
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
name: vault
|
||||
offset: 213670425
|
||||
length: 220
|
||||
snippetSha256: d9b23916d00e8085a4066974641ef77962f2e0aae6f4244688d2c4fe4286c92b
|
||||
fileSha256: fb484f1b458e5d2fd28270b406a8b26b28d040dddcaa1d099aa9ee4ac927b730
|
||||
|
||||
### byte snippet to follow ###
|
||||
ctstreamPragma</a>.
|
||||
:httpssocks Locked%s.logCT_LOGLOCAL0@level[INFO][WARN]env:///v1/%sDELETEcreateErrorserrorsclient/data/lookupactualAcceptregionawskmsocikmspkcs11%s%s%scloud:%s.%s:revoke1.20.2)(nil))(%#v) {...}frenchCo
|
||||
@@ -724,6 +724,20 @@ from-images:
|
||||
paths:
|
||||
- /bin/consul
|
||||
|
||||
- version: 1.20.2
|
||||
images:
|
||||
- ref: hashicorp/vault@sha256:5cd2003247e0a574a66c66aee1916b1e9e7f99640298f2e61271a8842d2d2a19
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /bin/vault
|
||||
|
||||
- version: 1.19.4
|
||||
images:
|
||||
- ref: hashicorp/vault@sha256:b5f675b0bf681568cd7354c697fe4ce953024312d6d23ee7216deda60c192bad
|
||||
platform: linux/arm64
|
||||
paths:
|
||||
- /bin/vault
|
||||
|
||||
- version: 3.0.2
|
||||
images:
|
||||
- ref: fluent/fluent-bit:3.0.2-amd64@sha256:7e6fe8efd51dda0739e355f58bf5e3b1623cbf2d4a23c06c7a365d9553e2d242
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
"github.com/gofiber/template/django/v3": [
|
||||
"cpe:2.3:a:gofiber:django:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/google/nftables": [
|
||||
"cpe:2.3:a:google:nftables:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/gookit/goutil": [
|
||||
"cpe:2.3:a:go_util_project:go_util:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -10556,6 +10559,9 @@
|
||||
"drawblog": [
|
||||
"cpe:2.3:a:drawblog_project:drawblog:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"drive-folder-embeder": [
|
||||
"cpe:2.3:a:azumbro:drive_folder_embedder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"droit-dark-mode": [
|
||||
"cpe:2.3:a:droitthemes:droit_dark_mode:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11858,6 +11864,9 @@
|
||||
"furikake": [
|
||||
"cpe:2.3:a:furikake_project:furikake:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"fusedesk": [
|
||||
"cpe:2.3:a:jeremyshapiro:fusedesk:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"fusion-builder": [
|
||||
"cpe:2.3:a:theme-fusion:avada:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12313,6 +12322,9 @@
|
||||
"gtbabel": [
|
||||
"cpe:2.3:a:gtbabel:gtbabel:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gtg-advanced-blocks": [
|
||||
"cpe:2.3:a:gutengeek:free_gutenberg_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gtm-server-side": [
|
||||
"cpe:2.3:a:stape:gtm_server_side:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13133,6 +13145,9 @@
|
||||
"cpe:2.3:a:joomsky:js_help_desk:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wiselyhub:js_help_desk:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"js_composer": [
|
||||
"cpe:2.3:a:wpbakery:page_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"jsmol2wp": [
|
||||
"cpe:2.3:a:jsmol2wp_project:jsmol2wp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13976,7 +13991,8 @@
|
||||
"cpe:2.3:a:mekshq:meks_flexible_shortcodes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meks-smart-author-widget": [
|
||||
"cpe:2.3:a:mekshq:meks_smart_author_widget:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:mekshq:meks_smart_author_widget:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:mekshq:smart_author_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meks-smart-social-widget": [
|
||||
"cpe:2.3:a:mekshq:meks_smart_social_widget:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -14603,6 +14619,9 @@
|
||||
"note-press": [
|
||||
"cpe:2.3:a:datainterlock:note_press:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"notice-faq": [
|
||||
"cpe:2.3:a:notice:notice_faq:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"notices": [
|
||||
"cpe:2.3:a:notices_project:notices:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15193,6 +15212,9 @@
|
||||
"plausible-analytics": [
|
||||
"cpe:2.3:a:plausible:plausible_analytics:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"play-ht": [
|
||||
"cpe:2.3:a:hammadh:play.ht:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"player": [
|
||||
"cpe:2.3:a:web-dorado:spidervplayer:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:web-dorado:web-dorado_spider_video_player:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -15455,6 +15477,9 @@
|
||||
"posts-reminder": [
|
||||
"cpe:2.3:a:lucasgarcia:posts_reminder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"posts-table-filterable": [
|
||||
"cpe:2.3:a:pluginus:tableon_-_wordpress_posts_table_filterable:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"posttabs": [
|
||||
"cpe:2.3:a:posttabs_project:posttabs:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15850,6 +15875,9 @@
|
||||
"randomtext": [
|
||||
"cpe:2.3:a:random_text_project:random_text:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rapid-cache": [
|
||||
"cpe:2.3:a:megaoptim:rapid_cache:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rara-one-click-demo-import": [
|
||||
"cpe:2.3:a:rarathemes:rara_one_click_demo_import:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18087,6 +18115,9 @@
|
||||
"tourfic": [
|
||||
"cpe:2.3:a:themefic:tourfic:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"tourmaster": [
|
||||
"cpe:2.3:a:goodlayers:tour_master:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"tournamatch": [
|
||||
"cpe:2.3:a:tournamatch:tournamatch:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -19525,6 +19556,9 @@
|
||||
"wp-backgrounds-lite": [
|
||||
"cpe:2.3:a:inoplugs:wp-backgrounds_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-backitup": [
|
||||
"cpe:2.3:a:wpbackitup:backup_and_restore_wordpress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-baidu-submit": [
|
||||
"cpe:2.3:a:wp_baidu_submit_project:wp_baidu_submit:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -21677,6 +21711,9 @@
|
||||
"posterity": [
|
||||
"cpe:2.3:a:sktthemes:posterity:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"pressmart": [
|
||||
"cpe:2.3:a:presslayouts:pressmart:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"regina-lite": [
|
||||
"cpe:2.3:a:machothemes:regina_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package java
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"crypto"
|
||||
"fmt"
|
||||
"io"
|
||||
"iter"
|
||||
"os"
|
||||
"path"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/scylladb/go-set/strset"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
@@ -391,20 +394,32 @@ func (j *archiveParser) discoverMainPackageFromPomInfo(ctx context.Context) (gro
|
||||
projects, _ := pomProjectByParentPath(j.archivePath, j.location, j.fileManifest.GlobMatch(false, pomXMLGlob))
|
||||
|
||||
// map of all the artifacts in the pom properties, in order to chek exact match with the filename
|
||||
artifactsMap := make(map[string]bool)
|
||||
artifactsMap := strset.New()
|
||||
for _, propertiesObj := range properties {
|
||||
artifactsMap[propertiesObj.ArtifactID] = true
|
||||
artifactsMap.Add(propertiesObj.ArtifactID)
|
||||
}
|
||||
|
||||
parentPaths := maps.Keys(properties)
|
||||
slices.Sort(parentPaths)
|
||||
for _, parentPath := range parentPaths {
|
||||
propertiesObj := properties[parentPath]
|
||||
for parentPath, propertiesObj := range sortedIter(properties) {
|
||||
// the logic for selecting the best name is as follows:
|
||||
// if we find an artifact id AND group id which are both contained in the filename
|
||||
// OR if we have an artifact id that exactly matches the filename, prefer this
|
||||
// OTHERWISE track the first matching pom properties with a pom.xml
|
||||
// FINALLY return the first matching pom properties
|
||||
if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name, artifactsMap) {
|
||||
pomProperties = propertiesObj
|
||||
if pomProperties.ArtifactID == "" { // keep the first match, or overwrite if we find more specific entries
|
||||
pomProperties = propertiesObj
|
||||
}
|
||||
if proj, exists := projects[parentPath]; exists {
|
||||
parsedPom = proj
|
||||
break
|
||||
if parsedPom == nil { // keep the first matching artifact if we don't find an exact match or groupid + artfiact id match
|
||||
pomProperties = propertiesObj // set this, as it may not be the first entry found
|
||||
parsedPom = proj
|
||||
}
|
||||
// if artifact ID is the entire filename or BOTH artifactID and groupID are contained in the artifact, prefer this match
|
||||
if strings.Contains(j.fileInfo.name, propertiesObj.GroupID) || j.fileInfo.name == propertiesObj.ArtifactID {
|
||||
pomProperties = propertiesObj // this is an exact match, use it
|
||||
parsedPom = proj
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,12 +444,13 @@ func (j *archiveParser) discoverMainPackageFromPomInfo(ctx context.Context) (gro
|
||||
return group, name, version, parsedPom
|
||||
}
|
||||
|
||||
func artifactIDMatchesFilename(artifactID, fileName string, artifactsMap map[string]bool) bool {
|
||||
// artifactIDMatchesFilename returns true if one starts with the other
|
||||
func artifactIDMatchesFilename(artifactID, fileName string, artifactsMap *strset.Set) bool {
|
||||
if artifactID == "" || fileName == "" {
|
||||
return false
|
||||
}
|
||||
// Ensure true is returned when filename matches the artifact ID, prevent random retrieval by checking prefix and suffix
|
||||
if _, exists := artifactsMap[fileName]; exists {
|
||||
if artifactsMap.Has(fileName) {
|
||||
return artifactID == fileName
|
||||
}
|
||||
// Use fallback check with suffix and prefix if no POM properties file matches the exact artifact name
|
||||
@@ -464,7 +480,7 @@ func (j *archiveParser) discoverPkgsFromAllMavenFiles(ctx context.Context, paren
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for parentPath, propertiesObj := range properties {
|
||||
for parentPath, propertiesObj := range sortedIter(properties) {
|
||||
var parsedPom *parsedPomProject
|
||||
if proj, exists := projects[parentPath]; exists {
|
||||
parsedPom = proj
|
||||
@@ -546,7 +562,7 @@ func discoverPkgsFromOpeners(ctx context.Context, location file.Location, opener
|
||||
var pkgs []pkg.Package
|
||||
var relationships []artifact.Relationship
|
||||
|
||||
for pathWithinArchive, archiveOpener := range openers {
|
||||
for pathWithinArchive, archiveOpener := range sortedIter(openers) {
|
||||
nestedPkgs, nestedRelationships, err := discoverPkgsFromOpener(ctx, location, pathWithinArchive, archiveOpener, cfg, parentPkg)
|
||||
if err != nil {
|
||||
log.WithFields("location", location.Path(), "error", err).Debug("unable to discover java packages from opener")
|
||||
@@ -604,7 +620,7 @@ func pomPropertiesByParentPath(archivePath string, location file.Location, extra
|
||||
}
|
||||
|
||||
propertiesByParentPath := make(map[string]pkg.JavaPomProperties)
|
||||
for filePath, fileContents := range contentsOfMavenPropertiesFiles {
|
||||
for filePath, fileContents := range sortedIter(contentsOfMavenPropertiesFiles) {
|
||||
pomProperties, err := parsePomProperties(filePath, strings.NewReader(fileContents))
|
||||
if err != nil {
|
||||
log.WithFields("contents-path", filePath, "location", location.Path(), "error", err).Debug("failed to parse pom.properties")
|
||||
@@ -633,7 +649,7 @@ func pomProjectByParentPath(archivePath string, location file.Location, extractP
|
||||
}
|
||||
|
||||
projectByParentPath := make(map[string]*parsedPomProject)
|
||||
for filePath, fileContents := range contentsOfMavenProjectFiles {
|
||||
for filePath, fileContents := range sortedIter(contentsOfMavenProjectFiles) {
|
||||
// TODO: when we support locations of paths within archives we should start passing the specific pom.xml location object instead of the top jar
|
||||
pom, err := maven.ParsePomXML(strings.NewReader(fileContents))
|
||||
if err != nil {
|
||||
@@ -784,3 +800,15 @@ func updateParentPackage(p pkg.Package, parentPkg *pkg.Package) {
|
||||
parentPkg.Metadata = parentMetadata
|
||||
}
|
||||
}
|
||||
|
||||
func sortedIter[K cmp.Ordered, V any](values map[K]V) iter.Seq2[K, V] {
|
||||
return func(yield func(K, V) bool) {
|
||||
keys := maps.Keys(values)
|
||||
slices.Sort(keys)
|
||||
for _, key := range keys {
|
||||
if !yield(key, values[key]) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1086,7 +1086,7 @@ func Test_artifactIDMatchesFilename(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, artifactIDMatchesFilename(tt.artifactID, tt.fileName, nil))
|
||||
assert.Equal(t, tt.want, artifactIDMatchesFilename(tt.artifactID, tt.fileName, strset.New()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1382,6 +1382,10 @@ func Test_deterministicMatchingPomProperties(t *testing.T) {
|
||||
fixture: "multiple-matching-2.11.5",
|
||||
expected: maven.NewID("org.multiple", "multiple-matching-1", "2.11.5"),
|
||||
},
|
||||
{
|
||||
fixture: "org.multiple-thename",
|
||||
expected: maven.NewID("org.multiple", "thename", "10.11.12"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
@@ -12,6 +12,7 @@ OPENSAML_CORE = opensaml-core-3.4.6
|
||||
API_ALL_SOURCES = api-all-2.0.0-sources
|
||||
SPRING_INSTRUMENTATION = spring-instrumentation-4.3.0-1.0
|
||||
MULTIPLE_MATCHING = multiple-matching-2.11.5
|
||||
ORG_MULTIPLE_THENAME = org.multiple-thename
|
||||
|
||||
|
||||
.DEFAULT_GOAL := fixtures
|
||||
@@ -48,7 +49,11 @@ $(CACHE_DIR)/$(MULTIPLE_MATCHING).jar:
|
||||
mkdir -p $(CACHE_DIR)
|
||||
cd $(MULTIPLE_MATCHING) && zip -r $(CACHE_PATH)/$(MULTIPLE_MATCHING).jar .
|
||||
|
||||
# Jenkins plugins typically do not have the version included in the archive name,
|
||||
$(CACHE_DIR)/$(ORG_MULTIPLE_THENAME).jar:
|
||||
mkdir -p $(CACHE_DIR)
|
||||
cd $(ORG_MULTIPLE_THENAME) && zip -r $(CACHE_PATH)/$(ORG_MULTIPLE_THENAME).jar .
|
||||
|
||||
# Jenkins plugins typically do not have the version included in the archive name,
|
||||
# so it is important to not include it in the generated test fixture
|
||||
$(CACHE_DIR)/gradle.hpi:
|
||||
mkdir -p $(CACHE_DIR)
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Manifest-Version: 1.0
|
||||
Created-By: Multi
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version=10.11.12
|
||||
groupId=com.multiple
|
||||
artifactId=thename
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.multiple</groupId>
|
||||
<artifactId>thename</artifactId>
|
||||
<version>10.11.12</version>
|
||||
</project>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version=10.11.12
|
||||
groupId=org.multiple
|
||||
artifactId=thename
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.multiple</groupId>
|
||||
<artifactId>thename</artifactId>
|
||||
<version>10.11.12</version>
|
||||
</project>
|
||||
Reference in New Issue
Block a user