-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support gathering additional arbitrary properties from referenced projects #5994
Support gathering additional arbitrary properties from referenced projects #5994
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of relying on ;;
as a separator, since a lot of people add ;
to the beginning or end of lists if they aren't sure whether a property is empty or not like
How annoying would it be to have a collection of Items like:
<ItemGroup>
<Net472AdditionalPropertiesFromProject>
<...>
</Net472AdditionalPropertiesFromProject>
<Netcoreapp3.1AdditionalPropertiesFromProject>
<...>
</Netcoreapp3.1AdditionalPropertiesFromProject>
</ItemGroup>
? Is it even possible to pass that through a ProjectReference?
@Forgind I think it will handle empty properties and empty lists of properties correctly, though I'm not 100% sure. Something like |
This was my case:
and then trying to pass that to another project. I'm not sure either, mostly because I get confused sometimes by item transforms and such. As I understand it, it would accept UsesProperties as a valid property (which it is) and add it to AdditionalPropertiesFromProject, then parsing would break the property in two, get confused, and silently use it incorrectly. I could be wrong. |
@cdmihai How would this interact with static graph? |
High-level questions (this implementation looks ok but I wonder if we can improve the overall design).
Those are both harder to implement with MSBuild logic and would suggest writing a new If we stick with delimited, maybe consider using one of the fancier unicode characters like |
Looks fine for static graph, as the msbuild task calling patterns haven't changed, just the data ferried by the calls, which is opaque to static graph builds. |
Can you also update the protocol doc in this PR? |
Team triage: |
@Forgind I've updated this to use Xml to pass the data around |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some nits, but this looks good, thanks!
@@ -0,0 +1,34 @@ | |||
using Microsoft.Build.Framework; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copyright header
src/Tasks/CombineXmlElements.cs
Outdated
@@ -0,0 +1,34 @@ | |||
using Microsoft.Build.Framework; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copyright header
|
||
Result = root.ToString(); | ||
|
||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return !HasLoggedErrors? Same below.
{ | ||
public class CombineXmlElements : TaskExtension | ||
{ | ||
public string RootElementName { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Required annotations for these?
@@ -1743,12 +1751,26 @@ Copyright (C) Microsoft Corporation. All rights reserved. | |||
<Target Name="GetTargetFrameworksWithPlatformForSingleTargetFramework" | |||
Returns="@(_TargetFrameworkInfo)"> | |||
|
|||
<ItemGroup> | |||
<_AdditionalTargetFrameworkInfoPropertyWithValue Include="@(AdditionalTargetFrameworkInfoProperty)"> | |||
<Value>$(%(AdditionalTargetFrameworkInfoProperty.Identity))</Value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't realize you could have a metadata reference as an identifier for a property. Neat!
Are the tests for this new flow in the sdk repo? If not, add some here? |
Yes, tests for this are in dotnet/sdk#15134 |
I've applied the code review feedback and retargeted this to the master branch for VS 16.10. |
Looks like this broke WCF as it doesn't handle cases like |
@ericstj Do you have more details on how it broke? Is it something we need to fix? I don't know if we support the old PCL TFMs anymore. |
I filed #6603 to track the regression. It was due to an invalid XML character in the TargetFramework. I imagine a fix would be to make sure you escape the strings which seems like something you might want to do regardless. I was able to help WCF find a workaround since they aren't actually building for PCLs (they are just trying to use CSProj + pack to correctly represent a package which overlaps with the PCL targeting packs). ericstj/wcf@66e68f2 |
… 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.
This allows additional properties to be gathered from project references via the project reference protocol. This is in order to support generating an error when a self-contained Executable references a non-SelfContained Executable, or vice versa, as described in dotnet/sdk#15117.
The referenced project can declare what additional properties should be gathered with
AdditionalTargetFrameworkInfoProperty
items:These items will then be included in the
AdditionalPropertiesFromProject
metadata on the_MSBuildProjectReferenceExistent
items. This value will havePropertyName=PropertyValue
combinations joined by semicolons, and those sets of properties for the differentTargetFramework
values will be joined by double semicolons. For example, a project multitargeted to two TargetFrameworks may have the following for theAdditionalPropertiesFromProject
metadata:Finding the right set of properties from the referenced project will required looking up the index of the
NearestTargetFramework
in theTargetFrameworks
, and using that index to select the set of properties in theAdditionalPropertiesFromProject
metadata. For example:This is implemented in dotnet/sdk#15134.
If anyone has suggestions for a better separator than a double semicolon to separate the list of property/values for each TargetFramework, let me know.