问题描述
我们开始使用 NuGet,但遇到了一些问题:
We are starting to use NuGet and we are having some issues:
(只是为了确保我们了解 NuGet 的工作原理)
packages.config(位于项目根目录)在您添加、更新或删除包时创建和更新.在这个文件中,包版本属性反映了正在使用的完整版本,所以在这个意义上它也是一个状态.可以将 allowedVersions 属性添加到包规范中,然后限制可以更新的版本.为了使包恢复工作,这个文件需要在源代码控制之下.
The packages.config (located in project-root) is created and updated as you add, update or delete packages. Within this file the package version property reflects the full version that is in use, so in this sense it is also a state. It is possible to add the allowedVersions property to the package specification, which is then a restriction on which versions that can be updated. To make package restore work, this file need to be under source control.
packages 文件夹位于解决方案根目录中,并在子文件夹中包含依赖包的下载版本,该子文件夹的名称与包名称(包括版本)匹配,以允许使用同一包的多个版本通过多项目解决方案中的不同项目.建议不要对它们进行源代码控制,因为它们是二进制文件,并且包还原可以在需要时重新创建它们.更新包时,将创建一个与更新匹配的新文件夹,其中包含该包.
The packages folder is located in the solution-root and contains a downloaded version of the dependent packages in a subfolder named to match the package names (including version), to allow multiple versions of the same package to be used by different projects in a multi-project solution. It is advised not to source control these as they are binaries and the fact that package restore can recreate them when needed. When a package is updated a new folder that matches the update is created with the package in it.
项目文件包含对 packages 文件夹中的包的引用,以便构建工作并且 Visual Studio 也能够提供自动完成、智能感知等.更新包时,项目文件中的引用会更新以匹配包文件夹中包的新位置.
The project-files contains a reference to the packages in the packages folder, in order for builds to work and for visual studio to also be able to provide autocomplete, intellisense and more. When a package is updated the references in the project-file are updated to match the new location of the package in the packages folder.
由于 packages.config 文件包条目包含完整的版本信息,我们需要不断更新源代码控制 repo 并进行更改.或者,我们可以在大多数情况下忽略这些变化,但是当版本发生变化时,我们(在大多数情况下)可以忽略它们.这似乎非常不必要,因为 NuGet 还原应该能够知道哪些版本是允许的(通过 allowedVersions).
Since the packages.config file package entries contains the full version-info we constantly need to update the source control repo with changes. Or, we could ignore the changes, most of the time, but when just the version has changed we would (in most cases) be able to ignore them. This seems very unnecessary as the NuGet restore should be able to know which versions are allowed (via allowedVersions).
必须手动添加 allowedVersions 属性,这很容易被遗忘.我们正在使用语义版本控制,所以对我们来说,在安装 Foo-1.1.0 版本时,应该隐含 allowedVersions="[1,2)" .
The allowedVersions property has to be manually added, something that is easily forgotten. We are using semantic versioning, so for us, when installing i.e. a Foo-1.1.0 version, allowedVersions="[1,2)" should be implied.
添加 allowedVersion 时,NuGet 包还原似乎无法找到 -prerelease 程序集(可能是错误?).
When adding the allowedVersion then NuGet package restore doesn't seem to be able to find -prerelease assemblies (maybe a bug?).
为什么 NuGet 在解决方案级别处理包?如果您正在使用包含项目-A (repo-1) 和项目-B (repo-2) 的混合搭配解决方案,那么解决方案级别的打包将无法正常工作.也就是说,如果您将该解决方案文件保存在单独的位置,事情可能仍然有效.但是,如果您随后设置另一个包含 project-A (repo-1) 和 project-C (repo-3) 的解决方案,那么 project-A 将突然需要再次进行包恢复,更糟糕的是,项目引用将是更改以匹配上次更改.回到第一个解决方案将有不起作用的引用.签入这些肯定会使它们不适用于其他人.
Why are packages handled by NuGet on a solution level? If you are working in a mix-and-match solution, which contains a project-A (repo-1) and project-B (repo-2), then the solution level packaging is not going to work well. That is, If you save that solution file in a separate location, things might still work afaik. But, if you then set up another solution which contains project-A (repo-1) and project-C (repo-3), then project-A would suddenly need a package-restore again, and worse, the project references would be changed to match the last change. Going back to the first solution will then have references that doesn't work. Checking in these will certainly make them not work for others.
在包更新时,项目文件引用会更新(以匹配新的文件夹名称和其中的 versionid),并将显示为未提交的更改.做出这种改变似乎是常态,但我们认为这应该没有必要.
On a package update, the project-file references are updated (to match the new foldernames with versionid in them) and will appear as an uncommitted change. Committing this change seems to be the norm, but in our opinion this should not be necessary.
关于 ExcludeVersion 的说明(可以建议作为上述问题的解决方案:
Notes about ExcludeVersion (which could be suggested as a solution to the above problem:
您只能在手动执行 NuGet 命令时提供该选项,afaik.通过 Visual Studio 中的 NuGet 菜单安装/更新包时,无法使用该选项.使用任何自动化工具意味着之后必须手动修复文件夹名称和项目引用.
You can only provide that option when you manually perform NuGet commands, afaik. When installing/updating packages via the NuGet menus in Visual Studio that option cannot be used. Using any of the automated tools means that the foldername and project-reference has to be fixed manually afterwards.
我们知道 ExcludeVersion 不是默认设置,可能是因为支持有人在多项目解决方案中工作的情况,其中不同的项目依赖于同一包的不同版本.
We know that ExcludeVersion is not the default setting, probably due to supporting the cases where someone is working in a multi-project solution, where the different projects depend on different versions of the same package.
(但是,这可能需要对 NuGet 生态系统进行重大更改?)
A - packages.config
我希望 packages.config 中的每个包元素都可以抛弃 allowedVersions 而是将版本更改为范围说明符.packages 元素还应该提供一种方法来单独识别从哪个源获取更新.最后,如果安装的包遵循语义版本控制,那么版本属性应该根据安装的版本自动设置版本范围.
I wish that each package element in packages.config could ditch allowedVersions and instead change version to be the range specifier. The packages element should also provide a way to separately identify which source to get the updates from. Finally, if an installed package follows Semantic Versioning then the version property should automatically setup the version-range according to the installed version.
示例 packages.config:
Sample packages.config:
`<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Foo" version="[1,2] source="Development Feed">
</packages>`
这会:
修复 package.config 文件提交过多的问题,因为 version 属性不再持续更新.
Fix the issue with excessive commits of the package.config file, since the version property is no longer constantly updated.
无需记住为语义版本化项目设置范围.
No need to remember to set the range for semantically versioned projects.
确保从所需的提要中获取包,并且不会因为在错误的来源中查找而浪费时间.
Ensure that packages are fetched from the desired feed and that time is not wasted by looking for it in the wrong sources.
B - Packages 文件夹和其中安装的包的名称
我希望包文件夹位于每个项目根目录中,并且子文件夹名称仅限于包名称,不包括版本.这将:
I wish that the packages folder was located in each project-root and that the subfolder names was limited to the package-name only, excluding the version. This would:
修复项目文件提交过多的问题,因为项目文件中的项目引用现在在更新后指向同一个包文件夹.
Fix the issue with excessive commits of the project-files, since the project-references in the project-file now points to the same package-folder after an update.
允许项目使用同一包的不同版本,因为它们彼此真正独立.
Allows projects to use different versions of the same package as they are then truly independent of each other.
我们很高兴听到所列问题的解决方案.
推荐答案
如 NuGet Enterprise - 不同成熟度包的最佳实践,我认为你让事情变得比必要的复杂:)
As suggested in NuGet Enterprise - best practices for different maturity levels of packages, I think you are making things more complicated than necessary :)
- 您为什么不想捕获编译代码时使用的包的版本?这是可靠诊断和可重复构建的关键信息.鉴于您可能会将代码更改提交回版本控制,因此提交用于帮助构建该源代码的包的详细信息非常有用.
- "当安装 Foo-1.1.0 版本时,应该隐含 allowedVersions="[1,2)"" 我不认为 allowedVersions 真的可以隐含,因为不是所有的NuGet 包遵循 SemVer(参见 log4net 1.2.11).为 allowedVersions 设置
grep
作为 CI 构建或 pre-commit/pre-push 开发检查的一部分应该可以捕捉到这一点.它不应该经常更改,并且密切关注它是有用的(如果其他团队和软件包正确使用 SemVer,无论如何 :)). - 要查找预发布包,您需要在 nuget 安装时使用
Prerelease
或-IncludePrerelease
标志. - 如果您正在使用混合匹配解决方案,其中包含项目-A (repo-1) 和项目-B (repo-2)" - 为什么要安排你的代码是这样的?单个解决方案的代码应该全部存在于同一个存储库中.跨存储库破坏解决方案代码肯定会很痛苦!
- 您可以告诉 nuget 使用无版本文件夹名称来安装包 (
-ExcludeVersion
).
- Why would you not want to capture the version of the package with which the code was compiled? This is crucial information for reliable diagnostics and repeatable builds. Given that you'd likely be committing code changes back to version control, committing details of which packages were used to help build that source is very useful.
- "when installing i.e. a Foo-1.1.0 version, allowedVersions="[1,2)" should be implied" I do not think that allowedVersions can ever really be implied, because not all NuGet packages adhere to SemVer (see the debacle with log4net 1.2.11). Setting up a
grep
for allowedVersions as part of either CI build or pre-commit/pre-push Dev checks should catch this. It should not change often, and it's useful to keep an eye on it (if other teams and packages are using SemVer correctly, anyhow :) ). - To find Prerelease packages you'll need the
Prerelease
or-IncludePrerelease
flags on nuget install. - "If you are working in a mix-and-match solution, which contains a project-A (repo-1) and project-B (repo-2)" - why have you arranged your code like this? The code for a single solution should live all in the same repo. Breaking solution code across repos is definitely going to be painful!
- You can tell nuget to use version-less folder names for installing packages (
-ExcludeVersion
).
我强烈建议放弃 Visual Studio NuGet 集成,转而使用命令行 nuget.exe
并构建脚本.这尤其与 #5 有关,但通常与与 NuGet 的交互有关.Visual Studio 集成在仅处理来自 nuget.org 提要的第 3 方公共包时非常好,但在处理内部 NuGet 提要和包时不够灵活.
I would strongly recommend ditching the Visual Studio NuGet integration in favour using the command-line nuget.exe
and build scripts instead. This relates particularly to #5 but to interaction with NuGet in general. The Visual Studio integration is nice when working solely with 3rd-party public packages from the nuget.org feed, but is not flexible enough for my liking when dealing with internal NuGet feeds and packages.
这篇关于与 packages.config、项目引用和解决方案范围的包文件夹有关的 NuGet 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!