Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ItemGroup include files with condition

Tags:

msbuild

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:

  1. Include all files
  2. Remove files that do not meet the condition
<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.

like image 412
Steven Liekens Avatar asked Mar 17 '23 02:03

Steven Liekens


1 Answers

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>
like image 197
Michael Baker Avatar answered Mar 18 '23 15:03

Michael Baker