update-package时约束PackageReference升级版本运行

Constrain PackageReference upgrade version when update-package run

在 .NET 的旧 packages.config NuGet 系统下,I could constrain the possible versions of a package that are considered when packages are updated by using the allowedVersions Package 元素上的属性

<package id="Newtonsoft.Json" version="10.0.3" allowedVersions="[10.0.3]" />

update-package 在 Visual studio 中的 运行 对于包含上述内容的项目,Newtonsoft.Json 不会发生更新,因为我已固定到 10.0.3 使用allowedVersions 属性。

如何在 PackageReference? Applying semver 语法下实现此功能,版本属性仅影响版本 restored - 它不限制更新。因此,如果我指定以下 PackageReference 和 运行 update-package,例如,如果 11.0.1 在我的 NuGet 存储库中,我将升级到 11.0.1。

<PackageReference Include="Newtonsoft.Json" Version="[10.0.3]" />

背景

我们依靠命令行工具来更新包,因为我们既有快速移动的内部包(每天更新多次),也有更稳定的低移动包(例如:ASP.NET)。在大型代码库上,手动更新 .csproj 文件中的每个依赖项对我们来说根本不可扩展(并且容易出错)。在 packages.config 下,我们可以 'pin' 我们不想升级的第三方包,也可以更新到最新的快速移动依赖项。

来自 :

At the moment, this is not possible. See this GitHub issue for tracking.

The cli commands for adding references however support updating single packages in a project by re-running dotnet add package The.Package.Id.

来自 GitHub Issue 4358:

There is no PackageReference replacement for update yet, the command to modify references is only in dotnet.

您可能想权衡关于此的开放功能请求 GitHub issue 4103(4358 作为重复关闭)。微软并没有把这个功能放在高优先级(它最初是在 2016 年 10 月开放的)。

可能的解决方法

选项 1

可以通过删除和添加引用来“更新”依赖项。根据 this post,使用命令明确指定版本将安装 确切版本 ,而不是最新版本。我还确认您可以使用以下命令添加版本限制:

dotnet remove NewCsproj.csproj package Newtonsoft.Json
dotnet add NewCsproj.csproj package Newtonsoft.Json -v [10.0.3]

你可以用这些命令做什么:

  1. 将包的版本号保存在一个文本文件中(也许只是将其命名为 packages.config)。
  2. 使用脚本创建您自己的“更新”命令,该命令读取文本文件并使用上述 2 个命令循环处理每个依赖项。该脚本可以设置为传递一个 .sln 文件来处理其中的每个项目。

选项 2

使用 MSBuild 从通用 MSBuild 文件“导入”依赖项,您可以在一个地方更新版本。

您可以定义自己的 <IncludeDependencies> 元素以包含每个项目的特定依赖项。

SomeProject.csproj

<Project Sdk="Microsoft.NET.Sdk">

    <IncludeDependencies>Newtonsoft.Json;FastMoving</IncludeDependencies>
    <Import Project="..\..\..\Dependencies.proj" />
  
    ...
  
</Project>

Dependencies.proj

<Project>

    <ItemGroup>
        <PackageReference Condition="$(IncludeDependencies.Contains('Newtonsoft.Json'))" Include="Newtonsoft.Json" Version="[10.0.3]" />
        <PackageReference Condition="$(IncludeDependencies.Contains('FastMoving'))" Include="FastMoving" Version="3.332.0" />
    </ItemGroup>
  
</Project>

这已从 https://github.com/NuGet/NuGet.Client/pull/2201 开始实施。如果您使用的是任何版本的 NuGet 5,PackageReference semver 约束现在应该可以按预期工作。

固定 - 另一种解决方法

这不会阻止更新,但如果有人这样做并更新,则会触发构建错误。它对自动更新的用例没有多大帮助,但它可能会帮助其他进行手动更新并需要某种固定方式的人。

<ItemGroup>
    <PackageReference Include="MongoDB.Driver" Version="2.13.*" GeneratePathProperty="true" />
</ItemGroup>

<Target Name="CheckPkgVersions" AfterTargets="AfterBuild">
    <Error Condition="!$(PkgMongoDB_Driver.Contains('2.13.'))" Text="MongoDB.Driver must remain at version 2.13.* to be compatible with MongoDB 3.4.21" />
</Target>