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?
Thanks
-
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 fromItemsToNormalize
that have a unique value for theFilename
metadata. If two or more items have the same value for theirFilename
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(); } } }
HTH, Kent
-
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>
Kent Boogaart : Sounds useful - thanks. Will try this next time I need it.
0 comments:
Post a Comment