Repository: CycloneDX/cdxgen (js)

Issue:
[Gradle] Incorrect dependency information in Gradle project
Hi!
The sbom included in [this repository](https://github.com/ajmalab/dependency-diff-check/blob/main/sbom.json) made with cdxgen@8.4.7 shows that `pkg:maven/org.flywaydb/flyway-mysql@9.17.0?type=jar` depends on `pkg:maven/io.opentelemetry/opentelemetry-jdbc@1.19.0?type=jar`. This is inaccurate, flyway-mysql only depends on `flyway-core` and `lombok`. The remaining refs are transitive dependencies coming via `pkg:maven/dependency-diff-check-service@latest?type=jar` which depends on `pkg:maven/dependency-diff-check-common-core@latest?type=jar`.

As per the [standard](https://cyclonedx.org/docs/1.4/json/#dependencies), only direct dependencies are expected in the `dependencies` block.

Pull request:
Handles a case where a gradle dependency
Fixes #318 and "undefined" ref bug

Patch:
diff --git a/utils.js b/utils.js
index dc3eb06c..5004cf2f 100644
--- a/utils.js
+++ b/utils.js
@@ -1204,6 +1204,7 @@ const parseGradleDep = function (
     const keys_cache = {};
     let last_level = 0;
     let last_purl = `pkg:maven/${rootProjectName}@${rootProjectVersion}?type=jar`;
+    const first_purl = last_purl;
     // Bug: 249. Get any sub-projects refered here
     const retMap = parseGradleProjects(rawOutput);
     const level_trees = {};
@@ -1229,54 +1230,68 @@ const parseGradleDep = function (
     let stack = [last_purl];
     const depRegex =
       /^.*?--- +(?<group>[^\s:]+):(?<name>[^\s:]+)(?::(?:{strictly [[]?)?(?<versionspecified>[^,\s:}]+))?(?:})?(?:[^->]* +-> +(?<versionoverride>[^\s:]+))?/gm;
-    while ((match = depRegex.exec(rawOutput))) {
-      const [line, group, name, versionspecified, versionoverride] = match;
-      const version = versionoverride || versionspecified;
-      const level = line.split(group)[0].length / 5;
-      if (version !== undefined) {
-        let purlString = new PackageURL(
-          "maven",
-          group,
-          name,
-          version,
-          { type: "jar" },
-          null
-        ).toString();
-        purlString = decodeURIComponent(purlString);
-        // Filter duplicates
-        if (!keys_cache[purlString]) {
-          keys_cache[purlString] = true;
-          if (group !== "project") {
-            deps.push({
-              group,
-              name: name,
-              version: version,
-              qualifiers: { type: "jar" }
-            });
-            if (!level_trees[purlString]) {
-              level_trees[purlString] = [];
-            }
-            if (level == 0 || last_purl === "") {
-              stack.push(purlString);
-            } else if (level > last_level) {
-              const cnodes = level_trees[last_purl] || [];
-              cnodes.push(purlString);
-              level_trees[last_purl] = cnodes;
-              if (stack[stack.length - 1] !== purlString) {
-                stack.push(purlString);
+    for (const rline of rawOutput.split("\n")) {
+      if (last_level !== 1) {
+        if (
+          !rline ||
+          rline.trim() === "" ||
+          rline.startsWith("+--- ") ||
+          rline.startsWith("--- ")
+        ) {
+          last_level = 1;
+        }
+      }
+      while ((match = depRegex.exec(rline))) {
+        const [line, group, name, versionspecified, versionoverride] = match;
+        const version = versionoverride || versionspecified;
+        const level = line.split(group)[0].length / 5;
+        if (version !== undefined) {
+          let purlString = new PackageURL(
+            "maven",
+            group,
+            name,
+            version,
+            { type: "jar" },
+            null
+          ).toString();
+          purlString = decodeURIComponent(purlString);
+
+          // Filter duplicates
+          if (!keys_cache[purlString]) {
+            keys_cache[purlString] = true;
+            if (group !== "project") {
+              deps.push({
+                group,
+                name: name,
+                version: version,
+                qualifiers: { type: "jar" }
+              });
+              if (!level_trees[purlString]) {
+                level_trees[purlString] = [];
               }
-            } else {
-              for (let i = level; i <= last_level; i++) {
-                stack.pop();
+              if (level == 0 || last_purl === "") {
+                stack.push(purlString);
+              } else if (level > last_level) {
+                const cnodes = level_trees[last_purl] || [];
+                cnodes.push(purlString);
+                level_trees[last_purl] = cnodes;
+                if (stack[stack.length - 1] !== purlString) {
+                  stack.push(purlString);
+                }
+              } else {
+                for (let i = level; i <= last_level; i++) {
+                  stack.pop();
+                }
+                const last_stack =
+                  stack.length > 0 ? stack[stack.length - 1] : first_purl;
+                const cnodes = level_trees[last_stack] || [];
+                cnodes.push(purlString);
+                level_trees[last_stack] = cnodes;
+                stack.push(purlString);
               }
-              const last_stack = stack[stack.length - 1];
-              const cnodes = level_trees[last_stack] || [];
-              cnodes.push(purlString);
-              level_trees[last_stack] = cnodes;
-              stack.push(purlString);
+              last_level = level;
+              last_purl = purlString;
             }
-            last_level = level;
-            last_purl = purlString;
           }
         }
       }


Test patch:
diff --git a/test/data/gradle-core.out b/test/data/gradle-core.out
new file mode 100644
index 00000000..b6fac494
--- /dev/null
+++ b/test/data/gradle-core.out
@@ -0,0 +1,136 @@
+
+------------------------------------------------------------
+Project ':dependency-diff-check-common-core'
+------------------------------------------------------------
+
+annotationProcessor - Annotation processors and their dependencies for source set 'main'.
+No dependencies
+
+api - API dependencies for source set 'main'. (n)
+No dependencies
+
+apiElements - API elements for main. (n)
+No dependencies
+
+archives - Configuration for archive artifacts. (n)
+No dependencies
+
+compileClasspath - Compile classpath for source set 'main'.
++--- org.apache.commons:commons-lang3:3.12.0
++--- com.fasterxml.jackson.core:jackson-core:2.14.2
+|    \--- com.fasterxml.jackson:jackson-bom:2.14.2
+|         \--- com.fasterxml.jackson.core:jackson-core:2.14.2 (c)
++--- io.opentelemetry:opentelemetry-jdbc:1.19.0 FAILED
+\--- io.grpc:grpc-core:1.49.2
+     \--- io.grpc:grpc-api:1.49.2
+          +--- io.grpc:grpc-context:1.49.2
+          +--- com.google.code.findbugs:jsr305:3.0.2
+          \--- com.google.errorprone:error_prone_annotations:2.14.0
+
+compileOnly - Compile only dependencies for source set 'main'. (n)
+No dependencies
+
+compileOnlyApi - Compile only API dependencies for source set 'main'. (n)
+No dependencies
+
+default - Configuration for default artifacts. (n)
+No dependencies
+
+implementation - Implementation only dependencies for source set 'main'. (n)
++--- org.apache.commons:commons-lang3:3.12.0 (n)
++--- com.fasterxml.jackson.core:jackson-core:2.14.2 (n)
++--- io.opentelemetry:opentelemetry-jdbc:1.19.0 (n)
+\--- io.grpc:grpc-core:1.49.2 (n)
+
+mainSourceElements - List of source directories contained in the Main SourceSet. (n)
+No dependencies
+
+runtimeClasspath - Runtime classpath of source set 'main'.
++--- org.apache.commons:commons-lang3:3.12.0
++--- com.fasterxml.jackson.core:jackson-core:2.14.2
+|    \--- com.fasterxml.jackson:jackson-bom:2.14.2
+|         \--- com.fasterxml.jackson.core:jackson-core:2.14.2 (c)
++--- io.opentelemetry:opentelemetry-jdbc:1.19.0 FAILED
+\--- io.grpc:grpc-core:1.49.2
+     +--- io.grpc:grpc-api:1.49.2
+     |    +--- io.grpc:grpc-context:1.49.2
+     |    +--- com.google.code.findbugs:jsr305:3.0.2
+     |    +--- com.google.errorprone:error_prone_annotations:2.14.0
+     |    \--- com.google.guava:guava:31.1-android
+     |         +--- com.google.guava:failureaccess:1.0.1
+     |         +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
+     |         +--- com.google.code.findbugs:jsr305:3.0.2
+     |         +--- org.checkerframework:checker-qual:3.12.0
+     |         +--- com.google.errorprone:error_prone_annotations:2.11.0 -> 2.14.0
+     |         \--- com.google.j2objc:j2objc-annotations:1.3
+     +--- com.google.code.gson:gson:2.9.0
+     +--- com.google.android:annotations:4.1.1.4
+     +--- org.codehaus.mojo:animal-sniffer-annotations:1.21
+     +--- com.google.errorprone:error_prone_annotations:2.14.0
+     +--- com.google.guava:guava:31.1-android (*)
+     \--- io.perfmark:perfmark-api:0.25.0
+
+runtimeElements - Elements of runtime for main. (n)
+No dependencies
+
+runtimeOnly - Runtime only dependencies for source set 'main'. (n)
+No dependencies
+
+testAnnotationProcessor - Annotation processors and their dependencies for source set 'test'.
+No dependencies
+
+testCompileClasspath - Compile classpath for source set 'test'.
++--- org.apache.commons:commons-lang3:3.12.0
++--- com.fasterxml.jackson.core:jackson-core:2.14.2
+|    \--- com.fasterxml.jackson:jackson-bom:2.14.2
+|         \--- com.fasterxml.jackson.core:jackson-core:2.14.2 (c)
++--- io.opentelemetry:opentelemetry-jdbc:1.19.0 FAILED
+\--- io.grpc:grpc-core:1.49.2
+     \--- io.grpc:grpc-api:1.49.2
+          +--- io.grpc:grpc-context:1.49.2
+          +--- com.google.code.findbugs:jsr305:3.0.2
+          \--- com.google.errorprone:error_prone_annotations:2.14.0
+
+testCompileOnly - Compile only dependencies for source set 'test'. (n)
+No dependencies
+
+testImplementation - Implementation only dependencies for source set 'test'. (n)
+No dependencies
+
+testResultsElementsForTest - Directory containing binary results of running tests for the test Test Suite's test target. (n)
+No dependencies
+
+testRuntimeClasspath - Runtime classpath of source set 'test'.
++--- org.apache.commons:commons-lang3:3.12.0
++--- com.fasterxml.jackson.core:jackson-core:2.14.2
+|    \--- com.fasterxml.jackson:jackson-bom:2.14.2
+|         \--- com.fasterxml.jackson.core:jackson-core:2.14.2 (c)
++--- io.opentelemetry:opentelemetry-jdbc:1.19.0 FAILED
+\--- io.grpc:grpc-core:1.49.2
+     +--- io.grpc:grpc-api:1.49.2
+     |    +--- io.grpc:grpc-context:1.49.2
+     |    +--- com.google.code.findbugs:jsr305:3.0.2
+     |    +--- com.google.errorprone:error_prone_annotations:2.14.0
+     |    \--- com.google.guava:guava:31.1-android
+     |         +--- com.google.guava:failureaccess:1.0.1
+     |         +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
+     |         +--- com.google.code.findbugs:jsr305:3.0.2
+     |         +--- org.checkerframework:checker-qual:3.12.0
+     |         +--- com.google.errorprone:error_prone_annotations:2.11.0 -> 2.14.0
+     |         \--- com.google.j2objc:j2objc-annotations:1.3
+     +--- com.google.code.gson:gson:2.9.0
+     +--- com.google.android:annotations:4.1.1.4
+     +--- org.codehaus.mojo:animal-sniffer-annotations:1.21
+     +--- com.google.errorprone:error_prone_annotations:2.14.0
+     +--- com.google.guava:guava:31.1-android (*)
+     \--- io.perfmark:perfmark-api:0.25.0
+
+testRuntimeOnly - Runtime only dependencies for source set 'test'. (n)
+No dependencies
+
+(c) - dependency constraint
+(*) - dependencies omitted (listed previously)
+
+(n) - Not resolved (configuration is not meant to be resolved)
+
+A web-based, searchable dependency report is available by adding the --scan option.
diff --git a/test/data/gradle-s.out b/test/data/gradle-s.out
new file mode 100644
index 00000000..0eede863
--- /dev/null
+++ b/test/data/gradle-s.out
@@ -0,0 +1,220 @@
+
+------------------------------------------------------------
+Project ':dependency-diff-check-client-starter'
+------------------------------------------------------------
+
+annotationProcessor - Annotation processors and their dependencies for source set 'main'.
+No dependencies
+
+api - API dependencies for source set 'main'. (n)
+\--- project dependency-diff-check-common-core (n)
+
+apiElements - API elements for main. (n)
+No dependencies
+
+archives - Configuration for archive artifacts. (n)
+No dependencies
+
+bootArchives - Configuration for Spring Boot archive artifacts. (n)
+No dependencies
+
+compileClasspath - Compile classpath for source set 'main'.
++--- project :dependency-diff-check-common-core
++--- org.springframework.boot:spring-boot-autoconfigure -> 3.0.1
+|    \--- org.springframework.boot:spring-boot:3.0.1
+|         +--- org.springframework:spring-core:6.0.3
+|         |    \--- org.springframework:spring-jcl:6.0.3
+|         \--- org.springframework:spring-context:6.0.3
+|              +--- org.springframework:spring-aop:6.0.3
+|              |    +--- org.springframework:spring-beans:6.0.3
+|              |    |    \--- org.springframework:spring-core:6.0.3 (*)
+|              |    \--- org.springframework:spring-core:6.0.3 (*)
+|              +--- org.springframework:spring-beans:6.0.3 (*)
+|              +--- org.springframework:spring-core:6.0.3 (*)
+|              \--- org.springframework:spring-expression:6.0.3
+|                   \--- org.springframework:spring-core:6.0.3 (*)
+\--- org.slf4j:slf4j-api:2.0.7
+
+compileOnly - Compile only dependencies for source set 'main'. (n)
+No dependencies
+
+compileOnlyApi - Compile only API dependencies for source set 'main'. (n)
+No dependencies
+
+default - Configuration for default artifacts. (n)
+No dependencies
+
+developmentOnly - Configuration for development-only dependencies such as Spring Boot's DevTools.
+No dependencies
+
+implementation - Implementation only dependencies for source set 'main'. (n)
++--- org.springframework.boot:spring-boot-autoconfigure (n)
+\--- org.slf4j:slf4j-api:2.0.7 (n)
+
+mainSourceElements - List of source directories contained in the Main SourceSet. (n)
+No dependencies
+
+productionRuntimeClasspath
++--- project :dependency-diff-check-common-core
+|    +--- org.apache.commons:commons-lang3:3.12.0
+|    +--- com.fasterxml.jackson.core:jackson-core:2.14.2 -> 2.14.1
+|    |    \--- com.fasterxml.jackson:jackson-bom:2.14.1
+|    |         \--- com.fasterxml.jackson.core:jackson-core:2.14.1 (c)
+|    +--- io.opentelemetry:opentelemetry-jdbc:1.19.0 FAILED
+|    \--- io.grpc:grpc-core:1.49.2
+|         +--- io.grpc:grpc-api:1.49.2
+|         |    +--- io.grpc:grpc-context:1.49.2
+|         |    +--- com.google.code.findbugs:jsr305:3.0.2
+|         |    +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         |    \--- com.google.guava:guava:31.1-android
+|         |         +--- com.google.guava:failureaccess:1.0.1
+|         |         +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
+|         |         +--- com.google.code.findbugs:jsr305:3.0.2
+|         |         +--- org.checkerframework:checker-qual:3.12.0
+|         |         +--- com.google.errorprone:error_prone_annotations:2.11.0 -> 2.14.0
+|         |         \--- com.google.j2objc:j2objc-annotations:1.3
+|         +--- com.google.code.gson:gson:2.9.0 -> 2.9.1
+|         +--- com.google.android:annotations:4.1.1.4
+|         +--- org.codehaus.mojo:animal-sniffer-annotations:1.21
+|         +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         +--- com.google.guava:guava:31.1-android (*)
+|         \--- io.perfmark:perfmark-api:0.25.0
++--- org.springframework.boot:spring-boot-autoconfigure -> 3.0.1
+|    \--- org.springframework.boot:spring-boot:3.0.1
+|         +--- org.springframework:spring-core:6.0.3
+|         |    \--- org.springframework:spring-jcl:6.0.3
+|         \--- org.springframework:spring-context:6.0.3
+|              +--- org.springframework:spring-aop:6.0.3
+|              |    +--- org.springframework:spring-beans:6.0.3
+|              |    |    \--- org.springframework:spring-core:6.0.3 (*)
+|              |    \--- org.springframework:spring-core:6.0.3 (*)
+|              +--- org.springframework:spring-beans:6.0.3 (*)
+|              +--- org.springframework:spring-core:6.0.3 (*)
+|              \--- org.springframework:spring-expression:6.0.3
+|                   \--- org.springframework:spring-core:6.0.3 (*)
+\--- org.slf4j:slf4j-api:2.0.7
+
+runtimeClasspath - Runtime classpath of source set 'main'.
++--- project :dependency-diff-check-common-core
+|    +--- org.apache.commons:commons-lang3:3.12.0
+|    +--- com.fasterxml.jackson.core:jackson-core:2.14.2 -> 2.14.1
+|    |    \--- com.fasterxml.jackson:jackson-bom:2.14.1
+|    |         \--- com.fasterxml.jackson.core:jackson-core:2.14.1 (c)
+|    +--- io.opentelemetry:opentelemetry-jdbc:1.19.0 FAILED
+|    \--- io.grpc:grpc-core:1.49.2
+|         +--- io.grpc:grpc-api:1.49.2
+|         |    +--- io.grpc:grpc-context:1.49.2
+|         |    +--- com.google.code.findbugs:jsr305:3.0.2
+|         |    +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         |    \--- com.google.guava:guava:31.1-android
+|         |         +--- com.google.guava:failureaccess:1.0.1
+|         |         +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
+|         |         +--- com.google.code.findbugs:jsr305:3.0.2
+|         |         +--- org.checkerframework:checker-qual:3.12.0
+|         |         +--- com.google.errorprone:error_prone_annotations:2.11.0 -> 2.14.0
+|         |         \--- com.google.j2objc:j2objc-annotations:1.3
+|         +--- com.google.code.gson:gson:2.9.0 -> 2.9.1
+|         +--- com.google.android:annotations:4.1.1.4
+|         +--- org.codehaus.mojo:animal-sniffer-annotations:1.21
+|         +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         +--- com.google.guava:guava:31.1-android (*)
+|         \--- io.perfmark:perfmark-api:0.25.0
++--- org.springframework.boot:spring-boot-autoconfigure -> 3.0.1
+|    \--- org.springframework.boot:spring-boot:3.0.1
+|         +--- org.springframework:spring-core:6.0.3
+|         |    \--- org.springframework:spring-jcl:6.0.3
+|         \--- org.springframework:spring-context:6.0.3
+|              +--- org.springframework:spring-aop:6.0.3
+|              |    +--- org.springframework:spring-beans:6.0.3
+|              |    |    \--- org.springframework:spring-core:6.0.3 (*)
+|              |    \--- org.springframework:spring-core:6.0.3 (*)
+|              +--- org.springframework:spring-beans:6.0.3 (*)
+|              +--- org.springframework:spring-core:6.0.3 (*)
+|              \--- org.springframework:spring-expression:6.0.3
+|                   \--- org.springframework:spring-core:6.0.3 (*)
+\--- org.slf4j:slf4j-api:2.0.7
+
+runtimeElements - Elements of runtime for main. (n)
+No dependencies
+
+runtimeOnly - Runtime only dependencies for source set 'main'. (n)
+No dependencies
+
+testAnnotationProcessor - Annotation processors and their dependencies for source set 'test'.
+No dependencies
+
+testCompileClasspath - Compile classpath for source set 'test'.
++--- project :dependency-diff-check-common-core
++--- org.springframework.boot:spring-boot-autoconfigure -> 3.0.1
+|    \--- org.springframework.boot:spring-boot:3.0.1
+|         +--- org.springframework:spring-core:6.0.3
+|         |    \--- org.springframework:spring-jcl:6.0.3
+|         \--- org.springframework:spring-context:6.0.3
+|              +--- org.springframework:spring-aop:6.0.3
+|              |    +--- org.springframework:spring-beans:6.0.3
+|              |    |    \--- org.springframework:spring-core:6.0.3 (*)
+|              |    \--- org.springframework:spring-core:6.0.3 (*)
+|              +--- org.springframework:spring-beans:6.0.3 (*)
+|              +--- org.springframework:spring-core:6.0.3 (*)
+|              \--- org.springframework:spring-expression:6.0.3
+|                   \--- org.springframework:spring-core:6.0.3 (*)
+\--- org.slf4j:slf4j-api:2.0.7
+
+testCompileOnly - Compile only dependencies for source set 'test'. (n)
+No dependencies
+
+testImplementation - Implementation only dependencies for source set 'test'. (n)
+No dependencies
+
+testResultsElementsForTest - Directory containing binary results of running tests for the test Test Suite's test target. (n)
+No dependencies
+
+testRuntimeClasspath - Runtime classpath of source set 'test'.
++--- project :dependency-diff-check-common-core
+|    +--- org.apache.commons:commons-lang3:3.12.0
+|    +--- com.fasterxml.jackson.core:jackson-core:2.14.2 -> 2.14.1
+|    |    \--- com.fasterxml.jackson:jackson-bom:2.14.1
+|    |         \--- com.fasterxml.jackson.core:jackson-core:2.14.1 (c)
+|    +--- io.opentelemetry:opentelemetry-jdbc:1.19.0 FAILED
+|    \--- io.grpc:grpc-core:1.49.2
+|         +--- io.grpc:grpc-api:1.49.2
+|         |    +--- io.grpc:grpc-context:1.49.2
+|         |    +--- com.google.code.findbugs:jsr305:3.0.2
+|         |    +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         |    \--- com.google.guava:guava:31.1-android
+|         |         +--- com.google.guava:failureaccess:1.0.1
+|         |         +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
+|         |         +--- com.google.code.findbugs:jsr305:3.0.2
+|         |         +--- org.checkerframework:checker-qual:3.12.0
+|         |         +--- com.google.errorprone:error_prone_annotations:2.11.0 -> 2.14.0
+|         |         \--- com.google.j2objc:j2objc-annotations:1.3
+|         +--- com.google.code.gson:gson:2.9.0 -> 2.9.1
+|         +--- com.google.android:annotations:4.1.1.4
+|         +--- org.codehaus.mojo:animal-sniffer-annotations:1.21
+|         +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         +--- com.google.guava:guava:31.1-android (*)
+|         \--- io.perfmark:perfmark-api:0.25.0
++--- org.springframework.boot:spring-boot-autoconfigure -> 3.0.1
+|    \--- org.springframework.boot:spring-boot:3.0.1
+|         +--- org.springframework:spring-core:6.0.3
+|         |    \--- org.springframework:spring-jcl:6.0.3
+|         \--- org.springframework:spring-context:6.0.3
+|              +--- org.springframework:spring-aop:6.0.3
+|              |    +--- org.springframework:spring-beans:6.0.3
+|              |    |    \--- org.springframework:spring-core:6.0.3 (*)
+|              |    \--- org.springframework:spring-core:6.0.3 (*)
+|              +--- org.springframework:spring-beans:6.0.3 (*)
+|              +--- org.springframework:spring-core:6.0.3 (*)
+|              \--- org.springframework:spring-expression:6.0.3
+|                   \--- org.springframework:spring-core:6.0.3 (*)
+\--- org.slf4j:slf4j-api:2.0.7
+
+testRuntimeOnly - Runtime only dependencies for source set 'test'. (n)
+No dependencies
+
+(c) - dependency constraint
+(*) - dependencies omitted (listed previously)
+
+(n) - Not resolved (configuration is not meant to be resolved)
+
+A web-based, searchable dependency report is available by adding the --scan option.
diff --git a/test/data/gradle-service.out b/test/data/gradle-service.out
new file mode 100644
index 00000000..00213584
--- /dev/null
+++ b/test/data/gradle-service.out
@@ -0,0 +1,199 @@
+
+------------------------------------------------------------
+Project ':dependency-diff-check-service'
+------------------------------------------------------------
+
+annotationProcessor - Annotation processors and their dependencies for source set 'main'.
+No dependencies
+
+apiElements - API elements for main. (n)
+No dependencies
+
+archives - Configuration for archive artifacts. (n)
+No dependencies
+
+compileClasspath - Compile classpath for source set 'main'.
++--- project :dependency-diff-check-common-core
++--- com.graphql-java:graphql-java:20.2
+|    +--- com.graphql-java:java-dataloader:3.2.0
+|    |    \--- org.slf4j:slf4j-api:1.7.30
+|    \--- org.reactivestreams:reactive-streams:1.0.3
+\--- org.flywaydb:flyway-mysql:9.17.0
+     \--- org.flywaydb:flyway-core:9.17.0
+          +--- com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.14.0
+          |    +--- com.fasterxml.jackson.core:jackson-databind:2.14.0
+          |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.14.0
+          |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.0
+          |    |    |         +--- com.fasterxml.jackson.core:jackson-core:2.14.0 (c)
+          |    |    |         +--- com.fasterxml.jackson.core:jackson-databind:2.14.0 (c)
+          |    |    |         +--- com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.14.0 (c)
+          |    |    |         \--- com.fasterxml.jackson.core:jackson-annotations:2.14.0 (c)
+          |    |    +--- com.fasterxml.jackson.core:jackson-core:2.14.0
+          |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.0 (*)
+          |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.0 (*)
+          |    +--- com.fasterxml.jackson.core:jackson-core:2.14.0 (*)
+          |    \--- com.fasterxml.jackson:jackson-bom:2.14.0 (*)
+          +--- org.apache.commons:commons-text:1.10.0
+          |    \--- org.apache.commons:commons-lang3:3.12.0
+          \--- com.google.code.gson:gson:2.10.1
+
+compileOnly - Compile only dependencies for source set 'main'. (n)
+No dependencies
+
+default - Configuration for default artifacts. (n)
+No dependencies
+
+implementation - Implementation only dependencies for source set 'main'. (n)
++--- project dependency-diff-check-common-core (n)
++--- com.graphql-java:graphql-java:20.2 (n)
+\--- org.flywaydb:flyway-mysql:9.17.0 (n)
+
+mainSourceElements - List of source directories contained in the Main SourceSet. (n)
+No dependencies
+
+runtimeClasspath - Runtime classpath of source set 'main'.
++--- project :dependency-diff-check-common-core
+|    +--- org.apache.commons:commons-lang3:3.12.0
+|    +--- com.fasterxml.jackson.core:jackson-core:2.14.2
+|    |    \--- com.fasterxml.jackson:jackson-bom:2.14.2
+|    |         +--- com.fasterxml.jackson.core:jackson-core:2.14.2 (c)
+|    |         +--- com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.14.2 (c)
+|    |         +--- com.fasterxml.jackson.core:jackson-databind:2.14.2 (c)
+|    |         \--- com.fasterxml.jackson.core:jackson-annotations:2.14.2 (c)
+|    +--- io.opentelemetry:opentelemetry-jdbc:1.19.0 FAILED
+|    \--- io.grpc:grpc-core:1.49.2
+|         +--- io.grpc:grpc-api:1.49.2
+|         |    +--- io.grpc:grpc-context:1.49.2
+|         |    +--- com.google.code.findbugs:jsr305:3.0.2
+|         |    +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         |    \--- com.google.guava:guava:31.1-android
+|         |         +--- com.google.guava:failureaccess:1.0.1
+|         |         +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
+|         |         +--- com.google.code.findbugs:jsr305:3.0.2
+|         |         +--- org.checkerframework:checker-qual:3.12.0
+|         |         +--- com.google.errorprone:error_prone_annotations:2.11.0 -> 2.14.0
+|         |         \--- com.google.j2objc:j2objc-annotations:1.3
+|         +--- com.google.code.gson:gson:2.9.0 -> 2.10.1
+|         +--- com.google.android:annotations:4.1.1.4
+|         +--- org.codehaus.mojo:animal-sniffer-annotations:1.21
+|         +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         +--- com.google.guava:guava:31.1-android (*)
+|         \--- io.perfmark:perfmark-api:0.25.0
++--- com.graphql-java:graphql-java:20.2
+|    +--- com.graphql-java:java-dataloader:3.2.0
+|    |    \--- org.slf4j:slf4j-api:1.7.30 -> 1.7.35
+|    +--- org.reactivestreams:reactive-streams:1.0.3
+|    \--- org.slf4j:slf4j-api:1.7.35
+\--- org.flywaydb:flyway-mysql:9.17.0
+     \--- org.flywaydb:flyway-core:9.17.0
+          +--- com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.14.0 -> 2.14.2
+          |    +--- com.fasterxml.jackson.core:jackson-databind:2.14.2
+          |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.14.2
+          |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.2 (*)
+          |    |    +--- com.fasterxml.jackson.core:jackson-core:2.14.2 (*)
+          |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.2 (*)
+          |    +--- com.fasterxml.jackson.core:jackson-core:2.14.2 (*)
+          |    \--- com.fasterxml.jackson:jackson-bom:2.14.2 (*)
+          +--- org.apache.commons:commons-text:1.10.0
+          |    \--- org.apache.commons:commons-lang3:3.12.0
+          \--- com.google.code.gson:gson:2.10.1
+
+runtimeElements - Elements of runtime for main. (n)
+No dependencies
+
+runtimeOnly - Runtime only dependencies for source set 'main'. (n)
+No dependencies
+
+testAnnotationProcessor - Annotation processors and their dependencies for source set 'test'.
+No dependencies
+
+testCompileClasspath - Compile classpath for source set 'test'.
++--- project :dependency-diff-check-common-core
++--- com.graphql-java:graphql-java:20.2
+|    +--- com.graphql-java:java-dataloader:3.2.0
+|    |    \--- org.slf4j:slf4j-api:1.7.30
+|    \--- org.reactivestreams:reactive-streams:1.0.3
+\--- org.flywaydb:flyway-mysql:9.17.0
+     \--- org.flywaydb:flyway-core:9.17.0
+          +--- com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.14.0
+          |    +--- com.fasterxml.jackson.core:jackson-databind:2.14.0
+          |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.14.0
+          |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.0
+          |    |    |         +--- com.fasterxml.jackson.core:jackson-core:2.14.0 (c)
+          |    |    |         +--- com.fasterxml.jackson.core:jackson-databind:2.14.0 (c)
+          |    |    |         +--- com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.14.0 (c)
+          |    |    |         \--- com.fasterxml.jackson.core:jackson-annotations:2.14.0 (c)
+          |    |    +--- com.fasterxml.jackson.core:jackson-core:2.14.0
+          |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.0 (*)
+          |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.0 (*)
+          |    +--- com.fasterxml.jackson.core:jackson-core:2.14.0 (*)
+          |    \--- com.fasterxml.jackson:jackson-bom:2.14.0 (*)
+          +--- org.apache.commons:commons-text:1.10.0
+          |    \--- org.apache.commons:commons-lang3:3.12.0
+          \--- com.google.code.gson:gson:2.10.1
+
+testCompileOnly - Compile only dependencies for source set 'test'. (n)
+No dependencies
+
+testImplementation - Implementation only dependencies for source set 'test'. (n)
+No dependencies
+
+testResultsElementsForTest - Directory containing binary results of running tests for the test Test Suite's test target. (n)
+No dependencies
+
+testRuntimeClasspath - Runtime classpath of source set 'test'.
++--- project :dependency-diff-check-common-core
+|    +--- org.apache.commons:commons-lang3:3.12.0
+|    +--- com.fasterxml.jackson.core:jackson-core:2.14.2
+|    |    \--- com.fasterxml.jackson:jackson-bom:2.14.2
+|    |         +--- com.fasterxml.jackson.core:jackson-core:2.14.2 (c)
+|    |         +--- com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.14.2 (c)
+|    |         +--- com.fasterxml.jackson.core:jackson-databind:2.14.2 (c)
+|    |         \--- com.fasterxml.jackson.core:jackson-annotations:2.14.2 (c)
+|    +--- io.opentelemetry:opentelemetry-jdbc:1.19.0 FAILED
+|    \--- io.grpc:grpc-core:1.49.2
+|         +--- io.grpc:grpc-api:1.49.2
+|         |    +--- io.grpc:grpc-context:1.49.2
+|         |    +--- com.google.code.findbugs:jsr305:3.0.2
+|         |    +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         |    \--- com.google.guava:guava:31.1-android
+|         |         +--- com.google.guava:failureaccess:1.0.1
+|         |         +--- com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
+|         |         +--- com.google.code.findbugs:jsr305:3.0.2
+|         |         +--- org.checkerframework:checker-qual:3.12.0
+|         |         +--- com.google.errorprone:error_prone_annotations:2.11.0 -> 2.14.0
+|         |         \--- com.google.j2objc:j2objc-annotations:1.3
+|         +--- com.google.code.gson:gson:2.9.0 -> 2.10.1
+|         +--- com.google.android:annotations:4.1.1.4
+|         +--- org.codehaus.mojo:animal-sniffer-annotations:1.21
+|         +--- com.google.errorprone:error_prone_annotations:2.14.0
+|         +--- com.google.guava:guava:31.1-android (*)
+|         \--- io.perfmark:perfmark-api:0.25.0
++--- com.graphql-java:graphql-java:20.2
+|    +--- com.graphql-java:java-dataloader:3.2.0
+|    |    \--- org.slf4j:slf4j-api:1.7.30 -> 1.7.35
+|    +--- org.reactivestreams:reactive-streams:1.0.3
+|    \--- org.slf4j:slf4j-api:1.7.35
+\--- org.flywaydb:flyway-mysql:9.17.0
+     \--- org.flywaydb:flyway-core:9.17.0
+          +--- com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.14.0 -> 2.14.2
+          |    +--- com.fasterxml.jackson.core:jackson-databind:2.14.2
+          |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.14.2
+          |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.2 (*)
+          |    |    +--- com.fasterxml.jackson.core:jackson-core:2.14.2 (*)
+          |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.2 (*)
+          |    +--- com.fasterxml.jackson.core:jackson-core:2.14.2 (*)
+          |    \--- com.fasterxml.jackson:jackson-bom:2.14.2 (*)
+          +--- org.apache.commons:commons-text:1.10.0
+          |    \--- org.apache.commons:commons-lang3:3.12.0
+          \--- com.google.code.gson:gson:2.10.1
+
+testRuntimeOnly - Runtime only dependencies for source set 'test'. (n)
+No dependencies
+
+(c) - dependency constraint
+(*) - dependencies omitted (listed previously)
+
+(n) - Not resolved (configuration is not meant to be resolved)
+
+A web-based, searchable dependency report is available by adding the --scan option.
diff --git a/utils.test.js b/utils.test.js
index 1cb4fe4b..d8a58061 100644
--- a/utils.test.js
+++ b/utils.test.js
@@ -205,12 +205,17 @@ test("parse gradle dependencies", () => {
     fs.readFileSync("./test/data/gradle-rich5.dep", { encoding: "utf-8" })
   );
   expect(parsedList.pkgList.length).toEqual(68);
-  expect(parsedList.dependenciesList.length).toEqual(69);
+  expect(parsedList.dependenciesList.length).toEqual(68);
   parsedList = utils.parseGradleDep(
     fs.readFileSync("./test/data/gradle-out-249.dep", { encoding: "utf-8" })
   );
   expect(parsedList.pkgList.length).toEqual(21);
   expect(parsedList.dependenciesList.length).toEqual(21);
+  parsedList = utils.parseGradleDep(
+    fs.readFileSync("./test/data/gradle-service.out", { encoding: "utf-8" })
+  );
+  expect(parsedList.pkgList.length).toEqual(35);
+  expect(parsedList.dependenciesList.length).toEqual(35);
 });
 
 test("parse gradle projects", () => {