From 5722a48b2bc8a10fc6453ac84a0ab4b4618c4175 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 01:02:33 +0000 Subject: [PATCH 1/5] Initial plan From 3cddd9bfca851f198c742a287006fcdab1de4685 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 01:08:00 +0000 Subject: [PATCH 2/5] Replace numeric requirement IDs with descriptive string IDs Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com> --- requirements.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/requirements.yaml b/requirements.yaml index a5a4db7..ffddb5c 100644 --- a/requirements.yaml +++ b/requirements.yaml @@ -16,7 +16,7 @@ sections: sections: - title: Library API requirements: - - id: CACH-LIB-001 + - id: CACH-Lib-EnsureCached title: The library shall provide a method to ensure a NuGet package is cached locally on the PC. justification: | Provides the core caching functionality of the library, allowing callers to ensure @@ -26,7 +26,7 @@ sections: - title: Platform Support requirements: - - id: CACH-PLT-001 + - id: CACH-Platform-Windows title: The library shall build and run on Windows platforms. justification: | DEMA Consulting libraries must support Windows as a major development platform. @@ -34,7 +34,7 @@ sections: # Tests link to "windows" to ensure results come from Windows platform - "windows@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-PLT-002 + - id: CACH-Platform-Linux title: The library shall build and run on Linux platforms. justification: | DEMA Consulting libraries must support Linux for CI/CD and containerized environments. @@ -42,7 +42,7 @@ sections: # Tests link to "ubuntu" to ensure results come from Linux platform - "ubuntu@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-PLT-007 + - id: CACH-Platform-MacOS title: The library shall build and run on macOS platforms. justification: | DEMA Consulting libraries must support macOS for developers using Apple platforms. @@ -50,28 +50,28 @@ sections: # Tests link to "macos" to ensure results come from macOS platform - "macos@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-PLT-003 + - id: CACH-Platform-Net8 title: The library shall support .NET 8 runtime. justification: | .NET 8 is an LTS release providing long-term stability for enterprise users. tests: - "net8.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-PLT-004 + - id: CACH-Platform-Net9 title: The library shall support .NET 9 runtime. justification: | .NET 9 support enables users to leverage the latest .NET features. tests: - "net9.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-PLT-005 + - id: CACH-Platform-Net10 title: The library shall support .NET 10 runtime. justification: | .NET 10 support ensures the library remains compatible with the latest .NET ecosystem. tests: - "net10.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-PLT-006 + - id: CACH-Platform-NetStd20 title: The library shall support .NET Standard 2.0, verified on .NET Framework 4.8.1 on Windows. justification: | .NET Standard 2.0 support ensures the library can be consumed by projects targeting From a80c6f0ba0c9846329425127e4638a772a03ebfd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 01:11:27 +0000 Subject: [PATCH 3/5] Rename requirement IDs: CACH- to Caching-, Platform to PLT Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com> --- requirements.yaml | 28 +++++++++---------- .../NuGetCacheTests.cs | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/requirements.yaml b/requirements.yaml index ffddb5c..07cefb0 100644 --- a/requirements.yaml +++ b/requirements.yaml @@ -16,7 +16,7 @@ sections: sections: - title: Library API requirements: - - id: CACH-Lib-EnsureCached + - id: Caching-Lib-EnsureCached title: The library shall provide a method to ensure a NuGet package is cached locally on the PC. justification: | Provides the core caching functionality of the library, allowing callers to ensure @@ -26,7 +26,7 @@ sections: - title: Platform Support requirements: - - id: CACH-Platform-Windows + - id: Caching-PLT-Windows title: The library shall build and run on Windows platforms. justification: | DEMA Consulting libraries must support Windows as a major development platform. @@ -34,7 +34,7 @@ sections: # Tests link to "windows" to ensure results come from Windows platform - "windows@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-Platform-Linux + - id: Caching-PLT-Linux title: The library shall build and run on Linux platforms. justification: | DEMA Consulting libraries must support Linux for CI/CD and containerized environments. @@ -42,7 +42,7 @@ sections: # Tests link to "ubuntu" to ensure results come from Linux platform - "ubuntu@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-Platform-MacOS + - id: Caching-PLT-MacOS title: The library shall build and run on macOS platforms. justification: | DEMA Consulting libraries must support macOS for developers using Apple platforms. @@ -50,28 +50,28 @@ sections: # Tests link to "macos" to ensure results come from macOS platform - "macos@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-Platform-Net8 + - id: Caching-PLT-Net8 title: The library shall support .NET 8 runtime. justification: | .NET 8 is an LTS release providing long-term stability for enterprise users. tests: - "net8.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-Platform-Net9 + - id: Caching-PLT-Net9 title: The library shall support .NET 9 runtime. justification: | .NET 9 support enables users to leverage the latest .NET features. tests: - "net9.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-Platform-Net10 + - id: Caching-PLT-Net10 title: The library shall support .NET 10 runtime. justification: | .NET 10 support ensures the library remains compatible with the latest .NET ecosystem. tests: - "net10.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder" - - id: CACH-Platform-NetStd20 + - id: Caching-PLT-NetStd20 title: The library shall support .NET Standard 2.0, verified on .NET Framework 4.8.1 on Windows. justification: | .NET Standard 2.0 support ensures the library can be consumed by projects targeting @@ -82,7 +82,7 @@ sections: - title: OTS Software requirements: - - id: CACH-OTS-MSTest + - id: Caching-OTS-MSTest title: MSTest shall execute unit tests and report results. justification: | MSTest (MSTest.TestFramework and MSTest.TestAdapter) is the unit-testing framework used @@ -93,7 +93,7 @@ sections: tests: - NuGetCache_EnsureCachedAsync_ReturnsPackageFolder - - id: CACH-OTS-ReqStream + - id: Caching-OTS-ReqStream title: ReqStream shall enforce that every requirement is linked to passing test evidence. justification: | DemaConsulting.ReqStream processes requirements.yaml and the TRX test-result files to @@ -105,7 +105,7 @@ sections: tests: - ReqStream_EnforcementMode - - id: CACH-OTS-BuildMark + - id: Caching-OTS-BuildMark title: BuildMark shall generate build-notes documentation from GitHub Actions metadata. justification: | DemaConsulting.BuildMark queries the GitHub API to capture workflow run details and @@ -116,7 +116,7 @@ sections: tests: - BuildMark_MarkdownReportGeneration - - id: CACH-OTS-VersionMark + - id: Caching-OTS-VersionMark title: VersionMark shall publish captured tool-version information. justification: | DemaConsulting.VersionMark reads version metadata for each dotnet tool used in the @@ -128,7 +128,7 @@ sections: - VersionMark_CapturesVersions - VersionMark_GeneratesMarkdownReport - - id: CACH-OTS-SarifMark + - id: Caching-OTS-SarifMark title: SarifMark shall convert CodeQL SARIF results into a markdown report. justification: | DemaConsulting.SarifMark reads the SARIF output produced by CodeQL code scanning and @@ -140,7 +140,7 @@ sections: - SarifMark_SarifReading - SarifMark_MarkdownReportGeneration - - id: CACH-OTS-SonarMark + - id: Caching-OTS-SonarMark title: SonarMark shall generate a SonarCloud quality report. justification: | DemaConsulting.SonarMark retrieves quality-gate and metrics data from SonarCloud and diff --git a/test/DemaConsulting.NuGet.Caching.Tests/NuGetCacheTests.cs b/test/DemaConsulting.NuGet.Caching.Tests/NuGetCacheTests.cs index 5f46cfd..1b5abbe 100644 --- a/test/DemaConsulting.NuGet.Caching.Tests/NuGetCacheTests.cs +++ b/test/DemaConsulting.NuGet.Caching.Tests/NuGetCacheTests.cs @@ -36,7 +36,7 @@ public class NuGetCacheTests /// package folder after downloading a known small package from nuget.org. /// /// - /// This test proves CACH-REQ-007: the library can ensure a NuGet package is cached locally. + /// This test proves Caching-Lib-EnsureCached: the library can ensure a NuGet package is cached locally. /// [TestMethod] public async Task NuGetCache_EnsureCachedAsync_ReturnsPackageFolder() From ca29acaf317de4553a70dd1ad36018013074ef16 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 01:29:01 +0000 Subject: [PATCH 4/5] Fix race condition in EnsureCachedAsync: check .nupkg.metadata instead of Directory.Exists Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com> --- src/DemaConsulting.NuGet.Caching/NuGetCache.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/DemaConsulting.NuGet.Caching/NuGetCache.cs b/src/DemaConsulting.NuGet.Caching/NuGetCache.cs index 74157fe..d847798 100644 --- a/src/DemaConsulting.NuGet.Caching/NuGetCache.cs +++ b/src/DemaConsulting.NuGet.Caching/NuGetCache.cs @@ -70,8 +70,11 @@ public static async Task EnsureCachedAsync( // {globalPackagesFolder}/{packageId.lower}/{version.lower}/ var packagePath = GetPackagePath(globalPackagesFolder, packageId, version.ToLowerInvariant()); - // Return immediately when the package is already present - the common hot path - if (Directory.Exists(packagePath)) + // Return immediately when the package is fully installed - the common hot path. + // Checking for the .nupkg.metadata file (written by NuGet as the last extraction step) + // rather than the directory avoids a race condition where concurrent callers see the + // directory before extraction is complete and return a partially-populated path. + if (File.Exists(Path.Combine(packagePath, ".nupkg.metadata"))) { return packagePath; } From 3aec9d42d010ffe55a34e19a7ba7286677e20ac0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Mar 2026 01:32:23 +0000 Subject: [PATCH 5/5] Use PathHelpers.SafePathCombine for .nupkg.metadata check Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com> --- src/DemaConsulting.NuGet.Caching/NuGetCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DemaConsulting.NuGet.Caching/NuGetCache.cs b/src/DemaConsulting.NuGet.Caching/NuGetCache.cs index d847798..f1af0cc 100644 --- a/src/DemaConsulting.NuGet.Caching/NuGetCache.cs +++ b/src/DemaConsulting.NuGet.Caching/NuGetCache.cs @@ -74,7 +74,7 @@ public static async Task EnsureCachedAsync( // Checking for the .nupkg.metadata file (written by NuGet as the last extraction step) // rather than the directory avoids a race condition where concurrent callers see the // directory before extraction is complete and return a partially-populated path. - if (File.Exists(Path.Combine(packagePath, ".nupkg.metadata"))) + if (File.Exists(PathHelpers.SafePathCombine(packagePath, ".nupkg.metadata"))) { return packagePath; }