Skip to content

update nuget packages#539

Merged
sensslen merged 8 commits into
mainfrom
simon/update-nuget-packages
May 17, 2026
Merged

update nuget packages#539
sensslen merged 8 commits into
mainfrom
simon/update-nuget-packages

Conversation

@sensslen
Copy link
Copy Markdown
Owner

@sensslen sensslen commented May 17, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Improved null-safety and version-comparison handling to reduce errors when processing package metadata.
    • More robust validation to prevent unexpected failures during license lookup and downloads.
  • Chores

    • Upgraded multiple project and test dependencies to newer stable versions for improved compatibility and maintenance.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

Warning

Rate limit exceeded

@sensslen has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 35 minutes and 14 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 56c2dcf5-a06e-4516-abc2-4bcc9cac3425

📥 Commits

Reviewing files that changed from the base of the PR and between 7b0dea1 and 88c18ae.

📒 Files selected for processing (4)
  • src/NuGetLicense/LicenseValidationOrchestrator.cs
  • src/NuGetUtility/Wrapper/HttpClientWrapper/FileDownloader.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs
  • tests/NuGetUtility.Test/ProjectFiltering/ProjectFiltererTest.cs
📝 Walkthrough

Walkthrough

Project-wide dependency bumps, C# primary-constructor refactors across many types, SPDX/license helper adjustments and minor null/version-safety checks, plus test wiring and pragma/string-literal cleanups.

Changes

Dependency Version Updates

Layer / File(s) Summary
Project dependency bumps
src/NuGetLicense/NuGetLicense.csproj, src/NuGetUtility/NuGetUtility.csproj
Bumped System.IO.Hashing and System.Collections.Immutable (10.0.7 → 10.0.8) and upgraded NuGet.ProjectModel / NuGet.Frameworks (7.3.1 → 7.6.0) in shared ItemGroups.
Test and target deps
tests/*/*.csproj, tests/targets/*/*.csproj
Updated TUnit to 1.44.39 across tests; TinyCsvParser to 3.0.11; Microsoft.Extensions.Logging.Abstractions to 10.0.8; Selenium.WebDriver to 4.44.0 in specified test/runtime targets.

Primary-constructor / refactor and behavior changes

Layer / File(s) Summary
Primary-constructor refactors
src/** (many files, e.g., CommandLineOptionsParser.cs, LicenseValidator.cs, PackageInformationReader.cs, wrappers under NuGetUtility/Wrapper)
Multiple classes converted to C# primary-constructor syntax, moving injected dependencies to constructor parameters and updating internal usages accordingly.
Null/version guards & metadata handling
src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs, GlobalPackagesFolderUtility.cs
Added ArgumentNullException guards for manifest metadata fields and safe version comparisons via WrappedNuGetVersion; adjusted license file path normalization.
License/SPDX helpers and compare logic
src/FileLicenseMatcher/SPDX/**
Refactored regex/collection initializers to target-typed new expressions, removed some wrapper helper methods, ensured disposals (using enumerator), and adjusted minor substring/exception message constructions.

Tests and small cleanups

Layer / File(s) Summary
Test wiring and pragmas
tests/FileLicenseMatcher.Test/**, tests/*/*Test.cs
Moved substitute/fixture initialization to inline fields, removed small constructors, localized S6966 pragma disables, simplified string literals used in test setups.
Misc small edits
.coderabbit.yaml, Program.cs, table/printing helpers`
Added a custom instructions block to .coderabbit.yaml; renamed SolutionPersistanceWrapper → SolutionPersistenceWrapper in code and usages; minor target-typed/collection expression modernizations in table/printer code.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

"I'm a rabbit with a patch and a prancing pen,
I nudged versions, hopped constructors, and tidied tests again.
Regexes trimmed, null guards set right,
Tests now scope pragmas cozy and tight.
Hoppity-hop — merge on, my friends!"

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch simon/update-nuget-packages

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/NuGetLicense/NuGetLicense.csproj (1)

23-26: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Update NuGet.ProjectModel and NuGet.Frameworks to a released version.

NuGet 7.6.0 is currently in preview and has not been officially released. Using unreleased versions in production dependencies poses significant risks including potential instability, lack of support, and incomplete API documentation. Update these packages to the latest released version (currently 7.5.x) or document justification for using preview software.

Note: The comment references src/NuGetLicense/NuGetLicense.csproj but the packages in question are in src/NuGetUtility/NuGetUtility.csproj at lines 23-24.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/NuGetLicense/NuGetLicense.csproj` around lines 23 - 26, The csproj is
referencing preview NuGet packages; update the PackageReference entries for
NuGet.ProjectModel and NuGet.Frameworks in the NuGetUtility project (look for
the PackageReference symbols NuGet.ProjectModel and NuGet.Frameworks in
src/NuGetUtility/NuGetUtility.csproj) to a released version (e.g., change the
Version attribute to the latest 7.5.x stable release without any preview
suffix), run dotnet restore/build to validate, and if the preview was
intentional add a short justification comment in the csproj and raise it in the
PR instead of keeping an unreleased dependency.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/NuGetUtility/NuGetUtility.csproj`:
- Around line 23-26: The project references `NuGet.ProjectModel` and
`NuGet.Frameworks` at version 7.6.0 (preview); change these PackageReference
entries to a stable 7.5.x release (e.g., set Version="7.5.0" or the latest
7.5.*) in the NuGetUtility.csproj to avoid using unreleased preview packages, or
if you must keep 7.6.0, add a clear justification comment and a short note in
project documentation explaining why a preview is required and the associated
risk acceptance; update the `PackageReference` versions for `NuGet.ProjectModel`
and `NuGet.Frameworks` (or add the justification) accordingly.

---

Outside diff comments:
In `@src/NuGetLicense/NuGetLicense.csproj`:
- Around line 23-26: The csproj is referencing preview NuGet packages; update
the PackageReference entries for NuGet.ProjectModel and NuGet.Frameworks in the
NuGetUtility project (look for the PackageReference symbols NuGet.ProjectModel
and NuGet.Frameworks in src/NuGetUtility/NuGetUtility.csproj) to a released
version (e.g., change the Version attribute to the latest 7.5.x stable release
without any preview suffix), run dotnet restore/build to validate, and if the
preview was intentional add a short justification comment in the csproj and
raise it in the PR instead of keeping an unreleased dependency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 38d73e87-da08-4c4a-a9f2-215bd8c91689

📥 Commits

Reviewing files that changed from the base of the PR and between c085817 and 81ae0f7.

📒 Files selected for processing (9)
  • src/NuGetLicense/NuGetLicense.csproj
  • src/NuGetUtility/NuGetUtility.csproj
  • tests/FileLicenseMatcher.Test/FileLicenseMatcher.Test.csproj
  • tests/NuGetLicense.Test/NuGetLicense.Test.csproj
  • tests/NuGetUtility.Test/NuGetUtility.Test.csproj
  • tests/NuGetUtility.UrlToLicenseMapping.Test/NuGetUtility.UrlToLicenseMapping.Test.csproj
  • tests/targets/MultiTargetProjectWithDifferentDependencies/MultiTargetProjectWithDifferentDependencies.csproj
  • tests/targets/PackageReferenceProject/PackageReferenceProject.csproj
  • tests/targets/VersionRangesProject/VersionRangesProject.csproj

Comment thread src/NuGetUtility/NuGetUtility.csproj
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/FileLicenseMatcher/Compare/LicenseMatcher.cs`:
- Around line 11-12: Add XML documentation to the public primary-constructor
declaration for the LicenseMatcher class: add a <summary> describing the purpose
of the LicenseMatcher type and its behavior, and add <param> tags for the
constructor parameters named fileSystem (IFileSystem) and fileLicenseMap
(IDictionary<string,string>) describing each parameter's role; ensure the XML
appears immediately above the primary-constructor declaration "public class
LicenseMatcher(IFileSystem fileSystem, IDictionary<string, string>
fileLicenseMap) : IFileLicenseMatcher" and follows the project's XML doc style
conventions.

In `@src/NuGetLicense/Output/Csv/CsvOutputFormatter.cs`:
- Line 9: Add XML documentation to the public primary-constructor record/class
CsvOutputFormatter describing its purpose and include <summary> plus <param>
tags for the constructor parameters printErrorsOnly and skipIgnoredPackages;
place the /// <summary> above the CsvOutputFormatter declaration and add ///
<param name="printErrorsOnly"> and /// <param name="skipIgnoredPackages">
entries explaining what each flag controls so the public API is properly
documented.

In `@src/NuGetLicense/Output/Json/JsonOutputFormatter.cs`:
- Around line 11-12: Add XML documentation to the public primary-constructor
class JsonOutputFormatter: add a <summary> describing the formatter's purpose
and behavior, and add <param> tags for the constructor parameters prettyPrint,
printErrorsOnly, and skipIgnoredPackages explaining what each flag controls;
ensure the XML comment is placed directly above the class declaration "public
class JsonOutputFormatter(bool prettyPrint, bool printErrorsOnly, bool
skipIgnoredPackages) : IOutputFormatter".

In `@src/NuGetUtility/ReferencedPackagesReader/ProjectsCollector.cs`:
- Around line 13-15: The check using
fileSystem.Path.GetExtension(inputPath).StartsWith(".sln") should be changed to
an exact, case-insensitive equality check to avoid matching extensions like
".slnf" or different case; replace the StartsWith call with a comparison using
Equals(".sln", StringComparison.OrdinalIgnoreCase) (or string.Equals with
StringComparison.OrdinalIgnoreCase) so the branch that calls
solutionPersistence.GetProjectsFromSolutionAsync and the fallback that returns
fileSystem.Path.GetFullPath(inputPath) behave correctly.

In `@src/NuGetUtility/Wrapper/HttpClientWrapper/FileDownloader.cs`:
- Around line 52-55: In TryDownload (FileDownloader.cs) you’re creating an
HttpRequestMessage and HttpResponseMessage that aren’t disposed and can leak
connections during the retry loop; wrap the HttpRequestMessage and the
HttpResponseMessage returned by client.SendAsync in using blocks (or explicit
try/finally Dispose calls) so both are always disposed after use, making sure to
read or copy the response content you need before disposing the response (e.g.,
use response.Content.ReadAsStreamAsync()/CopyToAsync into a MemoryStream if you
need the body after disposing). Replace the existing direct creations of request
and response around client.SendAsync with using (var request = new
HttpRequestMessage(...)) { var response = await client.SendAsync(...); using
(response) { ... } } (or equivalent try/finally) to ensure no HttpRequestMessage
or HttpResponseMessage instances are leaked across retries.

In
`@src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs`:
- Around line 34-36: The guard in GlobalPackagesFolderUtility.cs incorrectly
returns null when the manifest.Metadata.Version equals the package identity,
rejecting valid packages; in the method containing the check on
manifest.Metadata.Version, change the condition so it returns null only when
metadataVersion is missing or DOES NOT equal identity.Version (i.e., invert the
equality check using !new
WrappedNuGetVersion(metadataVersion).Equals(identity.Version) or compare
versions for inequality) so valid cached packages are accepted (refer to
manifest.Metadata.Version, metadataVersion, WrappedNuGetVersion, and
identity.Version).

In `@src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs`:
- Around line 15-16: The ArgumentNullException calls in the PackageIdentity
initializer use incorrect parameter names ("Id" and "Version"); update the two
throws so they pass the actual parameter name nameof(metadata) instead of
nameof(metadata.Id) and nameof(metadata.Version) in the Identity property
initializer (the PackageIdentity Identity = new(...) expression) so the
exception reports the correct parameter and removes analyzer warnings.

In
`@src/NuGetUtility/Wrapper/SolutionPersistenceWrapper/SolutionPersistenceWrapper.cs`:
- Line 10: The public class SolutionPersistenceWrapper (implementing
ISolutionPersistenceWrapper) lacks XML documentation; add an XML doc comment on
the public primary-constructor type declaration that includes a <summary>
describing the class responsibility and a <param> tag for each constructor
parameter (use the exact parameter names from the SolutionPersistenceWrapper
constructor), and include any relevant <returns> or <exception> tags if the
class exposes methods that require them; place the comment immediately above the
"public class SolutionPersistenceWrapper : ISolutionPersistenceWrapper"
declaration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 76277ff7-b516-41dd-b962-fa205e097c40

📥 Commits

Reviewing files that changed from the base of the PR and between 81ae0f7 and 68c893f.

📒 Files selected for processing (67)
  • src/FileLicenseMatcher/Combine/LicenseMatcher.cs
  • src/FileLicenseMatcher/Compare/LicenseMatcher.cs
  • src/FileLicenseMatcher/SPDX/FastLicenseMatcher.cs
  • src/FileLicenseMatcher/SPDX/JavaCore/LicenseTemplateRule.cs
  • src/FileLicenseMatcher/SPDX/JavaCore/LicenseTextHelper.cs
  • src/FileLicenseMatcher/SPDX/JavaCore/SpdxLicenseTemplateHelper.cs
  • src/FileLicenseMatcher/SPDX/JavaLibrary/CompareTemplateOutputHandler.cs
  • src/FileLicenseMatcher/SPDX/JavaLibrary/LicenseCompareHelper.cs
  • src/FileLicenseMatcher/SPDX/JavaLibrary/ParseInstruction.cs
  • src/NuGetLicense/CommandLineOptionsParser.cs
  • src/NuGetLicense/LicenseValidationOrchestrator.cs
  • src/NuGetLicense/LicenseValidator/LicenseDownloadException.cs
  • src/NuGetLicense/LicenseValidator/LicenseValidationResult.cs
  • src/NuGetLicense/LicenseValidator/LicenseValidator.cs
  • src/NuGetLicense/Output/Csv/CsvOutputFormatter.cs
  • src/NuGetLicense/Output/Json/JsonOutputFormatter.cs
  • src/NuGetLicense/Output/Table/TableOutputFormatter.cs
  • src/NuGetLicense/Program.cs
  • src/NuGetLicense/Serialization/ValidatedLicenseJsonConverterWithOmittingEmptyErrorList.cs
  • src/NuGetUtility/Output/Table/TablePrinter.cs
  • src/NuGetUtility/PackageInformationReader/PackageInformationReader.cs
  • src/NuGetUtility/PackageInformationReader/PackageMetadata.cs
  • src/NuGetUtility/ReferencedPackagesReader/ProjectsCollector.cs
  • src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs
  • src/NuGetUtility/Wrapper/HttpClientWrapper/DownloadFailedException.cs
  • src/NuGetUtility/Wrapper/HttpClientWrapper/FileDownloader.cs
  • src/NuGetUtility/Wrapper/MsBuildWrapper/ProjectWrapper.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Frameworks/WrappedNuGetFramework.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/NugetWrapperException.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/PackagesConfigReaderException.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/WrappedPackageDependency.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/AssetsPackageDependencyReader.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedLibraryDependency.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedLockFile.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedLockFileLibrary.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedLockFileTarget.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedPackageSpec.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedTargetFrameworkInformation.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/Core/Types/CachingDisposableSourceRepository.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/Core/Types/CachingPackageMetadataResource.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs
  • src/NuGetUtility/Wrapper/SolutionPersistenceWrapper/ISolutionPersistenceWrapper.cs
  • src/NuGetUtility/Wrapper/SolutionPersistenceWrapper/SolutionPersistenceWrapper.cs
  • tests/FileLicenseMatcher.Test/Combine/LicenseMatcherTest.cs
  • tests/FileLicenseMatcher.Test/Compare/LicenseMatcherTest.cs
  • tests/FileLicenseMatcher.Test/SPDX/LicenseMatcherTest.cs
  • tests/NuGetLicense.Test/CommandLineOptionsParserTest.cs
  • tests/NuGetLicense.Test/LicenseValidationOrchestratorTest.cs
  • tests/NuGetLicense.Test/Output/Csv/CsvOutputFormatterTests.cs
  • tests/NuGetLicense.Test/Output/Helper/NuGetVersion.cs
  • tests/NuGetLicense.Test/Output/Json/JsonOutputFormatterTest.cs
  • tests/NuGetLicense.Test/Output/Table/MarkdownTableOutputFormatterTest.cs
  • tests/NuGetLicense.Test/Output/Table/TableOutputFormatterTest.cs
  • tests/NuGetUtility.Test.Extensions/Helper/AsyncEnumerableExtension/AsyncEnumerable.cs
  • tests/NuGetUtility.Test.Extensions/Helper/AsyncEnumerableExtension/AsyncEnumerator.cs
  • tests/NuGetUtility.Test.Extensions/Helper/AutoFixture/NuGet/Versioning/NuGetVersionBuilder.cs
  • tests/NuGetUtility.Test/Architecture/ArchitectureTest.cs
  • tests/NuGetUtility.Test/Architecture/ConditionsExtensions.cs
  • tests/NuGetUtility.Test/Architecture/Rules/NugetAbstractionTest.cs
  • tests/NuGetUtility.Test/Extensions/HashSetExtensionsTest.cs
  • tests/NuGetUtility.Test/Extensions/ProjectExtensionsTest.cs
  • tests/NuGetUtility.Test/PackageInformationReader/PackageInformationReaderTest.cs
  • tests/NuGetUtility.Test/ProjectFiltering/ProjectFiltererTest.cs
  • tests/NuGetUtility.Test/ReferencedPackagesReader/ProjectsCollectorTest.cs
  • tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackageReaderTest.cs
  • tests/NuGetUtility.UrlToLicenseMapping.Test/UrlToLicenseMappingTest.cs
💤 Files with no reviewable changes (1)
  • tests/NuGetUtility.Test/Architecture/Rules/NugetAbstractionTest.cs
✅ Files skipped from review due to trivial changes (17)
  • src/NuGetUtility/Wrapper/SolutionPersistenceWrapper/ISolutionPersistenceWrapper.cs
  • src/NuGetUtility/Wrapper/HttpClientWrapper/DownloadFailedException.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/NugetWrapperException.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedTargetFrameworkInformation.cs
  • tests/NuGetUtility.Test/PackageInformationReader/PackageInformationReaderTest.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/AssetsPackageDependencyReader.cs
  • src/NuGetLicense/Serialization/ValidatedLicenseJsonConverterWithOmittingEmptyErrorList.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/PackagesConfigReaderException.cs
  • tests/NuGetUtility.UrlToLicenseMapping.Test/UrlToLicenseMappingTest.cs
  • tests/NuGetLicense.Test/CommandLineOptionsParserTest.cs
  • src/NuGetLicense/LicenseValidator/LicenseValidationResult.cs
  • src/NuGetUtility/PackageInformationReader/PackageMetadata.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/WrappedPackageDependency.cs
  • src/NuGetLicense/LicenseValidator/LicenseDownloadException.cs
  • src/FileLicenseMatcher/SPDX/FastLicenseMatcher.cs
  • src/FileLicenseMatcher/SPDX/JavaCore/LicenseTemplateRule.cs
  • tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackageReaderTest.cs

Comment thread src/FileLicenseMatcher/Compare/LicenseMatcher.cs
Comment thread src/NuGetLicense/Output/Csv/CsvOutputFormatter.cs
Comment thread src/NuGetLicense/Output/Json/JsonOutputFormatter.cs
Comment thread src/NuGetUtility/ReferencedPackagesReader/ProjectsCollector.cs Outdated
Comment thread src/NuGetUtility/Wrapper/HttpClientWrapper/FileDownloader.cs Outdated
Comment thread src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs Outdated
Comment thread src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs Outdated
@sensslen sensslen force-pushed the simon/update-nuget-packages branch 2 times, most recently from 352916f to 7dd6316 Compare May 17, 2026 15:54
@sensslen sensslen force-pushed the simon/update-nuget-packages branch from 7dd6316 to a5a0fd9 Compare May 17, 2026 18:03
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (2)
src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs (1)

17-18: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use the actual parameter name in ArgumentNullException constructors.

nameof(metadata.Id) evaluates to "Id" and nameof(metadata.Version) evaluates to "Version", but the constructor parameter is metadata. This produces analyzer warnings (CA1507) and misleading exception messages when thrown. Use nameof(metadata) for both exceptions to match the actual parameter name.

🔧 Proposed fix
-        public WrappedPackageMetadata(ManifestMetadata metadata)
-        {
-            Identity = new PackageIdentity(metadata.Id ?? throw new ArgumentNullException(nameof(metadata.Id)),
-                                           new WrappedNuGetVersion(metadata.Version ?? throw new ArgumentNullException(nameof(metadata.Version))));
+        public WrappedPackageMetadata(ManifestMetadata metadata)
+        {
+            Identity = new PackageIdentity(metadata.Id ?? throw new ArgumentNullException(nameof(metadata)),
+                                           new WrappedNuGetVersion(metadata.Version ?? throw new ArgumentNullException(nameof(metadata))));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs`
around lines 17 - 18, The ArgumentNullException usage in
WrappedPackageMetadata's constructor uses nameof(metadata.Id) and
nameof(metadata.Version) which produces wrong parameter names; update the two
throws so they pass nameof(metadata) instead (the null-checked parameter) when
constructing Identity (PackageIdentity and WrappedNuGetVersion) to eliminate
CA1507 warnings and produce correct exception messages.
src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs (1)

37-37: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Invert the version comparison to accept matching packages.

Line 37 returns null when the manifest version equals identity.Version, which rejects valid cached packages. The condition should return null only when the versions do not match. Add a negation operator before the Equals call.

🐛 Proposed fix
         if (manifest.Metadata.Version is not { } manifestVersion ||
-            new WrappedNuGetVersion(manifestVersion).Equals(identity.Version) ||
+            !new WrappedNuGetVersion(manifestVersion).Equals(identity.Version) ||
             manifest.Metadata.LicenseMetadata is not { } manifestLicenseMetadata)
         {
             return null;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs`
at line 37, The code in GlobalPackagesFolderUtility is currently returning null
when WrappedNuGetVersion(manifestVersion).Equals(identity.Version) is true,
which incorrectly rejects valid cached packages; change the conditional to
return null only when the versions do not match by negating the comparison
(i.e., use !WrappedNuGetVersion(manifestVersion).Equals(identity.Version)) so
the method (in GlobalPackagesFolderUtility) accepts packages when the manifest
version equals identity.Version.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In
`@src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs`:
- Line 37: The code in GlobalPackagesFolderUtility is currently returning null
when WrappedNuGetVersion(manifestVersion).Equals(identity.Version) is true,
which incorrectly rejects valid cached packages; change the conditional to
return null only when the versions do not match by negating the comparison
(i.e., use !WrappedNuGetVersion(manifestVersion).Equals(identity.Version)) so
the method (in GlobalPackagesFolderUtility) accepts packages when the manifest
version equals identity.Version.

In `@src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs`:
- Around line 17-18: The ArgumentNullException usage in WrappedPackageMetadata's
constructor uses nameof(metadata.Id) and nameof(metadata.Version) which produces
wrong parameter names; update the two throws so they pass nameof(metadata)
instead (the null-checked parameter) when constructing Identity (PackageIdentity
and WrappedNuGetVersion) to eliminate CA1507 warnings and produce correct
exception messages.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5c2074ed-1e3c-46ff-9196-071a8a29db67

📥 Commits

Reviewing files that changed from the base of the PR and between 68c893f and a5a0fd9.

📒 Files selected for processing (5)
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs
  • tests/FileLicenseMatcher.Test/Compare/LicenseMatcherTest.cs
  • tests/NuGetLicense.Test/CommandLineOptionsParserTest.cs
  • tests/NuGetUtility.UrlToLicenseMapping.Test/UrlToLicenseMappingTest.cs
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/NuGetLicense.Test/CommandLineOptionsParserTest.cs
  • tests/FileLicenseMatcher.Test/Compare/LicenseMatcherTest.cs

@sensslen sensslen force-pushed the simon/update-nuget-packages branch from a5a0fd9 to ef6d6f2 Compare May 17, 2026 18:10
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

♻️ Duplicate comments (2)
src/NuGetUtility/Wrapper/HttpClientWrapper/FileDownloader.cs (1)

53-56: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Dispose request and response objects in TryDownload.

Both objects are created per retry attempt and currently not disposed, which can exhaust HTTP resources.

💡 Proposed fix
-            var request = new HttpRequestMessage(HttpMethod.Get, url);
-
-            HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
+            using HttpRequestMessage request = new(HttpMethod.Get, url);
+            using HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token);
Do HttpRequestMessage and HttpResponseMessage implement IDisposable, and is explicit disposal recommended after SendAsync in retry loops?
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/NuGetUtility/Wrapper/HttpClientWrapper/FileDownloader.cs` around lines 53
- 56, In TryDownload, each retry creates an HttpRequestMessage and an
HttpResponseMessage but never disposes them; wrap the per-attempt
HttpRequestMessage and the HttpResponseMessage returned by client.SendAsync in
proper disposal (e.g., using or try/finally) so both are disposed after the
attempt finishes or before a retry; ensure you do not dispose the response until
any needed response.Content/stream is consumed or handed off, and dispose them
on all code paths (success, error, and cancellation) to avoid exhausting HTTP
resources.
src/NuGetUtility/ReferencedPackagesReader/ProjectsCollector.cs (1)

13-15: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use case-insensitive extension matching for solution detection.

Contains(extension) is case-sensitive here, so uppercase solution extensions won’t be recognized and won’t go through solution expansion.

💡 Proposed fix
-            return new[] { ".sln", ".slnx" }.Contains(extension)
+            return new[] { ".sln", ".slnx" }.Contains(extension, StringComparer.OrdinalIgnoreCase)
                 ? (await solutionPersistence.GetProjectsFromSolutionAsync(fileSystem.Path.GetFullPath(inputPath))).Where(fileSystem.File.Exists).Select(fileSystem.Path.GetFullPath)
                 : [fileSystem.Path.GetFullPath(inputPath)];
In .NET, does Enumerable.Contains(string) without an IEqualityComparer perform case-sensitive comparison?
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/NuGetUtility/ReferencedPackagesReader/ProjectsCollector.cs` around lines
13 - 15, The extension comparison is case-sensitive so uppercase extensions like
".SLN" are missed; update the conditional that checks extension (the extension
variable used in ProjectsCollector.cs before calling
solutionPersistence.GetProjectsFromSolutionAsync) to perform a case-insensitive
comparison (e.g., use Enumerable.Contains with StringComparer.OrdinalIgnoreCase
or otherwise compare with OrdinalIgnoreCase) so solution files are recognized
regardless of casing before invoking GetProjectsFromSolutionAsync and filtering
with fileSystem.File.Exists.
🧹 Nitpick comments (2)
src/NuGetLicense/Output/Table/TableOutputFormatter.cs (1)

9-10: ⚡ Quick win

Add XML docs for the public primary constructor.

Please add <summary> and <param> documentation for printErrorsOnly, skipIgnoredPackages, and printMarkdown.

As per coding guidelines, "Public APIs in C# should have XML documentation comments using <summary>, <param>, <returns>, <exception> tags as appropriate".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/NuGetLicense/Output/Table/TableOutputFormatter.cs` around lines 9 - 10,
Add XML documentation comments for the public primary constructor of
TableOutputFormatter: add a <summary> describing the constructor's purpose and
three <param> tags documenting printErrorsOnly (whether to only print error
entries), skipIgnoredPackages (whether to omit ignored packages from output),
and printMarkdown (whether to render output in Markdown format). Place the XML
docs immediately above the primary constructor declaration for
TableOutputFormatter(bool printErrorsOnly, bool skipIgnoredPackages, bool
printMarkdown = false) and use concise, clear descriptions following the
project's documentation style.
src/NuGetUtility/Wrapper/SolutionPersistenceWrapper/ISolutionPersistenceWrapper.cs (1)

6-8: ⚡ Quick win

Add XML documentation to this public interface and method.

This public API is missing XML docs (<summary>, <param>, <returns>), which makes the contract less discoverable.

Proposed patch
+    /// <summary>
+    /// Provides access to project paths contained in a solution file.
+    /// </summary>
     public interface ISolutionPersistenceWrapper
     {
+        /// <summary>
+        /// Gets project file paths from the specified solution.
+        /// </summary>
+        /// <param name="inputPath">Path to the solution file.</param>
+        /// <returns>A collection of project file paths.</returns>
         Task<IEnumerable<string>> GetProjectsFromSolutionAsync(string inputPath);
     }

As per coding guidelines "Public APIs in C# should have XML documentation comments using <summary>, <param>, <returns>, <exception> tags as appropriate".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/NuGetUtility/Wrapper/SolutionPersistenceWrapper/ISolutionPersistenceWrapper.cs`
around lines 6 - 8, Add XML documentation to the public interface
ISolutionPersistenceWrapper and its method GetProjectsFromSolutionAsync: add a
<summary> describing the purpose of the interface and the method, a <param
name="inputPath"> explaining the expected solution path, and a <returns>
describing the returned Task<IEnumerable<string>> (what the strings represent).
If the method can throw specific exceptions, include <exception> tags naming
them. Ensure the doc comments are placed immediately above the interface
declaration and the GetProjectsFromSolutionAsync method signature.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/NuGetLicense/LicenseValidationOrchestrator.cs`:
- Around line 90-93: The net472 build fails because
LicenseValidationOrchestrator.cs calls await os.DisposeAsync() when
shouldDisposeStream is true; change this to synchronous disposal compatible with
.NET Framework by replacing await os.DisposeAsync() with os.Dispose() (remove
the await), keeping the surrounding conditional and variable names
(shouldDisposeStream and os) intact so the stream is disposed synchronously.

In `@src/NuGetLicense/LicenseValidator/LicenseValidator.cs`:
- Around line 168-173: The AddOrUpdateLicense call in the "not allowed"
file-license path is recording info.LicenseMetadata.License even though
validation checked matchedLicense; change the argument passed to
AddOrUpdateLicense so it uses matchedLicense (the actual resolved/checked
license ID) instead of info.LicenseMetadata.License, keep the other parameters
(result, info, LicenseInformationOrigin.File, new
ValidationError(GetLicenseNotAllowedMessage(matchedLicense), context)) unchanged
so the stored license matches the message produced by
GetLicenseNotAllowedMessage.

In `@src/NuGetUtility/Wrapper/HttpClientWrapper/DownloadFailedException.cs`:
- Line 6: The declaration "public class DownloadFailedException(Uri url) :
Exception($"Download failed for URL: {url");" is invalid C# syntax; change the
declaration of DownloadFailedException into a normal class with a body and a
constructor: declare "public class DownloadFailedException : Exception" with an
explicit public constructor "public DownloadFailedException(Uri url) :
base($\"Download failed for URL: {url}\") { }" (optionally add serialization
ctor if needed) so the class has braces and a proper base Exception call.

In
`@src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs`:
- Around line 38-41: Guard against a null or empty License string before calling
PathUtility.GetPathWithDirectorySeparator: inside the block that checks
result.LicenseMetadata?.Type == Packaging.LicenseType.File, first verify
result.LicenseMetadata?.License is not null or whitespace (e.g., if
(string.IsNullOrWhiteSpace(result.LicenseMetadata.License)) { /* skip/log and
continue */ }), then compute normalizedPath via
NuGet.Common.PathUtility.GetPathWithDirectorySeparator(result.LicenseMetadata.License)
and call pkgStream.GetStream(normalizedPath); this prevents
GetPathWithDirectorySeparator and pkgStream.GetStream from throwing on malformed
nuspec metadata.

In `@tests/NuGetUtility.Test/ProjectFiltering/ProjectFiltererTest.cs`:
- Around line 13-21: The test expectations for includeSharedProjects=true are
wrong: update the Arguments entries in
ProjectFiltererTest.FilterProjects_ExcludesSharedProjects_WhenIncludeSharedProjectsIsFalse
so that for the four cases where includeSharedProjects is true (the last four
[Arguments] lines) the isFiltered boolean is false; this aligns the test with
ProjectFilter.FilterProjects (which returns all projects when
includeSharedProjects is true) and ensures the test data matches the behavior.

---

Duplicate comments:
In `@src/NuGetUtility/ReferencedPackagesReader/ProjectsCollector.cs`:
- Around line 13-15: The extension comparison is case-sensitive so uppercase
extensions like ".SLN" are missed; update the conditional that checks extension
(the extension variable used in ProjectsCollector.cs before calling
solutionPersistence.GetProjectsFromSolutionAsync) to perform a case-insensitive
comparison (e.g., use Enumerable.Contains with StringComparer.OrdinalIgnoreCase
or otherwise compare with OrdinalIgnoreCase) so solution files are recognized
regardless of casing before invoking GetProjectsFromSolutionAsync and filtering
with fileSystem.File.Exists.

In `@src/NuGetUtility/Wrapper/HttpClientWrapper/FileDownloader.cs`:
- Around line 53-56: In TryDownload, each retry creates an HttpRequestMessage
and an HttpResponseMessage but never disposes them; wrap the per-attempt
HttpRequestMessage and the HttpResponseMessage returned by client.SendAsync in
proper disposal (e.g., using or try/finally) so both are disposed after the
attempt finishes or before a retry; ensure you do not dispose the response until
any needed response.Content/stream is consumed or handed off, and dispose them
on all code paths (success, error, and cancellation) to avoid exhausting HTTP
resources.

---

Nitpick comments:
In `@src/NuGetLicense/Output/Table/TableOutputFormatter.cs`:
- Around line 9-10: Add XML documentation comments for the public primary
constructor of TableOutputFormatter: add a <summary> describing the
constructor's purpose and three <param> tags documenting printErrorsOnly
(whether to only print error entries), skipIgnoredPackages (whether to omit
ignored packages from output), and printMarkdown (whether to render output in
Markdown format). Place the XML docs immediately above the primary constructor
declaration for TableOutputFormatter(bool printErrorsOnly, bool
skipIgnoredPackages, bool printMarkdown = false) and use concise, clear
descriptions following the project's documentation style.

In
`@src/NuGetUtility/Wrapper/SolutionPersistenceWrapper/ISolutionPersistenceWrapper.cs`:
- Around line 6-8: Add XML documentation to the public interface
ISolutionPersistenceWrapper and its method GetProjectsFromSolutionAsync: add a
<summary> describing the purpose of the interface and the method, a <param
name="inputPath"> explaining the expected solution path, and a <returns>
describing the returned Task<IEnumerable<string>> (what the strings represent).
If the method can throw specific exceptions, include <exception> tags naming
them. Ensure the doc comments are placed immediately above the interface
declaration and the GetProjectsFromSolutionAsync method signature.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f3942ec4-2593-4d28-b66a-cc194db2a8ee

📥 Commits

Reviewing files that changed from the base of the PR and between a5a0fd9 and 7b0dea1.

📒 Files selected for processing (63)
  • .coderabbit.yaml
  • src/FileLicenseMatcher/Combine/LicenseMatcher.cs
  • src/FileLicenseMatcher/Compare/LicenseMatcher.cs
  • src/FileLicenseMatcher/SPDX/FastLicenseMatcher.cs
  • src/FileLicenseMatcher/SPDX/JavaCore/LicenseTemplateRule.cs
  • src/FileLicenseMatcher/SPDX/JavaCore/LicenseTextHelper.cs
  • src/FileLicenseMatcher/SPDX/JavaCore/SpdxLicenseTemplateHelper.cs
  • src/FileLicenseMatcher/SPDX/JavaLibrary/CompareTemplateOutputHandler.cs
  • src/FileLicenseMatcher/SPDX/JavaLibrary/LicenseCompareHelper.cs
  • src/FileLicenseMatcher/SPDX/JavaLibrary/ParseInstruction.cs
  • src/NuGetLicense/CommandLineOptionsParser.cs
  • src/NuGetLicense/LicenseValidationOrchestrator.cs
  • src/NuGetLicense/LicenseValidator/LicenseDownloadException.cs
  • src/NuGetLicense/LicenseValidator/LicenseValidationResult.cs
  • src/NuGetLicense/LicenseValidator/LicenseValidator.cs
  • src/NuGetLicense/Output/Csv/CsvOutputFormatter.cs
  • src/NuGetLicense/Output/Json/JsonOutputFormatter.cs
  • src/NuGetLicense/Output/Table/TableOutputFormatter.cs
  • src/NuGetLicense/Program.cs
  • src/NuGetUtility/Output/Table/TablePrinter.cs
  • src/NuGetUtility/PackageInformationReader/PackageInformationReader.cs
  • src/NuGetUtility/ReferencedPackagesReader/ProjectsCollector.cs
  • src/NuGetUtility/ReferencedPackagesReader/ReferencedPackageReader.cs
  • src/NuGetUtility/Wrapper/HttpClientWrapper/DownloadFailedException.cs
  • src/NuGetUtility/Wrapper/HttpClientWrapper/FileDownloader.cs
  • src/NuGetUtility/Wrapper/MsBuildWrapper/ProjectWrapper.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Frameworks/WrappedNuGetFramework.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/NugetWrapperException.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/PackagesConfigReaderException.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/WrappedPackageDependency.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/AssetsPackageDependencyReader.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedLibraryDependency.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedLockFile.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedLockFileLibrary.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedLockFileTarget.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedPackageSpec.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedTargetFrameworkInformation.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/Core/Types/CachingDisposableSourceRepository.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/Core/Types/CachingPackageMetadataResource.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/LicenseAugmentedPackageMetadata.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/WrappedPackageMetadata.cs
  • src/NuGetUtility/Wrapper/SolutionPersistenceWrapper/ISolutionPersistenceWrapper.cs
  • src/NuGetUtility/Wrapper/SolutionPersistenceWrapper/SolutionPersistenceWrapper.cs
  • tests/FileLicenseMatcher.Test/Combine/LicenseMatcherTest.cs
  • tests/FileLicenseMatcher.Test/SPDX/LicenseMatcherTest.cs
  • tests/NuGetLicense.Test/LicenseValidationOrchestratorTest.cs
  • tests/NuGetLicense.Test/Output/Csv/CsvOutputFormatterTests.cs
  • tests/NuGetLicense.Test/Output/Helper/NuGetVersion.cs
  • tests/NuGetLicense.Test/Output/Json/JsonOutputFormatterTest.cs
  • tests/NuGetLicense.Test/Output/Table/MarkdownTableOutputFormatterTest.cs
  • tests/NuGetLicense.Test/Output/Table/TableOutputFormatterTest.cs
  • tests/NuGetUtility.Test.Extensions/Helper/AsyncEnumerableExtension/AsyncEnumerable.cs
  • tests/NuGetUtility.Test.Extensions/Helper/AsyncEnumerableExtension/AsyncEnumerator.cs
  • tests/NuGetUtility.Test.Extensions/Helper/AutoFixture/NuGet/Versioning/NuGetVersionBuilder.cs
  • tests/NuGetUtility.Test/Architecture/ArchitectureTest.cs
  • tests/NuGetUtility.Test/Architecture/ConditionsExtensions.cs
  • tests/NuGetUtility.Test/Extensions/HashSetExtensionsTest.cs
  • tests/NuGetUtility.Test/Extensions/ProjectExtensionsTest.cs
  • tests/NuGetUtility.Test/PackageInformationReader/PackageInformationReaderTest.cs
  • tests/NuGetUtility.Test/ProjectFiltering/ProjectFiltererTest.cs
  • tests/NuGetUtility.Test/ReferencedPackagesReader/ProjectsCollectorTest.cs
  • tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackageReaderTest.cs
✅ Files skipped from review due to trivial changes (12)
  • src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/PackagesConfigReaderException.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/NugetWrapperException.cs
  • tests/NuGetUtility.Test/PackageInformationReader/PackageInformationReaderTest.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/LicenseAugmentedPackageMetadata.cs
  • src/FileLicenseMatcher/Combine/LicenseMatcher.cs
  • .coderabbit.yaml
  • src/NuGetUtility/Wrapper/NuGetWrapper/Packaging/Core/WrappedPackageDependency.cs
  • src/NuGetUtility/Output/Table/TablePrinter.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/WrappedTargetFrameworkInformation.cs
  • src/NuGetUtility/Wrapper/NuGetWrapper/ProjectModel/AssetsPackageDependencyReader.cs
  • src/NuGetLicense/Program.cs
  • tests/NuGetUtility.Test/ReferencedPackagesReader/ReferencedPackageReaderTest.cs

Comment thread src/NuGetLicense/LicenseValidationOrchestrator.cs
Comment thread src/NuGetLicense/LicenseValidator/LicenseValidator.cs
Comment on lines 38 to 41
if (result.LicenseMetadata?.Type == Packaging.LicenseType.File)
{
string normalizedPath = NuGet.Common.PathUtility.GetPathWithDirectorySeparator(manifest.Metadata.LicenseMetadata.License);
string normalizedPath = NuGet.Common.PathUtility.GetPathWithDirectorySeparator(result.LicenseMetadata.License);
using Stream licenseStream = pkgStream.GetStream(normalizedPath);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Guard LicenseMetadata.License before path normalization.

Type == File does not guarantee License is non-null/non-empty. Line 40 can throw on malformed nuspec metadata and fail package inspection.

Proposed fix
-            if (result.LicenseMetadata?.Type == Packaging.LicenseType.File)
+            if (result.LicenseMetadata?.Type == Packaging.LicenseType.File &&
+                !string.IsNullOrWhiteSpace(result.LicenseMetadata.License))
             {
                 string normalizedPath = NuGet.Common.PathUtility.GetPathWithDirectorySeparator(result.LicenseMetadata.License);
                 using Stream licenseStream = pkgStream.GetStream(normalizedPath);
                 using var reader = new StreamReader(licenseStream);
                 return new LicenseAugmentedPackageMetadata(result, reader.ReadToEnd());
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/NuGetUtility/Wrapper/NuGetWrapper/Protocol/GlobalPackagesFolderUtility.cs`
around lines 38 - 41, Guard against a null or empty License string before
calling PathUtility.GetPathWithDirectorySeparator: inside the block that checks
result.LicenseMetadata?.Type == Packaging.LicenseType.File, first verify
result.LicenseMetadata?.License is not null or whitespace (e.g., if
(string.IsNullOrWhiteSpace(result.LicenseMetadata.License)) { /* skip/log and
continue */ }), then compute normalizedPath via
NuGet.Common.PathUtility.GetPathWithDirectorySeparator(result.LicenseMetadata.License)
and call pkgStream.GetStream(normalizedPath); this prevents
GetPathWithDirectorySeparator and pkgStream.GetStream from throwing on malformed
nuspec metadata.

Comment thread tests/NuGetUtility.Test/ProjectFiltering/ProjectFiltererTest.cs
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
4 Security Hotspots

See analysis details on SonarQube Cloud

@sensslen sensslen merged commit e135abb into main May 17, 2026
43 of 44 checks passed
@sensslen sensslen deleted the simon/update-nuget-packages branch May 17, 2026 19:38
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