@lsmn
2016-01-15T08:59:16.000000Z
字数 1875
阅读 4572
.NET
包管理器
NuGet
Packet是一个面向.NET语言的包管理器,旨在作为广受欢迎的NuGet的一个替代选项。InfoQ联系了项目联合创始人Steffen Forkmann,了解更多有关Paket起源和特性的信息。
Packet是一个面向.NET语言的包管理器,旨在作为广受欢迎的NuGet的一个替代选项。InfoQ联系了项目联合创始人Steffen Forkmann,了解更多有关Paket起源和特性的信息。
InfoQ:考虑到NuGet的广泛应用,你们主要出于什么目的创建一个新的.NET包管理器?
Steffen Forkmann:虽然我们确实非常喜欢使用NuGet包,而且也为其生态系统做贡献,但在一些特殊的情况下,我们还是感觉很痛苦。大多数问题都是源于NuGet“它只是一个Visual Studio宏”的理念。这意味着,nuget.exe并没有被视为一个真正的依赖管理器,但作为一个宏,它允许开发人员下载包并Visual Studio项目内部引用它们。对于许多专业软件开发项目,这种隐藏依赖的理念带来了许多痛苦。加之nuget.exe存储包的路径里会带有版本号,而且没有全局概览,除非是在最简单的项目中,否则很快就会变得难以管理。
在我们开始Paket项目的时候,我们已经仔细进行过一些关于修改NuGet模型的讨论,但NuGet的团队明确表示,这不是他们想要的方式。由于Paket大多数新增功能都是破坏性的,他们无意将这些更改引入nuget.exe。
所以,为了解决我们自己的依赖管理问题,Alexander Gross和我就开始创建一个新的项目。项目的范围只是取代nuget.exe,也就是取代NuGet的客户端。另外,我们还制定了以下项目原则:
- 可以融入现有的NuGet生态系统
- 使用最少的工具(纯文本文件)做事
- 适用于所有平台
- 一切都是自动化的
- 创建一个优秀的社区
InfoQ:请您介绍下Paket中依赖解析的工作原理?它是如何处理冲突的?
SF:Paket使用paket.dependencies文件指定项目依赖。通常仅指定直接依赖,而且所允许的包的版本范围常常很广。在“paket install”的过程中,Paket需要指定特定包的具体版本,以及它们的传递性依赖。然后,这些版本会保存到paket.lock文件。
为了指定具体的版本,Paket需要解决如下约束满足问题:对于paket.dependencies文件中的每一个包以及它们所有的传递性依赖,均选择最新的版本,这样,所有的版本约束就都得到了满足。
对于这个问题,通常存在不止一个解决方案,而解析器会选择它找到的第一个方案。Paket的网站上有一篇文章更详细地解释了解析过程。
如果解析器无法找到一个有效的解决方案,那么它需要向用户报告一个错误。由于搜索树可以非常大,而且可能包含许多不同种类的失败,所以它只会报告最后一个它无法解析的冲突,以及一些有关这个冲突的来源信息。
与nuget.exe不同,在整个解决方案中,相同的包,Paket只允许用户使用一个版本。因此,用户不会无意中因为从不同的项目中引用同一个包的不同版本而引入版本冲突。如果实在需要同一个包的不同版本,那么可以通过依赖组来实现。
InfoQ:Paket支持所有.NET语言吗?(你们是否统计过它在C#和F#项目中的应用?)
SF:是的,Paket基本上支持所有的.NET语言——甚至是像Nemerle那样的东西。我们的大多数用户都是C#企业型公司,但由于我们没有跟踪我们的用户,所以我们没有任何相关的统计数据。
InfoQ:您希望看到Paket未来增加什么特性?哪个特性是用户要求最多的?
SF:目前,我们正致力于Paket 3.0的开发,它会带来一项重要的新特性。基本的思路是,用户可以在paket.dependencies文件中引用一个Git库,Paket会为用户克隆和构建项目。如果构建生成了NuGet包,那么用户可以把它们作为额外的包来源。
目前要求最多的特性是支持CoreCLR/DNX项目,但我们需要为此对project.json模型做些修改。遗憾的是,我们现在还没有想出一个满意的方案,但我们希望能够同微软的团队一起来解决这个问题。
InfoQ:您还有什么需要补充吗?
SF:我想谢谢所有的贡献者以及整个Paket社区,是他们让这个项目在如此短的时间内取得了如此巨大的成功。没有他们的帮助,这是不可能的。
Paket是一个托管在GitHub上的开源项目。读者可以从FsProjects页面查看文档。