Skip to content

fix(maven): resolve version ranges in component analysis#491

Open
Strum355 wants to merge 1 commit into
mainfrom
fix/maven-version-range-resolution
Open

fix(maven): resolve version ranges in component analysis#491
Strum355 wants to merge 1 commit into
mainfrom
fix/maven-version-range-resolution

Conversation

@Strum355
Copy link
Copy Markdown
Member

@Strum355 Strum355 commented May 21, 2026

Summary

Maven version ranges (e.g. [1.2.17,1.3.0), (1.0,2.0]) in pom.xml dependency versions are preserved verbatim by mvn help:effective-pom. Component analysis uses the effective POM to extract dependency versions, so range expressions end up as the version in the PackageURL (e.g. pkg:maven/log4j/log4j@[1.2.17,1.3.0)). The backend cannot look up vulnerabilities for a range-valued purl, so these dependencies are silently dropped — no editor diagnostics appear for them.

Stack analysis is unaffected because it uses mvn dependency:tree, which resolves ranges to concrete versions before output.

How it works

After extracting dependencies from the effective POM, resolveVersionRanges checks whether any dependency has a version range (starts with [ or (). If none do, it returns immediately — no performance impact for normal projects.

When ranges are detected, it runs mvn dependency:tree -DoutputType=text -Dscope=compile and parses the direct dependencies (depth 1) from the text output using the existing getDepth() and parseDep() methods. Each resolved groupId:artifactId → version mapping is collected, and range-valued versions in the dependency list are replaced with the concrete resolved versions before SBOM generation.

If the dependency tree invocation fails for any reason, a warning is logged and the method falls back to the original unresolved versions, so the overall flow is never broken.

Changes

  • JavaMavenProvider.java — Add isVersionRange and resolveVersionRanges methods. Call resolveVersionRanges in generateSbomFromEffectivePom after extracting deps from the effective POM.
  • Java_Maven_Provider_Test.java — Add deps_with_version_range test folder. Update test_the_provideComponent and test_the_provideComponent_With_Path mocks to dispatch both -Doutput= (effective POM) and -DoutputFile (dep tree) arguments, with -Doutput= changed from -Doutput to avoid matching -DoutputFile and -DoutputType.
  • src/test/resources/tst_manifests/maven/deps_with_version_range/ — New fixture with a range-valued dependency (log4j [1.2.17,1.3.0)), verifying both stack and component analysis resolve the range to 1.2.17.

Test plan

Ref: fabric8-analytics/fabric8-analytics-vscode-extension#812

🤖 Generated with Claude Code

Summary by Sourcery

Resolve Maven dependency version ranges when generating SBOMs so component analysis uses concrete versions instead of range expressions.

New Features:

  • Add Maven version range detection and resolution when building SBOMs from the effective POM using the dependency tree output.

Bug Fixes:

  • Ensure Maven dependencies declared with version ranges are included in component analysis by replacing range expressions with resolved versions.

Enhancements:

  • Extend Java Maven provider tests with a new fixture covering version range dependencies and adjust process mocking to handle both effective POM and dependency tree outputs.

Tests:

  • Add Maven test project and expected artifacts to verify version range resolution for both stack and component SBOM generation.

Maven version ranges (e.g. `[1.2.17,1.3.0)`, `(1.0,2.0]`) in pom.xml
dependency versions are preserved verbatim by `mvn help:effective-pom`.
Component analysis uses the effective POM to extract dependency versions,
so range expressions end up as the version in the PackageURL. The backend
cannot look up vulnerabilities for a range-valued purl, so these
dependencies were silently dropped from analysis results.

Stack analysis was unaffected because it uses `mvn dependency:tree`,
which resolves ranges to concrete versions before output.

Add `resolveVersionRanges` to detect range-valued versions in the
effective POM output and resolve them by running
`mvn dependency:tree -DoutputType=text -Dscope=compile`, parsing the
direct dependencies (depth 1) to extract the concrete versions Maven
selects. The resolution is guarded: it only runs when at least one
dependency has a version range, and falls back to the original range
values if the tree invocation fails.

Ref: fabric8-analytics/fabric8-analytics-vscode-extension#812

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 21, 2026

Reviewer's Guide

Adds Maven version range resolution for component analysis by invoking the dependency:tree plugin, and extends tests/fixtures to cover dependencies with version ranges and the new process invocation pattern.

Sequence diagram for resolving Maven version ranges in component analysis

sequenceDiagram
    participant JavaMavenProvider
    participant Maven as mvn_dependency_tree
    participant Operations
    participant DependencyAggregator

    JavaMavenProvider->>JavaMavenProvider: getDependencies(tmpEffPom)
    JavaMavenProvider->>JavaMavenProvider: resolveVersionRanges(deps)
    alt [any dependency has version range]
        JavaMavenProvider->>Operations: runProcess(manifestPath.getParent, cmd, getMvnExecEnvs)
        Operations->>Maven: maven-dependency-plugin:tree
        Maven-->>Operations: depTree.txt
        JavaMavenProvider->>JavaMavenProvider: getDepth(line)
        JavaMavenProvider->>JavaMavenProvider: parseDep(line)
        JavaMavenProvider->>DependencyAggregator: dep.version = resolvedVersions[key]
    else [no version ranges or failure]
        JavaMavenProvider-->>JavaMavenProvider: return original deps
    end
    JavaMavenProvider->>SbomFactory: addRoot(getRoot(tmpEffPom), readLicenseFromManifest)
    JavaMavenProvider->>SbomFactory: addDependency(dep)
Loading

File-Level Changes

Change Details Files
Resolve Maven version ranges in component analysis using dependency:tree output and integrate it into SBOM generation.
  • Introduce isVersionRange helper to detect Maven version range syntax.
  • Add resolveVersionRanges, which short-circuits when no ranges are present, runs maven-dependency-plugin:tree with text output, and parses direct dependencies using existing getDepth and parseDep helpers.
  • Build a groupId:artifactId to resolved-version map from the dependency tree and rewrite range-valued DependencyAggregator.version fields when resolutions are found.
  • Hook resolveVersionRanges into generateSbomFromEffectivePom so that dependencies from the effective POM are normalized before SBOM creation.
  • Log a warning and fall back to original dependency versions if dependency:tree invocation or parsing fails, and ensure the temporary output file is always cleaned up.
src/main/java/io/github/guacsec/trustifyda/providers/JavaMavenProvider.java
Update Java Maven provider tests to exercise version range resolution and support dual invocation of effective POM and dependency tree commands.
  • Extend the parameterized test folder list with a deps_with_version_range scenario.
  • Load a depTree.txt fixture alongside effectivePom.xml in component-related tests.
  • Adjust Operations.runProcess mocking to route -Doutput= calls to the effective POM fixture and -DoutputFile calls to the dependency tree fixture, avoiding collisions with -DoutputType.
  • Ensure existing path-based component tests also use the new dual-output mocking setup.
src/test/java/io/github/guacsec/trustifyda/providers/Java_Maven_Provider_Test.java
Add Maven test fixtures for a project with a dependency version range and corresponding expected SBOMs.
  • Add a pom.xml defining a log4j dependency with a [1.2.17,1.3.0) version range and a snappy-java dependency with a fixed version.
  • Add an effectivePom.xml representing the generated effective POM for the new test project, preserving the version range in the dependency section.
  • Introduce a depTree.txt fixture capturing the maven-dependency-plugin:tree output used to resolve concrete versions.
  • Add expected_component_sbom.json and expected_stack_sbom.json fixtures to validate that both component and stack analyses resolve the log4j range to a concrete version.
src/test/resources/tst_manifests/maven/deps_with_version_range/pom.xml
src/test/resources/tst_manifests/maven/deps_with_version_range/effectivePom.xml
src/test/resources/tst_manifests/maven/deps_with_version_range/depTree.txt
src/test/resources/tst_manifests/maven/deps_with_version_range/expected_component_sbom.json
src/test/resources/tst_manifests/maven/deps_with_version_range/expected_stack_sbom.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@Strum355 Strum355 requested review from a-oren and ruromero May 21, 2026 12:58
Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In resolveVersionRanges, consider logging the full exception (e.g., using log.log(Level.WARNING, ...) with the throwable) instead of only e.getMessage() so failures in the fallback path are easier to diagnose.
  • The new effectivePom.xml fixture under deps_with_version_range embeds absolute filesystem paths, which can cause noisy diffs and make the test data environment-specific; consider trimming these elements or replacing them with minimal, path-agnostic content needed for the test.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `resolveVersionRanges`, consider logging the full exception (e.g., using `log.log(Level.WARNING, ...)` with the throwable) instead of only `e.getMessage()` so failures in the fallback path are easier to diagnose.
- The new `effectivePom.xml` fixture under `deps_with_version_range` embeds absolute filesystem paths, which can cause noisy diffs and make the test data environment-specific; consider trimming these elements or replacing them with minimal, path-agnostic content needed for the test.

## Individual Comments

### Comment 1
<location path="src/main/java/io/github/guacsec/trustifyda/providers/JavaMavenProvider.java" line_range="259-268" />
<code_context>
+  private List<DependencyAggregator> resolveVersionRanges(List<DependencyAggregator> deps)
</code_context>
<issue_to_address>
**issue (bug_risk):** Deleting the temp file can throw and violate the "return original list" fallback guarantee

Per the Javadoc, failures in resolving version ranges should result in the original list being returned unchanged. However, `Files.deleteIfExists(tmpFile)` in the `finally` block can throw an `IOException` that bypasses the existing `catch (Exception e)` and leaks out of the method, violating that contract. Please isolate the delete in its own try/catch (logging or ignoring failures) so cleanup errors don’t alter the method’s behavior, or adjust the signature/contract if you intend to let such IOExceptions propagate.
</issue_to_address>

### Comment 2
<location path="src/test/java/io/github/guacsec/trustifyda/providers/Java_Maven_Provider_Test.java" line_range="155-159" />
<code_context>
+      depTree = new String(is.readAllBytes());
+    }
+
     try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
       mockedOperations
           .when(() -> Operations.runProcess(any(), any(), any()))
           .thenAnswer(
-              invocationOnMock ->
-                  getOutputFileAndOverwriteItWithMock(effectivePom, invocationOnMock, "-Doutput"));
+              invocationOnMock -> {
+                String result =
+                    getOutputFileAndOverwriteItWithMock(
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test ensuring we fall back gracefully when the dependency:tree invocation fails

The current tests only cover the successful path where `Operations.runProcess` writes both the effective POM and dep tree outputs. Please add a test (or parameterized case) where the mock throws for the `-DoutputFile` invocation to verify that:

- `provideComponent` / `provideComponent_With_Path` swallow the exception, and
- the SBOM is still produced (with unresolved versions, as now).

This will lock in the intended failure behavior and guard against regressions in error handling.

Suggested implementation:

```java
      mockedOperations
          .when(() -> Operations.runProcess(any(), any(), any()))
          .thenAnswer(
              invocationOnMock -> {
                String result =
                    getOutputFileAndOverwriteItWithMock(
                        effectivePom, invocationOnMock, "-Doutput=");
                if (result == null) {
                  result =
                      getOutputFileAndOverwriteItWithMock(
                          depTree, invocationOnMock, "-DoutputFile");
                }
                return result;
              });
      // Mock Operations.getCustomPathOrElse to return "mvn"
      mockedOperations.when(() -> Operations.getCustomPathOrElse(anyString())).thenReturn("mvn");

```

To implement the requested test coverage for the failure path of the `dependency:tree` invocation, add the following tests to `Java_Maven_Provider_Test.java` inside the test class (alongside the existing tests for `provideComponent` / `provideComponent_With_Path`). You may need to adjust variable names (`testFolder`, `provider`, etc.) to match your existing test setup.

1. **Add a test for `provideComponent` that simulates a failure of the `-DoutputFile` / dep tree invocation:**

```java
@Test
void testProvideComponent_DependencyTreeFailureFallsBackGracefully() throws Exception {
  String testFolder = "basic";

  String effectivePom;
  try (var is =
      getResourceAsStreamDecision(
          getClass(), String.format("tst_manifests/maven/%s/effectivePom.xml", testFolder))) {
    effectivePom = new String(is.readAllBytes(), StandardCharsets.UTF_8);
  }

  try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
    mockedOperations
        .when(() -> Operations.runProcess(any(), any(), any()))
        .thenAnswer(
            invocationOnMock -> {
              // First, handle the effective POM generation as usual
              String result =
                  getOutputFileAndOverwriteItWithMock(
                      effectivePom, invocationOnMock, "-Doutput=");
              if (result == null) {
                // Simulate failure of the dependency:tree invocation (-DoutputFile)
                throw new IOException("Simulated dependency:tree failure");
              }
              return result;
            });

    mockedOperations.when(() -> Operations.getCustomPathOrElse(anyString())).thenReturn("mvn");

    Java_Maven_Provider provider = new Java_Maven_Provider();
    Optional<Component> componentOpt = provider.provideComponent(testFolder);

    // Verify that the provider swallowed the failure and still produced a component / SBOM
    assertThat(componentOpt).isPresent();
    Component component = componentOpt.get();
    assertThat(component).isNotNull();

    // If your existing tests assert on SBOM contents, add similar assertions here.
    // For example, if unresolved versions are expected when dep tree is missing:
    // assertThat(component.getVersion()).isNull();
    // or check for whatever "unresolved" representation you're currently using.
  }
}
```

2. **Add a similar test for `provideComponent_With_Path` if that method exists and is covered by the existing success-path tests:**

```java
@Test
void testProvideComponentWithPath_DependencyTreeFailureFallsBackGracefully() throws Exception {
  String testFolder = "basic";

  String effectivePom;
  try (var is =
      getResourceAsStreamDecision(
          getClass(), String.format("tst_manifests/maven/%s/effectivePom.xml", testFolder))) {
    effectivePom = new String(is.readAllBytes(), StandardCharsets.UTF_8);
  }

  Path projectPath =
      Paths.get("src", "test", "resources", "tst_manifests", "maven", testFolder).toAbsolutePath();

  try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
    mockedOperations
        .when(() -> Operations.runProcess(any(), any(), any()))
        .thenAnswer(
            invocationOnMock -> {
              String result =
                  getOutputFileAndOverwriteItWithMock(
                      effectivePom, invocationOnMock, "-Doutput=");
              if (result == null) {
                // Simulate failure of the dependency:tree invocation (-DoutputFile)
                throw new IOException("Simulated dependency:tree failure");
              }
              return result;
            });

    mockedOperations.when(() -> Operations.getCustomPathOrElse(anyString())).thenReturn("mvn");

    Java_Maven_Provider provider = new Java_Maven_Provider();
    Optional<Component> componentOpt = provider.provideComponent_With_Path(projectPath);

    // Verify that the provider swallowed the failure and still produced a component / SBOM
    assertThat(componentOpt).isPresent();
    Component component = componentOpt.get();
    assertThat(component).isNotNull();

    // As above, assert on unresolved versions / missing dep-tree information as appropriate.
  }
}
```

3. **Notes / integration details:**

- Ensure you import any additional types used above if not already present:
  ```java
  import java.io.IOException;
  import java.nio.charset.StandardCharsets;
  import java.nio.file.Path;
  import java.nio.file.Paths;
  import java.util.Optional;
  ```
- The helper `getOutputFileAndOverwriteItWithMock(...)` and `getResourceAsStreamDecision(...)` are reused exactly as in your existing tests.
- Update the assertions at the end of each test to match however your SBOM represents unresolved dependency versions today (e.g., `null` version, placeholder string, absent dependencies, etc.). The key invariant is that:
  - No exception propagates from `provideComponent` / `provideComponent_With_Path`, and
  - A non-null SBOM / component is still returned despite the simulated `dependency:tree` failure.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +259 to +268
private List<DependencyAggregator> resolveVersionRanges(List<DependencyAggregator> deps)
throws IOException {
// Short-circuit: if no dep has a version range, return unchanged
boolean hasRanges = deps.stream().anyMatch(d -> isVersionRange(d.version));
if (!hasRanges) {
return deps;
}

Path tmpFile = Files.createTempFile("TRUSTIFY_DA_range_tree_", ".txt");
try {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Deleting the temp file can throw and violate the "return original list" fallback guarantee

Per the Javadoc, failures in resolving version ranges should result in the original list being returned unchanged. However, Files.deleteIfExists(tmpFile) in the finally block can throw an IOException that bypasses the existing catch (Exception e) and leaks out of the method, violating that contract. Please isolate the delete in its own try/catch (logging or ignoring failures) so cleanup errors don’t alter the method’s behavior, or adjust the signature/contract if you intend to let such IOExceptions propagate.

Comment on lines 155 to +159
try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
mockedOperations
.when(() -> Operations.runProcess(any(), any(), any()))
.thenAnswer(
invocationOnMock ->
getOutputFileAndOverwriteItWithMock(effectivePom, invocationOnMock, "-Doutput"));
invocationOnMock -> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add a test ensuring we fall back gracefully when the dependency:tree invocation fails

The current tests only cover the successful path where Operations.runProcess writes both the effective POM and dep tree outputs. Please add a test (or parameterized case) where the mock throws for the -DoutputFile invocation to verify that:

  • provideComponent / provideComponent_With_Path swallow the exception, and
  • the SBOM is still produced (with unresolved versions, as now).

This will lock in the intended failure behavior and guard against regressions in error handling.

Suggested implementation:

      mockedOperations
          .when(() -> Operations.runProcess(any(), any(), any()))
          .thenAnswer(
              invocationOnMock -> {
                String result =
                    getOutputFileAndOverwriteItWithMock(
                        effectivePom, invocationOnMock, "-Doutput=");
                if (result == null) {
                  result =
                      getOutputFileAndOverwriteItWithMock(
                          depTree, invocationOnMock, "-DoutputFile");
                }
                return result;
              });
      // Mock Operations.getCustomPathOrElse to return "mvn"
      mockedOperations.when(() -> Operations.getCustomPathOrElse(anyString())).thenReturn("mvn");

To implement the requested test coverage for the failure path of the dependency:tree invocation, add the following tests to Java_Maven_Provider_Test.java inside the test class (alongside the existing tests for provideComponent / provideComponent_With_Path). You may need to adjust variable names (testFolder, provider, etc.) to match your existing test setup.

  1. Add a test for provideComponent that simulates a failure of the -DoutputFile / dep tree invocation:
@Test
void testProvideComponent_DependencyTreeFailureFallsBackGracefully() throws Exception {
  String testFolder = "basic";

  String effectivePom;
  try (var is =
      getResourceAsStreamDecision(
          getClass(), String.format("tst_manifests/maven/%s/effectivePom.xml", testFolder))) {
    effectivePom = new String(is.readAllBytes(), StandardCharsets.UTF_8);
  }

  try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
    mockedOperations
        .when(() -> Operations.runProcess(any(), any(), any()))
        .thenAnswer(
            invocationOnMock -> {
              // First, handle the effective POM generation as usual
              String result =
                  getOutputFileAndOverwriteItWithMock(
                      effectivePom, invocationOnMock, "-Doutput=");
              if (result == null) {
                // Simulate failure of the dependency:tree invocation (-DoutputFile)
                throw new IOException("Simulated dependency:tree failure");
              }
              return result;
            });

    mockedOperations.when(() -> Operations.getCustomPathOrElse(anyString())).thenReturn("mvn");

    Java_Maven_Provider provider = new Java_Maven_Provider();
    Optional<Component> componentOpt = provider.provideComponent(testFolder);

    // Verify that the provider swallowed the failure and still produced a component / SBOM
    assertThat(componentOpt).isPresent();
    Component component = componentOpt.get();
    assertThat(component).isNotNull();

    // If your existing tests assert on SBOM contents, add similar assertions here.
    // For example, if unresolved versions are expected when dep tree is missing:
    // assertThat(component.getVersion()).isNull();
    // or check for whatever "unresolved" representation you're currently using.
  }
}
  1. Add a similar test for provideComponent_With_Path if that method exists and is covered by the existing success-path tests:
@Test
void testProvideComponentWithPath_DependencyTreeFailureFallsBackGracefully() throws Exception {
  String testFolder = "basic";

  String effectivePom;
  try (var is =
      getResourceAsStreamDecision(
          getClass(), String.format("tst_manifests/maven/%s/effectivePom.xml", testFolder))) {
    effectivePom = new String(is.readAllBytes(), StandardCharsets.UTF_8);
  }

  Path projectPath =
      Paths.get("src", "test", "resources", "tst_manifests", "maven", testFolder).toAbsolutePath();

  try (MockedStatic<Operations> mockedOperations = mockStatic(Operations.class)) {
    mockedOperations
        .when(() -> Operations.runProcess(any(), any(), any()))
        .thenAnswer(
            invocationOnMock -> {
              String result =
                  getOutputFileAndOverwriteItWithMock(
                      effectivePom, invocationOnMock, "-Doutput=");
              if (result == null) {
                // Simulate failure of the dependency:tree invocation (-DoutputFile)
                throw new IOException("Simulated dependency:tree failure");
              }
              return result;
            });

    mockedOperations.when(() -> Operations.getCustomPathOrElse(anyString())).thenReturn("mvn");

    Java_Maven_Provider provider = new Java_Maven_Provider();
    Optional<Component> componentOpt = provider.provideComponent_With_Path(projectPath);

    // Verify that the provider swallowed the failure and still produced a component / SBOM
    assertThat(componentOpt).isPresent();
    Component component = componentOpt.get();
    assertThat(component).isNotNull();

    // As above, assert on unresolved versions / missing dep-tree information as appropriate.
  }
}
  1. Notes / integration details:
  • Ensure you import any additional types used above if not already present:
    import java.io.IOException;
    import java.nio.charset.StandardCharsets;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.Optional;
  • The helper getOutputFileAndOverwriteItWithMock(...) and getResourceAsStreamDecision(...) are reused exactly as in your existing tests.
  • Update the assertions at the end of each test to match however your SBOM represents unresolved dependency versions today (e.g., null version, placeholder string, absent dependencies, etc.). The key invariant is that:
    • No exception propagates from provideComponent / provideComponent_With_Path, and
    • A non-null SBOM / component is still returned despite the simulated dependency:tree failure.

@github-actions
Copy link
Copy Markdown
Contributor

Test Results

525 tests   525 ✅  1m 54s ⏱️
 35 suites    0 💤
 35 files      0 ❌

Results for commit 45295f3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant