正常化的MSBuild项目的列表
题
我试图让我的项目的根目录下的所有单元测试程序集的列表。我可以做到这一点,如下所示:
<CreateItem Include="**\bin\**\*.UnitTest.*.dll">
<Output TaskParameter="Include" ItemName="Items"/>
</CreateItem>
然而,这将因为它们在多个子目录中存在相同的DLL多次发现。有一个简单的办法,我正常化基于项目的元数据(即文件名和扩展名),使我得到的唯一单元测试的DLL列表?还是我不得不求助于写我自己的任务是什么?
解决方案
在 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>
其他提示
虽然这是老了,我永远无法得到解决托马斯的工作我自己,但我没有找到那种只使用内置命令用的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();
}
}
}
不隶属于 StackOverflow