Auswertung von ItemGroups in msbuild

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:

1
2
3
4
5
6
7
8
9
10
<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:

1
2
3
4
5
6
7
8
9
10
11
12
13
<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.


Kick It auf dotnet-kicks.de
Dieser Eintrag wurde veröffentlicht in .NET und getagged . Bookmarken: Permanent-Link. Kommentieren oder ein Trackback hinterlassen: Trackback-URL.