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
4 changes: 2 additions & 2 deletions .github/skills/multithreaded-task-migration/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ b. Implement `IMultiThreadableTask` **only if** the task needs `TaskEnvironment`
[MSBuildMultiThreadableTask]
public class MyTask : Task, IMultiThreadableTask
{
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;
...
}
```
Expand Down Expand Up @@ -276,7 +276,7 @@ Assertions: Execute() return value, [Output] exact string, error message content
## Sign-Off Checklist

- [ ] `[MSBuildMultiThreadableTask]` on every concrete class (not just base — `Inherited=false`)
- [ ] `IMultiThreadableTask` on classes that use `TaskEnvironment` APIs, with default initializer `= new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance)`
- [ ] `IMultiThreadableTask` on classes that use `TaskEnvironment` APIs, with default initializer `= TaskEnvironment.Fallback`
- [ ] Every `[Output]` property: exact string value matches pre-migration
- [ ] Every `Log.LogError`/`LogWarning`: path in message matches pre-migration (use `OriginalValue`)
- [ ] Every `GetAbsolutePath` call: null/empty exception behavior matches old code path
Expand Down
2 changes: 1 addition & 1 deletion documentation/specs/multithreading/thread-safe-tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Similar to how MSBuild provides the abstract `Task` class with default implement
namespace Microsoft.Build.Utilities;
public abstract class MultiThreadableTask : Task, IMultiThreadableTask
{
public TaskEnvironment TaskEnvironment{ get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;
}
```

Expand Down
9 changes: 4 additions & 5 deletions src/Build.UnitTests/BackEnd/TaskEnvironment_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ private static TaskEnvironment CreateTaskEnvironment(string environmentType)
{
return environmentType switch
{
StubEnvironmentName => TaskEnvironmentHelper.CreateForTest(),
MultithreadedEnvironmentName => new TaskEnvironment(new MultiThreadedTaskEnvironmentDriver(GetResolvedTempPath())),
StubEnvironmentName => TaskEnvironment.Fallback,
MultithreadedEnvironmentName => TaskEnvironment.CreateWithProjectDirectoryAndEnvironment(GetResolvedTempPath()),
_ => throw new ArgumentException($"Unknown environment type: {environmentType}")
};
}
Expand Down Expand Up @@ -306,7 +306,7 @@ public void TaskEnvironment_StubEnvironment_ShouldAffectSystemEnvironment()
string testVarName = $"MSBUILD_STUB_ISOLATION_TEST_{Guid.NewGuid():N}";
string testVarValue = "stub_test_value";

var stubEnvironment = TaskEnvironmentHelper.CreateForTest();
var stubEnvironment = TaskEnvironment.Fallback;

try
{
Expand Down Expand Up @@ -336,10 +336,9 @@ public void TaskEnvironment_MultithreadedEnvironment_ShouldBeIsolatedFromSystem(
string testVarName = $"MSBUILD_MULTITHREADED_ISOLATION_TEST_{Guid.NewGuid():N}";
string testVarValue = "multithreaded_test_value";

using var driver = new MultiThreadedTaskEnvironmentDriver(
var multithreadedEnvironment = TaskEnvironment.CreateWithProjectDirectoryAndEnvironment(
GetResolvedTempPath(),
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase));
var multithreadedEnvironment = new TaskEnvironment(driver);

try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,11 +394,11 @@ public void SubmitBuildRequest(BuildRequest request)
{
string projectDirectoryFullPath = Path.GetDirectoryName(config.ProjectFullPath);
var environmentVariables = new Dictionary<string, string>(_componentHost.BuildParameters.BuildProcessEnvironmentInternal);
taskEnvironment = new TaskEnvironment(new MultiThreadedTaskEnvironmentDriver(projectDirectoryFullPath, environmentVariables));
taskEnvironment = TaskEnvironment.CreateWithProjectDirectoryAndEnvironment(projectDirectoryFullPath, environmentVariables);
}
else
{
taskEnvironment = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
taskEnvironment = TaskEnvironment.Fallback;
}

BuildRequestEntry entry = new BuildRequestEntry(request, config, taskEnvironment);
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/AssignTargetPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class AssignTargetPath : TaskExtension, IMultiThreadableTask
/// <summary>
/// Gets or sets the task execution environment for thread-safe path resolution.
/// </summary>
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;


/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/Copy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public Copy()
public bool FailIfNotIncremental { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

#endregion

Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/Delete.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public ITaskItem[] Files
public bool FailIfNotIncremental { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// Verify that the inputs are correct.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/DownloadFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public sealed class DownloadFile : TaskExtension, ICancelableTask, IIncrementalT
public bool FailIfNotIncremental { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// Gets or sets a <see cref="HttpMessageHandler"/> to use. This is used by unit tests to mock a connection to a remote server.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/FileIO/GetFileHash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ internal static readonly Dictionary<string, Func<HashAlgorithm>> SupportedAlgori
public ITaskItem[] Items { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

public override bool Execute()
{
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/FileIO/ReadLinesFromFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class ReadLinesFromFile : TaskExtension, IMultiThreadableTask
public ITaskItem File { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// Receives lines from file.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/FileIO/VerifyFileHash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Microsoft.Build.Tasks
public sealed class VerifyFileHash : TaskExtension, ICancelableTask, IMultiThreadableTask
{
/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// The file path.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/FileIO/WriteLinesToFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public class WriteLinesToFile : TaskExtension, IIncrementalTask, IMultiThreadabl
private static readonly Encoding s_defaultEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// File to write lines to.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/ListOperators/FindUnderPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class FindUnderPath : TaskExtension, IMultiThreadableTask
/// <summary>
/// Gets or sets the task execution environment for thread-safe path resolution.
/// </summary>
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// Filter based on whether items fall under this path or not.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/MakeDir.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public ITaskItem[] Directories
public bool FailIfNotIncremental { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

private ITaskItem[] _directories;

Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/Move.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public class Move : TaskExtension, ICancelableTask, IIncrementalTask, IMultiThre
public bool FailIfNotIncremental { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// Stop and return (in an undefined state) as soon as possible.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/RemoveDir.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class RemoveDir : TaskExtension, IIncrementalTask, IMultiThreadableTask
private ITaskItem[] _directories;

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

[Required]
public ITaskItem[] Directories
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/Touch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class Touch : TaskExtension, IIncrementalTask, IMultiThreadableTask
public ITaskItem[] TouchedFiles { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// Importance: high, normal, low (default normal)
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/Unzip.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public sealed class Unzip : TaskExtension, ICancelableTask, IIncrementalTask, IM
public bool FailIfNotIncremental { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <inheritdoc cref="ICancelableTask.Cancel"/>
public void Cancel()
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/WriteCodeFragment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace Microsoft.Build.Tasks
public class WriteCodeFragment : TaskExtension, IMultiThreadableTask
{
/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;
private const string TypeNameSuffix = "_TypeName";
private const string IsLiteralSuffix = "_IsLiteral";
private static readonly string[] NamespaceImports = ["System", "System.Reflection"];
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/XmlPeek.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class XmlPeek : TaskExtension, IMultiThreadableTask
#region Properties

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// The XPath Query.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/XmlPoke.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class XmlPoke : TaskExtension, IMultiThreadableTask
#region Properties

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// The XML input as file path.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/XslTransformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class XslTransformation : TaskExtension, IMultiThreadableTask
#region Members

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

/// <summary>
/// The output files.
Expand Down
2 changes: 1 addition & 1 deletion src/Tasks/ZipDirectory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public sealed class ZipDirectory : TaskExtension, IIncrementalTask, IMultiThread
public string? CompressionLevel { get; set; }

/// <inheritdoc />
public TaskEnvironment TaskEnvironment { get; set; } = new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
public TaskEnvironment TaskEnvironment { get; set; } = TaskEnvironment.Fallback;

public override bool Execute()
{
Expand Down
2 changes: 1 addition & 1 deletion src/UnitTests.Shared/TaskEnvironmentHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static class TaskEnvironmentHelper
/// <returns>A TaskEnvironment suitable for use in tests.</returns>
public static TaskEnvironment CreateForTest()
{
return new TaskEnvironment(MultiProcessTaskEnvironmentDriver.Instance);
return TaskEnvironment.Fallback;
}
}
}