繁体   English   中英

NuGet与packages.config,项目引用和solutionwide packages文件夹有关

[英]NuGet issues with packages.config, project references and the solutionwide packages folder

我们开始使用NuGet,我们遇到了一些问题:

首先是一些NuGet事实:

(只是为了确保我们了解NuGet的工作原理)

  • 在添加,更新或删除包时,会创建并更新packages.config(位于project-root中)。 在此文件中,包版本属性反映了正在使用的完整版本,因此从这个意义上说它也是一个状态。 可以将allowedVersions属性添加到包规范中,这是对可以更新的版本的限制。 要使程序包还原起作用,此文件需要受源代码管理。

  • packages文件夹位于solution-root中,并在子文件夹中包含一个下载版本的依赖包,其名称与包名称(包括版本)相匹配,以允许多个中的不同项目使用同一个包的多个版本 - 项目解决方案。 建议不要将它们作为二进制文件来源控制,并且包恢复可以在需要时重新创建它们。 更新包时,将使用其中的包创建与更新匹配的新文件夹。

  • 项目文件包含对packages文件夹中的包的引用,以使构建工作,并且visual studio也能够提供自动完成,智能感知等。 更新包时,项目文件中的引用将更新以匹配packages文件夹中包的新位置。

问题:

  1. 由于packages.config文件包条目包含完整的版本信息,因此我们经常需要更新源控件存储库。 或者,我们可以在大多数情况下忽略这些更改,但是当版本发生变化时,我们(在大多数情况下)会忽略它们。 这似乎是非常不必要的,因为NuGet恢复应该能够知道允许哪些版本(通过allowedVersions)。

  2. 必须手动添加allowedVersions属性,这很容易被遗忘。 我们正在使用语义版本控制,因此对于我们来说,在安装即Foo-1.1.0版本时,应隐含allowedVersions =“[1,2]”。

  3. 当添加allowedVersion时,NuGet包恢复似乎无法找到-prerelease程序集(可能是一个错误?)。

  4. 为什么NuGet在解决方案级别处理包? 如果您正在使用包含项目A(repo-1)和项目B(repo-2)的混合搭配解决方案,那么解决方案级别的打包将无法正常运行。 也就是说,如果您将该解决方案文件保存在一个单独的位置,那么事情可能仍然有效。 但是,如果你然后设置另一个包含项目-A(repo-1)和项目-C(repo-3)的解决方案,那么项目-A将突然再次需要一个包恢复,更糟糕的是,项目引用将是更改为匹配上次更改。 回到第一个解决方案将有参考不起作用。 检查这些肯定会使它们不适合其他人。

  5. 在程序包更新中,更新项目文件引用(以匹配其中包含versionid的新foldernames),并将显示为未提交的更改。 承诺这一变化似乎是常态,但我们认为这不是必要的。

关于ExcludeVersion的注释 (可以建议作为上述问题的解决方案:

  • 您只能在手动执行NuGet命令时提供该选项。 通过Visual Studio中的NuGet菜单安装/更新软件包时,无法使用该选项。 使用任何自动化工具意味着必须手动修复foldername和项目引用。

  • 我们知道ExcludeVersion不是默认设置,可能是因为支持某人在多项目解决方案中工作的情况,其中不同的项目依赖于同一个包的不同版本。

可能的解决方案?

(但是,这可能需要NuGet生态系统的重大变化?)

A - packages.config

我希望packages.config中的每个package元素都可以抛弃allowedVersions,而是将version更改为范围说明符。 packages元素还应提供一种单独标识从哪个源获取更新的方法。 最后,如果已安装的软件包遵循语义版本控制,则版本属性应根据安装的版本自动设置版本范围。

示例packages.config:

`<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Foo" version="[1,2] source="Development Feed">
</packages>`

这个会:

  • 修复了package.config文件过多提交的问题,因为版本属性不再经常更新。

  • 无需记住为语义版本的项目设置范围。

  • 确保从所需的源中获取包,并且通过在错误的源中查找它而不浪费时间。

B - Packages文件夹和其中已安装软件包的名称

我希望packages文件夹位于每个项目根目录中,并且子文件夹名称仅限于包名称,不包括版本。 这个会:

  • 修复了项目文件过多提交的问题,因为项目文件中的项目引用现在指向更新后的同一个包文件夹。

  • 允许项目使用相同包的不同版本,因为它们真正相互独立。


我们很高兴听到所列问题的解决方案。

正如NuGet Enterprise中所建议的那样- 针对不同成熟度级别的包的最佳实践 ,我认为你做的事情比必要的更复杂:)

  1. 为什么你不想捕获编译代码的包的版本? 这是可靠诊断和可重复构建的关键信息。 鉴于您可能会将代码更改提交回版本控制,提交有关使用哪些包来帮助构建该源的详细信息非常有用。
  2. 当安装即Foo-1.1.0版本时,allowedVersions =”[1,2]“应该暗示 ”我不认为允许版本真的可以被暗示,因为并非所有NuGet包都坚持SemVer(参见崩溃log4net 1.2.11 )。 设置一个grep for allowedVersions作为CI构建或预提交/ pre-push Dev检查的一部分应该抓住这个。 它不应该经常改变,并且注意它是有用的(如果其他团队和包正确地使用SemVer,无论如何:))。
  3. 要查找Prerelease包,您需要在nuget安装上使用Prerelease-IncludePrerelease标志。
  4. 如果您正在使用混合匹配解决方案,其中包含项目-A(repo-1)和项目-B(repo-2) ” - 为什么要安排这样的代码? 单个解决方案的代码应该存在于同一个repo中。 在回购中破解解决方案代码肯定会很痛苦!
  5. 您可以告诉nuget使用无版本文件夹名称来安装包( -ExcludeVersion )。

我强烈建议使用命令行nuget.exe和构建脚本来放弃Visual Studio NuGet集成。 这尤其涉及#5,但通常与NuGet的交互。 当单独使用nuget.org feed中的第三方公共包时,Visual Studio集成很好,但在处理内部NuGet提要和包时,它不够灵活。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM