Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
62f712a
Initial plan
Copilot Jul 20, 2026
695b6fa
Add TarDirectory task, registration, and resources
Copilot Jul 20, 2026
c0998f2
Add TarDirectory tests and docs; verified end-to-end
Copilot Jul 20, 2026
d769dc6
Address code review: remove redundant null-forgiving op and fix doc g…
Copilot Jul 20, 2026
6ba6a02
Error on unrecognized TarDirectory Compression instead of falling back
Copilot Jul 20, 2026
4835444
Add optional Format parameter to TarDirectory (Pax/Gnu/Ustar/V7)
Copilot Jul 20, 2026
e804b4a
Address review: rename recursive entry variable and avoid array alloc…
Copilot Jul 20, 2026
ae91e65
Simplify recursive foreach tuple deconstruction in TarDirectory
Copilot Jul 20, 2026
a89e30a
Update TFM to net11.0 and update accompanying files
ViktorHofer Jul 20, 2026
fa7d097
Try to fix build and template_feed style fixes
ViktorHofer Jul 20, 2026
e3e476d
Fix terminal logger tests
ViktorHofer Jul 20, 2026
4aa4918
Use a distinct stage2 binlog name to avoid collision with stage1
ViktorHofer Jul 20, 2026
d0c8407
Publish stage1 binlog alongside stage2 binlog in multi-stage builds
ViktorHofer Jul 20, 2026
81ffe89
Copy entire stage1 log folder back so CI publishes all stage1 logs
ViktorHofer Jul 20, 2026
81cfb85
Fix torn NuGet state in netcore bootstrap by not overlaying package N…
ViktorHofer Jul 20, 2026
82da8e8
Potential fix for pull request finding
ViktorHofer Jul 20, 2026
8a4f6aa
Potential fix for pull request finding
ViktorHofer Jul 20, 2026
0826b41
Update cts ymls
ViktorHofer Jul 20, 2026
81489a3
Merge net11.0 (#14455) to enable new BCL tar/compression APIs
Copilot Jul 20, 2026
2cf0cdc
Modernize TarDirectory with .NET 11 APIs and add ZStandard compression
Copilot Jul 20, 2026
6b0ebf0
Use scoped using declaration for compression stream disposal
Copilot Jul 20, 2026
56c9290
Merge branch 'main' into copilot/create-tar-files-task
ViktorHofer Jul 21, 2026
d6d155d
Inline TryParseFormat helper into its call site in TarDirectory
Copilot Jul 21, 2026
9078ac8
Remove redundant Compression* const fields in favor of TarCompression…
Copilot Jul 21, 2026
e23164c
Merge branch 'main' into copilot/create-tar-files-task
ViktorHofer Jul 21, 2026
640ca3d
Add Untar task mirroring Unzip for extracting tar archives
Copilot Jul 21, 2026
bc12d42
Convert TarDirectory to typed task-parameter binding
Copilot Jul 21, 2026
b0c19c1
Fix CI build failure: remove unused _enumOutput field (IDE0052)
Copilot Jul 22, 2026
902c727
Convert Untar to typed task-parameter binding
baronfel Jul 27, 2026
f15b146
Push BuildEngine3.Yield() past precondition checks in TarDirectory
baronfel Jul 27, 2026
b463549
Use FileInfo.OpenRead() to open source tar in Untar
baronfel Jul 27, 2026
5f30643
Use FileInfo.OpenWrite() to open the destination tar in TarDirectory
baronfel Jul 27, 2026
f3ff1b2
Rewrite TarDirectory to a sorted TarWriter loop for deterministic ord…
baronfel Jul 27, 2026
ae0c30f
Add DeterministicTimestamp parameter to TarDirectory
baronfel Jul 27, 2026
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
3 changes: 3 additions & 0 deletions documentation/specs/question.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ Error when SkipUnchangedFiles is true.
`ZipDirectory`
Error if the destination zip file doesn't exists.

`TarDirectory`
Error if the destination tar file doesn't exist.
Comment on lines +81 to +82

## Common Error

- **Typographical error**. Spelling, casing, or incorrect path. Check if the target inputs and outputs real files.
Expand Down
21 changes: 21 additions & 0 deletions src/Build.UnitTests/BackEnd/TaskBuilderTestTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,16 @@ public CustomStruct(IConvertible value)
/// </summary>
internal static readonly CustomStruct[] s_customStructArray = new CustomStruct[] { new CustomStruct(43), new CustomStruct(44) };

/// <summary>
/// An enum used to validate engine-level binding of string values to enum task parameters.
/// </summary>
public enum TestTaskEnum
{
None,
First,
Second,
}

/// <summary>
/// The task host.
/// </summary>
Expand Down Expand Up @@ -701,6 +711,17 @@ public AbsolutePath AbsolutePathParam
}
}

/// <summary>
/// An enum parameter, used to validate engine-level binding of string values to enum task parameters.
/// </summary>
public TestTaskEnum EnumParam
{
set
{
_testTaskHost?.ParameterSet("EnumParam", value);
}
}

/// <summary>
/// An AbsolutePath array parameter.
/// </summary>
Expand Down
43 changes: 43 additions & 0 deletions src/Build.UnitTests/BackEnd/TaskExecutionHost_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,49 @@ public void TestSetTaskItemIntArrayParamEmptyItem()

#endregion

#region Enum Params

/// <summary>
/// Validate that setting an enum parameter binds the string value (case-insensitively) to the enum member.
/// </summary>
[Fact]
public void TestSetEnumParam()
{
ValidateTaskParameter("EnumParam", "Second", TaskBuilderTestTask.TestTaskEnum.Second);
}

/// <summary>
/// Validate that enum binding is case-insensitive.
/// </summary>
[Fact]
public void TestSetEnumParamCaseInsensitive()
{
ValidateTaskParameter("EnumParam", "first", TaskBuilderTestTask.TestTaskEnum.First);
}

/// <summary>
/// Validate that setting the parameter with an empty value does not cause it to be set.
/// </summary>
[Fact]
public void TestSetEnumParamEmptyAttribute()
{
ValidateTaskParameterNotSet("EnumParam", "");
}

/// <summary>
/// Validate that setting an enum parameter to a value that does not map to a defined member is an error.
/// </summary>
[Fact]
public void TestSetEnumParamInvalidValue()
{
var parameters = GetStandardParametersDictionary(true);
parameters["EnumParam"] = ("NotADefinedValue", ElementLocation.Create("foo.proj"));

Should.Throw<InvalidProjectFileException>(() => _host.SetTaskParameters(parameters));
}

#endregion

#region FileInfo Params

/// <summary>
Expand Down
13 changes: 13 additions & 0 deletions src/Framework/ValueTypeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,19 @@ public static object Parse(string value, Type targetType)
return value;
}

// Enums bind by their (case-insensitive) member name, and values that do not map to a
// defined member are rejected so the engine surfaces a clear parameter-binding error.
if (targetType.IsEnum)
{
object result = Enum.Parse(targetType, value, ignoreCase: true);
if (!Enum.IsDefined(targetType, result))
{
throw new ArgumentException($"'{value}' is not a defined value of enum type {targetType.Name}.", nameof(value));
}

return result;
}
Comment on lines +97 to +108

// Everything else (numeric types, char, etc.) is converted via Convert.ChangeType, pinned
// to InvariantCulture. This is deliberately permissive: a future analyzer is expected to
// steer authors toward the first-class supported types above and away from relying on this
Expand Down
Loading
Loading