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
93 changes: 93 additions & 0 deletions src/Build.UnitTests/BuildEventArgsSerialization_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using FluentAssertions;
using Microsoft.Build.BackEnd;
Expand Down Expand Up @@ -875,6 +876,98 @@ public void RoundtripTaskParameterEventArgs()
e => TranslationHelpers.GetItemsString(e.Items));
}

[Fact]
public void AbsolutePathTaskParameterTextUsesOriginalValue()
{
var basePath = new AbsolutePath(Path.GetFullPath("."));
var path = new AbsolutePath("input.txt", basePath);

ItemGroupLoggingHelper.GetStringFromParameterValue(path).ShouldBe("input.txt");
}

[Fact]
public void TaskParameterEventForwardingPreservesAbsolutePathOriginalValue()
{
TaskParameterEventArgs args = CreateAbsolutePathTaskParameterEventArgs();
var memoryStream = new MemoryStream();
using (var binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8, leaveOpen: true))
{
args.WriteToStream(binaryWriter);
}

memoryStream.Position = 0;
#pragma warning disable SYSLIB0050 // Required to exercise the legacy event forwarding deserializer.
var forwardedArgs = (TaskParameterEventArgs)FormatterServices.GetUninitializedObject(typeof(TaskParameterEventArgs));
#pragma warning restore SYSLIB0050
using (var binaryReader = new BinaryReader(memoryStream, Encoding.UTF8, leaveOpen: true))
{
forwardedArgs.CreateFromStream(binaryReader, version: 0);
}

forwardedArgs.Items.Count.ShouldBe(1);
((ITaskItem)forwardedArgs.Items[0]).ItemSpec.ShouldBe("input.txt");
}

[Fact]
public void BinaryLogSerializationPreservesAbsolutePathOriginalValue()
{
TaskParameterEventArgs args = CreateAbsolutePathTaskParameterEventArgs();
var memoryStream = new MemoryStream();
using (var binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8, leaveOpen: true))
{
new BuildEventArgsWriter(binaryWriter).Write(args);
}

memoryStream.Position = 0;
using var reader = new BinaryReader(memoryStream, Encoding.UTF8, leaveOpen: true);
using var eventArgsReader = new BuildEventArgsReader(reader, BinaryLogger.FileFormatVersion);
var replayedArgs = (TaskParameterEventArgs)eventArgsReader.Read();

replayedArgs.Items.Count.ShouldBe(1);
((ITaskItem)replayedArgs.Items[0]).ItemSpec.ShouldBe("input.txt");
replayedArgs.Message.ShouldContain("input.txt");
replayedArgs.Message.ShouldNotContain(Path.GetFullPath("input.txt"));
}

[Fact]
public void BinaryLogSerializationWritesEmptyItemSpecForDefaultAbsolutePath()
{
var args = new TaskParameterEventArgs(
TaskParameterMessageKind.TaskInput,
"File",
propertyName: null,
"File",
new object[] { default(AbsolutePath) },
logItemMetadata: false,
DateTime.MinValue);
var memoryStream = new MemoryStream();
using (var binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8, leaveOpen: true))
{
new BuildEventArgsWriter(binaryWriter).Write(args);
}

memoryStream.Position = 0;
using var reader = new BinaryReader(memoryStream, Encoding.UTF8, leaveOpen: true);
using var eventArgsReader = new BuildEventArgsReader(reader, BinaryLogger.FileFormatVersion);
var replayedArgs = (TaskParameterEventArgs)eventArgsReader.Read();

replayedArgs.Items.Count.ShouldBe(1);
((ITaskItem)replayedArgs.Items[0]).ItemSpec.ShouldBe(string.Empty);
}

private static TaskParameterEventArgs CreateAbsolutePathTaskParameterEventArgs()
{
var basePath = new AbsolutePath(Path.GetFullPath("."));
return new TaskParameterEventArgs(
TaskParameterMessageKind.TaskInput,
"File",
propertyName: null,
"File",
new object[] { new AbsolutePath("input.txt", basePath) },
logItemMetadata: false,
DateTime.MinValue);
}

[Fact]
public void RoundtripProjectEvaluationStartedEventArgs()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,14 @@ private static void AppendStringFromParameterValue(ReuseableStringBuilder sb, ob
keyValuePairList.Clear();
}
}
else if (parameterValue is AbsolutePath absolutePath)
{
sb.Append(absolutePath.OriginalValue);
}
else if (TaskItemTypeDetector.IsSupportedPathType(parameterValue.GetType()))
{
sb.Append(ValueTypeParser.ToString(parameterValue));
}
Comment thread
OvesN marked this conversation as resolved.
else if (parameterValue.GetType().IsValueType)
{
sb.Append((string)Convert.ChangeType(parameterValue, typeof(string), CultureInfo.CurrentCulture));
Expand Down
5 changes: 5 additions & 0 deletions src/Build/Logging/BinaryLogger/BuildEventArgsWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -987,6 +987,11 @@ private void WriteTaskItemList(IEnumerable items, bool writeMetadata = true)
Write((byte)0);
}
}
else if (item is AbsolutePath absolutePath)
{
WriteDeduplicatedString(absolutePath.OriginalValue ?? string.Empty);
Write(0);
}
else
{
WriteDeduplicatedString(item?.ToString() ?? ""); // itemspec
Expand Down
11 changes: 9 additions & 2 deletions src/Framework/TaskItem_T.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,15 @@ public TaskItem(ITaskItem item)
/// <summary>Returns the FullPath metadata value if non-empty, otherwise falls back to itemSpec.</summary>
private static string GetFullPathOrItemSpec(ITaskItem item, string itemSpec)
{
string fullPath = item.GetMetadata("FullPath");
return !string.IsNullOrEmpty(fullPath) ? fullPath : itemSpec;
try
{
string fullPath = item.GetMetadata("FullPath");
return !string.IsNullOrEmpty(fullPath) ? fullPath : itemSpec;
}
catch (InvalidOperationException ex)
{
throw new ArgumentException($"Cannot create TaskItem<{typeof(T).Name}> from the provided item.", nameof(item), ex);
}
}

/// <summary>
Expand Down
5 changes: 5 additions & 0 deletions src/Framework/TaskParameterEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ private void WriteItem(BinaryWriter writer, object item)
writer.Write7BitEncodedInt(0);
}
}
else if (item is AbsolutePath absolutePath)
{
writer.Write(absolutePath.OriginalValue ?? string.Empty);
writer.Write7BitEncodedInt(0);
}
else // string or ValueType
{
writer.Write(item?.ToString() ?? "");
Expand Down
8 changes: 8 additions & 0 deletions src/Utilities.UnitTests/TaskItem_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,14 @@ public void FromITaskItem_PathLikeType_UsesFullPathMetadata()
item.Value.FullName.ShouldBe(expectedAbsolutePath);
}

[Fact]
public void FromITaskItem_InvalidPath_ThrowsArgumentException()
{
var backingItem = new TaskItem("bad\0path");

Should.Throw<ArgumentException>(() => new TaskItem<AbsolutePath>(backingItem));
}

[Fact]
public void FromITaskItem_NonPathType_UsesItemSpec()
{
Expand Down