我有一个包含以下packages.config的项目:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Framework.Infrastructure.Core" version="1.4.0.6" />
<package id="Framework.Infrastructure.Extensions" version="1.4.0.6" />
</packages>
Framework . *包位于我们的本地存储库中 .
我启用了Package Restore并将内部repo添加到了源代码中 . 但是,当我尝试从packages.config(基本上是 nuget install packages.config -sources....
)恢复软件包时,我收到以下错误:
error : Unable to find version '1.4.0.6' of package 'Framework.Infrastructure.Extensions'
error : Unable to find version '1.4.0.6' of package 'Framework.Infrastructure.Core'.
存储库不再包含程序包的 1.4.0.6 版本(几个月前相关),而是包含它的新版本(例如, 1.5.1.6 ) .
为什么NuGet没有找到新版本的软件包?我可以在packages.config中指定一些语法以确保下载最新版本吗?
简而言之,编写自定义脚本以更新我可以执行的包有什么用吗?
谢谢 .
4 回答
如果您只是从nuget中删除并重新安装软件包,则version属性将引用最新版本 .
您可能需要手动编辑packages.config以在从nuget重新安装之前删除旧的引用(因为我最近有一种情况,nuget不允许我安装新包,因为它认为我有旧的包存在)
如果有人遇到这种情况,我编写了一个PowerShell模块,并将其包装在NuGet包中,用户需要在模板创建时运行 . 该脚本遍历解决方案中的每个C#项目,找到其“packages.config”(如果有的话),然后删除并重新安装那里提到的每个包 .
显然,在一般方法和小错误方面都有很大的改进空间(例如,安装部分中的nuget命令不会在全名中包含空格的解决方案上运行),但这是一个开始 .
档案 NuGet-RestorePackagesInAllProjects.psm1
档案 init.ps1
包的 .nuspec 文件
我认为有些人误解了Package Restore的意图 . 此功能仅添加到NuGet,目的是不要将包检入版本控制 . 很多人都在抱怨提交二进制文件正在扩大其存储库的大小,并且当使用像git这样的DVCS时会更糟糕,其中整个存储库在本地下载并包含每个版本的软件包Foo .
那么Package Restore究竟做了什么?基本上它在每个项目的packages.config中查找并简单地下拉列出的包的特定版本 . 这就像删除你的包文件夹,然后做
git reset --hard
带回来(假设文件夹已签入) .为什么这很重要?为什么不升级到最新的软件包版本?如果您考虑Package Restore的最常见用例,即自动构建,那么应该为您提供线索 . 构建服务器应该只构建由开发人员测试和提交的项目 . 如果您让构建服务器决定何时更新包,那么您有一个尚未经过任何人测试的项目 . 作为开发人员,您应该决定何时进行升级 .
请记住,安装或更新软件包并不只是简单地下载.nupkg文件并添加引用 . 很多软件包都有副作用,例如更新.config文件,添加代码等 . 安装软件包时,所有这些副作用都会发生在本地副本上 . 您现在可以提交代码并排除包文件 .
当另一个开发人员或构建服务器检出代码时,他将使用完全相同的副作用代码减去包文件 . Package Restore只是从NuGet存储库中提取这些文件,现在我们拥有了处理这个项目所需的一切 .
NuGet团队承诺维护所有版本的软件包,以便您始终能够下载正确的版本 . 然而,正如我们几个月前看到的那样,当NuGet服务器出现故障时,它几乎瘫痪了Package Restore,很多人无法构建 .
我建议您设置自己的NuGet存储库(一个简单的文件共享),并保留您在那里使用的所有包的副本 . 这样,您就不依赖于构建的外部服务器 . 正如NuGet团队所做的那样,你应该保留所有版本的软件包 . 这样,如果您必须返回并构建项目的旧版本,您将确保拥有正确的软件包版本 .
我希望这可以解释该功能的工作原理以及它为何如此工作 .
我建议你阅读NuGet documentation for Versioning . 它解释了如何在
packages.config
文件中使用版本号(和范围)以允许Update-Package命令知道要升级到的可接受版本 .话虽如此,包恢复功能 will not 会自动为您更新包 .
有了这些信息,最好的工作流程IMO是:
安装要添加的任何新依赖项的最新稳定版本,除非您确实需要较旧(或预发布)版本
在CI版本中使用Package Restore,允许您在您的VCS中签入NuGet包 not
仅
Update-Package
如果......您需要从最新版本获得新的API调用或错误修复
你有一个很有信心的测试套件
你有时间处理潜在的后果
我不鼓励定期升级包,因为 . 如果项目运行良好,最好让项目与旧的依赖项保持一致,因为在更新任何版本时存在风险包 .
NuGet包应该遵循Semantic Versioning,它有很好的规则允许最无压力的包升级体验,但因为这没有强制实施(并且相信我,许多包发布者都不依赖它 . 即使包更新了只有少量版本增加,您无法确定(没有经过充分测试)新版本将与您的代码一起使用 .
总之,自动升级任何包通常是个坏主意 . 最好让开发人员明确选择更新任何给定的包,并且只有足够好的理由 .