Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand All @@ -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.
Expand Down
8 changes: 4 additions & 4 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="ktsu.CredentialCache" Version="1.3.21" />
<PackageVersion Include="ktsu.Essentials" Version="2.0.0" />
<PackageVersion Include="ktsu.Essentials.FileSystemProviders.Native" Version="2.0.0" />
<PackageVersion Include="ktsu.Essentials" Version="2.10.7" />
<PackageVersion Include="ktsu.Essentials.FileSystemProviders.Native" Version="2.10.7" />
<PackageVersion Include="ktsu.RunCommand" Version="1.9.5" />
<PackageVersion Include="ktsu.Semantics.Paths" Version="5.11.2" />
<PackageVersion Include="ktsu.Semantics.Strings" Version="5.11.2" />
Expand All @@ -20,7 +20,7 @@
<PackageVersion Include="Microsoft.Testing.Extensions.HangDump" Version="1.7.2" />
<PackageVersion Include="Microsoft.Testing.Extensions.HotReload" Version="1.7.2" />
<PackageVersion Include="Microsoft.Testing.Extensions.Retry" Version="1.7.2" />
<PackageVersion Include="Testably.Abstractions.FileSystem.Interface" Version="10.3.0" />
<PackageVersion Include="Testably.Abstractions.Testing" Version="7.0.2" />
<PackageVersion Include="Testably.Abstractions.FileSystem.Interface" Version="10.4.0" />
<PackageVersion Include="Testably.Abstractions.Testing" Version="7.1.1" />
</ItemGroup>
</Project>
2 changes: 2 additions & 0 deletions GitIntegration.Test/Fakes/FakeFileSystemProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
6 changes: 3 additions & 3 deletions GitIntegration/GitIntegration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -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. -->
<PackageReference Include="Testably.Abstractions.FileSystem.Interface" VersionOverride="10.0.0" PrivateAssets="all" />
<PackageReference Include="Testably.Abstractions.FileSystem.Interface" VersionOverride="10.4.0" PrivateAssets="all" />
</ItemGroup>
</Project>
Loading