Skip to content

Commit

Permalink
Update schema for combining TargetFramework info to allow for invalid…
Browse files Browse the repository at this point in the history
… xml names such as including '+' (#6699)

Fixes #6603

Context
The ability to gather extra properties from referenced projects was added in #5994. It used XML transformations to couch that logic in a way that MSBuild could understand.

Unfortunately, the XML-based logic assumed everything was a valid XML element. Ultimately, the goal of the change, at least as I understand it, was just to pass information.

Changes Made
TargetFrameworks had been XML elements, but some are not valid XML names. This was changed to being a property on the more generically named TargetFramework element. This also allows for escaping.

Testing
Verified that a simple case that had not previously worked now works and looked at what it produced in a debugger.

Notes
After this PR, the SDK can opt in. Then MSBuild can turn it on by default, and the SDK can stop specifying the property.
  • Loading branch information
Forgind committed Aug 16, 2021
1 parent b92bd70 commit 00166eb
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 13 deletions.
2 changes: 2 additions & 0 deletions documentation/ProjectReference-Protocol.md
Expand Up @@ -106,6 +106,8 @@ As of MSBuild 16.10, it is possible to gather additional properties from referen

These properties will then be gathered via the `GetTargetFrameworks` call. They will be available to the referencing project via the `AdditionalPropertiesFromProject` metadata on the `_MSBuildProjectReferenceExistent` item. The `AdditionalPropertiesFromProject` value will be an XML string which contains the values of the properties for each `TargetFramework` in the referenced project. For example:

> :warning: This format is being changed. Soon, the schema will replace <net5.0> with <TargetFramework Name="net5.0">. You can opt into that behavior early by setting the _UseAttributeForTargetFrameworkInfoPropertyNames property to true. This property will have no effect after the transition is complete.
```xml
<AdditionalProjectProperties>
<net5.0>
Expand Down
Expand Up @@ -164,6 +164,7 @@ public partial class CombineTargetFrameworkInfoProperties : Microsoft.Build.Task
[Microsoft.Build.Framework.OutputAttribute]
public string Result { get { throw null; } set { } }
public string RootElementName { get { throw null; } set { } }
public bool UseAttributeForTargetFrameworkInfoPropertyNames { get { throw null; } set { } }
public override bool Execute() { throw null; }
}
public partial class CombineXmlElements : Microsoft.Build.Tasks.TaskExtension
Expand Down
Expand Up @@ -94,6 +94,7 @@ public partial class CombineTargetFrameworkInfoProperties : Microsoft.Build.Task
[Microsoft.Build.Framework.OutputAttribute]
public string Result { get { throw null; } set { } }
public string RootElementName { get { throw null; } set { } }
public bool UseAttributeForTargetFrameworkInfoPropertyNames { get { throw null; } set { } }
public override bool Execute() { throw null; }
}
public partial class CombineXmlElements : Microsoft.Build.Tasks.TaskExtension
Expand Down
17 changes: 10 additions & 7 deletions src/Tasks/CombineTargetFrameworkInfoProperties.cs
Expand Up @@ -2,11 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.Build.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Build.Shared;
using System.Xml.Linq;

namespace Microsoft.Build.Tasks
Expand All @@ -26,6 +22,11 @@ public class CombineTargetFrameworkInfoProperties : TaskExtension
/// </summary>
public ITaskItem[] PropertiesAndValues { get; set; }

/// <summary>
/// Opts into or out of using the new schema with Property Name=... rather than just specifying the RootElementName.
/// </summary>
public bool UseAttributeForTargetFrameworkInfoPropertyNames { get; set; } = false;

/// <summary>
/// The generated XML representation of the properties and values.
/// </summary>
Expand All @@ -36,9 +37,11 @@ public override bool Execute()
{
if (PropertiesAndValues != null)
{
XElement root = new XElement(RootElementName);
XElement root = UseAttributeForTargetFrameworkInfoPropertyNames ?
new("TargetFramework", new XAttribute("Name", EscapingUtilities.Escape(RootElementName))) :
new(RootElementName);

foreach (var item in PropertiesAndValues)
foreach (ITaskItem item in PropertiesAndValues)
{
root.Add(new XElement(item.ItemSpec, item.GetMetadata("Value")));
}
Expand Down
5 changes: 0 additions & 5 deletions src/Tasks/CombineXmlElements.cs
Expand Up @@ -2,11 +2,6 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using Microsoft.Build.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace Microsoft.Build.Tasks
Expand Down
7 changes: 6 additions & 1 deletion src/Tasks/Microsoft.Common.CurrentVersion.targets
Expand Up @@ -1913,9 +1913,14 @@ Copyright (C) Microsoft Corporation. All rights reserved.
</_AdditionalTargetFrameworkInfoPropertyWithValue>
</ItemGroup>

<PropertyGroup>
<_UseAttributeForTargetFrameworkInfoPropertyNames Condition="'$(_UseAttributeForTargetFrameworkInfoPropertyNames)' == ''">false</_UseAttributeForTargetFrameworkInfoPropertyNames>
</PropertyGroup>

<CombineTargetFrameworkInfoProperties
RootElementName="$(TargetFramework)"
PropertiesAndValues="@(_AdditionalTargetFrameworkInfoPropertyWithValue)">
PropertiesAndValues="@(_AdditionalTargetFrameworkInfoPropertyWithValue)"
UseAttributeForTargetFrameworkInfoPropertyNames="$(_UseAttributeForTargetFrameworkInfoPropertyNames)">
<Output TaskParameter="Result"
PropertyName="_AdditionalTargetFrameworkInfoProperties"/>
</CombineTargetFrameworkInfoProperties>
Expand Down

0 comments on commit 00166eb

Please sign in to comment.