2008-12-12 15 views
6

Estoy tratando de obtener una lista de todos los conjuntos de pruebas de unidades en la raíz de mi proyecto. Puedo hacer esto de la siguiente manera:Normalización de una lista de elementos en MSBuild

<CreateItem Include="**\bin\**\*.UnitTest.*.dll"> 
    <Output TaskParameter="Include" ItemName="Items"/> 
</CreateItem> 

Sin embargo, esto va a encontrar los mismos DLL varias veces desde que existen en múltiples sub-directorios. ¿Existe una manera fácil para mí de normalizar en función de los metadatos del elemento (es decir, el nombre y la extensión del archivo) para que obtenga una lista de archivos DLL únicos de pruebas unitarias? ¿O debo recurrir a escribir mi propia tarea?

Respuesta

4

El MSBuild Extension Pack contiene la tarea MSBuildHelper, apoyando el comando RemoveDuplicateFiles.

<CreateItem Include="**\bin\**\*.UnitTest.*.dll"> 
    <Output TaskParameter="Include" ItemName="Items"/> 
</CreateItem> 
<MSBuild.ExtensionPack.Framework.MsBuildHelper TaskAction="RemoveDuplicateFiles" InputItems1="@(Items)"> 
    <Output TaskParameter="OutputItems" ItemName="Items"/> 
</MSBuild.ExtensionPack.Framework.MsBuildHelper> 
+0

Suena útil, gracias. Lo intentaré la próxima vez que lo necesite. –

2

Tuve una buena búsqueda en línea y no pude encontrar ninguna forma de hacerlo. Si alguien conoce una forma integrada y limpia, házmelo saber. Mientras tanto, escribí una tarea simple para hacer el trabajo. El uso es el siguiente:

<NormalizeByMetadata Items="@(ItemsToNormalize)" MetadataName="Filename"> 
    <Output TaskParameter="NormalizedItems" ItemName="MyNormalizedItems"/> 
</NormalizeByMetadata> 

Después de la tarea anterior se ha ejecutado, MyNormalizedItems contendrá sólo aquellos elementos de ItemsToNormalize que tienen un valor único para los Filename metadatos. Si dos o más elementos tienen el mismo valor para sus metadatos Filename, la primera coincidencia se incluirá en la salida.

El código para la tarea de MSBuild es:

public class NormalizeByMetadata : Task 
{ 
    [Required] 
    public ITaskItem[] Items 
    { 
     get; 
     set; 
    } 

    [Required] 
    public string MetadataName 
    { 
     get; 
     set; 
    } 

    [Output] 
    public ITaskItem[] NormalizedItems 
    { 
     get; 
     private set; 
    } 

    public override bool Execute() 
    { 
     NormalizedItems = Items.Distinct(new ItemEqualityComparer(MetadataName)).ToArray(); 
     return true; 
    } 

    private sealed class ItemEqualityComparer : IEqualityComparer<ITaskItem> 
    { 
     private readonly string _metadataName; 

     public ItemEqualityComparer(string metadataName) 
     { 
      Debug.Assert(metadataName != null); 
      _metadataName = metadataName; 
     } 

     public bool Equals(ITaskItem x, ITaskItem y) 
     { 
      if (x == null || y == null) 
      { 
       return x == y; 
      } 

      var xMetadata = x.GetMetadata(_metadataName); 
      var yMetadata = y.GetMetadata(_metadataName); 
      return string.Equals(xMetadata, yMetadata); 
     } 

     public int GetHashCode(ITaskItem obj) 
     { 
      if (obj == null) 
      { 
       return 0; 
      } 

      var objMetadata = obj.GetMetadata(_metadataName); 
      return objMetadata.GetHashCode(); 
     } 
    } 
} 
+0

¿Cómo crear pruebas unitarias para la tarea NormalizeByMetadata? – Kiquenet

4

pesar de que esto es viejo, nunca podría obtener una solución Thomas para trabajar a mí mismo, pero encontré una especie de solución utilizando sólo comandos integrados con v4.0 de msbuild:

<ItemGroup> 
    <TestAssemblies Include="$(SolutionRoot)\**\bin\*.Tests.dll" /> 
    <TestItems Include="%(TestAssemblies.FileName)%(TestAssemblies.Extension)"> 
     <ItemPath>%(TestAssemblies.Identity)</ItemPath> 
    </TestItems> 
    <DistinctTestItems Include="@(TestItems->Distinct())"></DistinctTestItems> 
</ItemGroup> 
<Message Text="%(DistinctTestItems.ItemPath)" Importance="high" /> 
Cuestiones relacionadas