Domanda

Sto cercando di ottenere un elenco di tutte le linee di prova unità sotto la radice del mio progetto. Posso fare questo nel modo seguente:

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

Tuttavia, questo sarà trovare le stesse DLL più volte dal momento che esistono in più sotto-directory. C'è un modo facile per me di normalizzare in base al punto di metadati (es. Il nome del file e l'estensione) in modo che ho un elenco di DLL di unit test unico nel suo genere? O devo ricorrere a scrivere il mio compito?

È stato utile?

Soluzione

Il Extension Pack MSBuild contiene l'attività MSBuildHelper , sostenendo il comando 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>

Altri suggerimenti

Anche se questo è vecchio, non avrei mai potuto ottenere la soluzione Thomas al lavoro me stesso, ma ho trovato una sorta di soluzione utilizzando solo comandi incorporati con v4.0 di 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" />

Documentazione: Voce Funzioni

Ho fatto una buona ricerca online e non sono riuscito a trovare un modo di fare questo. Se qualcuno conosce un modo integrato in un ambiente pulito, allora per favore fatemelo sapere. Nel frattempo, ho scritto un compito semplice per fare il lavoro. L'utilizzo è simile al seguente:

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

Dopo l'operazione di cui sopra ha eseguito, MyNormalizedItems conterrà solo gli elementi da ItemsToNormalize che hanno un valore unico per il Filename metadati. Se due o più elementi hanno lo stesso valore per i loro metadati <=>, la prima partita sarà incluso nell'output.

Il codice per l'attività 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();
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top