2008-12-12 32 views
6

Tôi đang cố gắng lấy danh sách tất cả các bộ kiểm thử đơn vị dưới gốc của dự án của tôi. Tôi có thể thực hiện việc này như sau:Bình thường hóa danh sách các mục trong MSBuild

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

Tuy nhiên, điều này sẽ tìm thấy cùng một tệp DLL nhiều lần vì chúng tồn tại trong nhiều thư mục con. Có một cách dễ dàng cho tôi để bình thường hóa dựa trên siêu dữ liệu mục (tức là tên tập tin và phần mở rộng) để tôi nhận được một danh sách các đơn vị kiểm tra duy nhất DLL? Hay tôi phải nghỉ để viết nhiệm vụ của riêng mình?

Trả lời

4

Các MSBuild Extension Pack chứa các nhiệm vụ MSBuildHelper, hỗ trợ lệnh 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

Âm thanh hữu ích - cảm ơn. Sẽ thử lần sau tôi cần nó. –

2

Tôi đã tìm kiếm trực tuyến tốt và không thể tìm thấy bất kỳ cách nào để thực hiện việc này. Nếu bất cứ ai biết một cách tích hợp sạch sẽ sau đó xin vui lòng cho tôi biết. Trong khi chờ đợi, tôi đã viết một nhiệm vụ đơn giản để thực hiện công việc. Việc sử dụng trông như thế này:

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

Sau khi nhiệm vụ trên đã được thực hiện, MyNormalizedItems sẽ chỉ chứa những mặt hàng từ ItemsToNormalize có một giá trị duy nhất cho Filename siêu dữ liệu. Nếu hai hoặc nhiều mục có cùng giá trị cho siêu dữ liệu Filename của chúng, kết quả phù hợp đầu tiên sẽ được bao gồm trong đầu ra.

Mã cho nhiệm vụ MSBuild là:

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

Làm thế nào để tạo thử nghiệm đơn vị cho NormalizeByMetadata Task? – Kiquenet

4

Mặc dù đây là cũ, tôi không bao giờ có thể nhận được Thomas giải pháp để làm việc bản thân mình, nhưng tôi đã tìm thấy loại một cách giải quyết chỉ sử dụng built-in lệnh với v4.0 của 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" /> 
Các vấn đề liên quan