Skip to content

Migrate GetReferenceAssemblyPaths task to TaskEnvironment API#13495

Open
OvesN wants to merge 1 commit intodotnet:mainfrom
OvesN:dev/veronikao/dev/veronikao/migrate-GetReferenceAssemblyPaths-task-to-Task-Environment-API
Open

Migrate GetReferenceAssemblyPaths task to TaskEnvironment API#13495
OvesN wants to merge 1 commit intodotnet:mainfrom
OvesN:dev/veronikao/dev/veronikao/migrate-GetReferenceAssemblyPaths-task-to-Task-Environment-API

Conversation

@OvesN
Copy link
Copy Markdown
Contributor

@OvesN OvesN commented Apr 7, 2026

Fixes #13494

Context

The GetReferenceAssemblyPaths task was made thread-safe for multithreaded MSBuild execution.

Changes Made

GetReferenceAssemblyPaths.cs

  • Replaced static bool? s_net35SP1SentinelAssemblyFound with static readonly Lazy<bool> using LazyThreadSafetyMode.PublicationOnly to ensure thread-safe initialization while preserving retry-on-failure behavior.
  • Routed path resolution through TaskEnvironment.GetAbsolutePath().

Testing

GetReferencePaths_Tests.cs

  • TestRelativeRootPathProducesSameResultAsAbsolute — runs the task twice (once with an absolute RootPath, once with a relative RootPath resolved via TaskEnvironment) and asserts identical output, validating that the TaskEnvironment.GetAbsolutePath() integration preserves behavior.
  • TestRelativeFallbackSearchPathProducesSameResultAsAbsolute — same pattern for TargetFrameworkFallbackSearchPaths: verifies a relative fallback path resolved via TaskEnvironment produces the same result as the equivalent absolute path.

@OvesN OvesN self-assigned this Apr 7, 2026
Copilot AI review requested due to automatic review settings April 7, 2026 08:27
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates the built-in GetReferenceAssemblyPaths task to the TaskEnvironment API to support correct path resolution under multithreaded MSBuild execution, and updates internal caching to be thread-safe.

Changes:

  • Mark GetReferenceAssemblyPaths as multithreadable and route relative path resolution through TaskEnvironment.GetAbsolutePath.
  • Replace a non-thread-safe static cache (bool?) with a thread-safe Lazy<bool> for the .NET 3.5 SP1 sentinel GAC lookup.
  • Add unit tests validating relative vs absolute behavior for RootPath and TargetFrameworkFallbackSearchPaths.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/Tasks/GetReferenceAssemblyPaths.cs Adds TaskEnvironment integration, multithreadable task surface, and thread-safe sentinel caching.
src/Tasks.UnitTests/GetReferencePaths_Tests.cs Adds regressions to ensure relative inputs resolved via TaskEnvironment match absolute-input behavior.

Comment on lines +168 to +172
AbsolutePath? absoluteRootPath = !string.IsNullOrEmpty(RootPath)
? TaskEnvironment.GetAbsolutePath(RootPath)
: new AbsolutePath(RootPath, ignoreRootedCheck: true);
IList<AbsolutePath> absoluteFallbackSearchPaths = ResolveAbsoluteFallbackSearchPaths(TargetFrameworkFallbackSearchPaths);

Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

Resolving RootPath/TargetFrameworkFallbackSearchPaths through TaskEnvironment.GetAbsolutePath(...) changes observable behavior when callers pass relative paths: ReferenceAssemblyPaths will now be absolute, whereas ToolLocationHelper.GetPathToReferenceAssemblies previously returned paths rooted in the original (possibly relative) inputs. For built-in tasks, this kind of behavior change should be gated behind a ChangeWave, or otherwise preserve legacy behavior when relative inputs are provided (while still fixing multithreaded correctness).

Copilot uses AI. Check for mistakes.
Comment on lines +336 to +340
public void TestRelativeRootPathProducesSameResultAsAbsolute()
{
using (var env = TestEnvironment.Create())
{
string baseDir = env.DefaultTestDirectory.Path;
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

Test convention: new tests should inject ITestOutputHelper (store as _output) and create the environment via TestEnvironment.Create(_output) so diagnostic output is captured in CI. Also prefer Shouldly assertions over adding new xUnit Assert calls in modified code.

Copilot uses AI. Check for mistakes.
Comment on lines +378 to +382
public void TestRelativeFallbackSearchPathProducesSameResultAsAbsolute()
{
using (var env = TestEnvironment.Create())
{
string baseDir = env.DefaultTestDirectory.Path;
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

Test convention: prefer using TestEnvironment env = TestEnvironment.Create(_output); (using-declaration, no braces) to align with repo patterns and ensure output capture. New assertions in this test should also use Shouldly rather than adding more xUnit Assert calls.

Copilot uses AI. Check for mistakes.
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.

Migrate GetReferenceAssemblyPaths to TaskEnvironment API

2 participants