Adam
Adam

Reputation: 1011

MSBuild Filtering ItemGroup of files with condition

This feels like it's so simple, but I cannot get it to work.

All I'm trying to achieve is a filtered list of the embedded resources. I've tried various approaches but I can't seem to get it right.

Here's what I thought was the right solution:

<ItemGroup>
  <AllEmbeddedResources Include="@(EmbeddedResource)" Condition="$(FullPath.Contains('Change')"/>
</ItemGroup>

Edit... To clarify, the results are without the condition, the list is all embedded resources, with the condition, the group is empty.

I've tried this inside and outside of target's, and I've tried getting the full list in one group, and then filtering in a separate group. I know I'm just misunderstanding some fundamental part of msbuild syntax, I just can't seem to work it out. Looking forward to being shown my stupid mistake!

Upvotes: 4

Views: 4265

Answers (2)

Cogent
Cogent

Reputation: 402

The Condition Attribute must return a boolean, and it operates on each element of the itemgroup. You can access each element using %(Identity). Say you have some unfiltered itemgroup called UnfilteredItems, and you want to filter those into a group called MyFilteredItems, using some regex pattern.

<ItemGroup>
  <MyFilteredItems Include="@(UnfilteredItems)" Condition="$([System.Text.RegularExpressions.Regex]::Match(%(Identity),'.*\\bin\\.*').Success)"/>
</ItemGroup> 

Upvotes: 1

Martin Ullrich
Martin Ullrich

Reputation: 100543

Inside a target, this can be done using the batching syntax for items and using the System.String.Copy method to be able to call instance functions on the string:

<Target Name="ListAllEmbeddedResources">
  <ItemGroup>
    <AllEmbeddedResources Include="@(EmbeddedResource)" Condition="$([System.String]::Copy(%(FullPath)).Contains('Change'))" />
  </ItemGroup>
  <Message Importance="high" Text="AllEmbeddedResources: %(AllEmbeddedResources.Identity)" />
</Target>

Note that this syntax only works inside a target and not during static evaluation (item group directly under the <Project> node).

Upvotes: 11

Related Questions