在MSBuild中规范化一个项目列表

7

我想获取项目根目录下的所有单元测试程序集列表。可以按照以下步骤完成:

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

然而,由于它们存在于多个子目录中,因此这将多次找到相同的DLL。是否有一种基于项元数据(即文件名和扩展名)归一化的简单方法,以便我得到唯一的单元测试DLL列表?还是我必须采取编写自己的任务的方式?
3个回答

8
尽管这篇文章有些过时,但我自己无法让 Thomas 的解决方案正常工作,不过我找到了一种方法,使用 v4.0 版本的 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" />

文档: 项函数


这应该是被接受的答案。内置功能就是你所需要的一切。 - marsze

4

MSBuild扩展包中包含任务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>

2

我在网上进行了充分的搜索,但没有找到任何一种方法来完成这个任务。如果有人知道一个干净简洁的内置方式,请告诉我。同时,我编写了一个简单的任务来完成这项工作。使用方法如下:

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

执行上述任务后,MyNormalizedItems 将仅包含 ItemsToNormalize 中那些在 Filename 元数据中具有唯一值的项。如果两个或多个项目具有相同的 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();
        }
    }
}

如何为 NormalizeByMetadata 任务创建单元测试? - Kiquenet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接