In MSBuild 12.0, can I include files in an <ItemGroup>
only when a condition is met?
My use case is that I want to create a collection of all .csproj
files for which a .nuspec
file with the same name exists (without extension).
- root_dir\
- build.proj
- Project1\
- Project1.csproj
- Project1.nuspec
- Project2\
- Project2.csproj
- Project3\
- Project3.csproj
- Project3.nuspec
I tried to do this with MSBuild transforms, but that didn't work.
<ItemGroup>
<ProjectWithNuspec Include="*\*.csproj"
Condition="Exists('@(ProjectWithNuspec->'%(Filename).nuspec')')">
</ItemGroup>
The item ProjectWithNuspec
does not seem to be initialized before the condition is evaluated.
I did figure out a way to do it in two steps:
<ItemGroup>
<ProjectWithNuspec Include="*\*.csproj">
<ProjectWithNuspec Remove="%(ProjectWithNuspec.Identity)"
Condition="!Exists('@(ProjectWithNuspec->'%(Filename).nuspec')')">
</ItemGroup>
Ideally, I'd like to be able to do this in a single step.
You are basically doing this the best way that can be expressed in MSBuild. For these sorts of transforms you almost always need an intermediate item group which you layer additional transforms to. Think of it like a pipeline, first you need all files (these go into group 1), now I need all files from group 1 which also match some other condition (group 2).
<ItemGroup>
<AllProjects Include="$(MyDir)\**\*.csproj" />
<AllProjectsWithNuspec Include="@(AllProjects)"
Condition="Exists('%(RecursiveDir)%(FileName).nuspec')" />
</ItemGroup>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With