2008-12-12 45 views
6

我想獲得我的項目根目錄下的所有單元測試程序集列表。我能做到這一點,如下所示:標準化MSBuild中的項目列表

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

然而,由於它們在多個子目錄中存在這樣會發現同樣的DLL多次。是否有一種簡單的方法讓我根據項目元數據進行規範化(即文件名和擴展名),以便獲得唯一單元測試DLL的列表?還是我必須訴諸寫我自己的任務?

回答

4

MSBuild Extension Pack的包含任務MSBuildHelper,支持命令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

聽起來很有用 - 謝謝。下次嘗試這個時候我需要它。 – 2009-08-24 09:17:35

2

我在網上有一個很好的搜索,找不到任何這樣做的方式。如果有人知道一個乾淨的內置方式,請讓我知道。同時,我寫了一個簡單的任務來完成這項工作。用法是這樣的:

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

上述任務已執行後,MyNormalizedItems只會包含ItemsToNormalize具備爲Filename元數據的獨特價值的項目。如果兩個或更多項目的元數據具有相同的值,則第一個匹配項將包含在輸出中。

用於MSBuild任務的代碼是:

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任務創建單元測試? – Kiquenet 2014-09-11 08:15:10

4

即使這是老了,我永遠無法得到解決托馬斯的工作,不過我的確發現僅使用內置命令用的MSBuild 4.0版解決方法的排序:

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