From b63cba04d3c70940e1f57bc5213a06732eab7d47 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 13:46:43 +0000 Subject: [PATCH 1/2] [patch] Update ktsu.Essentials to 2.10.7 and Testably.Abstractions to 10.4.0 ktsu.Essentials 2.10.7 forwards IFileSystem.RandomAccess, so it supports Testably.Abstractions.FileSystem.Interface 10.4.0. Raise the VersionOverride on the Interface reference to 10.4.0, the version that release's nuspec pins, so consumers that also resolve Interface 10.4.0 no longer hit a TypeLoadException in NativeFileSystemProvider. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_013j5p1tUWLykEtnhAziUkZa --- CLAUDE.md | 16 +++++++++------- Directory.Packages.props | 8 ++++---- GitIntegration/GitIntegration.csproj | 6 +++--- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 316fb9e..6a40e2f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -98,7 +98,7 @@ Octokit, and Azure DevOps, over a raw `HttpClient`). The solution uses: `GitCloneBuilder` uses for its advisory destination pre-check (`Directory.Exists`, `Directory.GetFileSystemEntries`); discovery itself needs none, since `git rev-parse --show-toplevel` does its own upward walk. -- `Testably.Abstractions.FileSystem.Interface` (`PrivateAssets="all"`, `VersionOverride="10.0.0"`) — +- `Testably.Abstractions.FileSystem.Interface` (`PrivateAssets="all"`, `VersionOverride="10.4.0"`) — see the KTSU0006 note below. - `ktsu.CredentialCache` — resolves hosting-provider credentials from the host's native keyring. - `Octokit` — GitHub API client backing `GitHubProvider`. @@ -119,12 +119,14 @@ of a transitively-referenced package requiring its own `PackageReference`. That reference must carry **both** `PrivateAssets="all"` (it exists only to satisfy the analyzer, not as part of this library's public surface) **and** a `VersionOverride` pinning it to the lowest -version any consumer could resolve — here, `10.0.0`, because `ktsu.Essentials` 2.0.0's own nuspec -pins that version, while the repo-wide central-package-management version floats higher (`10.3.0`). -Without the override, the library compiles against the higher version, but a consumer resolves -whatever `ktsu.Essentials` itself pins — the lower one. CoreCLR rolls assembly binds forward but -never backward, so a compiled reference to a higher version than what's actually present throws -`FileNotFoundException` for every consumer at runtime. This is invisible in the package's own build +version any consumer could resolve — here, `10.4.0`, because `ktsu.Essentials` 2.10.7's own nuspec +pins that version. The repo-wide central-package-management version is currently the same +(`10.4.0`), but it is free to float higher, and the override keeps it from taking the compiled +reference with it. Without the override, a higher central version means the library compiles +against that higher version, but a consumer resolves whatever `ktsu.Essentials` itself pins — the +lower one. CoreCLR rolls assembly binds forward but never backward, so a compiled reference to a +higher version than what's actually present throws `FileNotFoundException` for every consumer at +runtime. This is invisible in the package's own build and even in its nuspec; it only surfaces when something actually consumes the packed artifact. **Verifying the nuspec is not sufficient.** Any future `PackageReference` added solely to satisfy an analyzer needs this same treatment, not just this one. diff --git a/Directory.Packages.props b/Directory.Packages.props index 1169db7..65606fe 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -5,8 +5,8 @@ - - + + @@ -20,7 +20,7 @@ - - + + diff --git a/GitIntegration/GitIntegration.csproj b/GitIntegration/GitIntegration.csproj index 94dc3f1..8c6457f 100644 --- a/GitIntegration/GitIntegration.csproj +++ b/GitIntegration/GitIntegration.csproj @@ -60,12 +60,12 @@ .Interface. GitCloneBuilder's destination pre-check calls members declared on that base interface (Directory.Exists, Directory.GetFileSystemEntries), which the KTSU0006 analyzer treats as direct use of a transitively-referenced package requiring its own reference. - VersionOverride pins this reference to 10.0.0 rather than letting central transitive pinning - apply the repo-wide 10.3.0: ktsu.Essentials 2.0.0's own nuspec pins 10.0.0, and CoreCLR only + VersionOverride pins this reference to 10.4.0 rather than letting central transitive pinning + apply the repo-wide version: ktsu.Essentials 2.10.7's own nuspec pins 10.4.0, and CoreCLR only rolls assembly binds forward, never backward. A consumer resolves whichever version ktsu.Essentials pins, so this library must compile against the lowest version any consumer could resolve — a higher reference here cannot bind against a lower assembly at runtime and would throw FileNotFoundException for every consumer. --> - + From f69f40363b89adc56fc011d7eb99c6ec6a14aabc Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 13:48:47 +0000 Subject: [PATCH 2/2] [patch] Forward IFileSystem.RandomAccess in the test filesystem provider Testably.Abstractions 10.4.0 adds IFileSystem.RandomAccess, so the test project's FakeFileSystemProvider has to forward it to its MockFileSystem. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_013j5p1tUWLykEtnhAziUkZa --- GitIntegration.Test/Fakes/FakeFileSystemProvider.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GitIntegration.Test/Fakes/FakeFileSystemProvider.cs b/GitIntegration.Test/Fakes/FakeFileSystemProvider.cs index e3427f8..39ee871 100644 --- a/GitIntegration.Test/Fakes/FakeFileSystemProvider.cs +++ b/GitIntegration.Test/Fakes/FakeFileSystemProvider.cs @@ -37,4 +37,6 @@ internal sealed class FakeFileSystemProvider(MockFileSystem inner) : IFileSystem public IFileVersionInfoFactory FileVersionInfo => inner.FileVersionInfo; public IPath Path => inner.Path; + + public IRandomAccess RandomAccess => inner.RandomAccess; }