Auswertung von ItemGroups in msbuild

Standard

Neulich hatte ich das Problem, dass ItemGroups in msbuild offenbar
einmal zu Beginn ausgewertet werden und danach die Liste der Items bis
zum Ende des Builds nicht mehr aktualisiert wird. Wenn während des
Builds Verzeichnisse oder Dateien gelöscht bzw. erzeugt werden, stimmt
der Inhalt der ItemGroup nicht mehr mit dem tatsächlichen
Dateisysteminhalt überein.

Normalerweise ist das kein Problem, weil erstens der Source-Code zu
Beginn feststeht und diese Dateien während des Build-Prozesses nicht
gelöscht werden und zweitens Build-Artefakte, die in den nächsten
Buildsteps weiterverarbeitet werden, als Output-Parameter der Tasks zur
Verfügung stehens.

Ein Problem hat man allerdings, wenn man Tasks verwendet, die die
erzeugten Dateien nicht als Output-Parameter zur Verfügung stellen
(können) und diese Dateien weiterverarbeitet werden sollen.

Im folgenden Code-Snippet werden rekursiv alle Namen von
C#-Quellcodedateien ausgegeben, ein Verzeichnis gelöscht und danach
wieder alle C#-Dateinamen ausgegeben:

<project DefaultTargets="TestItems" xmlns="...">
  <itemGroup>
    <myItems Include="**.cs" />
  </itemGroup>
  <target Name="TestItems">
    <message Text="@(MyItems)" />
    <removeDir Directories="TestDir" />
    <message Text="@(MyItems)" />
  </target>
</project>

Auch nach dem Löschen des Verzeichnisses sind alle Dateien dieses
Verzeichnisses in der ItemGroup “MyItems” enthalten.

Um die ItemGroups aktuell zu halten, kann man den CreateItem-Task
verwenden:

<project DefaultTargets="TestItems" xmlns="...">
  <itemGroup>
    <myItems Include="**.cs" />
  </itemGroup>
  <target Name="TestItems">
    <message Text="@(MyItems)" />
    <removeDir Directories="TestDir" />
    <createItem Include="**.cs">
      <output TaskParameter="Include" ItemName="CurrentItems" />
    </createItem>
    <message Text="@(MyItems)" />
  </target>
</project>

In einigen Situationen ergeben sich daraus ziemlich unleserliche
Build-Skripts. Doch sollte man sich dann überlegen, ob msbuild das
richtige Tool ist.