Skip to content

Enable nullable annotations for NuGet.Protocol service index, repository signature, and registration types#7481

Merged
nkolev92 merged 1 commit into
devfrom
dev-nkolev92-protocolNullabilityResourceProvider
Jun 18, 2026
Merged

Enable nullable annotations for NuGet.Protocol service index, repository signature, and registration types#7481
nkolev92 merged 1 commit into
devfrom
dev-nkolev92-protocolNullabilityResourceProvider

Conversation

@nkolev92

@nkolev92 nkolev92 commented Jun 16, 2026

Copy link
Copy Markdown
Member

Bug

Progress: NuGet/Home#14851

Description

Enable nullable annotations for NuGet.Protocol Phase 15 (Service index / repository signature resources) and Phase 16 (Search model leaves — registration types + vulnerability metadata).

Files annotated (removed #nullable disable):

Phase 15 — Public resource types + providers:

  • ServiceIndexResourceV3.cs — service index resource with JObject and STJ code paths
  • ServiceIndexResourceV3Provider.cs — caching provider with retry logic
  • RepositorySignatureResource.cs — repository signing resource
  • RepositorySignatureResourceProvider.cs — provider with dual STJ/NSJ deserialization

Phase 16 — Internal registration DTOs + public vulnerability metadata:

  • RegistrationIndex.cs, RegistrationPage.cs, RegistrationLeafItem.cs — internal JSON DTOs
  • PackageVulnerabilityMetadata.cs — public vulnerability model

Key decisions:

  1. GetServiceEntryUri returns Uri?FirstOrDefault() can genuinely return null when no matching service type is registered. Callers that need non-null use ?? throw.

  2. httpSourceResource null checks with InvalidOperationException — Instead of suppressing with !, both providers now throw explicitly if GetResourceAsync<HttpSourceResource>() returns null. This is a coding error (misconfigured source), not a user error, so inline interpolated strings are used (same pattern as VulnerabilityInfoResourceV3). No shared resx string needed.

  3. RepositorySignatureResourceProvider deserialization null checksJsonSerializer.DeserializeAsync returns T?. Instead of model!, we use ?? throw new FatalProtocolException(...) to give a clear error at the deserialization boundary rather than an NRE later.

  4. RegistrationPage properties (Url, Lower, Upper) annotated non-null — The protocol spec guarantees these. Existing code already uses them without null checks (NuGetVersion.Parse(page.Lower)). Items stays nullable per its documented semantics. NULL_INC comment added to document the = null! initializers.

  5. PackageVulnerabilityMetadata.AdvisoryUrl annotated non-null — The protocol spec guarantees advisoryUrl is always present. Using = null! with a doc comment linking to the spec. This avoids forcing callers to add unnecessary ! or null checks.

  6. RepositorySignatureResource internal ctor — Added _ = model ?? throw and _ = source ?? throw guard clauses. Without annotation, callers would NRE on model.AllRepositorySigned with no useful diagnostics. Explicit throws give clear failure messages.

  7. ServiceIndexResourceV3 ctors — Same pattern: _ = index ?? throw and _ = model ?? throw since the public ctor delegates to internal and external callers could pass null.

PR Checklist

  • Meaningful title, helpful description and a linked NuGet/Home issue
  • Added tests
  • Link to an issue or pull request to update docs if this PR changes settings, environment variables, new feature, etc.

@nkolev92 nkolev92 marked this pull request as ready for review June 17, 2026 00:29
@nkolev92 nkolev92 requested a review from a team as a code owner June 17, 2026 00:29
@nkolev92 nkolev92 requested review from jebriede and martinrrm June 17, 2026 00:29
@nkolev92 nkolev92 merged commit 26ab65c into dev Jun 18, 2026
20 of 21 checks passed
@nkolev92 nkolev92 deleted the dev-nkolev92-protocolNullabilityResourceProvider branch June 18, 2026 17:21
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.

2 participants