Reputation: 86937
Currently, I've got he following code in an MSBuild
proj file. It's really simple. Define 4 variables and call my MSBuild Task once-per-variable :
<ItemGroup><JS_File1 Include="file1.js"/></ItemGroup>
<ItemGroup><JS_File1 Include="file2.js"/></ItemGroup>
<ItemGroup><JS_File1 Include="file3.js"/></ItemGroup>
<ItemGroup><JS_File1 Include="file4.js"/></ItemGroup>
<JavaScriptCompressorTask SourceFiles="@(JS_File1)" OutputFile="@(JS_File1).min"/>
<JavaScriptCompressorTask SourceFiles="@(JS_File2)" OutputFile="@(JS_File2).min"/>
<JavaScriptCompressorTask SourceFiles="@(JS_File3)" OutputFile="@(JS_File3).min"/>
<JavaScriptCompressorTask SourceFiles="@(JS_File4)" OutputFile="@(JS_File4).min"/>
Nothing exciting at all.
I was wondering if this could be refactored to something like this.
<ItemGroup>
<JS_File1 Include="file1.js"/>
<JS_File1 Include="file2.js"/>
<JS_File1 Include="file3.js"/>
<JS_File1 Include="file4.js"/>
</ItemGroup>
<!-- now this is the shiz i have no idea about -->
foreach(@(JS_Files))
<JavaScriptCompressorTask SourceFiles="@(theFile)" OutputFile="@(theFile).min"/>
Is it possible to do this, in MSBuild?
So that task is called once-per-file .. or more to the point, once-per-item-in-the-item-group?
Upvotes: 3
Views: 6628
Reputation: 1951
You can use item metadata to batch the task (see http://msdn.microsoft.com/en-us/library/ms171474.aspx).
All items have metadata called 'Identity,' which contains the value of the Include attribute. If you use metadata reference syntax %(Identity)
, that will instruct MSBuild to execute your task for each unique Include value.
<ItemGroup>
<JS_File1 Include="file1.js"/>
<JS_File1 Include="file2.js"/>
<JS_File1 Include="file3.js"/>
<JS_File1 Include="file4.js"/>
</ItemGroup>
<JavaScriptCompressorTask SourceFiles="@(JS_File1)" OutputFile="%(Identity).min"/>
Note that MSBuild knows that you are referencing the Identity metadata of the JS_File1 item group because you reference it in the task. Otherwise you would need to use the syntax %(JS_File1.Identity)
.
Upvotes: 4
Reputation: 6651
Like this, except use your task not my copy....
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Minifier" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Minifier">
<ItemGroup>
<JS_File1 Include="file1.js"/>
<JS_File1 Include="file2.js"/>
<JS_File1 Include="file3.js"/>
<JS_File1 Include="file4.js"/>
</ItemGroup>
<Copy SourceFiles="@(JS_File1)" DestinationFiles="@(JS_File1->'%(Filename).min')"/>
</Target>
</Project>
Hope thats helps.
Upvotes: 0