规范化 MSBuild 中的项目列表

发布于 2024-07-10 09:17:21 字数 331 浏览 11 评论 0原文

我正在尝试获取项目根目录下所有单元测试程序集的列表。 我可以按如下方式执行此操作:

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

但是,这会多次找到相同的 DLL,因为它们存在于多个子目录中。 有没有一种简单的方法可以让我根据项目元数据(即文件名和扩展名)进行规范化,以便获得唯一的单元测试 DLL 列表? 或者我必须求助于编写自己的任务吗?

I am trying to get a list of all unit test assemblies under the root of my project. I can do this as follows:

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

However, this will find the same DLLs multiple times since they exist in multiple sub-directories. Is there an easy way for me to normalize based on item metadata (ie. the file name and extension) so that I get a list of unique unit test DLLs? Or do I have to resort to writing my own task?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

二货你真萌 2024-07-17 09:17:21

尽管这已经很旧了,但我自己永远无法让 Thomas 解决方案发挥作用,但我确实找到了一种仅使用 msbuild v4.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" />

文档: 项目功能

Even though this is old, I could never get Thomas solution to work myself, but I did find sort of a workaround using only built-in commands with v4.0 of 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" />

Documentation: Item Functions

浅语花开 2024-07-17 09:17:21

MSBuild Extension Pack 包含任务 MSBuildHelper,支持命令 删除重复文件

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

The MSBuild Extension Pack contains the task MSBuildHelper, supporting the command 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>
噩梦成真你也成魔 2024-07-17 09:17:21

我在网上进行了很好的搜索,但找不到任何方法可以做到这一点。 如果有人知道干净的内置方式,请告诉我。 与此同时,我编写了一个简单的任务来完成这项工作。 用法如下:

<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();
        }
    }
}

I had a good search online and couldn't find any way of doing this. If anyone knows a clean built-in way then please let me know. In the meantime, I wrote a simple task to do the job. The usage looks like this:

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

After the above task has executed, MyNormalizedItems will contain only those items from ItemsToNormalize that have a unique value for the Filename metadata. If two or more items have the same value for their Filename metadata, the first match will be included in the output.

The code for the MSBuild task is:

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();
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文