Нормализация списка элементов в MSBuild

Я пытаюсь получить список всех сборок модульных тестов в корне моего проекта. Я могу сделать это следующим образом:

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

Тем не менее, это найдет одни и те же DLL несколько раз, так как они существуют в нескольких подкаталогах. Есть ли простой способ для меня нормализовать на основе метаданных элемента (т.е. имя файла и расширение), чтобы я получил список уникальных библиотек DLL модульного теста? Или я должен прибегнуть к написанию своего собственного задания?

12.12.2008 14:57:40
3 ОТВЕТА
РЕШЕНИЕ

Пакет расширения 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>
4
23.12.2016 17:42:15

У меня был хороший поиск в Интернете и я не мог найти способ сделать это. Если кто-нибудь знает чистый встроенный способ, пожалуйста, дайте мне знать. Тем временем я написал простую задачу, чтобы сделать работу. Использование выглядит следующим образом:

<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();
        }
    }
}
2
27.09.2011 16:40:14
Как создать модульный тест для задачи NormalizeByMetadata?
Kiquenet 11.09.2014 08:15:10

Несмотря на то, что это старое решение, я никогда не мог заставить решение 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" />

Документация: Функции товара

8
18.04.2018 10:09:12
Это должен быть принятый ответ. Встроенная функциональность - это все, что вам нужно.
marsze 18.04.2018 10:10:05