fix: resolve version-range bom-ref crash when scanning multi-project solutions#1071
Merged
fix: resolve version-range bom-ref crash when scanning multi-project solutions#1071
Conversation
1070dd0 to
d08d56e
Compare
Adds a failing E2E test that reproduces the 'Unable to locate valid bom ref for <pkg> [x.y.z, x.y.z]' crash. The scenario is a solution with two projects where one directly pins TestPkg.Shared 2.0.0 and the other depends on TestPkg.Consumer 1.0.0 whose nuspec declares TestPkg.Shared [1.0.0, 1.0.0]. That exact-range notation in project.assets.json defeats the bomRefLookup in Runner.cs and the name-only fallback fails because two versions are present. Signed-off-by: Michael Tsfoni <80639729+mtsfoni@users.noreply.github.com>
…solutions When a package's nuspec declares an exact-range dependency (e.g. [1.0.0]) and the project that consumes it has resolved a higher version of the same package directly, NuGet stores the range string verbatim in project.assets.json. ResolveDependencyVersionRanges cannot resolve it within that project's assets (2.0.0 does not satisfy [1.0.0]), leaving the range unresolved. In a multi-project solution where another project resolves 1.0.0, the merged BOM contains both versions. The name-only fallback in Runner.cs then finds two candidates and crashes with 'Unable to locate valid bom ref for X [1.0.0, 1.0.0]'. Fix: when the name-only fallback finds multiple candidates and dep.Value is a parseable VersionRange, use the range to select the single satisfying candidate before falling back to the error path. Adds a two-project E2E regression test that reproduces the exact topology from the issue report and asserts both the tool succeeds and the dependency edge points to the correct version. Signed-off-by: Michael Tsfoni <80639729+mtsfoni@users.noreply.github.com>
Signed-off-by: Michael Tsfoni <80639729+mtsfoni@users.noreply.github.com>
0c98ab7 to
29cadca
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When scanning a solution with multiple projects, the tool crashes with exit code 7:
Root cause
The crash requires this specific topology:
Pkg.Shared 2.0.0+Pkg.Consumer 1.0.0Pkg.Shared 1.0.0Pkg.Consumer's nuspec declares its dep onPkg.Sharedwith exact-range notation:[1.0.0]NuGet stores the exact-range constraint verbatim from the nuspec into
project.assets.json.ResolveDependencyVersionRangesinProjectAssetsFileService.cstries to resolve it by scanning the current project's runtime packages — but in ProjectA's assets, only2.0.0is present, and2.0.0does not satisfy[1.0.0]. The range string is left unresolved.After merging both projects' packages into the BOM, both
Shared 1.0.0(from ProjectB) and2.0.0(from ProjectA) are present. The name-only fallback inRunner.csfinds two candidates for the unresolved[1.0.0]range → crash.Fix
When the name-only fallback finds multiple candidates and
dep.Valueis a parseableVersionRange, use the range itself to select the single satisfying candidate before reaching the error path. This is a minimal, targeted change toRunner.cswith no changes to the existing resolution logic inProjectAssetsFileService.cs.[1.0.0].Satisfies(1.0.0)→ true,[1.0.0].Satisfies(2.0.0)→ false → exactly one match → correct bom-ref forShared 1.0.0.Result
Shared 1.0.0and2.0.0appear as distinct components in the BOM (correct — scanning a solution is a union of all projects)Pkg.Consumer's dependency edge points toShared@1.0.0(what its nuspec declares)CDXTestsolution withMicrosoft.CodeAnalysis.Workspaces.Commonat5.0.0and5.3.0)Testing
Adds an E2E regression test (
Issue903Tests) with a two-project solution using fake packages served from a BaGetter Testcontainer. The test:1.0.0) version, not2.0.0Closes #903