2011-01-24 16 views
11

Estoy escribiendo un script para msbuild que debería hacer dos lotes en un solo paso.
Ejemplo: 2 ItemGroupsDouble-Loop en msbuild?

<ItemGroup> 
<GroupOne Include="1" /> 
<GroupOne Include="2" /> 
</ItemGroup> 

<ItemGroup> 
<GroupTwo Include="A" /> 
<GroupTwo Include="B" /> 
</ItemGroup> 

Estos dos grupos se deben conducir uno dentro del otro:

<Message Text="%(GroupOne.Identity) %(GroupTwo.Identity)" /> 

esperaba que msbuild hace que el resultado de ambos lotes que dan

1 A 
2 A 
1 B 
2 B 

como resultado.
Pero eso no sucedió. En su lugar, se devuelve la siguiente basura inútil:

1 
2 
    A 
    B 

Hacerlo de la manera en que el blog desde el siguiente enlace propone (usando un propertyGroup local) como

<PropertyGroup> 
    <GroupOneStep>%(GroupOne.Identity)</GroupOneStep> 
</PropertyGroup> 
<Message Text="$(GroupOneStep) %(GroupTwo.Identity)" /> 

hace

2 A 
2 B 

Cualquier consejos? Me estoy volviendo loco. :-(

PS: He aquí una entrada de blog sobre el tema - por desgracia, no funciona como propsed allí: http://blogs.msdn.com/b/giuliov/archive/2010/04/30/gotcha-msbuild-nested-loops-double-batching.aspx

Respuesta

11

Pruebe lo siguiente para crear un nuevo ItemGroup usando la identidad del grupo 1 y la asignación de metadatos a la grupo nuevo elemento de la identidad (o cualquier otra metadatos) del grupo 2. a continuación, utilice la dosificación para iterar sobre el nuevo grupo.

<CreateItem Include="@(GroupOne)" AdditionalMetadata="Option1=%(GroupTwo.Identity)"> 
    <Output ItemName="_Group_Merged" TaskParameter="Include"/> 
</CreateItem> 

<Message Text="%(_Group_Merged.Identity)-%(_Group_Merged.Option1)" /> 

Si usted tiene más de dos grupos puede agregar entradas CreateItem fusionar el tercer grupo en _Group_Merged y luego iterar sobre ese grupo combinado.

<CreateItem Include="@(_Group_Merged)" AdditionalMetadata="Option2=%(GroupThree.Identity)"> 
    <Output ItemName="_Group_Merged2" TaskParameter="Include"/> 
</CreateItem> 

<Message Text="%(_Group_Merged2.Identity)-%(_Group_Merged2.Option1)-%(_Group_Merged2.Option2)" /> 
+0

Asistente ! ¡Eso funciona! :-) – Sascha

+0

Magia! Gracias –

11

Esta es una solución mucho más simple.

<Target Name="Default"> 
    <ItemGroup> 
     <Combined Include="@(GroupOne)"> 
      <GroupTwo>%(GroupTwo.Identity)</GroupTwo> 
     </Combined> 
    </ItemGroup> 

    <Message Text="%(Combined.Identity) %(Combined.GroupTwo) " /> 
</Target> 

El uso de un grupo de artículos intermedia Combined para crear un grupo de artículos intermedia que los lotes de tareas mensaje.

Si hace referencia a dos grupos de artículos en la misma tarea, Msbuild combinará en ambos por separado. que no es lo que quiere

Si tiene más ItemMetaData que necesita para manejar de forma explícita que para la segunda ItemGroup, La ItemGroup incluye con el símbolo de referencia @ automáticamente incluye la ItemMetaData, por lo que sólo necesita crea los metadatos adicionales del segundo grupo haciendo referencia explícitamente. He aquí un ejemplo:

<ItemGroup> 
    <GroupOne Include="1"> 
     <Name>One</Name> 
    </GroupOne> 
    <GroupOne Include="2"> 
     <Name>Two</Name> 
    </GroupOne> 
</ItemGroup> 

<ItemGroup> 
    <GroupTwo Include="A"> 
     <Name>Andrew</Name> 
    </GroupTwo> 
    <GroupTwo Include="B"> 
     <Name>Bob</Name> 
    </GroupTwo> 
</ItemGroup> 

<Target Name="Default"> 
    <ItemGroup> 
     <Combined Include="@(GroupOne)"> 
      <GroupTwo>%(GroupTwo.Identity)</GroupTwo> 
      <GroupTwoName>%(GroupTwo.Name)</GroupTwoName> 
     </Combined> 
    </ItemGroup> 

    <Message Text="%(Combined.Identity) %(Combined.Name) %(Combined.GroupTwoName) %(Combined.GroupTwo) " /> 
</Target> 
4

También se puede hacer bucles anidados triples utilizando la técnica de Dog Ears.

<Target Name="Test"> 
    <ItemGroup> 
     <Loop1 Include="L11" /> 
     <Loop1 Include="L12" /> 
     <Loop2 Include="L21" /> 
     <Loop2 Include="L22" /> 
     <Loop3 Include="L31" /> 
     <Loop3 Include="L32" /> 
     <Loop12 Include="@(Loop1)"> 
     <!-- Combine Loop1 and Loop2: Inherit each meta data of Loop1 and add some of Loop2. --> 
     <Loop2Identity>%(Loop2.Identity)</Loop2Identity> 
     </Loop12> 
     <Loop123 Include="@(Loop12)"> 
     <!-- Combine Loop12 and Loop3: Inherit each meta data of Loop12 and add some of Loop3. --> 
     <Loop3Identity>%(Loop3.Identity)</Loop3Identity> 
     </Loop123> 
    </ItemGroup> 
    <!-- Show all entries of Loop1 and Loop2 combined --> 
    <Message Text="Loop12.Identity=%(Loop12.Identity), Loop12.Value1=%(Loop12.Value1), Loop12.Loop2Identity=%(Loop12.Loop2Identity)"/> 
    <!-- Show all entries of Loop1, Loop2 and Loop3 combined --> 
    <Message Text="Loop123.Identity=%(Loop123.Identity), Loop123.Loop2Identity=%(Loop123.Loop2Identity) Loop123.Loop2Identity=%(Loop123.Loop3Identity)"/> 
    </Target> 
0

Durante dos bucles anidados esto funciona:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <ItemGroup> 
     <GroupOne Include="1" /> 
     <GroupOne Include="2" /> 
    </ItemGroup> 

    <ItemGroup> 
     <GroupTwo Include="A" /> 
     <GroupTwo Include="B" /> 
    </ItemGroup> 

    <Target Name="Exec" 
     Outputs="%(GroupOne.Identity)"> 
     <Message Text="Building @(GroupOne->'%(Identity)') %(GroupTwo.Identity)"/> 
    </Target> 

</Project> 

Resultados en:

Project "D:\tmp\msbuildtest\test.xml" on node 0 (default targets). 
    Building 1 A 
    Building 1 B 
Exec: 
    Building 2 A 
    Building 2 B 
Done Building Project "D:\tmp\msbuildtest\test.xml" (default targets).