diff --git a/docs/docs/references/configuration/cli/trivy_filesystem.md b/docs/docs/references/configuration/cli/trivy_filesystem.md
index 1bae026b3e30..4bf6aa064999 100644
--- a/docs/docs/references/configuration/cli/trivy_filesystem.md
+++ b/docs/docs/references/configuration/cli/trivy_filesystem.md
@@ -69,7 +69,7 @@ trivy filesystem [flags] PATH
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--password-stdin password from stdin. Comma-separated passwords are not supported.
- --pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
+ --pkg-relationships strings list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
diff --git a/docs/docs/references/configuration/cli/trivy_image.md b/docs/docs/references/configuration/cli/trivy_image.md
index 3c0c601b4c32..41bc6ce842bc 100644
--- a/docs/docs/references/configuration/cli/trivy_image.md
+++ b/docs/docs/references/configuration/cli/trivy_image.md
@@ -87,7 +87,7 @@ trivy image [flags] IMAGE_NAME
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--password-stdin password from stdin. Comma-separated passwords are not supported.
- --pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
+ --pkg-relationships strings list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--platform string set platform in the form os/arch if image is multi-platform capable
--podman-host string unix podman socket path to use for podman scanning
diff --git a/docs/docs/references/configuration/cli/trivy_kubernetes.md b/docs/docs/references/configuration/cli/trivy_kubernetes.md
index 0b342c28ea6e..9290ec0719b8 100644
--- a/docs/docs/references/configuration/cli/trivy_kubernetes.md
+++ b/docs/docs/references/configuration/cli/trivy_kubernetes.md
@@ -84,7 +84,7 @@ trivy kubernetes [flags] [CONTEXT]
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--password-stdin password from stdin. Comma-separated passwords are not supported.
- --pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
+ --pkg-relationships strings list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--qps float specify the maximum QPS to the master from this client (default 5)
--redis-ca string redis ca file location, if using redis as cache backend
diff --git a/docs/docs/references/configuration/cli/trivy_repository.md b/docs/docs/references/configuration/cli/trivy_repository.md
index 0567872e98ae..38ae6611b595 100644
--- a/docs/docs/references/configuration/cli/trivy_repository.md
+++ b/docs/docs/references/configuration/cli/trivy_repository.md
@@ -69,7 +69,7 @@ trivy repository [flags] (REPO_PATH | REPO_URL)
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--password-stdin password from stdin. Comma-separated passwords are not supported.
- --pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
+ --pkg-relationships strings list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
diff --git a/docs/docs/references/configuration/cli/trivy_rootfs.md b/docs/docs/references/configuration/cli/trivy_rootfs.md
index f198187fb85d..b84dcc5cd2c3 100644
--- a/docs/docs/references/configuration/cli/trivy_rootfs.md
+++ b/docs/docs/references/configuration/cli/trivy_rootfs.md
@@ -71,7 +71,7 @@ trivy rootfs [flags] ROOTDIR
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--password-stdin password from stdin. Comma-separated passwords are not supported.
- --pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
+ --pkg-relationships strings list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
diff --git a/docs/docs/references/configuration/cli/trivy_sbom.md b/docs/docs/references/configuration/cli/trivy_sbom.md
index 0419efece923..9456e8883532 100644
--- a/docs/docs/references/configuration/cli/trivy_sbom.md
+++ b/docs/docs/references/configuration/cli/trivy_sbom.md
@@ -49,7 +49,7 @@ trivy sbom [flags] SBOM_PATH
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
--password-stdin password from stdin. Comma-separated passwords are not supported.
- --pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
+ --pkg-relationships strings list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
diff --git a/docs/docs/references/configuration/cli/trivy_vm.md b/docs/docs/references/configuration/cli/trivy_vm.md
index 577a58b0f800..1074d878d866 100644
--- a/docs/docs/references/configuration/cli/trivy_vm.md
+++ b/docs/docs/references/configuration/cli/trivy_vm.md
@@ -61,7 +61,7 @@ trivy vm [flags] VM_IMAGE
-o, --output string output file name
--output-plugin-arg string [EXPERIMENTAL] output plugin arguments
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
- --pkg-relationships strings list of package relationships (unknown,root,direct,indirect) (default [unknown,root,direct,indirect])
+ --pkg-relationships strings list of package relationships (unknown,root,workspace,direct,indirect) (default [unknown,root,workspace,direct,indirect])
--pkg-types strings list of package types (os,library) (default [os,library])
--redis-ca string redis ca file location, if using redis as cache backend
--redis-cert string redis certificate file location, if using redis as cache backend
diff --git a/docs/docs/references/configuration/config-file.md b/docs/docs/references/configuration/config-file.md
index 56f77a14e888..365d2e5a57a9 100644
--- a/docs/docs/references/configuration/config-file.md
+++ b/docs/docs/references/configuration/config-file.md
@@ -447,6 +447,7 @@ pkg:
relationships:
- unknown
- root
+ - workspace
- direct
- indirect
diff --git a/integration/testdata/composer.lock.json.golden b/integration/testdata/composer.lock.json.golden
index 5e2e49d8b965..00172acfdf53 100644
--- a/integration/testdata/composer.lock.json.golden
+++ b/integration/testdata/composer.lock.json.golden
@@ -26,7 +26,7 @@
"Name": "guzzlehttp/guzzle",
"Identifier": {
"PURL": "pkg:composer/guzzlehttp/guzzle@7.4.4",
- "UID": "c26bf8868607a91c"
+ "UID": "b08c57e1706dce2d"
},
"Version": "7.4.4",
"Licenses": [
@@ -49,7 +49,7 @@
"Name": "guzzlehttp/psr7",
"Identifier": {
"PURL": "pkg:composer/guzzlehttp/psr7@1.8.3",
- "UID": "1730859e3ff83ab9"
+ "UID": "75a904f2b589910f"
},
"Version": "1.8.3",
"Licenses": [
@@ -73,7 +73,7 @@
"PkgName": "guzzlehttp/psr7",
"PkgIdentifier": {
"PURL": "pkg:composer/guzzlehttp/psr7@1.8.3",
- "UID": "1730859e3ff83ab9"
+ "UID": "75a904f2b589910f"
},
"InstalledVersion": "1.8.3",
"FixedVersion": "1.8.4",
diff --git a/integration/testdata/conan.json.golden b/integration/testdata/conan.json.golden
index d34caa079428..edc975f7a897 100644
--- a/integration/testdata/conan.json.golden
+++ b/integration/testdata/conan.json.golden
@@ -26,7 +26,7 @@
"Name": "poco",
"Identifier": {
"PURL": "pkg:conan/poco@1.9.4",
- "UID": "312753cebe80c0eb"
+ "UID": "1c5e3b385e0d9c68"
},
"Version": "1.9.4",
"Relationship": "direct",
@@ -50,7 +50,7 @@
"Name": "bzip2",
"Identifier": {
"PURL": "pkg:conan/bzip2@1.0.8",
- "UID": "6e2ff993df2d9107"
+ "UID": "fcee910413ab7575"
},
"Version": "1.0.8",
"Indirect": true,
@@ -68,7 +68,7 @@
"Name": "expat",
"Identifier": {
"PURL": "pkg:conan/expat@2.4.8",
- "UID": "71c2d92d60f7f21c"
+ "UID": "1a3fe92a43620875"
},
"Version": "2.4.8",
"Indirect": true,
@@ -86,7 +86,7 @@
"Name": "openssl",
"Identifier": {
"PURL": "pkg:conan/openssl@1.1.1q",
- "UID": "13c605db6afa69dd"
+ "UID": "d009c32d2d560ed1"
},
"Version": "1.1.1q",
"Indirect": true,
@@ -104,7 +104,7 @@
"Name": "pcre",
"Identifier": {
"PURL": "pkg:conan/pcre@8.43",
- "UID": "4e01c692a67e12e4"
+ "UID": "452827dd216c920e"
},
"Version": "8.43",
"Indirect": true,
@@ -126,7 +126,7 @@
"Name": "sqlite3",
"Identifier": {
"PURL": "pkg:conan/sqlite3@3.39.2",
- "UID": "43bc9c58092c7c9e"
+ "UID": "8e926335e2fce900"
},
"Version": "3.39.2",
"Indirect": true,
@@ -144,7 +144,7 @@
"Name": "zlib",
"Identifier": {
"PURL": "pkg:conan/zlib@1.2.12",
- "UID": "d6faf8d6dfd1985"
+ "UID": "dfef9b967a82df9f"
},
"Version": "1.2.12",
"Indirect": true,
@@ -165,7 +165,7 @@
"PkgName": "pcre",
"PkgIdentifier": {
"PURL": "pkg:conan/pcre@8.43",
- "UID": "4e01c692a67e12e4"
+ "UID": "452827dd216c920e"
},
"InstalledVersion": "8.43",
"FixedVersion": "8.45",
diff --git a/integration/testdata/gomod-skip.json.golden b/integration/testdata/gomod-skip.json.golden
index 877fd627b89a..7c720157798c 100644
--- a/integration/testdata/gomod-skip.json.golden
+++ b/integration/testdata/gomod-skip.json.golden
@@ -27,7 +27,7 @@
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@v2.7.1%2Bincompatible",
- "UID": "9d949a7b01249e68"
+ "UID": "782e16d5a74c9fa6"
},
"InstalledVersion": "v2.7.1+incompatible",
"FixedVersion": "v2.8.0",
@@ -54,7 +54,7 @@
"PkgName": "github.com/open-policy-agent/opa",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/open-policy-agent/opa@v0.35.0",
- "UID": "e89e2b0d8977e2a"
+ "UID": "3e43f458a7c60c10"
},
"InstalledVersion": "v0.35.0",
"FixedVersion": "0.37.0",
@@ -101,7 +101,7 @@
"PkgName": "golang.org/x/text",
"PkgIdentifier": {
"PURL": "pkg:golang/golang.org/x/text@v0.3.6",
- "UID": "3050088ce9eb2ce4"
+ "UID": "9c987ed7494d95be"
},
"InstalledVersion": "v0.3.6",
"FixedVersion": "0.3.7",
@@ -134,7 +134,7 @@
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@v2.7.1%2Bincompatible",
- "UID": "2f7f0fa81860b8f1"
+ "UID": "97673687db393443"
},
"InstalledVersion": "v2.7.1+incompatible",
"FixedVersion": "v2.8.0",
diff --git a/integration/testdata/gomod-vex.json.golden b/integration/testdata/gomod-vex.json.golden
index 34d96dc0ce95..dbe235013378 100644
--- a/integration/testdata/gomod-vex.json.golden
+++ b/integration/testdata/gomod-vex.json.golden
@@ -27,7 +27,7 @@
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@v2.7.1%2Bincompatible",
- "UID": "9d949a7b01249e68"
+ "UID": "782e16d5a74c9fa6"
},
"InstalledVersion": "v2.7.1+incompatible",
"FixedVersion": "v2.8.0",
@@ -54,7 +54,7 @@
"PkgName": "golang.org/x/text",
"PkgIdentifier": {
"PURL": "pkg:golang/golang.org/x/text@v0.3.6",
- "UID": "3050088ce9eb2ce4"
+ "UID": "9c987ed7494d95be"
},
"InstalledVersion": "v0.3.6",
"FixedVersion": "0.3.7",
@@ -87,7 +87,7 @@
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@v2.7.1%2Bincompatible",
- "UID": "2f7f0fa81860b8f1"
+ "UID": "97673687db393443"
},
"InstalledVersion": "v2.7.1+incompatible",
"FixedVersion": "v2.8.0",
@@ -121,7 +121,7 @@
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@v2.7.1%2Bincompatible",
- "UID": "3ad40723ed2fce22"
+ "UID": "48e3a06649df4bd4"
},
"InstalledVersion": "v2.7.1+incompatible",
"FixedVersion": "v2.8.0",
diff --git a/integration/testdata/gomod.json.golden b/integration/testdata/gomod.json.golden
index 551b787cadd6..43249e07a9c7 100644
--- a/integration/testdata/gomod.json.golden
+++ b/integration/testdata/gomod.json.golden
@@ -27,7 +27,7 @@
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@v2.7.1%2Bincompatible",
- "UID": "9d949a7b01249e68"
+ "UID": "782e16d5a74c9fa6"
},
"InstalledVersion": "v2.7.1+incompatible",
"FixedVersion": "v2.8.0",
@@ -54,7 +54,7 @@
"PkgName": "github.com/open-policy-agent/opa",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/open-policy-agent/opa@v0.35.0",
- "UID": "e89e2b0d8977e2a"
+ "UID": "3e43f458a7c60c10"
},
"InstalledVersion": "v0.35.0",
"FixedVersion": "0.37.0",
@@ -101,7 +101,7 @@
"PkgName": "golang.org/x/text",
"PkgIdentifier": {
"PURL": "pkg:golang/golang.org/x/text@v0.3.6",
- "UID": "3050088ce9eb2ce4"
+ "UID": "9c987ed7494d95be"
},
"InstalledVersion": "v0.3.6",
"FixedVersion": "0.3.7",
@@ -134,7 +134,7 @@
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@v2.7.1%2Bincompatible",
- "UID": "2f7f0fa81860b8f1"
+ "UID": "97673687db393443"
},
"InstalledVersion": "v2.7.1+incompatible",
"FixedVersion": "v2.8.0",
@@ -168,7 +168,7 @@
"PkgName": "github.com/docker/distribution",
"PkgIdentifier": {
"PURL": "pkg:golang/github.com/docker/distribution@v2.7.1%2Bincompatible",
- "UID": "3ad40723ed2fce22"
+ "UID": "48e3a06649df4bd4"
},
"InstalledVersion": "v2.7.1+incompatible",
"FixedVersion": "v2.8.0",
diff --git a/integration/testdata/nuget.json.golden b/integration/testdata/nuget.json.golden
index b4ec872a839c..76fe3d706214 100644
--- a/integration/testdata/nuget.json.golden
+++ b/integration/testdata/nuget.json.golden
@@ -26,7 +26,7 @@
"Name": "Newtonsoft.Json",
"Identifier": {
"PURL": "pkg:nuget/Newtonsoft.Json@12.0.3",
- "UID": "d4249b2442e303e9"
+ "UID": "1cec16ca9d4718aa"
},
"Version": "12.0.3",
"Relationship": "direct",
@@ -43,7 +43,7 @@
"Name": "NuGet.Frameworks",
"Identifier": {
"PURL": "pkg:nuget/NuGet.Frameworks@5.7.0",
- "UID": "6fa0c117039de82a"
+ "UID": "ed284c615e250d47"
},
"Version": "5.7.0",
"Relationship": "direct",
@@ -66,7 +66,7 @@
"PkgName": "Newtonsoft.Json",
"PkgIdentifier": {
"PURL": "pkg:nuget/Newtonsoft.Json@12.0.3",
- "UID": "d4249b2442e303e9"
+ "UID": "1cec16ca9d4718aa"
},
"InstalledVersion": "12.0.3",
"FixedVersion": "13.0.1",
diff --git a/integration/testdata/pnpm.json.golden b/integration/testdata/pnpm.json.golden
index 3edd379d10cb..6f8de4e57568 100644
--- a/integration/testdata/pnpm.json.golden
+++ b/integration/testdata/pnpm.json.golden
@@ -26,7 +26,7 @@
"Name": "jquery",
"Identifier": {
"PURL": "pkg:npm/jquery@3.3.9",
- "UID": "53ca18565a4b6a47"
+ "UID": "2a8ffed0b32cf950"
},
"Version": "3.3.9",
"Licenses": [
@@ -40,7 +40,7 @@
"Name": "lodash",
"Identifier": {
"PURL": "pkg:npm/lodash@4.17.4",
- "UID": "31eadfcf58a6b128"
+ "UID": "29795971f23e7bf6"
},
"Version": "4.17.4",
"Licenses": [
@@ -57,7 +57,7 @@
"PkgName": "jquery",
"PkgIdentifier": {
"PURL": "pkg:npm/jquery@3.3.9",
- "UID": "53ca18565a4b6a47"
+ "UID": "2a8ffed0b32cf950"
},
"InstalledVersion": "3.3.9",
"FixedVersion": "3.4.0",
@@ -190,7 +190,7 @@
"PkgName": "lodash",
"PkgIdentifier": {
"PURL": "pkg:npm/lodash@4.17.4",
- "UID": "31eadfcf58a6b128"
+ "UID": "29795971f23e7bf6"
},
"InstalledVersion": "4.17.4",
"FixedVersion": "4.17.12",
diff --git a/integration/testdata/poetry.json.golden b/integration/testdata/poetry.json.golden
index 384c982876d3..916ec8e8e139 100644
--- a/integration/testdata/poetry.json.golden
+++ b/integration/testdata/poetry.json.golden
@@ -26,7 +26,7 @@
"Name": "click",
"Identifier": {
"PURL": "pkg:pypi/click@8.1.3",
- "UID": "37edb5c90a97272e"
+ "UID": "d76da06fc75f0439"
},
"Version": "8.1.3",
"Relationship": "direct",
@@ -40,7 +40,7 @@
"Name": "werkzeug",
"Identifier": {
"PURL": "pkg:pypi/werkzeug@0.14",
- "UID": "4176be111ad01070"
+ "UID": "d14d05cca13c7a6b"
},
"Version": "0.14",
"Relationship": "direct",
@@ -51,7 +51,7 @@
"Name": "colorama",
"Identifier": {
"PURL": "pkg:pypi/colorama@0.4.6",
- "UID": "895013c17f373da3"
+ "UID": "c7ed705c1cc43242"
},
"Version": "0.4.6",
"Indirect": true,
@@ -66,7 +66,7 @@
"PkgName": "werkzeug",
"PkgIdentifier": {
"PURL": "pkg:pypi/werkzeug@0.14",
- "UID": "4176be111ad01070"
+ "UID": "d14d05cca13c7a6b"
},
"InstalledVersion": "0.14",
"FixedVersion": "0.15.3",
diff --git a/integration/testdata/pom.json.golden b/integration/testdata/pom.json.golden
index a583f02ce8e9..12bfa057e429 100644
--- a/integration/testdata/pom.json.golden
+++ b/integration/testdata/pom.json.golden
@@ -27,7 +27,7 @@
"PkgName": "com.fasterxml.jackson.core:jackson-databind",
"PkgIdentifier": {
"PURL": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1",
- "UID": "a704d87fd1c0b0e1"
+ "UID": "9c69fdeffb7ee6d4"
},
"InstalledVersion": "2.9.1",
"FixedVersion": "2.9.10.4",
@@ -93,7 +93,7 @@
"PkgName": "com.fasterxml.jackson.core:jackson-databind",
"PkgIdentifier": {
"PURL": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.1",
- "UID": "a704d87fd1c0b0e1"
+ "UID": "9c69fdeffb7ee6d4"
},
"InstalledVersion": "2.9.1",
"FixedVersion": "2.9.10.7",
diff --git a/integration/testdata/pubspec.lock.json.golden b/integration/testdata/pubspec.lock.json.golden
index a96211ac9119..cdbb89bf7b83 100644
--- a/integration/testdata/pubspec.lock.json.golden
+++ b/integration/testdata/pubspec.lock.json.golden
@@ -26,7 +26,7 @@
"Name": "http",
"Identifier": {
"PURL": "pkg:pub/http@0.13.2",
- "UID": "b2aa9906ee615d4c"
+ "UID": "fe8339221b1b26b8"
},
"Version": "0.13.2",
"Relationship": "direct",
@@ -37,7 +37,7 @@
"Name": "shelf",
"Identifier": {
"PURL": "pkg:pub/shelf@1.3.1",
- "UID": "8367a65de5b4cda0"
+ "UID": "6d23c3a1f807b8ab"
},
"Version": "1.3.1",
"Indirect": true,
@@ -52,7 +52,7 @@
"PkgName": "http",
"PkgIdentifier": {
"PURL": "pkg:pub/http@0.13.2",
- "UID": "b2aa9906ee615d4c"
+ "UID": "fe8339221b1b26b8"
},
"InstalledVersion": "0.13.2",
"FixedVersion": "0.13.3",
diff --git a/integration/testdata/yarn.json.golden b/integration/testdata/yarn.json.golden
index 16b6c37584a1..c90131a428ed 100644
--- a/integration/testdata/yarn.json.golden
+++ b/integration/testdata/yarn.json.golden
@@ -26,7 +26,7 @@
"Name": "jquery",
"Identifier": {
"PURL": "pkg:npm/jquery@3.2.1",
- "UID": "c7da6fd622178ea0"
+ "UID": "eab2410537cf8504"
},
"Version": "3.2.1",
"Licenses": [
@@ -49,7 +49,7 @@
"PkgName": "jquery",
"PkgIdentifier": {
"PURL": "pkg:npm/jquery@3.2.1",
- "UID": "c7da6fd622178ea0"
+ "UID": "eab2410537cf8504"
},
"InstalledVersion": "3.2.1",
"FixedVersion": "3.4.0",
diff --git a/pkg/dependency/parser/java/pom/parse.go b/pkg/dependency/parser/java/pom/parse.go
index 60a83ba9d81b..9f9afc35d99a 100644
--- a/pkg/dependency/parser/java/pom/parse.go
+++ b/pkg/dependency/parser/java/pom/parse.go
@@ -115,15 +115,18 @@ func (p *Parser) Parse(r xio.ReadSeekerAt) ([]ftypes.Package, []ftypes.Dependenc
// Cache root POM
p.cache.put(result.artifact, result)
- return p.parseRoot(root.artifact(), make(map[string]struct{}))
+ rootArt := root.artifact()
+ rootArt.Relationship = ftypes.RelationshipRoot
+
+ return p.parseRoot(rootArt, make(map[string]struct{}))
}
+// nolint: gocyclo
func (p *Parser) parseRoot(root artifact, uniqModules map[string]struct{}) ([]ftypes.Package, []ftypes.Dependency, error) {
// Prepare a queue for dependencies
queue := newArtifactQueue()
// Enqueue root POM
- root.Relationship = ftypes.RelationshipRoot
root.Module = false
queue.enqueue(root)
@@ -166,7 +169,9 @@ func (p *Parser) parseRoot(root artifact, uniqModules map[string]struct{}) ([]ft
}
// mark artifact as Direct, if saved artifact is Direct
// take a look `hard requirement for the specified version` test
- if uniqueArt.Relationship == ftypes.RelationshipRoot || uniqueArt.Relationship == ftypes.RelationshipDirect {
+ if uniqueArt.Relationship == ftypes.RelationshipRoot ||
+ uniqueArt.Relationship == ftypes.RelationshipWorkspace ||
+ uniqueArt.Relationship == ftypes.RelationshipDirect {
art.Relationship = uniqueArt.Relationship
}
// We don't need to overwrite dependency location for hard links
@@ -180,7 +185,7 @@ func (p *Parser) parseRoot(root artifact, uniqModules map[string]struct{}) ([]ft
return nil, nil, xerrors.Errorf("resolve error (%s): %w", art, err)
}
- if art.Relationship == ftypes.RelationshipRoot {
+ if art.Relationship == ftypes.RelationshipRoot || art.Relationship == ftypes.RelationshipWorkspace {
// Managed dependencies in the root POM affect transitive dependencies
rootDepManagement = p.resolveDepManagement(result.properties, result.dependencyManagement)
@@ -243,6 +248,12 @@ func (p *Parser) parseRoot(root artifact, uniqModules map[string]struct{}) ([]ft
return packageID(dependOnName, ver), ver != ""
})
+ // `mvn` shows modules separately from the root package and does not show module nesting.
+ // So we can add all modules as dependencies of root package.
+ if art.Relationship == ftypes.RelationshipRoot {
+ dependsOn = append(dependsOn, lo.Keys(uniqModules)...)
+ }
+
sort.Strings(dependsOn)
if len(dependsOn) > 0 {
deps = append(deps, ftypes.Dependency{
@@ -279,7 +290,8 @@ func (p *Parser) parseModule(currentPath, relativePath string) (artifact, error)
}
moduleArtifact := module.artifact()
- moduleArtifact.Module = true // TODO: introduce RelationshipModule?
+ moduleArtifact.Module = true
+ moduleArtifact.Relationship = ftypes.RelationshipWorkspace
p.cache.put(moduleArtifact, result)
diff --git a/pkg/dependency/parser/java/pom/parse_test.go b/pkg/dependency/parser/java/pom/parse_test.go
index 8d0bf002d6dc..eb1a7b6b9bb7 100644
--- a/pkg/dependency/parser/java/pom/parse_test.go
+++ b/pkg/dependency/parser/java/pom/parse_test.go
@@ -1214,7 +1214,7 @@ func TestPom_Parse(t *testing.T) {
Name: "com.example:module",
Version: "1.1.1",
Licenses: []string{"Apache 2.0"},
- Relationship: ftypes.RelationshipRoot, // TODO: Several root modules break SBOM relationships
+ Relationship: ftypes.RelationshipWorkspace,
},
{
ID: "org.example:example-dependency:1.2.3",
@@ -1230,24 +1230,15 @@ func TestPom_Parse(t *testing.T) {
Relationship: ftypes.RelationshipIndirect,
},
},
- // maven doesn't include modules in dep tree of root pom
- // for modules uses separate graph:
- // ➜ mvn dependency:tree
- // [INFO] --------------------------------[ jar ]---------------------------------
- // [INFO]
- // [INFO] --- dependency:3.6.0:tree (default-cli) @ module ---
- // [INFO] com.example:module:jar:1.1.1
- // [INFO] \- org.example:example-dependency:jar:1.2.3:compile
- // [INFO] \- org.example:example-api:jar:2.0.0:compile
- // [INFO]
- // [INFO] ----------------------< com.example:aggregation >-----------------------
- // [INFO] Building aggregation 1.0.0 [2/2]
- // [INFO] from pom.xml
- // [INFO] --------------------------------[ pom ]---------------------------------
- // [INFO]
- // [INFO] --- dependency:3.6.0:tree (default-cli) @ aggregation ---
- // [INFO] com.example:aggregation:pom:1.0.0
+ // `mvn` doesn't include modules in dep tree of root pom and builds separate graphs.
+ // But we have `root` and `workspace` relationships, so we can merge these graphs.
wantDeps: []ftypes.Dependency{
+ {
+ ID: "com.example:aggregation:1.0.0",
+ DependsOn: []string{
+ "com.example:module:1.1.1",
+ },
+ },
{
ID: "com.example:module:1.1.1",
DependsOn: []string{
@@ -1262,29 +1253,78 @@ func TestPom_Parse(t *testing.T) {
},
},
},
+ {
+ name: "nested modules",
+ inputFile: filepath.Join("testdata", "nested-modules", "pom.xml"),
+ local: true,
+ want: []ftypes.Package{
+ {
+ ID: "com.example:root:1.0.0",
+ Name: "com.example:root",
+ Version: "1.0.0",
+ Relationship: ftypes.RelationshipRoot,
+ },
+ {
+ ID: "com.example:module1:1.0.0",
+ Name: "com.example:module1",
+ Version: "1.0.0",
+ Relationship: ftypes.RelationshipWorkspace,
+ },
+ {
+ ID: "com.example:module2:2.0.0",
+ Name: "com.example:module2",
+ Version: "2.0.0",
+ Relationship: ftypes.RelationshipWorkspace,
+ },
+ {
+ ID: "org.example:example-api:1.7.30",
+ Name: "org.example:example-api",
+ Version: "1.7.30",
+ Licenses: []string{
+ "The Apache Software License, Version 2.0",
+ },
+ Relationship: ftypes.RelationshipDirect,
+ },
+ },
+ wantDeps: []ftypes.Dependency{
+ {
+ ID: "com.example:module2:2.0.0",
+ DependsOn: []string{
+ "org.example:example-api:1.7.30",
+ },
+ },
+ {
+ ID: "com.example:root:1.0.0",
+ DependsOn: []string{
+ "com.example:module1:1.0.0",
+ "com.example:module2:2.0.0",
+ },
+ },
+ },
+ },
{
name: "Infinity loop for modules",
inputFile: filepath.Join("testdata", "modules-infinity-loop", "pom.xml"),
local: true,
want: []ftypes.Package{
+ {
+ ID: "org.example:root:1.0.0",
+ Name: "org.example:root",
+ Version: "1.0.0",
+ Relationship: ftypes.RelationshipRoot,
+ },
// as module
{
ID: "org.example:module-1:2.0.0",
Name: "org.example:module-1",
Version: "2.0.0",
- Relationship: ftypes.RelationshipRoot,
+ Relationship: ftypes.RelationshipWorkspace,
},
{
ID: "org.example:module-2:3.0.0",
Name: "org.example:module-2",
Version: "3.0.0",
- Relationship: ftypes.RelationshipRoot, // TODO: Several root modules break SBOM relationships
- },
- {
- ID: "org.example:root:1.0.0",
- Name: "org.example:root",
- Version: "1.0.0",
- Relationship: ftypes.RelationshipRoot, // TODO: Several root modules break SBOM relationships
+ Relationship: ftypes.RelationshipWorkspace,
},
// as dependency
{
@@ -1301,6 +1341,13 @@ func TestPom_Parse(t *testing.T) {
"org.example:module-1:2.0.0",
},
},
+ {
+ ID: "org.example:root:1.0.0",
+ DependsOn: []string{
+ "org.example:module-1:2.0.0",
+ "org.example:module-2:3.0.0",
+ },
+ },
},
},
{
@@ -1318,13 +1365,13 @@ func TestPom_Parse(t *testing.T) {
ID: "com.example:module1:1.1.1",
Name: "com.example:module1",
Version: "1.1.1",
- Relationship: ftypes.RelationshipRoot,
+ Relationship: ftypes.RelationshipWorkspace,
},
{
ID: "com.example:module2:1.1.1",
Name: "com.example:module2",
Version: "1.1.1",
- Relationship: ftypes.RelationshipRoot,
+ Relationship: ftypes.RelationshipWorkspace,
},
{
ID: "org.example:example-api:1.7.30",
@@ -1342,6 +1389,13 @@ func TestPom_Parse(t *testing.T) {
},
},
wantDeps: []ftypes.Dependency{
+ {
+ ID: "com.example:aggregation:1.0.0",
+ DependsOn: []string{
+ "com.example:module1:1.1.1",
+ "com.example:module2:1.1.1",
+ },
+ },
{
ID: "com.example:module1:1.1.1",
DependsOn: []string{
diff --git a/pkg/dependency/parser/java/pom/testdata/nested-modules/module1/module2/pom.xml b/pkg/dependency/parser/java/pom/testdata/nested-modules/module1/module2/pom.xml
new file mode 100644
index 000000000000..16417a171747
--- /dev/null
+++ b/pkg/dependency/parser/java/pom/testdata/nested-modules/module1/module2/pom.xml
@@ -0,0 +1,18 @@
+
+ 4.0.0
+
+ com.example
+ module2
+ 2.0.0
+
+ pom
+
+
+
+ org.example
+ example-api
+ 1.7.30
+
+
+
diff --git a/pkg/dependency/parser/java/pom/testdata/nested-modules/module1/pom.xml b/pkg/dependency/parser/java/pom/testdata/nested-modules/module1/pom.xml
new file mode 100644
index 000000000000..9e22eb6ba815
--- /dev/null
+++ b/pkg/dependency/parser/java/pom/testdata/nested-modules/module1/pom.xml
@@ -0,0 +1,14 @@
+
+ 4.0.0
+
+ com.example
+ module1
+ 1.0.0
+
+ pom
+
+
+ module2
+
+
diff --git a/pkg/dependency/parser/java/pom/testdata/nested-modules/pom.xml b/pkg/dependency/parser/java/pom/testdata/nested-modules/pom.xml
new file mode 100644
index 000000000000..48d741859053
--- /dev/null
+++ b/pkg/dependency/parser/java/pom/testdata/nested-modules/pom.xml
@@ -0,0 +1,16 @@
+
+ 4.0.0
+
+ com.example
+ root
+ 1.0.0
+
+ pom
+
+
+ module1
+
+
+
+
diff --git a/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedlibs.golden b/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedlibs.golden
index 7c52aef32965..2ff8a71a1628 100644
--- a/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedlibs.golden
+++ b/pkg/fanal/test/integration/testdata/goldens/vuln-image1.2.3.expectedlibs.golden
@@ -8,7 +8,7 @@
"Name": "dotenv",
"Identifier": {
"PURL": "pkg:gem/dotenv@2.7.2",
- "UID": "bf323ef200ea177a"
+ "UID": "81de7d5923ef6698"
},
"Version": "2.7.2",
"Relationship": "direct",
@@ -25,7 +25,7 @@
"Name": "faker",
"Identifier": {
"PURL": "pkg:gem/faker@1.9.3",
- "UID": "b5ac01b24ab4ed39"
+ "UID": "8a05db8580a33fba"
},
"Version": "1.9.3",
"Relationship": "direct",
@@ -45,7 +45,7 @@
"Name": "json",
"Identifier": {
"PURL": "pkg:gem/json@2.2.0",
- "UID": "cb6c1eb54f8c6e9d"
+ "UID": "9d93d18f97484cf3"
},
"Version": "2.2.0",
"Relationship": "direct",
@@ -62,7 +62,7 @@
"Name": "pry",
"Identifier": {
"PURL": "pkg:gem/pry@0.12.2",
- "UID": "1349a1afdbbc80bc"
+ "UID": "7d01d0d732a91bb7"
},
"Version": "0.12.2",
"Relationship": "direct",
@@ -83,7 +83,7 @@
"Name": "rails",
"Identifier": {
"PURL": "pkg:gem/rails@5.2.0",
- "UID": "edef417a0d4c73e"
+ "UID": "21e56669bd72df57"
},
"Version": "5.2.0",
"Relationship": "direct",
@@ -113,7 +113,7 @@
"Name": "rubocop",
"Identifier": {
"PURL": "pkg:gem/rubocop@0.67.2",
- "UID": "68a7b25b67dfb858"
+ "UID": "957ab983044aa9f3"
},
"Version": "0.67.2",
"Relationship": "direct",
@@ -139,7 +139,7 @@
"Name": "actioncable",
"Identifier": {
"PURL": "pkg:gem/actioncable@5.2.3",
- "UID": "a2f0009734c47a50"
+ "UID": "ecd29a77dc997777"
},
"Version": "5.2.3",
"Indirect": true,
@@ -162,7 +162,7 @@
"Name": "actionmailer",
"Identifier": {
"PURL": "pkg:gem/actionmailer@5.2.3",
- "UID": "957dd2cc6d970211"
+ "UID": "b12f20a3315669b8"
},
"Version": "5.2.3",
"Indirect": true,
@@ -187,7 +187,7 @@
"Name": "actionpack",
"Identifier": {
"PURL": "pkg:gem/actionpack@5.2.3",
- "UID": "b4e4b4e5f7967b8a"
+ "UID": "3e6d8c3a4893cd5"
},
"Version": "5.2.3",
"Indirect": true,
@@ -213,7 +213,7 @@
"Name": "actionview",
"Identifier": {
"PURL": "pkg:gem/actionview@5.2.3",
- "UID": "e303cfc150443baf"
+ "UID": "3dcfe274dee232cf"
},
"Version": "5.2.3",
"Indirect": true,
@@ -238,7 +238,7 @@
"Name": "activejob",
"Identifier": {
"PURL": "pkg:gem/activejob@5.2.3",
- "UID": "107f18a1d47c926e"
+ "UID": "2c50cfba90b99d4f"
},
"Version": "5.2.3",
"Indirect": true,
@@ -260,7 +260,7 @@
"Name": "activemodel",
"Identifier": {
"PURL": "pkg:gem/activemodel@5.2.3",
- "UID": "22b9bacf4efb92d7"
+ "UID": "eefced6054bc7118"
},
"Version": "5.2.3",
"Indirect": true,
@@ -281,7 +281,7 @@
"Name": "activerecord",
"Identifier": {
"PURL": "pkg:gem/activerecord@5.2.3",
- "UID": "a30ec4dd4f1cad0d"
+ "UID": "54a0e498d3a27a9e"
},
"Version": "5.2.3",
"Indirect": true,
@@ -304,7 +304,7 @@
"Name": "activestorage",
"Identifier": {
"PURL": "pkg:gem/activestorage@5.2.3",
- "UID": "4e3f0e59a70b38a9"
+ "UID": "6b878767cc5bc16d"
},
"Version": "5.2.3",
"Indirect": true,
@@ -327,7 +327,7 @@
"Name": "activesupport",
"Identifier": {
"PURL": "pkg:gem/activesupport@5.2.3",
- "UID": "b83d5718f12b7df1"
+ "UID": "75237905ecef3213"
},
"Version": "5.2.3",
"Indirect": true,
@@ -351,7 +351,7 @@
"Name": "arel",
"Identifier": {
"PURL": "pkg:gem/arel@9.0.0",
- "UID": "9a68b51c670c5d28"
+ "UID": "2b27003c3d80c500"
},
"Version": "9.0.0",
"Indirect": true,
@@ -369,7 +369,7 @@
"Name": "ast",
"Identifier": {
"PURL": "pkg:gem/ast@2.4.0",
- "UID": "fad54f55dc524edc"
+ "UID": "7094963eecbb4a3a"
},
"Version": "2.4.0",
"Indirect": true,
@@ -387,7 +387,7 @@
"Name": "builder",
"Identifier": {
"PURL": "pkg:gem/builder@3.2.3",
- "UID": "4998ad08ac24b078"
+ "UID": "f47fc1abe3df2caa"
},
"Version": "3.2.3",
"Indirect": true,
@@ -405,7 +405,7 @@
"Name": "coderay",
"Identifier": {
"PURL": "pkg:gem/coderay@1.1.2",
- "UID": "a48fa0679d10835e"
+ "UID": "a912844ee6e547a5"
},
"Version": "1.1.2",
"Indirect": true,
@@ -423,7 +423,7 @@
"Name": "concurrent-ruby",
"Identifier": {
"PURL": "pkg:gem/concurrent-ruby@1.1.5",
- "UID": "bca3d9447a1c8032"
+ "UID": "1faccd8f356486f8"
},
"Version": "1.1.5",
"Indirect": true,
@@ -441,7 +441,7 @@
"Name": "crass",
"Identifier": {
"PURL": "pkg:gem/crass@1.0.4",
- "UID": "63d9762f8a29e52"
+ "UID": "aa66047c25aa8a3"
},
"Version": "1.0.4",
"Indirect": true,
@@ -459,7 +459,7 @@
"Name": "erubi",
"Identifier": {
"PURL": "pkg:gem/erubi@1.8.0",
- "UID": "de475f0ffcba457d"
+ "UID": "4f991bd1dc25f425"
},
"Version": "1.8.0",
"Indirect": true,
@@ -477,7 +477,7 @@
"Name": "globalid",
"Identifier": {
"PURL": "pkg:gem/globalid@0.4.2",
- "UID": "daff7877b36bd14b"
+ "UID": "7d42bb634d2ea5ca"
},
"Version": "0.4.2",
"Indirect": true,
@@ -498,7 +498,7 @@
"Name": "i18n",
"Identifier": {
"PURL": "pkg:gem/i18n@1.6.0",
- "UID": "66065208a829ff94"
+ "UID": "ff898062ba167e1a"
},
"Version": "1.6.0",
"Indirect": true,
@@ -519,7 +519,7 @@
"Name": "jaro_winkler",
"Identifier": {
"PURL": "pkg:gem/jaro_winkler@1.5.2",
- "UID": "9a5b22728e40960b"
+ "UID": "6a6b64429b52aaa8"
},
"Version": "1.5.2",
"Indirect": true,
@@ -537,7 +537,7 @@
"Name": "loofah",
"Identifier": {
"PURL": "pkg:gem/loofah@2.2.3",
- "UID": "61fc41b2f5521a64"
+ "UID": "370b8e0d823dff03"
},
"Version": "2.2.3",
"Indirect": true,
@@ -559,7 +559,7 @@
"Name": "mail",
"Identifier": {
"PURL": "pkg:gem/mail@2.7.1",
- "UID": "edee06a4b6e79f92"
+ "UID": "5e4c71169d7a349f"
},
"Version": "2.7.1",
"Indirect": true,
@@ -580,7 +580,7 @@
"Name": "marcel",
"Identifier": {
"PURL": "pkg:gem/marcel@0.3.3",
- "UID": "4695d691e0d7ac17"
+ "UID": "f43c52096c4ad09c"
},
"Version": "0.3.3",
"Indirect": true,
@@ -601,7 +601,7 @@
"Name": "method_source",
"Identifier": {
"PURL": "pkg:gem/method_source@0.9.2",
- "UID": "b96872ad7feeedb2"
+ "UID": "1fa86750277a95a3"
},
"Version": "0.9.2",
"Indirect": true,
@@ -619,7 +619,7 @@
"Name": "mimemagic",
"Identifier": {
"PURL": "pkg:gem/mimemagic@0.3.3",
- "UID": "54089ae8801a3144"
+ "UID": "a350af0aa168b20c"
},
"Version": "0.3.3",
"Indirect": true,
@@ -637,7 +637,7 @@
"Name": "mini_mime",
"Identifier": {
"PURL": "pkg:gem/mini_mime@1.0.1",
- "UID": "ea53b65af3f9c07c"
+ "UID": "ccc534b1135f68c9"
},
"Version": "1.0.1",
"Indirect": true,
@@ -655,7 +655,7 @@
"Name": "mini_portile2",
"Identifier": {
"PURL": "pkg:gem/mini_portile2@2.4.0",
- "UID": "503f9a3009616732"
+ "UID": "f3fa9c142de41168"
},
"Version": "2.4.0",
"Indirect": true,
@@ -673,7 +673,7 @@
"Name": "minitest",
"Identifier": {
"PURL": "pkg:gem/minitest@5.11.3",
- "UID": "1d1c12205a5ea0c1"
+ "UID": "37b0b09d82d19b2"
},
"Version": "5.11.3",
"Indirect": true,
@@ -691,7 +691,7 @@
"Name": "nio4r",
"Identifier": {
"PURL": "pkg:gem/nio4r@2.3.1",
- "UID": "1f214c910b2d6498"
+ "UID": "169da6540acc34de"
},
"Version": "2.3.1",
"Indirect": true,
@@ -709,7 +709,7 @@
"Name": "nokogiri",
"Identifier": {
"PURL": "pkg:gem/nokogiri@1.10.3",
- "UID": "4cadfe4426354933"
+ "UID": "a4dde592ac75f50b"
},
"Version": "1.10.3",
"Indirect": true,
@@ -730,7 +730,7 @@
"Name": "parallel",
"Identifier": {
"PURL": "pkg:gem/parallel@1.17.0",
- "UID": "f31aa3a8599717a1"
+ "UID": "ca10abfedb4b138b"
},
"Version": "1.17.0",
"Indirect": true,
@@ -748,7 +748,7 @@
"Name": "parser",
"Identifier": {
"PURL": "pkg:gem/parser@2.6.3.0",
- "UID": "fa2f74869e82d572"
+ "UID": "2bd5a2d3958a34d"
},
"Version": "2.6.3.0",
"Indirect": true,
@@ -769,7 +769,7 @@
"Name": "psych",
"Identifier": {
"PURL": "pkg:gem/psych@3.1.0",
- "UID": "34bd03308f382650"
+ "UID": "3b654c74c1c64d48"
},
"Version": "3.1.0",
"Indirect": true,
@@ -787,7 +787,7 @@
"Name": "rack",
"Identifier": {
"PURL": "pkg:gem/rack@2.0.7",
- "UID": "d9f77162d5199665"
+ "UID": "76cbaa6e040e1770"
},
"Version": "2.0.7",
"Indirect": true,
@@ -805,7 +805,7 @@
"Name": "rack-test",
"Identifier": {
"PURL": "pkg:gem/rack-test@1.1.0",
- "UID": "ce77144d56bbfcc7"
+ "UID": "cc4cf2b36612b845"
},
"Version": "1.1.0",
"Indirect": true,
@@ -826,7 +826,7 @@
"Name": "rails-dom-testing",
"Identifier": {
"PURL": "pkg:gem/rails-dom-testing@2.0.3",
- "UID": "f86753ba2b01f92d"
+ "UID": "51790bcbc34a4f9f"
},
"Version": "2.0.3",
"Indirect": true,
@@ -848,7 +848,7 @@
"Name": "rails-html-sanitizer",
"Identifier": {
"PURL": "pkg:gem/rails-html-sanitizer@1.0.3",
- "UID": "ca9d0e53040b92a7"
+ "UID": "3d074a9f84d5431a"
},
"Version": "1.0.3",
"Indirect": true,
@@ -869,7 +869,7 @@
"Name": "railties",
"Identifier": {
"PURL": "pkg:gem/railties@5.2.3",
- "UID": "79238ef7535ec96f"
+ "UID": "f4c2fc2260f590e8"
},
"Version": "5.2.3",
"Indirect": true,
@@ -894,7 +894,7 @@
"Name": "rainbow",
"Identifier": {
"PURL": "pkg:gem/rainbow@3.0.0",
- "UID": "b370837d83c44cb7"
+ "UID": "40028b39c319ccd6"
},
"Version": "3.0.0",
"Indirect": true,
@@ -912,7 +912,7 @@
"Name": "rake",
"Identifier": {
"PURL": "pkg:gem/rake@12.3.2",
- "UID": "4f4252bdb5e59b57"
+ "UID": "ad3a9cdaf7f45094"
},
"Version": "12.3.2",
"Indirect": true,
@@ -930,7 +930,7 @@
"Name": "ruby-progressbar",
"Identifier": {
"PURL": "pkg:gem/ruby-progressbar@1.10.0",
- "UID": "3955293b43d2fd52"
+ "UID": "2d6a80c63f6249f9"
},
"Version": "1.10.0",
"Indirect": true,
@@ -948,7 +948,7 @@
"Name": "sprockets",
"Identifier": {
"PURL": "pkg:gem/sprockets@3.7.2",
- "UID": "116e2747536e43f5"
+ "UID": "16df8dd119914f55"
},
"Version": "3.7.2",
"Indirect": true,
@@ -970,7 +970,7 @@
"Name": "sprockets-rails",
"Identifier": {
"PURL": "pkg:gem/sprockets-rails@3.2.1",
- "UID": "24b0c150e29c714e"
+ "UID": "3e708458a3535611"
},
"Version": "3.2.1",
"Indirect": true,
@@ -993,7 +993,7 @@
"Name": "thor",
"Identifier": {
"PURL": "pkg:gem/thor@0.20.3",
- "UID": "85877345b4057dc4"
+ "UID": "f2e43df8162dd43c"
},
"Version": "0.20.3",
"Indirect": true,
@@ -1011,7 +1011,7 @@
"Name": "thread_safe",
"Identifier": {
"PURL": "pkg:gem/thread_safe@0.3.6",
- "UID": "2851ab474c97947e"
+ "UID": "baaae7551e2b7a2d"
},
"Version": "0.3.6",
"Indirect": true,
@@ -1029,7 +1029,7 @@
"Name": "tzinfo",
"Identifier": {
"PURL": "pkg:gem/tzinfo@1.2.5",
- "UID": "1ef6e099466a3dd"
+ "UID": "b257df460b48c02e"
},
"Version": "1.2.5",
"Indirect": true,
@@ -1050,7 +1050,7 @@
"Name": "unicode-display_width",
"Identifier": {
"PURL": "pkg:gem/unicode-display_width@1.5.0",
- "UID": "5212ef154d81feeb"
+ "UID": "451db3c980d2abb2"
},
"Version": "1.5.0",
"Indirect": true,
@@ -1068,7 +1068,7 @@
"Name": "websocket-driver",
"Identifier": {
"PURL": "pkg:gem/websocket-driver@0.7.0",
- "UID": "6d4862fcfa71d8db"
+ "UID": "6c3ccfb2b719d633"
},
"Version": "0.7.0",
"Indirect": true,
@@ -1089,7 +1089,7 @@
"Name": "websocket-extensions",
"Identifier": {
"PURL": "pkg:gem/websocket-extensions@0.1.3",
- "UID": "84dd4f30cc911d14"
+ "UID": "9b87af4231c82ab8"
},
"Version": "0.1.3",
"Indirect": true,
diff --git a/pkg/fanal/types/package.go b/pkg/fanal/types/package.go
index 2726aa8ad8c8..340ad868b10d 100644
--- a/pkg/fanal/types/package.go
+++ b/pkg/fanal/types/package.go
@@ -16,6 +16,7 @@ type Relationship int
const (
RelationshipUnknown Relationship = iota
RelationshipRoot
+ RelationshipWorkspace // For maven `modules`. TODO use it for cargo and npm workspaces
RelationshipDirect
RelationshipIndirect
)
@@ -24,6 +25,7 @@ var (
Relationships = []Relationship{
RelationshipUnknown,
RelationshipRoot,
+ RelationshipWorkspace,
RelationshipDirect,
RelationshipIndirect,
}
@@ -31,6 +33,7 @@ var (
relationshipNames = [...]string{
"unknown",
"root",
+ "workspace",
"direct",
"indirect",
}
diff --git a/pkg/sbom/io/encode_test.go b/pkg/sbom/io/encode_test.go
index 7b040f07d68b..93cdd2a9410c 100644
--- a/pkg/sbom/io/encode_test.go
+++ b/pkg/sbom/io/encode_test.go
@@ -765,6 +765,366 @@ func TestEncoder_Encode(t *testing.T) {
},
wantVulns: make(map[uuid.UUID][]core.Vulnerability),
},
+ {
+ name: "multimodule maven project",
+ report: types.Report{
+ SchemaVersion: 2,
+ ArtifactName: "pom.xml",
+ ArtifactType: artifact.TypeFilesystem,
+ Results: []types.Result{
+ {
+ Target: "pom.xml",
+ Type: ftypes.Pom,
+ Class: types.ClassLangPkg,
+ Packages: []ftypes.Package{
+ {
+ ID: "com.example:root:1.0.0",
+ Name: "com.example:root",
+ Version: "1.0.0",
+ Identifier: ftypes.PkgIdentifier{
+ UID: "f684ec661900abbf",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "com.example",
+ Name: "root",
+ Version: "1.0.0",
+ },
+ },
+ Relationship: ftypes.RelationshipRoot,
+ DependsOn: []string{
+ "com.example:module1:1.0.0",
+ "com.example:module2:2.0.0",
+ },
+ },
+ {
+ ID: "com.example:module1:1.0.0",
+ Name: "com.example:module1",
+ Version: "1.0.0",
+ Identifier: ftypes.PkgIdentifier{
+ UID: "ce0d29336874c431",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "com.example",
+ Name: "module1",
+ Version: "1.0.0",
+ },
+ },
+ Relationship: ftypes.RelationshipWorkspace,
+ DependsOn: []string{
+ "org.example:example-api:1.1.1",
+ },
+ },
+ {
+ ID: "com.example:module2:2.0.0",
+ Name: "com.example:module2",
+ Version: "2.0.0",
+ Identifier: ftypes.PkgIdentifier{
+ UID: "387238ffef6dfa9d",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "com.example",
+ Name: "module2",
+ Version: "2.0.0",
+ },
+ },
+ Relationship: ftypes.RelationshipWorkspace,
+ DependsOn: []string{
+ "org.example:example-dependency:1.2.3",
+ },
+ },
+ {
+ ID: "org.example:example-api:1.1.1",
+ Name: "org.example:example-api",
+ Version: "1.1.1",
+ Identifier: ftypes.PkgIdentifier{
+ UID: "45cdc62618708bb7",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "org.example",
+ Name: "example-api",
+ Version: "1.1.1",
+ },
+ },
+ Relationship: ftypes.RelationshipDirect,
+ },
+ {
+ ID: "org.example:example-dependency:1.2.3",
+ Name: "org.example:example-dependency",
+ Version: "1.2.3",
+ Identifier: ftypes.PkgIdentifier{
+ UID: "52fbe353a46651",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "org.example",
+ Name: "example-dependency",
+ Version: "1.2.3",
+ },
+ },
+ Relationship: ftypes.RelationshipDirect,
+ DependsOn: []string{
+ "org.example:example-api:2.0.0",
+ },
+ },
+ {
+ ID: "org.example:example-api:2.0.0",
+ Name: "org.example:example-api",
+ Version: "2.0.0",
+ Identifier: ftypes.PkgIdentifier{
+ UID: "f71d14b6d2bd8810",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "org.example",
+ Name: "example-api",
+ Version: "2.0.0",
+ },
+ },
+ Relationship: ftypes.RelationshipIndirect,
+ },
+ },
+ },
+ },
+ },
+ wantComponents: map[uuid.UUID]*core.Component{
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"): {
+ Type: core.TypeFilesystem,
+ Name: "pom.xml",
+ Root: true,
+ Properties: []core.Property{
+ {
+ Name: core.PropertySchemaVersion,
+ Value: "2",
+ },
+ },
+ PkgIdentifier: ftypes.PkgIdentifier{
+ BOMRef: "3ff14136-e09f-4df9-80ea-000000000001",
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"): {
+ Type: core.TypeApplication,
+ Name: "pom.xml",
+ Properties: []core.Property{
+ {
+ Name: core.PropertyClass,
+ Value: "lang-pkgs",
+ },
+ {
+ Name: core.PropertyType,
+ Value: "pom",
+ },
+ },
+ PkgIdentifier: ftypes.PkgIdentifier{
+ BOMRef: "3ff14136-e09f-4df9-80ea-000000000002",
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000003"): {
+ Type: core.TypeLibrary,
+ Group: "com.example",
+ Name: "root",
+ Version: "1.0.0",
+ SrcFile: "pom.xml",
+ Properties: []core.Property{
+ {
+ Name: core.PropertyPkgID,
+ Value: "com.example:root:1.0.0",
+ },
+ {
+ Name: core.PropertyPkgType,
+ Value: "pom",
+ },
+ },
+ PkgIdentifier: ftypes.PkgIdentifier{
+ UID: "f684ec661900abbf",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "com.example",
+ Name: "root",
+ Version: "1.0.0",
+ },
+ BOMRef: "pkg:maven/com.example/root@1.0.0",
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000004"): {
+ Type: core.TypeLibrary,
+ Group: "com.example",
+ Name: "module1",
+ Version: "1.0.0",
+ SrcFile: "pom.xml",
+ Properties: []core.Property{
+ {
+ Name: core.PropertyPkgID,
+ Value: "com.example:module1:1.0.0",
+ },
+ {
+ Name: core.PropertyPkgType,
+ Value: "pom",
+ },
+ },
+ PkgIdentifier: ftypes.PkgIdentifier{
+ UID: "ce0d29336874c431",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "com.example",
+ Name: "module1",
+ Version: "1.0.0",
+ },
+ BOMRef: "pkg:maven/com.example/module1@1.0.0",
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000005"): {
+ Type: core.TypeLibrary,
+ Group: "com.example",
+ Name: "module2",
+ Version: "2.0.0",
+ SrcFile: "pom.xml",
+ Properties: []core.Property{
+ {
+ Name: core.PropertyPkgID,
+ Value: "com.example:module2:2.0.0",
+ },
+ {
+ Name: core.PropertyPkgType,
+ Value: "pom",
+ },
+ },
+ PkgIdentifier: ftypes.PkgIdentifier{
+ UID: "387238ffef6dfa9d",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "com.example",
+ Name: "module2",
+ Version: "2.0.0",
+ },
+ BOMRef: "pkg:maven/com.example/module2@2.0.0",
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000006"): {
+ Type: core.TypeLibrary,
+ Group: "org.example",
+ Name: "example-api",
+ Version: "1.1.1",
+ SrcFile: "pom.xml",
+ Properties: []core.Property{
+ {
+ Name: core.PropertyPkgID,
+ Value: "org.example:example-api:1.1.1",
+ },
+ {
+ Name: core.PropertyPkgType,
+ Value: "pom",
+ },
+ },
+ PkgIdentifier: ftypes.PkgIdentifier{
+ UID: "45cdc62618708bb7",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "org.example",
+ Name: "example-api",
+ Version: "1.1.1",
+ },
+ BOMRef: "pkg:maven/org.example/example-api@1.1.1",
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000007"): {
+ Type: core.TypeLibrary,
+ Group: "org.example",
+ Name: "example-dependency",
+ Version: "1.2.3",
+ SrcFile: "pom.xml",
+ Properties: []core.Property{
+ {
+ Name: core.PropertyPkgID,
+ Value: "org.example:example-dependency:1.2.3",
+ },
+ {
+ Name: core.PropertyPkgType,
+ Value: "pom",
+ },
+ },
+ PkgIdentifier: ftypes.PkgIdentifier{
+ UID: "52fbe353a46651",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "org.example",
+ Name: "example-dependency",
+ Version: "1.2.3",
+ },
+ BOMRef: "pkg:maven/org.example/example-dependency@1.2.3",
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000008"): {
+ Type: core.TypeLibrary,
+ Group: "org.example",
+ Name: "example-api",
+ Version: "2.0.0",
+ SrcFile: "pom.xml",
+ Properties: []core.Property{
+ {
+ Name: core.PropertyPkgID,
+ Value: "org.example:example-api:2.0.0",
+ },
+ {
+ Name: core.PropertyPkgType,
+ Value: "pom",
+ },
+ },
+ PkgIdentifier: ftypes.PkgIdentifier{
+ UID: "f71d14b6d2bd8810",
+ PURL: &packageurl.PackageURL{
+ Type: packageurl.TypeMaven,
+ Namespace: "org.example",
+ Name: "example-api",
+ Version: "2.0.0",
+ },
+ BOMRef: "pkg:maven/org.example/example-api@2.0.0",
+ },
+ },
+ },
+ wantRels: map[uuid.UUID][]core.Relationship{
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"): {
+ {
+ Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"),
+ Type: core.RelationshipContains,
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"): {
+ {
+ Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000003"),
+ Type: core.RelationshipContains,
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000003"): {
+ {
+ Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000004"),
+ Type: core.RelationshipDependsOn,
+ },
+ {
+ Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000005"),
+ Type: core.RelationshipDependsOn,
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000004"): {
+ {
+ Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000006"),
+ Type: core.RelationshipDependsOn,
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000005"): {
+ {
+ Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000007"),
+ Type: core.RelationshipDependsOn,
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000006"): nil,
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000007"): {
+ {
+ Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000008"),
+ Type: core.RelationshipDependsOn,
+ },
+ },
+ uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000008"): nil,
+ },
+ wantVulns: make(map[uuid.UUID][]core.Vulnerability),
+ },
{
name: "json file created from SBOM file (BOM is empty)",
report: types.Report{