2011-01-24 14 views
11

Sto scrivendo uno script per msbuild che dovrebbe fare due batch in un solo passaggio.
Esempio: 2 ItemGroupsDouble-Loop in msbuild?

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

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

Questi due gruppi deve essere avvolto dentro l'altro:

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

speravo che msbuild rende il risultato da entrambi i lotti dando

1 A 
2 A 
1 B 
2 B 

come risultato.
Ma non è successo. Invece, ha restituito il seguente stronzate inutili:

1 
2 
    A 
    B 

Farlo il modo in cui il blog dal link sottostante propone (utilizzando un propertyGroup locale) come

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

rende

2 A 
2 B 

Qualsiasi suggerimenti? Sto impazzendo :-(

PS: Ecco un blogpost sul tema - purtroppo non funziona come ci, proposto: http://blogs.msdn.com/b/giuliov/archive/2010/04/30/gotcha-msbuild-nested-loops-double-batching.aspx

risposta

11

Provate a creare una nuova ItemGroup utilizzando l'identità del gruppo 1 e assegnando metadati al nuovo gruppo elemento dalla identità (o qualsiasi altri metadati) del gruppo 2. Quindi utilizzare dosaggio per iterare il nuovo gruppo.

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

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

Se si dispone di più di due gruppi è possibile aggiungere voci CreateItem di fondere il terzo gruppo in _Group_Merged e quindi itera su quel gruppo combinato

<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

Wizard! Che funzioni! :-) – Sascha

+0

Magico! Grazie –

11

Questa è una soluzione molto più semplice.

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

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

Utilizzando un gruppo di articoli intermedio Combined per creare un gruppo di articoli intermedio che i lotti attività Message on.

Se si fa riferimento a due gruppi di articoli nella stessa attività, Msbuild eseguirà il batch su entrambi separatamente. che non è ciò che si desidera

Se avete più ItemMetaData è necessario gestire in modo esplicito che per il secondo ItemGroup, L'ItemGroup incluso con il simbolo di riferimento @ include automaticamente l'ItemMetaData, quindi avrete solo bisogno di creare il MetaData aggiuntivo dal secondo gruppo facendo riferimento esplicitamente. Ecco un esempio:

<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

Si può anche creare dei cicli triple nidificati utilizzando la tecnica della 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

Per due cicli annidati funziona:

<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> 

Risultati in:

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).