MSBuild - 根据具体情况引入PackageReference

问题描述 投票:0回答:1

这个想法是,如果

BuildConfigurations
元数据中未指定活动/当前构建配置,则将引用的项目作为包拉取。否则,它将被添加为
ProjectReference
。在这种情况下,
MaterialBalance
Pricing
应作为包拉出。

这是代码;

<ItemGroup>
    <CustomProjectReference Include="..\ProjectName.MaterialBalance\ProjectName.MaterialBalance.csproj" PackageName="ProjectName.MaterialBalance" PackageVersion="$(AllVersions)" BuildConfigurations="Debug,Release,Prod,MaterialBalance"/>
    <CustomProjectReference Include="..\ProjectName.Pricing\ProjectName.Pricing.csproj" PackageName="ProjectName.Pricing" PackageVersion="$(AllVersions)" BuildConfigurations="Debug,Release,Prod,Pricing"/>
</ItemGroup>
<Target Name="SetPackageReferences" BeforeTargets="CollectPackageReferences">
    <ItemGroup>
        <PackageReference Include="@(CustomProjectReference->'%(PackageName)')" Version="%(CustomProjectReference.PackageVersion)" Condition="!$([System.String]::new('%(CustomProjectReference.BuildConfigurations)').Contains('$(Configuration)'))" />
    </ItemGroup>
</Target>

提供的目标

SetPackageReferences
正在按预期工作,包已恢复并且项目已构建。但是 Visual Studio 依赖关系树 无法按预期工作,我已将其报告为问题 here

如果我可以在目标/评估时间之外添加具有特定条件的包引用,我就不会出现依赖关系树问题。

您是否认为有任何替代方法可以在目标/评估时间之外实现

此目的?在 Target 之外,功能非常有限,这不起作用,需要批处理; <ItemGroup> <PackageReference Include="@(CustomProjectReference->'%(PackageName)')" Version="%(CustomProjectReference.PackageVersion)" Condition="!$([System.String]::new('%(CustomProjectReference.BuildConfigurations)').Contains('$(Configuration)'))" /> </ItemGroup>


msbuild
1个回答
0
投票
%

字符可能会令人困惑。

%
引入了元数据引用,但元数据引用的含义可能根据上下文而有很大不同。
转变

@(CustomProjectReference->'%(PackageName)')

transform
的示例。像 @(CustomProjectReference) 这样的项目集合引用可以选择进行转换。
给定以下消息任务:

<Message Text="@(CustomProjectReference)" /> <Message Text="@(CustomProjectReference->'%(PackageName)')" /> <Message Text="@(CustomProjectReference->'name is %(Filename) and ext is %(Extension)')" />

输出将是:

..\ProjectName.MaterialBalance\ProjectName.MaterialBalance.csproj;..\ProjectName.Pricing\ProjectName.Pricing.csproj ProjectName.MaterialBalance;ProjectName.Pricing name is ProjectName.MaterialBalance and ext is .csproj;name is ProjectName.Pricing and ext is .csproj

批处理

不在转换表达式中的元数据引用在目标内部或目标的一部分时进行批处理。批处理(正如您所触及的)仅适用于目标内的任务(任务批处理)和目标上的任务(目标批处理)。

元数据自参考

这留下了不在转换表达式中且不在目标中的元数据引用。这可以在项目中用作对其自身元数据的自引用。

使用

Remove

和 MatchOnMetadata 创建子集 给定

<ItemGroup> <CustomProjectReference Include="..\ProjectName.MaterialBalance\ProjectName.MaterialBalance.csproj" PackageName="ProjectName.MaterialBalance" PackageVersion="$(AllVersions)" BuildConfigurations="Debug,Release,Prod,MaterialBalance"/> <CustomProjectReference Include="..\ProjectName.Pricing\ProjectName.Pricing.csproj" PackageName="ProjectName.Pricing" PackageVersion="$(AllVersions)" BuildConfigurations="Debug,Release,Prod,Pricing"/> </ItemGroup>

有两件事需要实现:

    CustomProjectReference
  • 项目映射到
    PackageReference
    根据 
  • $(Configuration)
  • 进行过滤。
    
    
  • 映射可能如下所示:

<ItemGroup> <_tmpPackageRef Include="@(CustomProjectReference->'%(PackageName)')" Version="%(PackageVersion)" /> </ItemGroup>

@(CustomProjectReference)

中项目的现有元数据将被继承。如果您将消息任务放入适当的目标中,您可以测试并查看。

    <Message Text="@(_tmpPackageRef->'%(Identity) %(BuildConfigurations)', '%0d%0a')" />

将会显示

ProjectName.MaterialBalance Debug,Release,Prod,MaterialBalance ProjectName.Pricing Debug,Release,Prod,Pricing

过滤很棘手,因为 
BuildConfigurations

元数据的值是一个列表。但

Contains()
测试的结果可以是元数据,可以在映射时创建。可以添加
HasConfig
可用于过滤。 (请注意,此处不能使用否定运算符
!
。)
  <ItemGroup>
    <_tmpPackageRef Include="@(CustomProjectReference->'%(PackageName)')" Version="%(PackageVersion)" HasConfig="$([System.String]::new('%(BuildConfigurations)').Contains('$(Configuration)'))" />
  </ItemGroup>

将它们放在一起可能如下所示:

<ItemGroup> <_tmpPackageRef Include="@(CustomProjectReference->'%(PackageName)')" Version="%(PackageVersion)" HasConfig="$([System.String]::new('%(BuildConfigurations)').Contains('$(Configuration)'))" /> <_Tester Include="True" HasConfig="%(Identity)" /> <_tmpPackageRef Remove="@(_Tester)" MatchOnMetadata="HasConfig" /> </ItemGroup> <ItemGroup> <PackageReference Include="@(_tmpPackageRef)" /> </ItemGroup>

_Tester

物品收藏仅适用于

Remove
_Tester
的目的是提供一个
HasConfig
Include
的值可以是任何值。我选择包含
True
和自我参考来设置
HasConfig
。匹配适用于
True
(不是
False
),因为匹配的项目将被删除,仅留下
$(Configuration)
的当前值不在
BuildConfigurations
中的项目。
    

© www.soinside.com 2019 - 2024. All rights reserved.