diff --git a/src/Tasks.UnitTests/CombineTargetFrameworkInfoProperties_Tests.cs b/src/Tasks.UnitTests/CombineTargetFrameworkInfoProperties_Tests.cs new file mode 100644 index 00000000000..ea0a3b0f166 --- /dev/null +++ b/src/Tasks.UnitTests/CombineTargetFrameworkInfoProperties_Tests.cs @@ -0,0 +1,37 @@ +// 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.Tasks; +using Shouldly; +using Xunit; + +namespace Microsoft.Build.UnitTests +{ + public sealed class CombineTargetFrameworkInfoProperties_Tests + { + /// + /// https://github.com/dotnet/msbuild/issues/8320 + /// + [Theory] + [InlineData(null, false, "MSB3991")] + [InlineData("", false, "MSB3991")] + [InlineData(null, true, "MSB3992")] + public void RootElementNameNotValid(string rootElementName, bool UseAttributeForTargetFrameworkInfoPropertyNames, string errorCode) + { + MockEngine e = new MockEngine(); + var task = new CombineTargetFrameworkInfoProperties(); + task.BuildEngine = e; + var items = new ITaskItem[] + { + new TaskItemData("ItemSpec1", null) + }; + task.RootElementName = rootElementName; + task.PropertiesAndValues = items; + task.UseAttributeForTargetFrameworkInfoPropertyNames = UseAttributeForTargetFrameworkInfoPropertyNames; + task.Execute().ShouldBe(false); + e.AssertLogContains(errorCode); + } + } +} diff --git a/src/Tasks/CombineTargetFrameworkInfoProperties.cs b/src/Tasks/CombineTargetFrameworkInfoProperties.cs index 6830ba9cb99..7506fbc8be0 100644 --- a/src/Tasks/CombineTargetFrameworkInfoProperties.cs +++ b/src/Tasks/CombineTargetFrameworkInfoProperties.cs @@ -18,7 +18,6 @@ public class CombineTargetFrameworkInfoProperties : TaskExtension /// The root element name to use for the generated XML string /// public string RootElementName { get; set; } - /// /// Items to include in the XML. The ItemSpec should be the property name, and it should have Value metadata for its value. /// @@ -39,16 +38,24 @@ public override bool Execute() { if (PropertiesAndValues != null) { - XElement root = UseAttributeForTargetFrameworkInfoPropertyNames ? - new("TargetFramework", new XAttribute("Name", EscapingUtilities.Escape(RootElementName))) : - new(RootElementName); - - foreach (ITaskItem item in PropertiesAndValues) + if ((!UseAttributeForTargetFrameworkInfoPropertyNames && string.IsNullOrEmpty(RootElementName)) || (UseAttributeForTargetFrameworkInfoPropertyNames && RootElementName == null)) { - root.Add(new XElement(item.ItemSpec, item.GetMetadata("Value"))); + string resource = UseAttributeForTargetFrameworkInfoPropertyNames ? "CombineTargetFrameworkInfoProperties.NotNullRootElementName" : "CombineTargetFrameworkInfoProperties.NotNullAndEmptyRootElementName"; + Log.LogErrorWithCodeFromResources(resource, nameof(RootElementName), nameof(UseAttributeForTargetFrameworkInfoPropertyNames)); } + else + { + XElement root = UseAttributeForTargetFrameworkInfoPropertyNames ? + new("TargetFramework", new XAttribute("Name", EscapingUtilities.Escape(RootElementName))) : + new(RootElementName); - Result = root.ToString(); + foreach (ITaskItem item in PropertiesAndValues) + { + root.Add(new XElement(item.ItemSpec, item.GetMetadata("Value"))); + } + + Result = root.ToString(); + } } return !Log.HasLoggedErrors; } diff --git a/src/Tasks/Resources/Strings.resx b/src/Tasks/Resources/Strings.resx index fdf44f5268a..8b337bb2db5 100644 --- a/src/Tasks/Resources/Strings.resx +++ b/src/Tasks/Resources/Strings.resx @@ -2985,6 +2985,18 @@ PFX signing not supported on .NET Core. + + + + MSB3991: '{0}' is not set or empty. When {1} is false, make sure to set a non-empty value for '{0}'. + {StrBegin="MSB3991: "} + + + MSB3992: '{0}' is not set. When {1} is true, make sure to set a value for '{0}'. + {StrBegin="MSB3992: "} +