2008-12-12 33 views
6

'daki öğelerin bir listesini normalleştirme Projemin kökü altındaki tüm birim test derlemeleri listesini almaya çalışıyorum. aşağıdaki gibi bunu yapabilirim: bunlar birden çok alt dizinleri yer aldığındanMSBuild

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

Ancak bu aynı DLL birden çok kez bulacaksınız. Eşsiz birim test DLL'lerinin bir listesini alabilmem için öğe meta verilerine (yani dosya adı ve uzantısı) dayalı olarak normalleştirmem için kolay bir yol var mı? Yoksa kendi görevimi yazmak için başvurmalı mıyım?

cevap

4

MSBuild Extension PackRemoveDuplicateFiles komutunu destekleyen MSBuildHelper görevi içerir.

<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

Yararlı geliyor - teşekkürler. İhtiyacım olana kadar bunu deneyeceğim. –

2

İnternette iyi bir arama yaptım ve bunu yapmanın hiçbir yolunu bulamadım. Eğer herkes temiz bir şekilde bilirse lütfen bana bildirin. Bu arada, işi yapmak için basit bir görev yazdım. kullanım şuna benzer: Yukarıdaki görev yürüttü sonra

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

, MyNormalizedItemsFilename meta verileri için farklı bir değere sahip ItemsToNormalize sadece bu öğeleri içerecek. İki veya daha fazla öğe, Filename meta verileri için aynı değere sahipse, ilk eşleme çıktıya dahil edilir.

MSBuild görev kodudur:

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

NormalizeByMetadata Görev için birim testi nasıl oluşturulur? – Kiquenet

4

bu eski olsa da, kendimi işe Thomas çözümünü asla olabilir ama msbuild ait v4.0 ile yalnızca yerleşik komutları kullanarak geçici bir çözüm çeşit buldunuz:

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