зеркало из https://github.com/dotnet/msbuild.git
Deprecate binfmt in build event args (#8917)
* Fix to properly serialize TargetFinishedEventArgs.TargetOutput * New extended EventArgs for custom events data * Make ExternalProject*EventArgs serialize without BinaryFormatter * Issue warnings only on dotnetcore runtime. * Make deser constructors internal --------- Co-authored-by: YuliiaKovalova <ykovalova@microsoft.com> Co-authored-by: YuliiaKovalova <95473390+YuliiaKovalova@users.noreply.github.com> Co-authored-by: Ladi Prosek <ladi.prosek@gmail.com>
This commit is contained in:
Родитель
60363d0313
Коммит
f121098b3b
|
@ -13,6 +13,9 @@
|
|||
<PackageVersion Include="BenchmarkDotNet" Version="0.13.1" />
|
||||
<PackageVersion Update="BenchmarkDotNet" Condition="'$(BenchmarkDotNetVersion)' != ''" Version="$(BenchmarkDotNetVersion)" />
|
||||
|
||||
<PackageVersion Include="FluentAssertions" Version="6.11.0" />
|
||||
<PackageVersion Update="FluentAssertions" Condition="'$(FluentAssertionsVersion)' != ''" Version="$(FluentAssertionsVersion)" />
|
||||
|
||||
<PackageVersion Include="LargeAddressAware" Version="1.0.5" />
|
||||
<PackageVersion Update="LargeAddressAware" Condition="'$(LargeAddressAwareVersion)' != ''" Version="$(LargeAddressAwareVersion)" />
|
||||
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Build.BackEnd.Logging;
|
||||
using Microsoft.Build.Evaluation;
|
||||
using Microsoft.Build.Execution;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Shared;
|
||||
using Microsoft.Build.UnitTests;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.NetCore.Extensions;
|
||||
using static Microsoft.Build.UnitTests.ObjectModelHelpers;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Microsoft.Build.Engine.UnitTests.BackEnd
|
||||
{
|
||||
public class BuildManager_Logging_Tests : IDisposable
|
||||
{
|
||||
private string _mainProject = @"
|
||||
<Project>
|
||||
|
||||
<Target Name=`MainTarget`>
|
||||
<MSBuild Projects=`{0}` Targets=`ChildTarget` />
|
||||
</Target>
|
||||
|
||||
</Project>";
|
||||
|
||||
private string _childProjectWithCustomBuildEvent = $@"
|
||||
<Project>
|
||||
|
||||
<UsingTask TaskName=""CustomBuildEventTask"" AssemblyFile=""{Assembly.GetExecutingAssembly().Location}"" />
|
||||
<Target Name=`ChildTarget`>
|
||||
<CustomBuildEventTask />
|
||||
</Target>
|
||||
|
||||
</Project>";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The mock logger for testing.
|
||||
/// </summary>
|
||||
private readonly MockLogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// The standard build manager for each test.
|
||||
/// </summary>
|
||||
private readonly BuildManager _buildManager;
|
||||
|
||||
/// <summary>
|
||||
/// The project collection used.
|
||||
/// </summary>
|
||||
private readonly ProjectCollection _projectCollection;
|
||||
|
||||
private readonly TestEnvironment _env;
|
||||
private readonly ITestOutputHelper _output;
|
||||
|
||||
/// <summary>
|
||||
/// SetUp
|
||||
/// </summary>
|
||||
public BuildManager_Logging_Tests(ITestOutputHelper output)
|
||||
{
|
||||
_output = output;
|
||||
// Ensure that any previous tests which may have been using the default BuildManager do not conflict with us.
|
||||
BuildManager.DefaultBuildManager.Dispose();
|
||||
|
||||
_logger = new MockLogger(output);
|
||||
_buildManager = new BuildManager();
|
||||
_projectCollection = new ProjectCollection();
|
||||
|
||||
_env = TestEnvironment.Create(output);
|
||||
}
|
||||
|
||||
[DotNetOnlyTheory]
|
||||
[InlineData("1", true)]
|
||||
[InlineData("0", false)]
|
||||
[InlineData(null, true)]
|
||||
public void Build_WithCustomBuildArgs_NetCore(string envVariableValue, bool isWarningExpected)
|
||||
=> TestCustomEventWarning<BuildErrorEventArgs>(envVariableValue, isWarningExpected);
|
||||
|
||||
[WindowsFullFrameworkOnlyTheory]
|
||||
[InlineData("1", true)]
|
||||
[InlineData("0", false)]
|
||||
[InlineData(null, false)]
|
||||
public void Build_WithCustomBuildArgs_Framework(string envVariableValue, bool isWarningExpected) =>
|
||||
TestCustomEventWarning<BuildWarningEventArgs>(envVariableValue, isWarningExpected);
|
||||
|
||||
private void TestCustomEventWarning<T>(string envVariableValue, bool isWarningExpected) where T : LazyFormattedBuildEventArgs
|
||||
{
|
||||
var testFiles = _env.CreateTestProjectWithFiles(string.Empty, new[] { "main", "child1" }, string.Empty);
|
||||
|
||||
ILoggingService service = LoggingService.CreateLoggingService(LoggerMode.Synchronous, 1);
|
||||
service.RegisterLogger(_logger);
|
||||
|
||||
_env.SetEnvironmentVariable("MSBUILDCUSTOMBUILDEVENTWARNING", envVariableValue);
|
||||
_env.SetEnvironmentVariable("MSBUILDNOINPROCNODE", "1");
|
||||
|
||||
_buildManager.BeginBuild(BuildParameters);
|
||||
|
||||
try
|
||||
{
|
||||
var child1ProjectPath = testFiles.CreatedFiles[1];
|
||||
var cleanedUpChildContents = CleanupFileContents(_childProjectWithCustomBuildEvent);
|
||||
File.WriteAllText(child1ProjectPath, cleanedUpChildContents);
|
||||
|
||||
var mainProjectPath = testFiles.CreatedFiles[0];
|
||||
var cleanedUpMainContents = CleanupFileContents(string.Format(_mainProject, child1ProjectPath));
|
||||
File.WriteAllText(mainProjectPath, cleanedUpMainContents);
|
||||
|
||||
var buildRequestData = new BuildRequestData(
|
||||
mainProjectPath,
|
||||
new Dictionary<string, string>(),
|
||||
MSBuildConstants.CurrentToolsVersion,
|
||||
new[] { "MainTarget" },
|
||||
null);
|
||||
|
||||
var submission = _buildManager.PendBuildRequest(buildRequestData);
|
||||
var result = submission.Execute();
|
||||
var allEvents = _logger.AllBuildEvents;
|
||||
|
||||
if (isWarningExpected)
|
||||
{
|
||||
allEvents.OfType<T>().ShouldHaveSingleItem();
|
||||
allEvents.First(x => x is T).Message.ShouldContain(
|
||||
string.Format(ResourceUtilities.GetResourceString("DeprecatedEventSerialization"),
|
||||
"MyCustomBuildEventArgs"));
|
||||
}
|
||||
else
|
||||
{
|
||||
allEvents.OfType<T>().ShouldBeEmpty();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_buildManager.EndBuild();
|
||||
}
|
||||
}
|
||||
|
||||
private BuildParameters BuildParameters => new BuildParameters(_projectCollection)
|
||||
{
|
||||
DisableInProcNode = true,
|
||||
EnableNodeReuse = false,
|
||||
Loggers = new ILogger[] { _logger }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// TearDown
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_buildManager.Dispose();
|
||||
_projectCollection.Dispose();
|
||||
_env.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Utilities;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Microsoft.Build.UnitTests
|
||||
{
|
||||
public class CustomBuildEventTask : Task
|
||||
{
|
||||
public override bool Execute()
|
||||
{
|
||||
MyCustomBuildEventArgs customBuildEvent = new() { RawMessage = "A message from MyCustomBuildEventArgs" };
|
||||
BuildEngine.LogCustomEvent(customBuildEvent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class MyCustomBuildEventArgs : CustomBuildEventArgs { }
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Build.BackEnd;
|
||||
using Microsoft.Build.Framework;
|
||||
using Microsoft.Build.Shared;
|
||||
|
@ -57,8 +58,21 @@ namespace Microsoft.Build.UnitTests.BackEnd
|
|||
ProjectStartedEventArgs projectStarted = new ProjectStartedEventArgs(-1, "message", "help", "ProjectFile", "targetNames", null, null, null);
|
||||
ProjectFinishedEventArgs projectFinished = new ProjectFinishedEventArgs("message", "help", "ProjectFile", true);
|
||||
ExternalProjectStartedEventArgs externalStartedEvent = new ExternalProjectStartedEventArgs("message", "help", "senderName", "projectFile", "targetNames");
|
||||
ExternalProjectFinishedEventArgs externalFinishedEvent = new("message", "help", "senderName", "projectFile", true);
|
||||
ProjectEvaluationStartedEventArgs evaluationStarted = new ProjectEvaluationStartedEventArgs();
|
||||
ProjectEvaluationFinishedEventArgs evaluationFinished = new ProjectEvaluationFinishedEventArgs();
|
||||
AssemblyLoadBuildEventArgs assemblyLoad = new(AssemblyLoadingContext.Evaluation, null, null, "path", Guid.NewGuid(), null);
|
||||
ExtendedBuildErrorEventArgs extError = new("extError", "SubCategoryForSchemaValidationErrors", "MSB4000", "file", 1, 2, 3, 4, "message", "help", "sender");
|
||||
ExtendedBuildWarningEventArgs extWarning = new("extWarn", "SubCategoryForSchemaValidationErrors", "MSB4000", "file", 1, 2, 3, 4, "message", "help", "sender");
|
||||
ExtendedBuildMessageEventArgs extMessage = new("extMsg", "SubCategoryForSchemaValidationErrors", "MSB4000", "file", 1, 2, 3, 4, "message", "help", "sender", MessageImportance.Normal);
|
||||
ExtendedCustomBuildEventArgs extCustom = new("extCustom", "message", "help", "sender");
|
||||
CriticalBuildMessageEventArgs criticalMessage = new("Subcategory", "Code", "File", 1, 2, 3, 4, "{0}", "HelpKeyword", "Sender", DateTime.Now, "arg1");
|
||||
PropertyInitialValueSetEventArgs propInit = new("prop", "val", "propsource", "message", "help", "sender", MessageImportance.Normal);
|
||||
MetaprojectGeneratedEventArgs metaProjectGenerated = new("metaName", "path", "message");
|
||||
PropertyReassignmentEventArgs propReassign = new("prop", "prevValue", "newValue", "loc", "message", "help", "sender", MessageImportance.Normal);
|
||||
ResponseFileUsedEventArgs responseFileUsed = new("path");
|
||||
UninitializedPropertyReadEventArgs uninitializedPropertyRead = new("prop", "message", "help", "sender", MessageImportance.Normal);
|
||||
EnvironmentVariableReadEventArgs environmentVariableRead = new("env", "message", "help", "sender", MessageImportance.Normal);
|
||||
|
||||
VerifyLoggingPacket(buildFinished, LoggingEventType.BuildFinishedEvent);
|
||||
VerifyLoggingPacket(buildStarted, LoggingEventType.BuildStartedEvent);
|
||||
|
@ -76,7 +90,20 @@ namespace Microsoft.Build.UnitTests.BackEnd
|
|||
VerifyLoggingPacket(projectFinished, LoggingEventType.ProjectFinishedEvent);
|
||||
VerifyLoggingPacket(evaluationStarted, LoggingEventType.ProjectEvaluationStartedEvent);
|
||||
VerifyLoggingPacket(evaluationFinished, LoggingEventType.ProjectEvaluationFinishedEvent);
|
||||
VerifyLoggingPacket(externalStartedEvent, LoggingEventType.CustomEvent);
|
||||
VerifyLoggingPacket(externalStartedEvent, LoggingEventType.ExternalProjectStartedEvent);
|
||||
VerifyLoggingPacket(externalFinishedEvent, LoggingEventType.ExternalProjectFinishedEvent);
|
||||
VerifyLoggingPacket(assemblyLoad, LoggingEventType.AssemblyLoadEvent);
|
||||
VerifyLoggingPacket(extError, LoggingEventType.ExtendedBuildErrorEvent);
|
||||
VerifyLoggingPacket(extWarning, LoggingEventType.ExtendedBuildWarningEvent);
|
||||
VerifyLoggingPacket(extMessage, LoggingEventType.ExtendedBuildMessageEvent);
|
||||
VerifyLoggingPacket(extCustom, LoggingEventType.ExtendedCustomEvent);
|
||||
VerifyLoggingPacket(criticalMessage, LoggingEventType.CriticalBuildMessage);
|
||||
VerifyLoggingPacket(propInit, LoggingEventType.PropertyInitialValueSet);
|
||||
VerifyLoggingPacket(metaProjectGenerated, LoggingEventType.MetaprojectGenerated);
|
||||
VerifyLoggingPacket(propReassign, LoggingEventType.PropertyReassignment);
|
||||
VerifyLoggingPacket(responseFileUsed, LoggingEventType.ResponseFileUsedEvent);
|
||||
VerifyLoggingPacket(uninitializedPropertyRead, LoggingEventType.UninitializedPropertyRead);
|
||||
VerifyLoggingPacket(environmentVariableRead, LoggingEventType.EnvironmentVariableReadEvent);
|
||||
}
|
||||
|
||||
private static BuildEventContext CreateBuildEventContext()
|
||||
|
@ -218,6 +245,13 @@ namespace Microsoft.Build.UnitTests.BackEnd
|
|||
{
|
||||
BuildEventArgs[] testArgs = new BuildEventArgs[]
|
||||
{
|
||||
new ResponseFileUsedEventArgs("path"),
|
||||
new UninitializedPropertyReadEventArgs("prop", "message", "help", "sender", MessageImportance.Normal),
|
||||
new EnvironmentVariableReadEventArgs("env", "message", "help", "sender", MessageImportance.Normal) { BuildEventContext = new BuildEventContext(1, 2, 3, 4, 5, 6) },
|
||||
new PropertyReassignmentEventArgs("prop", "prevValue", "newValue", "loc", "message", "help", "sender", MessageImportance.Normal),
|
||||
new PropertyInitialValueSetEventArgs("prop", "val", "propsource", "message", "help", "sender", MessageImportance.Normal),
|
||||
new MetaprojectGeneratedEventArgs("metaName", "path", "message"),
|
||||
new CriticalBuildMessageEventArgs("Subcategory", "Code", "File", 1, 2, 3, 4, "{0}", "HelpKeyword", "Sender", DateTime.Now, "arg1"),
|
||||
new BuildFinishedEventArgs("Message", "Keyword", true),
|
||||
new BuildStartedEventArgs("Message", "Help"),
|
||||
new BuildMessageEventArgs("Message", "help", "sender", MessageImportance.Low),
|
||||
|
@ -236,11 +270,36 @@ namespace Microsoft.Build.UnitTests.BackEnd
|
|||
new ProjectStartedEventArgs(-1, "message", "help", "ProjectFile", "targetNames", null, null, null),
|
||||
new ProjectFinishedEventArgs("message", "help", "ProjectFile", true),
|
||||
new ExternalProjectStartedEventArgs("message", "help", "senderName", "projectFile", "targetNames"),
|
||||
new ExternalProjectFinishedEventArgs("message", "help", "senderName", "projectFile", true),
|
||||
CreateProjectEvaluationStarted(),
|
||||
CreateProjectEvaluationFinished(),
|
||||
CreateTargetSkipped()
|
||||
new AssemblyLoadBuildEventArgs(AssemblyLoadingContext.Evaluation, "init", "aname", "path", Guid.NewGuid(), "domain", MessageImportance.Normal),
|
||||
CreateTargetSkipped(),
|
||||
new ExtendedBuildErrorEventArgs("extError", "SubCategoryForSchemaValidationErrors", "MSB4000", "file", 1, 2, 3, 4, "message", "help", "sender", DateTime.UtcNow, "arg1")
|
||||
{
|
||||
ExtendedData = "{'long-json':'mostly-strings'}",
|
||||
ExtendedMetadata = new Dictionary<string, string> { { "m1", "v1" }, { "m2", "v2" } },
|
||||
BuildEventContext = new BuildEventContext(1, 2, 3, 4, 5, 6, 7)
|
||||
},
|
||||
new ExtendedBuildWarningEventArgs("extWarn", "SubCategoryForSchemaValidationErrors", "MSB4000", "file", 1, 2, 3, 4, "message", "help", "sender", DateTime.UtcNow, "arg1")
|
||||
{
|
||||
ExtendedData = "{'long-json':'mostly-strings'}",
|
||||
ExtendedMetadata = new Dictionary<string, string> { { "m1", "v1" }, { "m2", "v2" } },
|
||||
BuildEventContext = new BuildEventContext(1, 2, 3, 4, 5, 6, 7)
|
||||
},
|
||||
new ExtendedBuildMessageEventArgs("extWarn", "SubCategoryForSchemaValidationErrors", "MSB4000", "file", 1, 2, 3, 4, "message", "help", "sender", MessageImportance.Normal, DateTime.UtcNow, "arg1")
|
||||
{
|
||||
ExtendedData = "{'long-json':'mostly-strings'}",
|
||||
ExtendedMetadata = new Dictionary<string, string> { { "m1", "v1" }, { "m2", "v2" } },
|
||||
BuildEventContext = new BuildEventContext(1, 2, 3, 4, 5, 6, 7)
|
||||
},
|
||||
new ExtendedCustomBuildEventArgs("extCustom", "message", "help", "sender", DateTime.UtcNow, "arg1")
|
||||
{
|
||||
ExtendedData = "{'long-json':'mostly-strings'}",
|
||||
ExtendedMetadata = new Dictionary<string, string> { { "m1", "v1" }, { "m2", "v2" } },
|
||||
BuildEventContext = new BuildEventContext(1, 2, 3, 4, 5, 6, 7)
|
||||
},
|
||||
};
|
||||
|
||||
foreach (BuildEventArgs arg in testArgs)
|
||||
{
|
||||
LogMessagePacket packet = new LogMessagePacket(new KeyValuePair<int, BuildEventArgs>(0, arg));
|
||||
|
@ -250,7 +309,17 @@ namespace Microsoft.Build.UnitTests.BackEnd
|
|||
|
||||
LogMessagePacket deserializedPacket = tempPacket as LogMessagePacket;
|
||||
|
||||
CompareLogMessagePackets(packet, deserializedPacket);
|
||||
packet.Should().BeEquivalentTo(deserializedPacket, options => options
|
||||
.RespectingRuntimeTypes());
|
||||
|
||||
BuildEventArgs args = packet.NodeBuildEvent?.Value;
|
||||
BuildEventArgs desArgs = deserializedPacket?.NodeBuildEvent?.Value;
|
||||
desArgs.Should().BeEquivalentTo(args, options => options
|
||||
.RespectingRuntimeTypes()
|
||||
// Since we use struct DictionaryEntry of class TaskItemData, generated DictionaryEntry.Equals compare TaskItemData by references.
|
||||
// Bellow will instruct equivalency test to not use DictionaryEntry.Equals but its public members for equivalency tests.
|
||||
.ComparingByMembers<DictionaryEntry>()
|
||||
.WithTracing(), "Roundtrip deserialization of message type {0} should be equivalent", args.GetType().Name);
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
@ -273,249 +342,6 @@ namespace Microsoft.Build.UnitTests.BackEnd
|
|||
Assert.True(Object.ReferenceEquals(buildEvent, packet.NodeBuildEvent.Value.Value)); // "Expected buildEvent to have the same object reference as packet.BuildEvent"
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two BuildEventArgs objects for equivalence.
|
||||
/// </summary>
|
||||
private void CompareNodeBuildEventArgs(KeyValuePair<int, BuildEventArgs> leftTuple, KeyValuePair<int, BuildEventArgs> rightTuple, bool expectInvalidBuildEventContext)
|
||||
{
|
||||
BuildEventArgs left = leftTuple.Value;
|
||||
BuildEventArgs right = rightTuple.Value;
|
||||
|
||||
if (expectInvalidBuildEventContext)
|
||||
{
|
||||
Assert.Equal(BuildEventContext.Invalid, right.BuildEventContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(left.BuildEventContext, right.BuildEventContext);
|
||||
}
|
||||
|
||||
Assert.Equal(leftTuple.Key, rightTuple.Key);
|
||||
Assert.Equal(left.HelpKeyword, right.HelpKeyword);
|
||||
Assert.Equal(left.Message, right.Message);
|
||||
Assert.Equal(left.SenderName, right.SenderName);
|
||||
Assert.Equal(left.ThreadId, right.ThreadId);
|
||||
Assert.Equal(left.Timestamp, right.Timestamp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two LogMessagePacket objects for equivalence.
|
||||
/// </summary>
|
||||
private void CompareLogMessagePackets(LogMessagePacket left, LogMessagePacket right)
|
||||
{
|
||||
Assert.Equal(left.EventType, right.EventType);
|
||||
Assert.Equal(left.NodeBuildEvent.Value.Value.GetType(), right.NodeBuildEvent.Value.Value.GetType());
|
||||
|
||||
CompareNodeBuildEventArgs(left.NodeBuildEvent.Value, right.NodeBuildEvent.Value, left.EventType == LoggingEventType.CustomEvent /* expectInvalidBuildEventContext */);
|
||||
|
||||
switch (left.EventType)
|
||||
{
|
||||
case LoggingEventType.BuildErrorEvent:
|
||||
BuildErrorEventArgs leftError = left.NodeBuildEvent.Value.Value as BuildErrorEventArgs;
|
||||
BuildErrorEventArgs rightError = right.NodeBuildEvent.Value.Value as BuildErrorEventArgs;
|
||||
Assert.NotNull(leftError);
|
||||
Assert.NotNull(rightError);
|
||||
Assert.Equal(leftError.Code, rightError.Code);
|
||||
Assert.Equal(leftError.ColumnNumber, rightError.ColumnNumber);
|
||||
Assert.Equal(leftError.EndColumnNumber, rightError.EndColumnNumber);
|
||||
Assert.Equal(leftError.EndLineNumber, rightError.EndLineNumber);
|
||||
Assert.Equal(leftError.File, rightError.File);
|
||||
Assert.Equal(leftError.LineNumber, rightError.LineNumber);
|
||||
Assert.Equal(leftError.Message, rightError.Message);
|
||||
Assert.Equal(leftError.Subcategory, rightError.Subcategory);
|
||||
break;
|
||||
|
||||
case LoggingEventType.BuildFinishedEvent:
|
||||
BuildFinishedEventArgs leftFinished = left.NodeBuildEvent.Value.Value as BuildFinishedEventArgs;
|
||||
BuildFinishedEventArgs rightFinished = right.NodeBuildEvent.Value.Value as BuildFinishedEventArgs;
|
||||
Assert.NotNull(leftFinished);
|
||||
Assert.NotNull(rightFinished);
|
||||
Assert.Equal(leftFinished.Succeeded, rightFinished.Succeeded);
|
||||
break;
|
||||
|
||||
case LoggingEventType.BuildMessageEvent:
|
||||
BuildMessageEventArgs leftMessage = left.NodeBuildEvent.Value.Value as BuildMessageEventArgs;
|
||||
BuildMessageEventArgs rightMessage = right.NodeBuildEvent.Value.Value as BuildMessageEventArgs;
|
||||
Assert.NotNull(leftMessage);
|
||||
Assert.NotNull(rightMessage);
|
||||
Assert.Equal(leftMessage.Importance, rightMessage.Importance);
|
||||
break;
|
||||
|
||||
case LoggingEventType.BuildStartedEvent:
|
||||
BuildStartedEventArgs leftBuildStart = left.NodeBuildEvent.Value.Value as BuildStartedEventArgs;
|
||||
BuildStartedEventArgs rightBuildStart = right.NodeBuildEvent.Value.Value as BuildStartedEventArgs;
|
||||
Assert.NotNull(leftBuildStart);
|
||||
Assert.NotNull(rightBuildStart);
|
||||
break;
|
||||
|
||||
case LoggingEventType.BuildWarningEvent:
|
||||
BuildWarningEventArgs leftBuildWarn = left.NodeBuildEvent.Value.Value as BuildWarningEventArgs;
|
||||
BuildWarningEventArgs rightBuildWarn = right.NodeBuildEvent.Value.Value as BuildWarningEventArgs;
|
||||
Assert.NotNull(leftBuildWarn);
|
||||
Assert.NotNull(rightBuildWarn);
|
||||
Assert.Equal(leftBuildWarn.Code, rightBuildWarn.Code);
|
||||
Assert.Equal(leftBuildWarn.ColumnNumber, rightBuildWarn.ColumnNumber);
|
||||
Assert.Equal(leftBuildWarn.EndColumnNumber, rightBuildWarn.EndColumnNumber);
|
||||
Assert.Equal(leftBuildWarn.EndLineNumber, rightBuildWarn.EndLineNumber);
|
||||
Assert.Equal(leftBuildWarn.File, rightBuildWarn.File);
|
||||
Assert.Equal(leftBuildWarn.LineNumber, rightBuildWarn.LineNumber);
|
||||
Assert.Equal(leftBuildWarn.Subcategory, rightBuildWarn.Subcategory);
|
||||
break;
|
||||
|
||||
case LoggingEventType.CustomEvent:
|
||||
ExternalProjectStartedEventArgs leftCustom = left.NodeBuildEvent.Value.Value as ExternalProjectStartedEventArgs;
|
||||
ExternalProjectStartedEventArgs rightCustom = right.NodeBuildEvent.Value.Value as ExternalProjectStartedEventArgs;
|
||||
Assert.NotNull(leftCustom);
|
||||
Assert.NotNull(rightCustom);
|
||||
Assert.Equal(leftCustom.ProjectFile, rightCustom.ProjectFile);
|
||||
Assert.Equal(leftCustom.TargetNames, rightCustom.TargetNames);
|
||||
break;
|
||||
|
||||
case LoggingEventType.ProjectFinishedEvent:
|
||||
ProjectFinishedEventArgs leftProjectFinished = left.NodeBuildEvent.Value.Value as ProjectFinishedEventArgs;
|
||||
ProjectFinishedEventArgs rightProjectFinished = right.NodeBuildEvent.Value.Value as ProjectFinishedEventArgs;
|
||||
Assert.NotNull(leftProjectFinished);
|
||||
Assert.NotNull(rightProjectFinished);
|
||||
Assert.Equal(leftProjectFinished.ProjectFile, rightProjectFinished.ProjectFile);
|
||||
Assert.Equal(leftProjectFinished.Succeeded, rightProjectFinished.Succeeded);
|
||||
break;
|
||||
|
||||
case LoggingEventType.ProjectStartedEvent:
|
||||
ProjectStartedEventArgs leftProjectStarted = left.NodeBuildEvent.Value.Value as ProjectStartedEventArgs;
|
||||
ProjectStartedEventArgs rightProjectStarted = right.NodeBuildEvent.Value.Value as ProjectStartedEventArgs;
|
||||
Assert.NotNull(leftProjectStarted);
|
||||
Assert.NotNull(rightProjectStarted);
|
||||
Assert.Equal(leftProjectStarted.ParentProjectBuildEventContext, rightProjectStarted.ParentProjectBuildEventContext);
|
||||
Assert.Equal(leftProjectStarted.ProjectFile, rightProjectStarted.ProjectFile);
|
||||
Assert.Equal(leftProjectStarted.ProjectId, rightProjectStarted.ProjectId);
|
||||
Assert.Equal(leftProjectStarted.TargetNames, rightProjectStarted.TargetNames);
|
||||
|
||||
// UNDONE: (Serialization.) We don't actually serialize the items at this time.
|
||||
// Assert.AreEqual(leftProjectStarted.Items, rightProjectStarted.Items);
|
||||
// UNDONE: (Serialization.) We don't actually serialize properties at this time.
|
||||
// Assert.AreEqual(leftProjectStarted.Properties, rightProjectStarted.Properties);
|
||||
break;
|
||||
|
||||
case LoggingEventType.ProjectEvaluationStartedEvent:
|
||||
ProjectEvaluationStartedEventArgs leftEvaluationStarted = left.NodeBuildEvent.Value.Value as ProjectEvaluationStartedEventArgs;
|
||||
ProjectEvaluationStartedEventArgs rightEvaluationStarted = right.NodeBuildEvent.Value.Value as ProjectEvaluationStartedEventArgs;
|
||||
Assert.NotNull(leftEvaluationStarted);
|
||||
Assert.NotNull(rightEvaluationStarted);
|
||||
Assert.Equal(leftEvaluationStarted.ProjectFile, rightEvaluationStarted.ProjectFile);
|
||||
break;
|
||||
|
||||
case LoggingEventType.ProjectEvaluationFinishedEvent:
|
||||
ProjectEvaluationFinishedEventArgs leftEvaluationFinished = left.NodeBuildEvent.Value.Value as ProjectEvaluationFinishedEventArgs;
|
||||
ProjectEvaluationFinishedEventArgs rightEvaluationFinished = right.NodeBuildEvent.Value.Value as ProjectEvaluationFinishedEventArgs;
|
||||
Assert.NotNull(leftEvaluationFinished);
|
||||
Assert.NotNull(rightEvaluationFinished);
|
||||
Assert.Equal(leftEvaluationFinished.ProjectFile, rightEvaluationFinished.ProjectFile);
|
||||
Assert.Equal(leftEvaluationFinished.ProfilerResult, rightEvaluationFinished.ProfilerResult);
|
||||
Assert.Equal(
|
||||
TranslationHelpers.GetPropertiesString(leftEvaluationFinished.GlobalProperties),
|
||||
TranslationHelpers.GetPropertiesString(rightEvaluationFinished.GlobalProperties));
|
||||
Assert.Equal(
|
||||
TranslationHelpers.GetPropertiesString(leftEvaluationFinished.Properties),
|
||||
TranslationHelpers.GetPropertiesString(rightEvaluationFinished.Properties));
|
||||
Assert.Equal(
|
||||
TranslationHelpers.GetMultiItemsString(leftEvaluationFinished.Items),
|
||||
TranslationHelpers.GetMultiItemsString(rightEvaluationFinished.Items));
|
||||
break;
|
||||
|
||||
case LoggingEventType.TargetFinishedEvent:
|
||||
TargetFinishedEventArgs leftTargetFinished = left.NodeBuildEvent.Value.Value as TargetFinishedEventArgs;
|
||||
TargetFinishedEventArgs rightTargetFinished = right.NodeBuildEvent.Value.Value as TargetFinishedEventArgs;
|
||||
Assert.NotNull(leftTargetFinished);
|
||||
Assert.NotNull(rightTargetFinished);
|
||||
Assert.Equal(leftTargetFinished.ProjectFile, rightTargetFinished.ProjectFile);
|
||||
Assert.Equal(leftTargetFinished.Succeeded, rightTargetFinished.Succeeded);
|
||||
Assert.Equal(leftTargetFinished.TargetFile, rightTargetFinished.TargetFile);
|
||||
Assert.Equal(leftTargetFinished.TargetName, rightTargetFinished.TargetName);
|
||||
// TODO: target output translation is a special case and is done in TranslateTargetFinishedEvent
|
||||
// Assert.Equal(leftTargetFinished.TargetOutputs, rightTargetFinished.TargetOutputs);
|
||||
break;
|
||||
|
||||
case LoggingEventType.TargetStartedEvent:
|
||||
TargetStartedEventArgs leftTargetStarted = left.NodeBuildEvent.Value.Value as TargetStartedEventArgs;
|
||||
TargetStartedEventArgs rightTargetStarted = right.NodeBuildEvent.Value.Value as TargetStartedEventArgs;
|
||||
Assert.NotNull(leftTargetStarted);
|
||||
Assert.NotNull(rightTargetStarted);
|
||||
Assert.Equal(leftTargetStarted.ProjectFile, rightTargetStarted.ProjectFile);
|
||||
Assert.Equal(leftTargetStarted.TargetFile, rightTargetStarted.TargetFile);
|
||||
Assert.Equal(leftTargetStarted.TargetName, rightTargetStarted.TargetName);
|
||||
break;
|
||||
|
||||
case LoggingEventType.TargetSkipped:
|
||||
TargetSkippedEventArgs leftTargetSkipped = left.NodeBuildEvent.Value.Value as TargetSkippedEventArgs;
|
||||
TargetSkippedEventArgs rightTargetSkipped = right.NodeBuildEvent.Value.Value as TargetSkippedEventArgs;
|
||||
Assert.Equal(leftTargetSkipped.BuildReason, rightTargetSkipped.BuildReason);
|
||||
Assert.Equal(leftTargetSkipped.SkipReason, rightTargetSkipped.SkipReason);
|
||||
Assert.Equal(leftTargetSkipped.BuildEventContext, rightTargetSkipped.BuildEventContext);
|
||||
Assert.Equal(leftTargetSkipped.OriginalBuildEventContext, rightTargetSkipped.OriginalBuildEventContext);
|
||||
Assert.Equal(leftTargetSkipped.Condition, rightTargetSkipped.Condition);
|
||||
Assert.Equal(leftTargetSkipped.EvaluatedCondition, rightTargetSkipped.EvaluatedCondition);
|
||||
Assert.Equal(leftTargetSkipped.Importance, rightTargetSkipped.Importance);
|
||||
Assert.Equal(leftTargetSkipped.OriginallySucceeded, rightTargetSkipped.OriginallySucceeded);
|
||||
Assert.Equal(leftTargetSkipped.ProjectFile, rightTargetSkipped.ProjectFile);
|
||||
Assert.Equal(leftTargetSkipped.TargetFile, rightTargetSkipped.TargetFile);
|
||||
Assert.Equal(leftTargetSkipped.TargetName, rightTargetSkipped.TargetName);
|
||||
Assert.Equal(leftTargetSkipped.ParentTarget, rightTargetSkipped.ParentTarget);
|
||||
break;
|
||||
|
||||
case LoggingEventType.TaskCommandLineEvent:
|
||||
TaskCommandLineEventArgs leftCommand = left.NodeBuildEvent.Value.Value as TaskCommandLineEventArgs;
|
||||
TaskCommandLineEventArgs rightCommand = right.NodeBuildEvent.Value.Value as TaskCommandLineEventArgs;
|
||||
Assert.NotNull(leftCommand);
|
||||
Assert.NotNull(rightCommand);
|
||||
Assert.Equal(leftCommand.CommandLine, rightCommand.CommandLine);
|
||||
Assert.Equal(leftCommand.Importance, rightCommand.Importance);
|
||||
Assert.Equal(leftCommand.TaskName, rightCommand.TaskName);
|
||||
break;
|
||||
|
||||
case LoggingEventType.TaskParameterEvent:
|
||||
var leftTaskParameter = left.NodeBuildEvent.Value.Value as TaskParameterEventArgs;
|
||||
var rightTaskParameter = right.NodeBuildEvent.Value.Value as TaskParameterEventArgs;
|
||||
Assert.NotNull(leftTaskParameter);
|
||||
Assert.NotNull(rightTaskParameter);
|
||||
Assert.Equal(leftTaskParameter.Kind, rightTaskParameter.Kind);
|
||||
Assert.Equal(leftTaskParameter.ItemType, rightTaskParameter.ItemType);
|
||||
Assert.Equal(leftTaskParameter.Items.Count, rightTaskParameter.Items.Count);
|
||||
Assert.Equal(leftTaskParameter.Message, rightTaskParameter.Message);
|
||||
Assert.Equal(leftTaskParameter.BuildEventContext, rightTaskParameter.BuildEventContext);
|
||||
Assert.Equal(leftTaskParameter.Timestamp, rightTaskParameter.Timestamp);
|
||||
Assert.Equal(leftTaskParameter.LineNumber, rightTaskParameter.LineNumber);
|
||||
Assert.Equal(leftTaskParameter.ColumnNumber, rightTaskParameter.ColumnNumber);
|
||||
break;
|
||||
|
||||
case LoggingEventType.TaskFinishedEvent:
|
||||
TaskFinishedEventArgs leftTaskFinished = left.NodeBuildEvent.Value.Value as TaskFinishedEventArgs;
|
||||
TaskFinishedEventArgs rightTaskFinished = right.NodeBuildEvent.Value.Value as TaskFinishedEventArgs;
|
||||
Assert.NotNull(leftTaskFinished);
|
||||
Assert.NotNull(rightTaskFinished);
|
||||
Assert.Equal(leftTaskFinished.ProjectFile, rightTaskFinished.ProjectFile);
|
||||
Assert.Equal(leftTaskFinished.Succeeded, rightTaskFinished.Succeeded);
|
||||
Assert.Equal(leftTaskFinished.TaskFile, rightTaskFinished.TaskFile);
|
||||
Assert.Equal(leftTaskFinished.TaskName, rightTaskFinished.TaskName);
|
||||
break;
|
||||
|
||||
case LoggingEventType.TaskStartedEvent:
|
||||
TaskStartedEventArgs leftTaskStarted = left.NodeBuildEvent.Value.Value as TaskStartedEventArgs;
|
||||
TaskStartedEventArgs rightTaskStarted = right.NodeBuildEvent.Value.Value as TaskStartedEventArgs;
|
||||
Assert.NotNull(leftTaskStarted);
|
||||
Assert.NotNull(rightTaskStarted);
|
||||
Assert.Equal(leftTaskStarted.ProjectFile, rightTaskStarted.ProjectFile);
|
||||
Assert.Equal(leftTaskStarted.TaskFile, rightTaskStarted.TaskFile);
|
||||
Assert.Equal(leftTaskStarted.TaskName, rightTaskStarted.TaskName);
|
||||
Assert.Equal(leftTaskStarted.LineNumber, rightTaskStarted.LineNumber);
|
||||
Assert.Equal(leftTaskStarted.ColumnNumber, rightTaskStarted.ColumnNumber);
|
||||
break;
|
||||
|
||||
default:
|
||||
Assert.True(false, string.Format("Unexpected logging event type {0}", left.EventType));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -385,6 +385,61 @@ namespace Microsoft.Build.UnitTests.BackEnd
|
|||
Assert.Equal("testCustomBuildEvent", _customLogger.LastCustom.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test that extended custom events are logged properly
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void TestLogExtendedCustomEventNotSerializableMP()
|
||||
{
|
||||
_mockHost.BuildParameters.MaxNodeCount = 4;
|
||||
|
||||
// Log the custom event args. (Pretend that the task actually did this.)
|
||||
_taskHost.LogCustomEvent(new ExtendedCustomBuildEventArgs("testExtCustomBuildEvent", "ext message", null, null));
|
||||
|
||||
// Make sure our custom logger received the actual custom event and not some fake.
|
||||
Assert.True(_customLogger.LastCustom is ExtendedCustomBuildEventArgs); // "Expected custom build Event"
|
||||
Assert.Equal("ext message", _customLogger.LastCustom.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestLogExtendedCustomErrorNotSerializableMP()
|
||||
{
|
||||
_mockHost.BuildParameters.MaxNodeCount = 4;
|
||||
|
||||
// Log the custom event args. (Pretend that the task actually did this.)
|
||||
_taskHost.LogErrorEvent(new ExtendedBuildErrorEventArgs("testExtCustomBuildError", null, null, null, 0, 0, 0, 0,"ext err message", null, null));
|
||||
|
||||
// Make sure our custom logger received the actual custom event and not some fake.
|
||||
Assert.True(_customLogger.LastError is ExtendedBuildErrorEventArgs); // "Expected custom build Event"
|
||||
Assert.Equal("ext err message", _customLogger.LastError.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestLogExtendedCustomWarningNotSerializableMP()
|
||||
{
|
||||
_mockHost.BuildParameters.MaxNodeCount = 4;
|
||||
|
||||
// Log the custom event args. (Pretend that the task actually did this.)
|
||||
_taskHost.LogWarningEvent(new ExtendedBuildWarningEventArgs("testExtCustomBuildWarning", null, null, null, 0, 0, 0, 0, "ext warn message", null, null));
|
||||
|
||||
// Make sure our custom logger received the actual custom event and not some fake.
|
||||
Assert.True(_customLogger.LastWarning is ExtendedBuildWarningEventArgs); // "Expected custom build Event"
|
||||
Assert.Equal("ext warn message", _customLogger.LastWarning.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestLogExtendedCustomMessageNotSerializableMP()
|
||||
{
|
||||
_mockHost.BuildParameters.MaxNodeCount = 4;
|
||||
|
||||
// Log the custom event args. (Pretend that the task actually did this.)
|
||||
_taskHost.LogMessageEvent(new ExtendedBuildMessageEventArgs("testExtCustomBuildMessage", "ext message", null, null, MessageImportance.Normal));
|
||||
|
||||
// Make sure our custom logger received the actual custom event and not some fake.
|
||||
Assert.True(_customLogger.LastMessage is ExtendedBuildMessageEventArgs); // "Expected custom build Event"
|
||||
Assert.Equal("ext message", _customLogger.LastMessage.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test that errors are logged properly
|
||||
/// </summary>
|
||||
|
|
|
@ -13,6 +13,7 @@ using Microsoft.Build.Framework.Profiler;
|
|||
using Microsoft.Build.Logging;
|
||||
using Microsoft.Build.Shared;
|
||||
using Microsoft.Build.UnitTests.BackEnd;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
|
||||
#nullable disable
|
||||
|
@ -262,6 +263,40 @@ namespace Microsoft.Build.UnitTests
|
|||
e => string.Join(", ", e.RawArguments ?? Array.Empty<object>()));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void RoundtripExtendedErrorEventArgs_SerializedAsError(bool useArguments)
|
||||
{
|
||||
var args = new ExtendedBuildErrorEventArgs(
|
||||
"extendedDataType",
|
||||
"Subcategory",
|
||||
"Code",
|
||||
"File",
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
"Message with arguments: '{0}'",
|
||||
"Help",
|
||||
"SenderName",
|
||||
DateTime.Parse("9/1/2021 12:02:07 PM"),
|
||||
useArguments ? new object[] { "argument0" } : null);
|
||||
|
||||
// For now we don't serialize extended data into binary log
|
||||
Roundtrip<BuildErrorEventArgs>(args,
|
||||
e => e.Code,
|
||||
e => e.ColumnNumber.ToString(),
|
||||
e => e.EndColumnNumber.ToString(),
|
||||
e => e.EndLineNumber.ToString(),
|
||||
e => e.File,
|
||||
e => e.LineNumber.ToString(),
|
||||
e => e.Message,
|
||||
e => e.ProjectFile,
|
||||
e => e.Subcategory,
|
||||
e => string.Join(", ", e.RawArguments ?? Array.Empty<object>()));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
|
@ -294,6 +329,40 @@ namespace Microsoft.Build.UnitTests
|
|||
e => string.Join(", ", e.RawArguments ?? Array.Empty<object>()));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void RoundtripExtendedWarningEventArgs_SerializedAsWarning(bool useArguments)
|
||||
{
|
||||
var args = new ExtendedBuildWarningEventArgs(
|
||||
"extendedDataType",
|
||||
"Subcategory",
|
||||
"Code",
|
||||
"File",
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
"Message with arguments: '{0}'",
|
||||
"Help",
|
||||
"SenderName",
|
||||
DateTime.Parse("9/1/2021 12:02:07 PM"),
|
||||
useArguments ? new object[] { "argument0" } : null);
|
||||
|
||||
// For now we don't serialize extended data into binary log
|
||||
Roundtrip<BuildWarningEventArgs>(args,
|
||||
e => e.Code,
|
||||
e => e.ColumnNumber.ToString(),
|
||||
e => e.EndColumnNumber.ToString(),
|
||||
e => e.EndLineNumber.ToString(),
|
||||
e => e.File,
|
||||
e => e.LineNumber.ToString(),
|
||||
e => e.Message,
|
||||
e => e.ProjectFile,
|
||||
e => e.Subcategory,
|
||||
e => string.Join(", ", e.RawArguments ?? Array.Empty<object>()));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
|
@ -328,6 +397,122 @@ namespace Microsoft.Build.UnitTests
|
|||
e => string.Join(", ", e.RawArguments ?? Array.Empty<object>()));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void RoundtripExtendedBuildMessageEventArgs_SerializedAsMessage(bool useArguments)
|
||||
{
|
||||
var args = new ExtendedBuildMessageEventArgs(
|
||||
"extendedDataType",
|
||||
"Subcategory",
|
||||
"Code",
|
||||
"File",
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
"Message",
|
||||
"Help",
|
||||
"SenderName",
|
||||
MessageImportance.High,
|
||||
DateTime.Parse("12/12/2015 06:11:56 PM"),
|
||||
useArguments ? new object[] { "argument0" } : null);
|
||||
|
||||
Roundtrip<BuildMessageEventArgs>(args,
|
||||
e => e.Code,
|
||||
e => e.ColumnNumber.ToString(),
|
||||
e => e.EndColumnNumber.ToString(),
|
||||
e => e.EndLineNumber.ToString(),
|
||||
e => e.File,
|
||||
e => e.LineNumber.ToString(),
|
||||
e => e.Message,
|
||||
e => e.Importance.ToString(),
|
||||
e => e.ProjectFile,
|
||||
e => e.Subcategory,
|
||||
e => string.Join(", ", e.RawArguments ?? Array.Empty<object>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundtripAssemblyLoadBuild()
|
||||
{
|
||||
string assemblyName = Guid.NewGuid().ToString();
|
||||
string assemblyPath = Guid.NewGuid().ToString();
|
||||
Guid mvid = Guid.NewGuid();
|
||||
string loadingInitiator = Guid.NewGuid().ToString();
|
||||
string appDomainName = Guid.NewGuid().ToString();
|
||||
AssemblyLoadingContext context =
|
||||
(AssemblyLoadingContext)(new Random().Next(Enum.GetNames(typeof(AssemblyLoadingContext)).Length));
|
||||
|
||||
AssemblyLoadBuildEventArgs args = new(context, loadingInitiator, assemblyName, assemblyPath, mvid, appDomainName);
|
||||
|
||||
Roundtrip(args,
|
||||
e => e.Code,
|
||||
e => e.ColumnNumber.ToString(),
|
||||
e => e.EndColumnNumber.ToString(),
|
||||
e => e.EndLineNumber.ToString(),
|
||||
e => e.File,
|
||||
e => e.LineNumber.ToString(),
|
||||
e => e.Message,
|
||||
e => e.Importance.ToString(),
|
||||
e => e.ProjectFile,
|
||||
e => e.Subcategory,
|
||||
e => e.LoadingContext.ToString(),
|
||||
e => e.AssemblyName,
|
||||
e => e.AssemblyPath,
|
||||
e => e.MVID.ToString(),
|
||||
e => e.AppDomainDescriptor,
|
||||
e => string.Join(", ", e.RawArguments ?? Array.Empty<object>()));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void ExtendedCustomBuildEventArgs_SerializedAsMessage(bool withOptionalData)
|
||||
{
|
||||
ExtendedCustomBuildEventArgs args = new(
|
||||
type: "TypeOfExtendedCustom",
|
||||
message: withOptionalData ? "a message with args {0} {1}" : null,
|
||||
helpKeyword: withOptionalData ? "MSBT123" : null,
|
||||
senderName: withOptionalData ? $"UnitTest {Guid.NewGuid()}" : null,
|
||||
eventTimestamp: withOptionalData ? DateTime.Parse("3/1/2017 11:11:56 AM") : DateTime.Now,
|
||||
messageArgs: withOptionalData ? new object[] { "arg0val", "arg1val" } : null)
|
||||
{
|
||||
ExtendedData = withOptionalData ? "{'long-json':'mostly-strings'}" : null,
|
||||
ExtendedMetadata = withOptionalData ? new Dictionary<string, string> { { "m1", "v1" }, { "m2", "v2" } } : null,
|
||||
BuildEventContext = withOptionalData ? new BuildEventContext(1, 2, 3, 4, 5, 6, 7) : null,
|
||||
};
|
||||
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
var binaryWriter = new BinaryWriter(memoryStream);
|
||||
var buildEventArgsWriter = new BuildEventArgsWriter(binaryWriter);
|
||||
buildEventArgsWriter.Write(args);
|
||||
|
||||
memoryStream.Position = 0;
|
||||
var binaryReader = new BinaryReader(memoryStream);
|
||||
|
||||
using var buildEventArgsReader = new BuildEventArgsReader(binaryReader, BinaryLogger.FileFormatVersion);
|
||||
var deserialized = buildEventArgsReader.Read();
|
||||
BuildMessageEventArgs desArgs = (BuildMessageEventArgs)deserialized;
|
||||
|
||||
desArgs.ShouldBeOfType(typeof(BuildMessageEventArgs));
|
||||
|
||||
desArgs.Message.ShouldBe(args.Message);
|
||||
desArgs.HelpKeyword.ShouldBe(args.HelpKeyword);
|
||||
desArgs.SenderName.ShouldBe(args.SenderName);
|
||||
desArgs.Importance.ShouldBe(MessageImportance.Normal);
|
||||
desArgs.Timestamp.ShouldBe(args.Timestamp);
|
||||
|
||||
if (withOptionalData)
|
||||
{
|
||||
desArgs.BuildEventContext.ShouldBe(args.BuildEventContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
desArgs.BuildEventContext.ShouldBe(BuildEventContext.Invalid);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RoundtripResponseFileUsedEventArgs()
|
||||
{
|
||||
|
@ -689,7 +874,7 @@ namespace Microsoft.Build.UnitTests
|
|||
Assert.Equal(length, memoryStream.Position);
|
||||
|
||||
Assert.NotNull(deserializedArgs);
|
||||
Assert.Equal(args.GetType(), deserializedArgs.GetType());
|
||||
Assert.Equal(typeof(T), deserializedArgs.GetType());
|
||||
|
||||
foreach (var field in fieldsToCompare)
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.IO.Compression" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
|
||||
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="System.Net.Http" />
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Microsoft.Build.BackEnd
|
|||
/// Constructor for deserialization
|
||||
/// </summary>
|
||||
private LogMessagePacket(ITranslator translator)
|
||||
: base(translator)
|
||||
: base(translator, new TargetFinishedTranslator(TranslateTargetFinishedEvent))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -901,9 +901,60 @@ namespace Microsoft.Build.BackEnd.Logging
|
|||
|
||||
LogMessagePacket loggingPacket = (LogMessagePacket)packet;
|
||||
InjectNonSerializedData(loggingPacket);
|
||||
|
||||
WarnOnDeprecatedCustomArgsSerialization(loggingPacket);
|
||||
|
||||
ProcessLoggingEvent(loggingPacket.NodeBuildEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializing unknown CustomEvent which has to use unsecure BinaryFormatter by TranslateDotNet.
|
||||
/// Since BinaryFormatter is going to be deprecated, log warning so users can use new Extended*EventArgs instead of custom
|
||||
/// EventArgs derived from existing EventArgs.
|
||||
/// </summary>
|
||||
private void WarnOnDeprecatedCustomArgsSerialization(LogMessagePacket loggingPacket)
|
||||
{
|
||||
if (loggingPacket.EventType == LoggingEventType.CustomEvent
|
||||
&& ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_8)
|
||||
&& Traits.Instance.EscapeHatches.EnableWarningOnCustomBuildEvent)
|
||||
{
|
||||
BuildEventArgs buildEvent = loggingPacket.NodeBuildEvent.Value.Value;
|
||||
BuildEventContext buildEventContext = buildEvent?.BuildEventContext ?? BuildEventContext.Invalid;
|
||||
|
||||
string message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword(
|
||||
out string warningCode,
|
||||
out string helpKeyword,
|
||||
"DeprecatedEventSerialization",
|
||||
buildEvent?.GetType().Name ?? string.Empty);
|
||||
|
||||
BuildWarningEventArgs warning = new(
|
||||
null,
|
||||
warningCode,
|
||||
BuildEventFileInfo.Empty.File,
|
||||
BuildEventFileInfo.Empty.Line,
|
||||
BuildEventFileInfo.Empty.Column,
|
||||
BuildEventFileInfo.Empty.EndLine,
|
||||
BuildEventFileInfo.Empty.EndColumn,
|
||||
message,
|
||||
helpKeyword,
|
||||
"MSBuild");
|
||||
|
||||
warning.BuildEventContext = buildEventContext;
|
||||
if (warning.ProjectFile == null && buildEventContext.ProjectContextId != BuildEventContext.InvalidProjectContextId)
|
||||
{
|
||||
warning.ProjectFile = buildEvent switch
|
||||
{
|
||||
BuildMessageEventArgs buildMessageEvent => buildMessageEvent.ProjectFile,
|
||||
BuildErrorEventArgs buildErrorEvent => buildErrorEvent.ProjectFile,
|
||||
BuildWarningEventArgs buildWarningEvent => buildWarningEvent.ProjectFile,
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
ProcessLoggingEvent(warning);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register an instantiated logger which implements the ILogger interface. This logger will be registered to a specific event
|
||||
/// source (the central logger event source) which will receive all logging messages for a given build.
|
||||
|
@ -1438,42 +1489,93 @@ namespace Microsoft.Build.BackEnd.Logging
|
|||
{
|
||||
if (ShouldTreatWarningAsMessage(warningEvent))
|
||||
{
|
||||
buildEventArgs = new BuildMessageEventArgs(
|
||||
warningEvent.Subcategory,
|
||||
warningEvent.Code,
|
||||
warningEvent.File,
|
||||
warningEvent.LineNumber,
|
||||
warningEvent.ColumnNumber,
|
||||
warningEvent.EndLineNumber,
|
||||
warningEvent.EndColumnNumber,
|
||||
warningEvent.Message,
|
||||
warningEvent.HelpKeyword,
|
||||
warningEvent.SenderName,
|
||||
MessageImportance.Low,
|
||||
warningEvent.Timestamp)
|
||||
if (buildEventArgs is ExtendedBuildWarningEventArgs extWarningEvent)
|
||||
{
|
||||
BuildEventContext = warningEvent.BuildEventContext,
|
||||
ProjectFile = warningEvent.ProjectFile,
|
||||
};
|
||||
buildEventArgs = new ExtendedBuildMessageEventArgs(
|
||||
extWarningEvent.ExtendedType,
|
||||
extWarningEvent.Subcategory,
|
||||
extWarningEvent.Code,
|
||||
extWarningEvent.File,
|
||||
extWarningEvent.LineNumber,
|
||||
extWarningEvent.ColumnNumber,
|
||||
extWarningEvent.EndLineNumber,
|
||||
extWarningEvent.EndColumnNumber,
|
||||
extWarningEvent.Message,
|
||||
extWarningEvent.HelpKeyword,
|
||||
extWarningEvent.SenderName,
|
||||
MessageImportance.Low,
|
||||
extWarningEvent.Timestamp)
|
||||
{
|
||||
BuildEventContext = warningEvent.BuildEventContext,
|
||||
ProjectFile = warningEvent.ProjectFile,
|
||||
ExtendedMetadata = extWarningEvent.ExtendedMetadata,
|
||||
ExtendedData = extWarningEvent.ExtendedData,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
buildEventArgs = new BuildMessageEventArgs(
|
||||
warningEvent.Subcategory,
|
||||
warningEvent.Code,
|
||||
warningEvent.File,
|
||||
warningEvent.LineNumber,
|
||||
warningEvent.ColumnNumber,
|
||||
warningEvent.EndLineNumber,
|
||||
warningEvent.EndColumnNumber,
|
||||
warningEvent.Message,
|
||||
warningEvent.HelpKeyword,
|
||||
warningEvent.SenderName,
|
||||
MessageImportance.Low,
|
||||
warningEvent.Timestamp)
|
||||
{
|
||||
BuildEventContext = warningEvent.BuildEventContext,
|
||||
ProjectFile = warningEvent.ProjectFile,
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (ShouldTreatWarningAsError(warningEvent))
|
||||
{
|
||||
buildEventArgs = new BuildErrorEventArgs(
|
||||
warningEvent.Subcategory,
|
||||
warningEvent.Code,
|
||||
warningEvent.File,
|
||||
warningEvent.LineNumber,
|
||||
warningEvent.ColumnNumber,
|
||||
warningEvent.EndLineNumber,
|
||||
warningEvent.EndColumnNumber,
|
||||
warningEvent.Message,
|
||||
warningEvent.HelpKeyword,
|
||||
warningEvent.SenderName,
|
||||
warningEvent.Timestamp)
|
||||
if (warningEvent is ExtendedBuildWarningEventArgs extWarningEvent)
|
||||
{
|
||||
BuildEventContext = warningEvent.BuildEventContext,
|
||||
ProjectFile = warningEvent.ProjectFile,
|
||||
};
|
||||
buildEventArgs = new ExtendedBuildErrorEventArgs(
|
||||
extWarningEvent.ExtendedType,
|
||||
extWarningEvent.Subcategory,
|
||||
extWarningEvent.Code,
|
||||
extWarningEvent.File,
|
||||
extWarningEvent.LineNumber,
|
||||
extWarningEvent.ColumnNumber,
|
||||
extWarningEvent.EndLineNumber,
|
||||
extWarningEvent.EndColumnNumber,
|
||||
extWarningEvent.Message,
|
||||
extWarningEvent.HelpKeyword,
|
||||
extWarningEvent.SenderName,
|
||||
extWarningEvent.Timestamp)
|
||||
{
|
||||
BuildEventContext = warningEvent.BuildEventContext,
|
||||
ProjectFile = warningEvent.ProjectFile,
|
||||
ExtendedMetadata = extWarningEvent.ExtendedMetadata,
|
||||
ExtendedData = extWarningEvent.ExtendedData,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
buildEventArgs = new BuildErrorEventArgs(
|
||||
warningEvent.Subcategory,
|
||||
warningEvent.Code,
|
||||
warningEvent.File,
|
||||
warningEvent.LineNumber,
|
||||
warningEvent.ColumnNumber,
|
||||
warningEvent.EndLineNumber,
|
||||
warningEvent.EndColumnNumber,
|
||||
warningEvent.Message,
|
||||
warningEvent.HelpKeyword,
|
||||
warningEvent.SenderName,
|
||||
warningEvent.Timestamp)
|
||||
{
|
||||
BuildEventContext = warningEvent.BuildEventContext,
|
||||
ProjectFile = warningEvent.ProjectFile,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1080,7 +1080,9 @@ namespace Microsoft.Build.BackEnd
|
|||
internal bool IsEventSerializable(BuildEventArgs e)
|
||||
{
|
||||
#pragma warning disable SYSLIB0050
|
||||
if (!e.GetType().GetTypeInfo().IsSerializable)
|
||||
// Types which are not serializable and are not IExtendedBuildEventArgs as
|
||||
// those always implement custom serialization by WriteToStream and CreateFromStream.
|
||||
if (!e.GetType().GetTypeInfo().IsSerializable && e is not IExtendedBuildEventArgs)
|
||||
#pragma warning restore SYSLIB0050
|
||||
{
|
||||
_taskLoggingContext.LogWarning(null, new BuildEventFileInfo(string.Empty), "ExpectedEventToBeSerializable", e.GetType().Name);
|
||||
|
|
|
@ -572,7 +572,28 @@ namespace Microsoft.Build.Execution
|
|||
{
|
||||
if (_nodeEndpoint.LinkStatus == LinkStatus.Active)
|
||||
{
|
||||
#if RUNTIME_TYPE_NETCORE
|
||||
if (packet is LogMessagePacketBase logMessage
|
||||
&& logMessage.EventType == LoggingEventType.CustomEvent
|
||||
&& ChangeWaves.AreFeaturesEnabled(ChangeWaves.Wave17_8)
|
||||
&& Traits.Instance.EscapeHatches.EnableWarningOnCustomBuildEvent)
|
||||
{
|
||||
BuildEventArgs buildEvent = logMessage.NodeBuildEvent.Value.Value;
|
||||
|
||||
// Serializing unknown CustomEvent which has to use unsecure BinaryFormatter by TranslateDotNet<T>
|
||||
// Since BinaryFormatter is deprecated in dotnet 8+, log error so users discover root cause easier
|
||||
// then by reading CommTrace where it would be otherwise logged as critical infra error.
|
||||
_loggingService.LogError(_loggingContext?.BuildEventContext ?? BuildEventContext.Invalid, null, BuildEventFileInfo.Empty,
|
||||
"DeprecatedEventSerialization",
|
||||
buildEvent?.GetType().Name ?? string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
_nodeEndpoint.SendData(packet);
|
||||
}
|
||||
#else
|
||||
_nodeEndpoint.SendData(packet);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -338,7 +338,9 @@ namespace Microsoft.Build.BackEnd
|
|||
internal bool IsEventSerializable(BuildEventArgs e)
|
||||
{
|
||||
#pragma warning disable SYSLIB0050
|
||||
if (!e.GetType().GetTypeInfo().IsSerializable)
|
||||
// Types which are not serializable and are not IExtendedBuildEventArgs as
|
||||
// those always implement custom serialization by WriteToStream and CreateFromStream.
|
||||
if (!e.GetType().GetTypeInfo().IsSerializable && e is not IExtendedBuildEventArgs)
|
||||
#pragma warning restore SYSLIB0050
|
||||
{
|
||||
_loggingContext.LogWarning(null, new BuildEventFileInfo(string.Empty), "ExpectedEventToBeSerializable", e.GetType().Name);
|
||||
|
|
|
@ -156,6 +156,7 @@ namespace Microsoft.Build.Logging
|
|||
TaskCommandLine
|
||||
TaskParameter
|
||||
UninitializedPropertyRead
|
||||
ExtendedMessage
|
||||
BuildStatus
|
||||
TaskStarted
|
||||
TaskFinished
|
||||
|
@ -168,11 +169,13 @@ namespace Microsoft.Build.Logging
|
|||
ProjectEvaluationStarted
|
||||
ProjectEvaluationFinished
|
||||
BuildError
|
||||
ExtendedBuildError
|
||||
BuildWarning
|
||||
ExtendedBuildWarning
|
||||
CustomBuild
|
||||
ExternalProjectStarted
|
||||
ExternalProjectFinished
|
||||
|
||||
ExtendedCustomBuild
|
||||
*/
|
||||
|
||||
private void WriteCore(BuildEventArgs e)
|
||||
|
|
|
@ -31,7 +31,6 @@ namespace Microsoft.Build.Framework.UnitTests
|
|||
AssemblyLoadBuildEventArgs argDeserialized = new();
|
||||
int packetVersion = (Environment.Version.Major * 10) + Environment.Version.Minor;
|
||||
argDeserialized.CreateFromStream(br, packetVersion);
|
||||
|
||||
argDeserialized.LoadingInitiator.ShouldBe(loadingInitiator);
|
||||
argDeserialized.AssemblyName.ShouldBe(assemblyName);
|
||||
argDeserialized.AssemblyPath.ShouldBe(assemblyPath);
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.Build.Framework.UnitTests;
|
||||
|
||||
public class ExtendedBuildEventArgs_Tests
|
||||
{
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
[Theory]
|
||||
public void ExtendedCustomBuildEventArgs_SerializationDeserialization(bool withOptionalData)
|
||||
{
|
||||
ExtendedCustomBuildEventArgs arg = new(
|
||||
type: "TypeOfExtendedCustom",
|
||||
message: withOptionalData ? "a message with args {0} {1}" : null,
|
||||
helpKeyword: withOptionalData ? "MSBT123" : null,
|
||||
senderName: withOptionalData ? $"UnitTest {Guid.NewGuid()}" : null,
|
||||
eventTimestamp: withOptionalData ? DateTime.Parse("3/1/2017 11:11:56 AM") : DateTime.Now,
|
||||
messageArgs: withOptionalData ? new object[] { "arg0val", "arg1val" } : null)
|
||||
{
|
||||
ExtendedData = withOptionalData ? "{'long-json':'mostly-strings'}" : null,
|
||||
ExtendedMetadata = withOptionalData ? new Dictionary<string, string?> { {"m1", "v1" }, { "m2", "v2" } } : null,
|
||||
BuildEventContext = withOptionalData ? new BuildEventContext(1, 2, 3, 4, 5, 6, 7) : null,
|
||||
};
|
||||
|
||||
using MemoryStream stream = new MemoryStream();
|
||||
using BinaryWriter bw = new BinaryWriter(stream);
|
||||
arg.WriteToStream(bw);
|
||||
|
||||
stream.Position = 0;
|
||||
using BinaryReader br = new BinaryReader(stream);
|
||||
ExtendedCustomBuildEventArgs argDeserialized = new();
|
||||
argDeserialized.CreateFromStream(br, 80);
|
||||
|
||||
argDeserialized.Should().BeEquivalentTo(arg);
|
||||
}
|
||||
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
[Theory]
|
||||
public void ExtendedErrorEventArgs_SerializationDeserialization(bool withOptionalData)
|
||||
{
|
||||
ExtendedBuildErrorEventArgs arg = new(
|
||||
type: "TypeOfExtendedCustom",
|
||||
subcategory: withOptionalData ? "sub-type" : null,
|
||||
code: withOptionalData ? "a-code" : null,
|
||||
file: withOptionalData ? ".\\dev\\my.csproj" : null,
|
||||
lineNumber: withOptionalData ? 1 : default,
|
||||
columnNumber: withOptionalData ? 2 : default,
|
||||
endLineNumber: withOptionalData ? 3 : default,
|
||||
endColumnNumber: withOptionalData ? 4 : default,
|
||||
message: withOptionalData ? "a message with args {0} {1}" : null,
|
||||
helpKeyword: withOptionalData ? "MSBT123" : null,
|
||||
senderName: withOptionalData ? $"UnitTest {Guid.NewGuid()}" : null,
|
||||
helpLink: withOptionalData ? "(001)2234456" : null,
|
||||
eventTimestamp: withOptionalData ? DateTime.Parse("3/1/2017 11:11:56 AM") : DateTime.Now,
|
||||
messageArgs: withOptionalData ? new object[] { "arg0val", "arg1val" } : null)
|
||||
{
|
||||
ExtendedData = withOptionalData ? "{'long-json':'mostly-strings'}" : null,
|
||||
ExtendedMetadata = withOptionalData ? new Dictionary<string, string?> { { "m1", "v1" }, { "m2", "v2" } } : null,
|
||||
BuildEventContext = withOptionalData ? new BuildEventContext(1, 2, 3, 4, 5, 6, 7) : null,
|
||||
};
|
||||
|
||||
using MemoryStream stream = new MemoryStream();
|
||||
using BinaryWriter bw = new BinaryWriter(stream);
|
||||
arg.WriteToStream(bw);
|
||||
|
||||
stream.Position = 0;
|
||||
using BinaryReader br = new BinaryReader(stream);
|
||||
ExtendedBuildErrorEventArgs argDeserialized = new();
|
||||
argDeserialized.CreateFromStream(br, 80);
|
||||
|
||||
argDeserialized.Should().BeEquivalentTo(arg);
|
||||
}
|
||||
|
||||
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
[Theory]
|
||||
public void ExtendedWarningEventArgs_SerializationDeserialization(bool withOptionalData)
|
||||
{
|
||||
ExtendedBuildWarningEventArgs arg = new(
|
||||
type: "TypeOfExtendedCustom",
|
||||
subcategory: withOptionalData ? "sub-type" : null,
|
||||
code: withOptionalData ? "a-code" : null,
|
||||
file: withOptionalData ? ".\\dev\\my.csproj" : null,
|
||||
lineNumber: withOptionalData ? 1 : default,
|
||||
columnNumber: withOptionalData ? 2 : default,
|
||||
endLineNumber: withOptionalData ? 3 : default,
|
||||
endColumnNumber: withOptionalData ? 4 : default,
|
||||
message: withOptionalData ? "a message with args {0} {1}" : null,
|
||||
helpKeyword: withOptionalData ? "MSBT123" : null,
|
||||
senderName: withOptionalData ? $"UnitTest {Guid.NewGuid()}" : null,
|
||||
helpLink: withOptionalData ? "(001)2234456" : null,
|
||||
eventTimestamp: withOptionalData ? DateTime.Parse("3/1/2017 11:11:56 AM") : DateTime.Now,
|
||||
messageArgs: withOptionalData ? new object[] { "arg0val", "arg1val" } : null)
|
||||
{
|
||||
ExtendedData = withOptionalData ? "{'long-json':'mostly-strings'}" : null,
|
||||
ExtendedMetadata = withOptionalData ? new Dictionary<string, string?> { { "m1", "v1" }, { "m2", "v2" } } : null,
|
||||
BuildEventContext = withOptionalData ? new BuildEventContext(1, 2, 3, 4, 5, 6, 7) : null,
|
||||
};
|
||||
|
||||
using MemoryStream stream = new MemoryStream();
|
||||
using BinaryWriter bw = new BinaryWriter(stream);
|
||||
arg.WriteToStream(bw);
|
||||
|
||||
stream.Position = 0;
|
||||
using BinaryReader br = new BinaryReader(stream);
|
||||
ExtendedBuildWarningEventArgs argDeserialized = new();
|
||||
argDeserialized.CreateFromStream(br, 80);
|
||||
|
||||
argDeserialized.Should().BeEquivalentTo(arg);
|
||||
}
|
||||
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
[Theory]
|
||||
public void ExtendedMessageEventArgs_SerializationDeserialization(bool withOptionalData)
|
||||
{
|
||||
ExtendedBuildMessageEventArgs arg = new(
|
||||
type: "TypeOfExtendedCustom",
|
||||
subcategory: withOptionalData ? "sub-type" : null,
|
||||
code: withOptionalData ? "a-code" : null,
|
||||
file: withOptionalData ? ".\\dev\\my.csproj" : null,
|
||||
lineNumber: withOptionalData ? 1 : default,
|
||||
columnNumber: withOptionalData ? 2 : default,
|
||||
endLineNumber: withOptionalData ? 3 : default,
|
||||
endColumnNumber: withOptionalData ? 4 : default,
|
||||
message: withOptionalData ? "a message with args {0} {1}" : null,
|
||||
helpKeyword: withOptionalData ? "MSBT123" : null,
|
||||
senderName: withOptionalData ? $"UnitTest {Guid.NewGuid()}" : null,
|
||||
importance: withOptionalData ? MessageImportance.Normal : default,
|
||||
eventTimestamp: withOptionalData ? DateTime.Parse("3/1/2017 11:11:56 AM") : DateTime.Now,
|
||||
messageArgs: withOptionalData ? new object[] { "arg0val", "arg1val" } : null)
|
||||
{
|
||||
ExtendedData = withOptionalData ? "{'long-json':'mostly-strings'}" : null,
|
||||
ExtendedMetadata = withOptionalData ? new Dictionary<string, string?> { { "m1", "v1" }, { "m2", "v2" } } : null,
|
||||
BuildEventContext = withOptionalData ? new BuildEventContext(1, 2, 3, 4, 5, 6, 7) : null,
|
||||
};
|
||||
|
||||
using MemoryStream stream = new MemoryStream();
|
||||
using BinaryWriter bw = new BinaryWriter(stream);
|
||||
arg.WriteToStream(bw);
|
||||
|
||||
stream.Position = 0;
|
||||
using BinaryReader br = new BinaryReader(stream);
|
||||
ExtendedBuildMessageEventArgs argDeserialized = new();
|
||||
argDeserialized.CreateFromStream(br, 80);
|
||||
|
||||
argDeserialized.Should().BeEquivalentTo(arg);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtendedCustomBuildEventArgs_Ctors()
|
||||
{
|
||||
var ea = new ExtendedCustomBuildEventArgs();
|
||||
ea = new ExtendedCustomBuildEventArgs("type");
|
||||
ea = new ExtendedCustomBuildEventArgs("type", "Message {0}", "Help", "sender");
|
||||
ea = new ExtendedCustomBuildEventArgs("type", "Message {0}", "Help", "sender", DateTime.Now);
|
||||
ea = new ExtendedCustomBuildEventArgs("type", "Message {0}", "Help", "sender", DateTime.Now, "arg1");
|
||||
ea = new ExtendedCustomBuildEventArgs("type");
|
||||
ea = new ExtendedCustomBuildEventArgs("type", null, null, null);
|
||||
ea = new ExtendedCustomBuildEventArgs("type", null, null, null, default(DateTime));
|
||||
ea = new ExtendedCustomBuildEventArgs("type", null, null, null, default(DateTime), null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtendedBuildErrorEventArgs_Ctors()
|
||||
{
|
||||
var ea = new ExtendedBuildErrorEventArgs();
|
||||
ea = new ExtendedBuildErrorEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "Message", "HelpKeyword", "sender");
|
||||
ea = new ExtendedBuildErrorEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "Message", "HelpKeyword", "sender", DateTime.Now);
|
||||
ea = new ExtendedBuildErrorEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "{0}", "HelpKeyword", "sender", DateTime.Now, "Message");
|
||||
ea = new ExtendedBuildErrorEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "{0}", "HelpKeyword", "sender", "HelpLink", DateTime.Now, "Message");
|
||||
ea = new ExtendedBuildErrorEventArgs("type", null, null, null, 1, 2, 3, 4, null, null, null);
|
||||
ea = new ExtendedBuildErrorEventArgs("type", null, null, null, 1, 2, 3, 4, null, null, null, DateTime.Now);
|
||||
ea = new ExtendedBuildErrorEventArgs("type", null, null, null, 1, 2, 3, 4, null, null, null, null, DateTime.Now, null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtendedBuildWarningEventArgs_Ctors()
|
||||
{
|
||||
var ea = new ExtendedBuildWarningEventArgs();
|
||||
ea = new ExtendedBuildWarningEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "Message", "HelpKeyword", "sender");
|
||||
ea = new ExtendedBuildWarningEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "Message", "HelpKeyword", "sender", DateTime.Now);
|
||||
ea = new ExtendedBuildWarningEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "{0}", "HelpKeyword", "sender", DateTime.Now, "Message");
|
||||
ea = new ExtendedBuildWarningEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "{0}", "HelpKeyword", "sender", "HelpLink", DateTime.Now, "Message");
|
||||
ea = new ExtendedBuildWarningEventArgs("type", null, null, null, 1, 2, 3, 4, null, null, null);
|
||||
ea = new ExtendedBuildWarningEventArgs("type", null, null, null, 1, 2, 3, 4, null, null, null, DateTime.Now);
|
||||
ea = new ExtendedBuildWarningEventArgs("type", null, null, null, 1, 2, 3, 4, null, null, null, null, DateTime.Now, null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExtendedBuildMessageEventArgs_Ctors()
|
||||
{
|
||||
var ea = new ExtendedBuildMessageEventArgs();
|
||||
ea = new ExtendedBuildMessageEventArgs("type");
|
||||
ea = new ExtendedBuildMessageEventArgs("type", "Message", "HelpKeyword", "sender", MessageImportance.High);
|
||||
ea = new ExtendedBuildMessageEventArgs("type", "Message", "HelpKeyword", "sender", MessageImportance.High, DateTime.Now);
|
||||
ea = new ExtendedBuildMessageEventArgs("type", "Message", "HelpKeyword", "sender", MessageImportance.High, DateTime.Now, "arg1");
|
||||
ea = new ExtendedBuildMessageEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "Message", "HelpKeyword", "sender", MessageImportance.High);
|
||||
ea = new ExtendedBuildMessageEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "Message", "HelpKeyword", "sender", MessageImportance.High, DateTime.Now);
|
||||
ea = new ExtendedBuildMessageEventArgs("type", "Subcategory", "Code", "File", 1, 2, 3, 4, "{0}", "HelpKeyword", "sender", MessageImportance.High, DateTime.Now, "Message");
|
||||
ea = new ExtendedBuildMessageEventArgs("type");
|
||||
ea = new ExtendedBuildMessageEventArgs("type", null, null, null, default);
|
||||
ea = new ExtendedBuildMessageEventArgs("type", null, null, null, default, DateTime.Now);
|
||||
ea = new ExtendedBuildMessageEventArgs("type", null, null, null, default, default, null);
|
||||
ea = new ExtendedBuildMessageEventArgs("type", null, null, null, 1, 2, 3, 4, null, null, null, default);
|
||||
ea = new ExtendedBuildMessageEventArgs("type", null, null, null, 1, 2, 3, 4, null, null, null, default, DateTime.Now);
|
||||
ea = new ExtendedBuildMessageEventArgs("type", null, null, null, 1, 2, 3, 4, null, null, null, default, DateTime.Now, null);
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" />
|
||||
<PackageReference Include="Microsoft.IO.Redist" Condition="'$(FeatureMSIORedist)' == 'true'" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Setup.Configuration.Interop" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Shared;
|
||||
|
||||
namespace Microsoft.Build.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Generic custom error events including extended data for event enriching.
|
||||
/// Extended data are implemented by <see cref="IExtendedBuildEventArgs"/>
|
||||
/// </summary>
|
||||
public sealed class ExtendedBuildErrorEventArgs : BuildErrorEventArgs, IExtendedBuildEventArgs
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string ExtendedType { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, string?>? ExtendedMetadata { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string? ExtendedData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor. Used for deserialization.
|
||||
/// </summary>
|
||||
internal ExtendedBuildErrorEventArgs() : this("undefined") { }
|
||||
|
||||
/// <summary>
|
||||
/// This constructor specifies only type of extended data.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
public ExtendedBuildErrorEventArgs(string type) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows all event data to be initialized
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
public ExtendedBuildErrorEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor which allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
public ExtendedBuildErrorEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName, DateTime eventTimestamp)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName, eventTimestamp) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor which allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
/// <param name="messageArgs">message arguments</param>
|
||||
public ExtendedBuildErrorEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName, DateTime eventTimestamp, params object[]? messageArgs)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName, eventTimestamp, messageArgs) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor which allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="helpLink">A link pointing to more information about the error </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
/// <param name="messageArgs">message arguments</param>
|
||||
public ExtendedBuildErrorEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName, string? helpLink, DateTime eventTimestamp, params object[]? messageArgs)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName, helpLink, eventTimestamp, messageArgs) => ExtendedType = type;
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
writer.WriteExtendedBuildEventData(this);
|
||||
}
|
||||
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
reader.ReadExtendedBuildEventData(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Shared;
|
||||
|
||||
namespace Microsoft.Build.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Generic custom build events including extended data for event enriching.
|
||||
/// Extended data are implemented by <see cref="IExtendedBuildEventArgs"/>
|
||||
/// </summary>
|
||||
public sealed class ExtendedBuildMessageEventArgs : BuildMessageEventArgs, IExtendedBuildEventArgs
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string ExtendedType { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, string?>? ExtendedMetadata { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string? ExtendedData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor. Used for deserialization.
|
||||
/// </summary>
|
||||
internal ExtendedBuildMessageEventArgs() : this("undefined") { }
|
||||
|
||||
/// <summary>
|
||||
/// This constructor specifies only type of extended data.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
public ExtendedBuildMessageEventArgs(string type) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows all event data to be initialized
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="importance">importance of the message</param>
|
||||
public ExtendedBuildMessageEventArgs(string type, string? message, string? helpKeyword, string? senderName, MessageImportance importance)
|
||||
: base(message, helpKeyword, senderName, importance) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="importance">importance of the message</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
public ExtendedBuildMessageEventArgs(string type, string? message, string? helpKeyword, string? senderName, MessageImportance importance, DateTime eventTimestamp)
|
||||
: base(message, helpKeyword, senderName, importance, eventTimestamp) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="importance">importance of the message</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
/// <param name="messageArgs">message arguments</param>
|
||||
public ExtendedBuildMessageEventArgs(string type, string? message, string? helpKeyword, string? senderName, MessageImportance importance, DateTime eventTimestamp, params object[]? messageArgs)
|
||||
: base(message, helpKeyword, senderName, importance, eventTimestamp, messageArgs) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows all event data to be initialized
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="importance">importance of the message</param>
|
||||
public ExtendedBuildMessageEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName, MessageImportance importance)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName, importance) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor which allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="importance">importance of the message</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
public ExtendedBuildMessageEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName, MessageImportance importance, DateTime eventTimestamp)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName, importance, eventTimestamp) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor which allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="importance">importance of the message</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
/// <param name="messageArgs">message arguments</param>
|
||||
public ExtendedBuildMessageEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName, MessageImportance importance, DateTime eventTimestamp, params object[]? messageArgs)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName, importance, eventTimestamp, messageArgs) => ExtendedType = type;
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
writer.WriteExtendedBuildEventData(this);
|
||||
}
|
||||
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
reader.ReadExtendedBuildEventData(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Shared;
|
||||
|
||||
namespace Microsoft.Build.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Generic custom warning events including extended data for event enriching.
|
||||
/// Extended data are implemented by <see cref="IExtendedBuildEventArgs"/>
|
||||
/// </summary>
|
||||
public sealed class ExtendedBuildWarningEventArgs : BuildWarningEventArgs, IExtendedBuildEventArgs
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string ExtendedType { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, string?>? ExtendedMetadata { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string? ExtendedData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor. Used for deserialization.
|
||||
/// </summary>
|
||||
internal ExtendedBuildWarningEventArgs() : this("undefined") { }
|
||||
|
||||
/// <summary>
|
||||
/// This constructor specifies only type of extended data.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
public ExtendedBuildWarningEventArgs(string type) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows all event data to be initialized
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
public ExtendedBuildWarningEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor which allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
public ExtendedBuildWarningEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName, DateTime eventTimestamp)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName, eventTimestamp) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor which allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
/// <param name="messageArgs">message arguments</param>
|
||||
public ExtendedBuildWarningEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName, DateTime eventTimestamp, params object[]? messageArgs)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName, eventTimestamp, messageArgs) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor which allows a timestamp to be set
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="subcategory">event sub-category</param>
|
||||
/// <param name="code">event code</param>
|
||||
/// <param name="file">file associated with the event</param>
|
||||
/// <param name="lineNumber">line number (0 if not applicable)</param>
|
||||
/// <param name="columnNumber">column number (0 if not applicable)</param>
|
||||
/// <param name="endLineNumber">end line number (0 if not applicable)</param>
|
||||
/// <param name="endColumnNumber">end column number (0 if not applicable)</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="helpLink">A link pointing to more information about the error </param>
|
||||
/// <param name="senderName">name of event sender</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
/// <param name="messageArgs">message arguments</param>
|
||||
public ExtendedBuildWarningEventArgs(string type, string? subcategory, string? code, string? file, int lineNumber, int columnNumber, int endLineNumber, int endColumnNumber,
|
||||
string? message, string? helpKeyword, string? senderName, string? helpLink, DateTime eventTimestamp, params object[]? messageArgs)
|
||||
: base(subcategory, code, file, lineNumber, columnNumber, endLineNumber, endColumnNumber, message, helpKeyword, senderName, helpLink, eventTimestamp, messageArgs) => ExtendedType = type;
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
writer.WriteExtendedBuildEventData(this);
|
||||
}
|
||||
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
reader.ReadExtendedBuildEventData(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Shared;
|
||||
|
||||
namespace Microsoft.Build.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Generic custom event.
|
||||
/// Extended data are implemented by <see cref="IExtendedBuildEventArgs"/>
|
||||
/// </summary>
|
||||
public sealed class ExtendedCustomBuildEventArgs : CustomBuildEventArgs, IExtendedBuildEventArgs
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string ExtendedType { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, string?>? ExtendedMetadata { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string? ExtendedData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows event data to be initialized.
|
||||
/// </summary>
|
||||
/// <seealso cref="IExtendedBuildEventArgs.ExtendedType"/>
|
||||
internal ExtendedCustomBuildEventArgs() : this("undefined") {}
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows event data to be initialized.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <seealso cref="IExtendedBuildEventArgs.ExtendedType"/>
|
||||
public ExtendedCustomBuildEventArgs(string type) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows event data to be initialized.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of sender</param>
|
||||
public ExtendedCustomBuildEventArgs(string type, string? message, string? helpKeyword, string? senderName) : base(message, helpKeyword, senderName) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows event data to be initialized including timestamp.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of sender</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
public ExtendedCustomBuildEventArgs(string type, string? message, string? helpKeyword, string? senderName, DateTime eventTimestamp) : base(message, helpKeyword, senderName, eventTimestamp) => ExtendedType = type;
|
||||
|
||||
/// <summary>
|
||||
/// This constructor allows event data to be initialized including timestamp.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of <see cref="IExtendedBuildEventArgs.ExtendedType"/>.</param>
|
||||
/// <param name="message">text message</param>
|
||||
/// <param name="helpKeyword">help keyword </param>
|
||||
/// <param name="senderName">name of sender</param>
|
||||
/// <param name="eventTimestamp">Timestamp when event was created</param>
|
||||
/// <param name="messageArgs">Message arguments</param>
|
||||
public ExtendedCustomBuildEventArgs(string type, string? message, string? helpKeyword, string? senderName, DateTime eventTimestamp, params object[]? messageArgs) : base(message, helpKeyword, senderName, eventTimestamp, messageArgs) => ExtendedType = type;
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
writer.WriteExtendedBuildEventData(this);
|
||||
}
|
||||
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
reader.ReadExtendedBuildEventData(this);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Shared;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -16,6 +18,8 @@ namespace Microsoft.Build.Framework
|
|||
// immutable; adding new fields in the next version of the type
|
||||
// without following certain special FX guidelines, can break both
|
||||
// forward and backward compatibility
|
||||
// NOTE: Although this class has been modified and do not longer relay on [Serializable]
|
||||
// and BinaryFormatter. We have left it [Serializable] for backward compatibility reasons.
|
||||
[Serializable]
|
||||
public class ExternalProjectFinishedEventArgs : CustomBuildEventArgs
|
||||
{
|
||||
|
@ -93,5 +97,19 @@ namespace Microsoft.Build.Framework
|
|||
return succeeded;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
writer.WriteOptionalString(projectFile);
|
||||
writer.Write(succeeded);
|
||||
}
|
||||
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
projectFile = reader.ReadOptionalString();
|
||||
succeeded = reader.ReadBoolean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Shared;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -16,6 +18,8 @@ namespace Microsoft.Build.Framework
|
|||
// immutable; adding new fields in the next version of the type
|
||||
// without following certain special FX guidelines, can break both
|
||||
// forward and backward compatibility
|
||||
// NOTE: Although this class has been modified and do not longer relay on [Serializable]
|
||||
// and BinaryFormatter. We have left it [Serializable] for backward compatibility reasons.
|
||||
[Serializable]
|
||||
public class ExternalProjectStartedEventArgs : CustomBuildEventArgs
|
||||
{
|
||||
|
@ -95,5 +99,19 @@ namespace Microsoft.Build.Framework
|
|||
return targetNames;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
writer.WriteOptionalString(projectFile);
|
||||
writer.WriteOptionalString(targetNames);
|
||||
}
|
||||
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
projectFile = reader.ReadOptionalString();
|
||||
targetNames = reader.ReadOptionalString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Microsoft.Build.Framework;
|
||||
|
||||
/// <summary>
|
||||
/// Interface for Extended EventArgs to allow enriching particular events with extended data.
|
||||
/// Deriving from EventArgs will be deprecated soon and using Extended EventArgs is recommended for custom Event Args.
|
||||
/// </summary>
|
||||
public interface IExtendedBuildEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique string identifying type of extended data so receiver side knows how to interpret, deserialize and handle <see cref="ExtendedData"/>.
|
||||
/// </summary>
|
||||
string ExtendedType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Metadata of <see cref="ExtendedData"/>.
|
||||
/// Example usage:
|
||||
/// - data which needed in custom code to properly routing this message without interpreting/deserializing <see cref="ExtendedData"/>.
|
||||
/// - simple extended data can be transferred in form of dictionary key-value per one extended property.
|
||||
/// </summary>
|
||||
Dictionary<string, string?>? ExtendedMetadata { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Transparent data as string.
|
||||
/// Custom code is responsible to serialize and deserialize this string to structured data - if needed.
|
||||
/// Custom code can use any serialization they deem safe - e.g. json for textual data, base64 for binary data...
|
||||
/// </summary>
|
||||
string? ExtendedData { get; set; }
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using Microsoft.Build.Shared;
|
||||
using System.IO;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -27,5 +29,19 @@ namespace Microsoft.Build.Framework
|
|||
this.metaprojectXml = metaprojectXml;
|
||||
this.ProjectFile = metaprojectPath;
|
||||
}
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
|
||||
writer.WriteOptionalString(metaprojectXml);
|
||||
}
|
||||
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
|
||||
metaprojectXml = reader.ReadOptionalString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Shared;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -56,5 +58,23 @@ namespace Microsoft.Build.Framework
|
|||
/// The source of the property.
|
||||
/// </summary>
|
||||
public string PropertySource { get; set; }
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
|
||||
writer.WriteOptionalString(PropertyName);
|
||||
writer.WriteOptionalString(PropertyValue);
|
||||
writer.WriteOptionalString(PropertySource);
|
||||
}
|
||||
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
|
||||
PropertyName = reader.ReadOptionalString();
|
||||
PropertyValue = reader.ReadOptionalString();
|
||||
PropertySource = reader.ReadOptionalString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Shared;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -79,5 +81,25 @@ namespace Microsoft.Build.Framework
|
|||
return RawMessage;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
|
||||
writer.WriteOptionalString(PropertyName);
|
||||
writer.WriteOptionalString(NewValue);
|
||||
writer.WriteOptionalString(PreviousValue);
|
||||
writer.WriteOptionalString(Location);
|
||||
}
|
||||
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
|
||||
PropertyName = reader.ReadOptionalString();
|
||||
NewValue = reader.ReadOptionalString();
|
||||
PreviousValue = reader.ReadOptionalString();
|
||||
Location = reader.ReadOptionalString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -372,6 +372,29 @@ namespace Microsoft.Build.Framework
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows displaying the deprecation warning for BinaryFormatter in your current environment.
|
||||
/// </summary>
|
||||
public bool EnableWarningOnCustomBuildEvent
|
||||
{
|
||||
get
|
||||
{
|
||||
var value = Environment.GetEnvironmentVariable("MSBUILDCUSTOMBUILDEVENTWARNING");
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
// If variable is not set explicitly, for .NETCORE warning appears.
|
||||
#if RUNTIME_TYPE_NETCORE
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
return value == "1";
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? ParseNullableBoolFromEnvironmentVariable(string environmentVariable)
|
||||
{
|
||||
var value = Environment.GetEnvironmentVariable(environmentVariable);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Build.Shared;
|
||||
|
||||
#nullable disable
|
||||
|
||||
|
@ -42,5 +44,18 @@ namespace Microsoft.Build.Framework
|
|||
/// The name of the uninitialized property that was read.
|
||||
/// </summary>
|
||||
public string PropertyName { get; set; }
|
||||
|
||||
internal override void WriteToStream(BinaryWriter writer)
|
||||
{
|
||||
base.WriteToStream(writer);
|
||||
|
||||
writer.WriteOptionalString(PropertyName);
|
||||
}
|
||||
internal override void CreateFromStream(BinaryReader reader, int version)
|
||||
{
|
||||
base.CreateFromStream(reader, version);
|
||||
|
||||
PropertyName = reader.ReadOptionalString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1147,7 +1147,9 @@ namespace Microsoft.Build.CommandLine
|
|||
if (_nodeEndpoint?.LinkStatus == LinkStatus.Active)
|
||||
{
|
||||
#pragma warning disable SYSLIB0050
|
||||
if (!e.GetType().GetTypeInfo().IsSerializable)
|
||||
// Types which are not serializable and are not IExtendedBuildEventArgs as
|
||||
// those always implement custom serialization by WriteToStream and CreateFromStream.
|
||||
if (!e.GetType().GetTypeInfo().IsSerializable && e is not IExtendedBuildEventArgs)
|
||||
#pragma warning disable SYSLIB0050
|
||||
{
|
||||
// log a warning and bail. This will end up re-calling SendBuildEvent, but we know for a fact
|
||||
|
@ -1156,7 +1158,8 @@ namespace Microsoft.Build.CommandLine
|
|||
return;
|
||||
}
|
||||
|
||||
_nodeEndpoint.SendData(new LogMessagePacket(new KeyValuePair<int, BuildEventArgs>(_currentConfiguration.NodeId, e)));
|
||||
LogMessagePacket logMessage = new LogMessagePacket(new KeyValuePair<int, BuildEventArgs>(_currentConfiguration.NodeId, e));
|
||||
_nodeEndpoint.SendData(logMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,9 @@
|
|||
<Compile Include="..\Framework\ITaskItem2.cs">
|
||||
<Link>ITaskItem2.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Framework\IExtendedBuildEventArgs.cs">
|
||||
<Link>IExtendedBuildEventArgs.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Framework\AssemblyUtilities.cs" />
|
||||
<Compile Include="..\Framework\ResponseFileUsedEventArgs.cs" />
|
||||
<Compile Include="..\Shared\BufferedReadStream.cs" />
|
||||
|
|
|
@ -99,5 +99,30 @@ namespace Microsoft.Build.Shared
|
|||
{
|
||||
return new Guid(reader.ReadBytes(sizeof(Guid)));
|
||||
}
|
||||
|
||||
public static void ReadExtendedBuildEventData(this BinaryReader reader, IExtendedBuildEventArgs data)
|
||||
{
|
||||
data.ExtendedType = reader.ReadString();
|
||||
data.ExtendedData = reader.ReadOptionalString();
|
||||
|
||||
bool haveMetadata = reader.ReadBoolean();
|
||||
if (haveMetadata)
|
||||
{
|
||||
data.ExtendedMetadata = new();
|
||||
|
||||
int count = reader.Read7BitEncodedInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
string key = reader.ReadString();
|
||||
string? value = reader.ReadOptionalString();
|
||||
|
||||
data.ExtendedMetadata.Add(key, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data.ExtendedMetadata = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.Build.Framework;
|
||||
|
@ -111,5 +112,22 @@ namespace Microsoft.Build.Shared
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteExtendedBuildEventData(this BinaryWriter writer, IExtendedBuildEventArgs data)
|
||||
{
|
||||
writer.Write(data.ExtendedType);
|
||||
writer.WriteOptionalString(data.ExtendedData);
|
||||
|
||||
writer.Write(data.ExtendedMetadata != null);
|
||||
if (data.ExtendedMetadata != null)
|
||||
{
|
||||
writer.Write7BitEncodedInt(data.ExtendedMetadata.Count);
|
||||
foreach (KeyValuePair<string, string?> kvp in data.ExtendedMetadata)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
writer.WriteOptionalString(kvp.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,6 +145,61 @@ namespace Microsoft.Build.Shared
|
|||
/// Event is an AssemblyLoadBuildEventArgs
|
||||
/// </summary>
|
||||
AssemblyLoadEvent = 21,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="ExternalProjectStartedEventArgs"/>
|
||||
/// </summary>
|
||||
ExternalProjectStartedEvent = 22,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="ExternalProjectFinishedEventArgs"/>
|
||||
/// </summary>
|
||||
ExternalProjectFinishedEvent = 23,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="ExtendedCustomBuildEventArgs"/>
|
||||
/// </summary>
|
||||
ExtendedCustomEvent = 24,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="ExtendedBuildErrorEventArgs"/>
|
||||
/// </summary>
|
||||
ExtendedBuildErrorEvent = 25,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="ExtendedBuildWarningEventArgs"/>
|
||||
/// </summary>
|
||||
ExtendedBuildWarningEvent = 26,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="ExtendedBuildMessageEventArgs"/>
|
||||
/// </summary>
|
||||
ExtendedBuildMessageEvent = 27,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="CriticalBuildMessageEventArgs"/>
|
||||
/// </summary>
|
||||
CriticalBuildMessage = 28,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="MetaprojectGeneratedEventArgs"/>
|
||||
/// </summary>
|
||||
MetaprojectGenerated = 29,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="PropertyInitialValueSetEventArgs"/>
|
||||
/// </summary>
|
||||
PropertyInitialValueSet = 30,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="PropertyReassignmentEventArgs"/>
|
||||
/// </summary>
|
||||
PropertyReassignment = 31,
|
||||
|
||||
/// <summary>
|
||||
/// Event is <see cref="UninitializedPropertyReadEventArgs"/>
|
||||
/// </summary>
|
||||
UninitializedPropertyRead = 32
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
@ -230,8 +285,9 @@ namespace Microsoft.Build.Shared
|
|||
/// <summary>
|
||||
/// Constructor for deserialization
|
||||
/// </summary>
|
||||
protected LogMessagePacketBase(ITranslator translator)
|
||||
protected LogMessagePacketBase(ITranslator translator, TargetFinishedTranslator targetFinishedTranslator = null)
|
||||
{
|
||||
_targetFinishedTranslator = targetFinishedTranslator;
|
||||
Translate(translator);
|
||||
}
|
||||
|
||||
|
@ -339,7 +395,8 @@ namespace Microsoft.Build.Shared
|
|||
#if !TASKHOST && !MSBUILDENTRYPOINTEXE
|
||||
if (_buildEvent is ProjectEvaluationStartedEventArgs
|
||||
or ProjectEvaluationFinishedEventArgs
|
||||
or EnvironmentVariableReadEventArgs)
|
||||
or EnvironmentVariableReadEventArgs
|
||||
or ResponseFileUsedEventArgs)
|
||||
{
|
||||
// switch to serialization methods that we provide in this file
|
||||
// and don't use the WriteToStream inherited from LazyFormattedBuildEventArgs
|
||||
|
@ -536,6 +593,17 @@ namespace Microsoft.Build.Shared
|
|||
LoggingEventType.ProjectImportedEvent => new ProjectImportedEventArgs(),
|
||||
LoggingEventType.TargetSkipped => new TargetSkippedEventArgs(),
|
||||
LoggingEventType.Telemetry => new TelemetryEventArgs(),
|
||||
LoggingEventType.ExtendedCustomEvent => new ExtendedCustomBuildEventArgs(),
|
||||
LoggingEventType.ExtendedBuildErrorEvent => new ExtendedBuildErrorEventArgs(),
|
||||
LoggingEventType.ExtendedBuildWarningEvent => new ExtendedBuildWarningEventArgs(),
|
||||
LoggingEventType.ExtendedBuildMessageEvent => new ExtendedBuildMessageEventArgs(),
|
||||
LoggingEventType.ExternalProjectStartedEvent => new ExternalProjectStartedEventArgs(null, null, null, null, null),
|
||||
LoggingEventType.ExternalProjectFinishedEvent => new ExternalProjectFinishedEventArgs(null, null, null, null, false),
|
||||
LoggingEventType.CriticalBuildMessage => new CriticalBuildMessageEventArgs(null, null, null, -1, -1, -1, -1, null, null, null),
|
||||
LoggingEventType.MetaprojectGenerated => new MetaprojectGeneratedEventArgs(null, null, null),
|
||||
LoggingEventType.PropertyInitialValueSet => new PropertyInitialValueSetEventArgs(),
|
||||
LoggingEventType.PropertyReassignment => new PropertyReassignmentEventArgs(),
|
||||
LoggingEventType.UninitializedPropertyRead => new UninitializedPropertyReadEventArgs(),
|
||||
#endif
|
||||
_ => throw new InternalErrorException("Should not get to the default of GetBuildEventArgFromId ID: " + _eventType)
|
||||
};
|
||||
|
@ -573,6 +641,15 @@ namespace Microsoft.Build.Shared
|
|||
{
|
||||
return LoggingEventType.ProjectStartedEvent;
|
||||
}
|
||||
else if (eventType == typeof(ExternalProjectStartedEventArgs))
|
||||
{
|
||||
return LoggingEventType.ExternalProjectStartedEvent;
|
||||
}
|
||||
else if (eventType == typeof(ExternalProjectFinishedEventArgs))
|
||||
{
|
||||
return LoggingEventType.ExternalProjectFinishedEvent;
|
||||
}
|
||||
|
||||
#if !TASKHOST
|
||||
else if (eventType == typeof(ProjectEvaluationFinishedEventArgs))
|
||||
{
|
||||
|
@ -598,6 +675,42 @@ namespace Microsoft.Build.Shared
|
|||
{
|
||||
return LoggingEventType.AssemblyLoadEvent;
|
||||
}
|
||||
else if (eventType == typeof(ExtendedCustomBuildEventArgs))
|
||||
{
|
||||
return LoggingEventType.ExtendedCustomEvent;
|
||||
}
|
||||
else if (eventType == typeof(ExtendedBuildErrorEventArgs))
|
||||
{
|
||||
return LoggingEventType.ExtendedBuildErrorEvent;
|
||||
}
|
||||
else if (eventType == typeof(ExtendedBuildWarningEventArgs))
|
||||
{
|
||||
return LoggingEventType.ExtendedBuildWarningEvent;
|
||||
}
|
||||
else if (eventType == typeof(ExtendedBuildMessageEventArgs))
|
||||
{
|
||||
return LoggingEventType.ExtendedBuildMessageEvent;
|
||||
}
|
||||
else if (eventType == typeof(CriticalBuildMessageEventArgs))
|
||||
{
|
||||
return LoggingEventType.CriticalBuildMessage;
|
||||
}
|
||||
else if (eventType == typeof(MetaprojectGeneratedEventArgs))
|
||||
{
|
||||
return LoggingEventType.MetaprojectGenerated;
|
||||
}
|
||||
else if (eventType == typeof(PropertyInitialValueSetEventArgs))
|
||||
{
|
||||
return LoggingEventType.PropertyInitialValueSet;
|
||||
}
|
||||
else if (eventType == typeof(PropertyReassignmentEventArgs))
|
||||
{
|
||||
return LoggingEventType.PropertyReassignment;
|
||||
}
|
||||
else if (eventType == typeof(UninitializedPropertyReadEventArgs))
|
||||
{
|
||||
return LoggingEventType.UninitializedPropertyRead;
|
||||
}
|
||||
#endif
|
||||
else if (eventType == typeof(TargetStartedEventArgs))
|
||||
{
|
||||
|
@ -690,12 +803,6 @@ namespace Microsoft.Build.Shared
|
|||
case LoggingEventType.BuildWarningEvent:
|
||||
WriteBuildWarningEventToStream((BuildWarningEventArgs)buildEvent, translator);
|
||||
break;
|
||||
case LoggingEventType.ProjectStartedEvent:
|
||||
WriteExternalProjectStartedEventToStream((ExternalProjectStartedEventArgs)buildEvent, translator);
|
||||
break;
|
||||
case LoggingEventType.ProjectFinishedEvent:
|
||||
WriteExternalProjectFinishedEventToStream((ExternalProjectFinishedEventArgs)buildEvent, translator);
|
||||
break;
|
||||
case LoggingEventType.EnvironmentVariableReadEvent:
|
||||
WriteEnvironmentVariableReadEventArgs((EnvironmentVariableReadEventArgs)buildEvent, translator);
|
||||
break;
|
||||
|
@ -712,37 +819,20 @@ namespace Microsoft.Build.Shared
|
|||
private void WriteEnvironmentVariableReadEventArgs(EnvironmentVariableReadEventArgs environmentVariableReadEventArgs, ITranslator translator)
|
||||
{
|
||||
string name = environmentVariableReadEventArgs.EnvironmentVariableName;
|
||||
MessageImportance importance = environmentVariableReadEventArgs.Importance;
|
||||
|
||||
translator.Translate(ref name);
|
||||
BuildEventContext context = environmentVariableReadEventArgs.BuildEventContext;
|
||||
translator.TranslateEnum(ref importance, (int)importance);
|
||||
|
||||
#if !CLR2COMPATIBILITY
|
||||
DateTime timestamp = environmentVariableReadEventArgs.RawTimestamp;
|
||||
BuildEventContext context = environmentVariableReadEventArgs.BuildEventContext;
|
||||
|
||||
translator.Translate(ref timestamp);
|
||||
translator.Translate(ref context);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize ExternalProjectFinished Event Argument to the stream
|
||||
/// </summary>
|
||||
private void WriteExternalProjectFinishedEventToStream(ExternalProjectFinishedEventArgs externalProjectFinishedEventArgs, ITranslator translator)
|
||||
{
|
||||
string projectFile = externalProjectFinishedEventArgs.ProjectFile;
|
||||
translator.Translate(ref projectFile);
|
||||
|
||||
bool succeeded = externalProjectFinishedEventArgs.Succeeded;
|
||||
translator.Translate(ref succeeded);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ExternalProjectStartedEvent
|
||||
/// </summary>
|
||||
private void WriteExternalProjectStartedEventToStream(ExternalProjectStartedEventArgs externalProjectStartedEventArgs, ITranslator translator)
|
||||
{
|
||||
string projectFile = externalProjectStartedEventArgs.ProjectFile;
|
||||
translator.Translate(ref projectFile);
|
||||
|
||||
string targetNames = externalProjectStartedEventArgs.TargetNames;
|
||||
translator.Translate(ref targetNames);
|
||||
}
|
||||
|
||||
#region Writes to Stream
|
||||
|
||||
/// <summary>
|
||||
|
@ -829,7 +919,13 @@ namespace Microsoft.Build.Shared
|
|||
private void WriteResponseFileUsedEventToStream(ResponseFileUsedEventArgs responseFileUsedEventArgs, ITranslator translator)
|
||||
{
|
||||
string filePath = responseFileUsedEventArgs.ResponseFilePath;
|
||||
|
||||
translator.Translate(ref filePath);
|
||||
|
||||
#if !CLR2COMPATIBILITY
|
||||
DateTime timestamp = responseFileUsedEventArgs.RawTimestamp;
|
||||
translator.Translate(ref timestamp);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !TASKHOST && !MSBUILDENTRYPOINTEXE
|
||||
|
@ -1066,8 +1162,6 @@ namespace Microsoft.Build.Shared
|
|||
{
|
||||
LoggingEventType.TaskCommandLineEvent => ReadTaskCommandLineEventFromStream(translator, message, helpKeyword, senderName),
|
||||
LoggingEventType.BuildErrorEvent => ReadTaskBuildErrorEventFromStream(translator, message, helpKeyword, senderName),
|
||||
LoggingEventType.ProjectStartedEvent => ReadExternalProjectStartedEventFromStream(translator, message, helpKeyword, senderName),
|
||||
LoggingEventType.ProjectFinishedEvent => ReadExternalProjectFinishedEventFromStream(translator, message, helpKeyword, senderName),
|
||||
LoggingEventType.BuildMessageEvent => ReadBuildMessageEventFromStream(translator, message, helpKeyword, senderName),
|
||||
LoggingEventType.ResponseFileUsedEvent => ReadResponseFileUsedEventFromStream(translator, message, helpKeyword, senderName),
|
||||
LoggingEventType.BuildWarningEvent => ReadBuildWarningEventFromStream(translator, message, helpKeyword, senderName),
|
||||
|
@ -1082,60 +1176,24 @@ namespace Microsoft.Build.Shared
|
|||
private EnvironmentVariableReadEventArgs ReadEnvironmentVariableReadEventFromStream(ITranslator translator, string message, string helpKeyword, string senderName)
|
||||
{
|
||||
string environmentVariableName = null;
|
||||
MessageImportance importance = default;
|
||||
|
||||
translator.Translate(ref environmentVariableName);
|
||||
BuildEventContext context = null;
|
||||
translator.TranslateEnum(ref importance, (int)importance);
|
||||
|
||||
EnvironmentVariableReadEventArgs args = new(environmentVariableName, message, helpKeyword, senderName, importance);
|
||||
|
||||
#if !CLR2COMPATIBILITY
|
||||
DateTime timestamp = default;
|
||||
BuildEventContext context = null;
|
||||
translator.Translate(ref timestamp);
|
||||
translator.Translate(ref context);
|
||||
#endif
|
||||
EnvironmentVariableReadEventArgs args = new(environmentVariableName, message);
|
||||
args.RawTimestamp = timestamp;
|
||||
args.BuildEventContext = context;
|
||||
#endif
|
||||
return args;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read and reconstruct a ProjectFinishedEventArgs from the stream
|
||||
/// </summary>
|
||||
private ExternalProjectFinishedEventArgs ReadExternalProjectFinishedEventFromStream(ITranslator translator, string message, string helpKeyword, string senderName)
|
||||
{
|
||||
string projectFile = null;
|
||||
translator.Translate(ref projectFile);
|
||||
|
||||
bool succeeded = true;
|
||||
translator.Translate(ref succeeded);
|
||||
|
||||
ExternalProjectFinishedEventArgs buildEvent =
|
||||
new ExternalProjectFinishedEventArgs(
|
||||
message,
|
||||
helpKeyword,
|
||||
senderName,
|
||||
projectFile,
|
||||
succeeded);
|
||||
|
||||
return buildEvent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read and reconstruct a ProjectStartedEventArgs from the stream
|
||||
/// </summary>
|
||||
private ExternalProjectStartedEventArgs ReadExternalProjectStartedEventFromStream(ITranslator translator, string message, string helpKeyword, string senderName)
|
||||
{
|
||||
string projectFile = null;
|
||||
translator.Translate(ref projectFile);
|
||||
|
||||
string targetNames = null;
|
||||
translator.Translate(ref targetNames);
|
||||
|
||||
ExternalProjectStartedEventArgs buildEvent =
|
||||
new ExternalProjectStartedEventArgs(
|
||||
message,
|
||||
helpKeyword,
|
||||
senderName,
|
||||
projectFile,
|
||||
targetNames);
|
||||
|
||||
return buildEvent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read and reconstruct a BuildWarningEventArgs from the stream
|
||||
/// </summary>
|
||||
|
@ -1256,6 +1314,14 @@ namespace Microsoft.Build.Shared
|
|||
string responseFilePath = String.Empty;
|
||||
translator.Translate(ref responseFilePath);
|
||||
ResponseFileUsedEventArgs buildEvent = new ResponseFileUsedEventArgs(responseFilePath);
|
||||
|
||||
#if !CLR2COMPATIBILITY
|
||||
DateTime timestamp = default;
|
||||
translator.Translate(ref timestamp);
|
||||
buildEvent.RawTimestamp = timestamp;
|
||||
#endif
|
||||
|
||||
|
||||
return buildEvent;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
<data name="ExpectedEventToBeSerializable" Visibility="Public">
|
||||
<value>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</value>
|
||||
</data>
|
||||
<data name="DeprecatedEventSerialization" Visibility="Public">
|
||||
<value>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</value>
|
||||
</data>
|
||||
<data name="FileLocation" Visibility="Public">
|
||||
<value>{0} ({1},{2})</value>
|
||||
<comment>A file location to be embedded in a string.</comment>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: Bylo nalezeno konfliktní sestavení pro sestavení úlohy {0} v umístění {1}.</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">Očekávalo se, že typ události {0} bude možné serializovat pomocí serializátoru .NET. Událost nebylo možné serializovat a byla ignorována.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: Eine mit der Aufgabenassembly "{0}" in Konflikt stehende Assembly wurde in "{1}" gefunden.</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">Es wurde erwartet, dass der Ereignistyp "{0}" mithilfe des .NET-Serialisierers serialisierbar ist. Das Ereignis war nicht serialisierbar und wurde ignoriert.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: Se detectó un ensamblado conflictivo para el ensamblado de tarea "{0}" en "{1}".</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">Se esperaba que el tipo de evento "{0}" fuera serializable con el serializador .NET. El evento no era serializable y se ha omitido.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: un assembly en conflit avec l'assembly de tâche "{0}" a été trouvé sur "{1}".</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">Le type d'événement "{0}" devait être sérialisable à l'aide du sérialiseur .NET. L'événement n'était pas sérialisable et a été ignoré.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: rilevato un assembly in conflitto per l'assembly dell'attività "{0}" in "{1}".</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">È previsto un tipo di evento "{0}" serializzabile con il serializzatore .NET. L'evento non era serializzabile ed è stato ignorato.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: タスク アセンブリ "{0}" に対して競合しているアセンブリが "{1}" で見つかりました。</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">イベントの種類 "{0}" は .NET シリアライザーを使用してシリアル化可能であることが想定されていましたが、シリアル化可能でなかったため無視されました。</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: 작업 어셈블리 "{0}"과(와) 충돌하는 어셈블리가 "{1}"에 있습니다.</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">이벤트 유형 "{0}"은(는) .NET serializer를 사용하여 serialize할 수 있어야 합니다. 이 이벤트는 serialize할 수 없으므로 무시되었습니다.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: Zestaw, który wywołuje konflikt z zestawem zadania „{0}”, został znaleziony w „{1}”.</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">Oczekiwano, że zdarzenie typu „{0}” będzie uszeregowane przy użyciu serializatora platformy .NET. Zdarzenie nie może podlegać szeregowaniu, dlatego zostało zignorowane.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: Foi encontrado um assembly conflitante no assembly da tarefa "{0}" em "{1}".</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">Era esperado que o tipo de evento "{0}" fosse serializável usando o serializador .NET. O evento não era serializável e foi ignorado.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: в "{1}" обнаружена сборка, конфликтующая со сборкой задачи "{0}".</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">Необходимо, чтобы тип события "{0}" был сериализуемым с помощью сериализатора .NET. Событие не было сериализуемым и было пропущено.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: "{0}" görev derlemesi için "{1}" konumunda çakışan derleme bulundu.</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">"{0}" olay türünün .NET serileştiricisi kullanılarak serileştirilebilir olması bekleniyordu. Olay serileştirilebilir değildi ve yoksayıldı.</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: 在“{1}”处发现了与任务程序集“{0}”冲突的程序集。</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">事件类型“{0}”应可以使用 .NET 序列化程序进行序列化。此事件不可序列化,已忽略它。</target>
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
<target state="translated">MSB4008: 已在 "{1}" 中發現工作組件 "{0}" 的衝突組件。</target>
|
||||
<note>{StrBegin="MSB4008: "}UE: This message is shown when the type/class of a task cannot be resolved uniquely from a single assembly.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="DeprecatedEventSerialization">
|
||||
<source>Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</source>
|
||||
<target state="new">Usage of unsecure BinaryFormatter during serialization of custom event type '{0}'. This will be deprecated soon. Please use Extended*EventArgs instead. More info: https://aka.ms/msbuild/eventargs</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="ExpectedEventToBeSerializable">
|
||||
<source>Event type "{0}" was expected to be serializable using the .NET serializer. The event was not serializable and has been ignored.</source>
|
||||
<target state="translated">事件類型 "{0}" 應該可以使用 .NET 序列化程式序列化。此事件不可序列化,已略過。</target>
|
||||
|
|
Загрузка…
Ссылка в новой задаче