Msbuild: Implement a way to merge one item into another

Created on 18 Jul 2017  路  2Comments  路  Source: dotnet/msbuild

Given item types A and B, there should be an easy way in MSBuild to merge B into A.

Possible ways to do merging:

  1. Metadata merging

    1. Additive: Apply the metadata from the elements of B[B鈭〢] to the elements A[B鈭〢]

    2. Overwrite: Overwrite the metadata from the elements of B[B鈭〢] to the elements A[B鈭〢]

  2. Item merging:

    1. Intersection: Merge (additive or overwrite) the metadata from the elements of B[B鈭〢] to the elements A[B鈭〢]

    2. Union: Merge (additive or overwrite) the metadata from the elements of B[B鈭〢] to the elements A[B鈭〢], and insert the elements B\A into A

Probably the most useful merging is intersection item merging with additive metadata. Possible syntax implementations for only this type of merging:

  • reuse the current Update operation. If the Update query is an item reference, and there is no metadata defined, do merging instead.
<Foo Update="@(Bar)"> // applies all the metadata from Bar into Foo
<Foo Update="@(Bar)" KeepMetadata="Tar"> // applies only metadata named "Tar" from Bar into Foo
<Foo Update="@(Bar)" RemoveMetadata="Tar"> // applies all metadata except "Tar" from Bar into Foo

The drawback is that MSBuild currently treats <Foo Update="@(Bar)"/> as a noop (i.e. for all items in Foo that match in Bar, do nothing), so we'll break the existing noop behaviour. Since it's a pretty benign behaviour, it probably doesn't happen too often.

  • add a new Merge operation
<Foo Merge="@(Bar)"> // applies all the metadata from Bar into Foo
<Foo Merge="@(Bar)" KeepMetadata="Tar"> // applies only metadata named "Tar" from Bar into Foo
<Foo Merge="@(Bar)" RemoveMetadata="Tar"> // applies all metadata except "Tar" from Bar into Foo

The advantages of Merge:

  • it disambiguates behaviour by item operations. This way each operation does something consistent (Update single metadata via a matching query Vs Merging all metadata of one item type into another item type).
  • it allows extensibility to the other merging types via configuration attributes (e.g. <Foo Merge="@(Bar)" MetadataMergeStrategy="overwrite" ItemMergeStrategy="Union">)
Language

Most helpful comment

I would implement a task @vatsan-madhavan. It's often possible to do it in pure MSBuild but IME the output is incomprehensible even to the author as of about half an hour after writing it.

All 2 comments

Are there patterns for how any of these can be implemented today within targets, esp. _Intersection_ with merging of metadata?

/cc @nguerrera, @rainersigwald

I would implement a task @vatsan-madhavan. It's often possible to do it in pure MSBuild but IME the output is incomprehensible even to the author as of about half an hour after writing it.

Was this page helpful?
0 / 5 - 0 ratings