Thursday, March 8, 2007

Creating lists based on output from actions in your build script

I'm being haunted by the blog police at work so I figure I'd post something instead of watching the telly today...

Sometimes when you create builds scripts for MSBuild you need to create collections based on the result of other actions in the script (for example after retrieving the latest files from source control or the output from a compilation). The problem is that it will not work when using wildcards since the expansion of the wildcards is done upfront before actually running the build script, so if your depending on the result from a get from source control for instance the first time you run your script the collection will be empty (since we have not yet retrieved the files) and ever execution after that will be based on the previous executions result (that is the files retrieved from source control the latest run).

To get past this you'll either need to create a target that contains a <CreateItem> action with the path to the files in question then this will be evaluated during the execution of the script. But what if I want to create a reusable target that can be driven by creating an <ItemGroup> what then?

I've created a target that you can use to do this which is based on the concept of using escaped asterisks (%2a) when specifying the path to the files in question it looks like this:

<ItemGroup>
   <!--Dynamic List of Typelibraries-->
   <FileList Include="$(SolutionRoot)\Typelibraries\%2a%2a\%2a.tlb">
      <OutDir>MyFlattenOutput\</OutDir>
   </FileList>
</ItemGroup>

<Target Name="AfterGet">
   <CallTarget Targets ="CopyFiles"/>
</Target>

<Target Name="CopyFiles">
   <Message Text="Copying Files" />

   <!—Create list of files-->
   <CreateItem Include="%(FileList.Identity)"
                            AdditionalMetadata="OutDir=%(FileList.OutDir)">
      <Output ItemName="ExpandedFileList" TaskParameter="Include"/>
   </CreateItem>

   <Copy SourceFiles="@(ExpandedFileList)"
                DestinationFiles="@(ExpandedFileList ->'$(DropLocation)\$(BuildNumber)\%(OutDir)%(RecursiveDir)\%(Filename)%(Extension)')"
   ContinueOnError="True" />
</Target>

Well that's all there is to it hope someone out there will have some use for this...

No comments:

Post a Comment