Kent Boogaart
Kent Boogaart

Reputation: 178770

Is there a way to update a PackageReference to some minimum version in Directory.Build.targets?

Using .NET Core 5, is there a way to set a minimum version for a PackageReference via a Directory.Build.targets file?

We have a set of projects, most of which need to use a specific version of a package that is referenced by default by the compiler (FSharp.Core). However, one or two projects need a higher version. Therefore, we have a Directory.Build.targets that has:

<ItemGroup>
  <PackageReference Update="FSharp.Core" Version="4.7.2" />
</ItemGroup>

Most project files therefore don't need any mention of FSharp.Core, but a couple would like a higher version, so they have this in their project files:

<ItemGroup>
  <PackageReference Update="FSharp.Core" Version="5.0.2" />
</ItemGroup>

However, the Directory.Build.targets file then downgrades the version as you'd expect. I don't want it to do this. I instead want the Directory.Build.targets file to impose a minimum version of 4.7.2.

I figured I could put a Condition on the PackageReference that only applies if the existing PackageReference has a Version < 4.7.2. But I haven't been able to figure out the MSBuild way of doing that, and am rapidly coming to the conclusion that it may not even be possible.

Here's where I'm at so far:

<Project>
  <ItemGroup>
    <FSharpCoreReferencesRequiringUpgrading Include="@(PackageReference)" Condition="$(%(Identity)) == 'FSharp.Core'"/>
  </ItemGroup> 

  <ItemGroup>
    <PackageReference Update="FSharp.Core" Version="4.7.2" />
  </ItemGroup>
</Project>

By using an MSBuild Message task I've been trying to figure out what incantations are required to modify the Condition on FSharpCoreReferencesRequiringUpgrading such that it:

  1. filters out all package references other than FSharp.Core
  2. filters out all package references that are 4.7.2 or higher

I'm stuck on the first step because doing a simple string comparison as above does not work, and attempting to invoke ToString() or Include on the PackageReference does not work:

<!--
error MSB4184: The expression "%(Identity).ToString()" cannot be evaluated.
-->
Condition="$(%(Identity).ToString()) == 'FSharp.Core'"

Does anyone know if this is possible and how to go about it?

UPDATE 1: I've created a repro here

UPDATE 2: I've added an example of a fix suggested by David Kean (@davkean) here. However, I've definitely not implemented it correctly yet as I've obviously misunderstood him

UPDATE 3: I've added an example of another fix that works with all my testing, this time based on a recommendation from @Taskkant here. The fix is here

Upvotes: 2

Views: 844

Answers (1)

weichch
weichch

Reputation: 10055

UPDATE

Try this in Directory.Build.targets:

<Project>
  <PropertyGroup Condition="'$(UseHigherFSharpCoreVersion)' != 'true'">
    <FSharpCorePackageVersion>4.7.2</FSharpCorePackageVersion>
  </PropertyGroup>
  
  <PropertyGroup Condition="'$(UseHigherFSharpCoreVersion)' == 'true'">
    <FSharpCorePackageVersion>5.0.2</FSharpCorePackageVersion>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Update="FSharp.Core" Version="$(FSharpCorePackageVersion)" />
  </ItemGroup>
</Project>

Then in fsproj where higher version should be used:

<PropertyGroup>
  <UseHigherFSharpCoreVersion>true</UseHigherFSharpCoreVersion>
</PropertyGroup>

Upvotes: 1

Related Questions