Вопрос

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

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

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

Это было полезно?

Решение

Тот Самый Пакет расширений MSBuild содержит задачу 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>

Другие советы

Несмотря на то, что это старое решение, я никогда не мог заставить решение Thomas работать самостоятельно, но я нашел своего рода обходной путь, используя только встроенные команды с версией 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" />

Документация: Функции элемента

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

<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();
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top