我正在尝试获取项目根目录下的所有单元测试程序集的列表。我可以这样做:
<CreateItem Include="**\bin\**\*.UnitTest.*.dll">
<Output TaskParameter="Include" ItemName="Items"/>
</CreateItem>
但是,由于它们存在于多个子目录中,因此会多次找到相同的DLL。有没有一种简单的方法让我根据项目元数据(即文件名和扩展名)进行规范化,以便获得一个唯一的单元测试DLL列表?或者我是否必须自己编写自己的任务?
答案 0 :(得分:6)
即使这已经过时了,我也无法让托马斯解决方案自行工作,但我确实找到了一种解决方法,只使用内置命令和vbu.0的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" />
答案 1 :(得分:4)
MSBuild Extension Pack包含 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>
答案 2 :(得分:2)
我在线搜索得很好,找不到任何方法。如果有人知道干净的内置方式,请告诉我。与此同时,我写了一个简单的任务来完成这项工作。用法如下:
<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();
}
}
}