2020年7月16日

依赖关系解决优化——ActiveState的方法

依赖关系。他们是最好的,但也是最差的。你可以指望PyPI(Python包索引)或CPAN(综合Perl归档网络),为从日期和时间处理到日志到web服务客户端等许多事情提供包。这可以节省大量的时间,但依赖性解决也可能耗费大量的时间。

有时您尝试安装包A,却发现它的依赖树包括包B,您已经在使用它,但它是一个更高的主版本。你使用的工具警告过你吗?有些工具只是自动升级包B。许多生态系统都有固定软件包版本和只进行受控升级的工具,但这些工具也有自己的缺点。

有一个用户友好的系统来管理您的依赖关系不是很好吗?如果你能添加一个新包,看看你的依赖树是什么,那就太好了一旦它被添加,在承诺它之前。如果依赖关系管理系统跟踪包之间的冲突,了解特定于平台的依赖关系,甚至跟踪系统级的依赖关系,比如C和c++库,那就更好了。

依赖关系解析是188bet金宝搏备用.当您创建一个项目并开始添加需求时,我们会告诉您这些需求有哪些依赖性。有时我们需要告诉您,由于依赖关系冲突,您的需求是不可能的。

每种语言生态系统都需要依赖管理。Perl拥有最古老的依赖项管理工具链之一,从1995年创建CPAN开始。Python随后在2000年推出了PyPI。

这些生态系统的依赖关系解决是通过本地运行的包管理工具完成的。过去,这些工具在系统范围的语言安装上运行,但现在我们有了像这样的工具perlbrewvirtualenv允许每个项目安装语言。

但这些工具只是简单地处理C/ c++库和外部工具。当包需要OpenSSL之类的库或Fortran编译器之类的工具时,包作者必须编写在安装阶段运行的代码(通过Makefile.PL或setup.py)。如果不存在依赖项,则安装失败。如果幸运的话,您会得到一条有用的消息,告诉您缺少了什么,此时您需要自己安装库或工具。如果你在Linux上,你通常可以依赖你的操作系统供应商的包管理器。在macOS上家酿.而在Windows上疼痛

对于各种类型的条件依赖关系也存在类似的问题,比如当依赖关系只需要在特定的平台或CPU体系结构上时可能会发生。语言生态系统通常最多只能为这类事情提供有限的支持,而且还是要由包作者手工添加适当的检查和错误消息。

Acti188bet金宝搏备用veState平台的目标是处理每种语言的每个依赖项。这意味着要处理C/ c++级别的库、外部工具和所有存在的条件依赖项。更进一步,我们的最终目标是支持多语言项目。这意味着您可以同时使用Python和Perl包创建项目,我们将确保这两种语言使用相同的(最新的)OpenSSL版本。

依赖项元数据的概念

我们在库存数据库中存储了所有关于包/模块/库等的元数据——所有你可以用来构建语言运行时的东西。

任何库存项目都可以有依赖性。例如,Python核心版本3.8.2依赖于OpenSSL和其他几个C库,而Python的请求存货项目取决于urllib3、Python核心以及其他几个Python库。

然而,比起让库存道具直接依赖于其他道具,它们更依赖于“功能”。每个库存项目以及操作系统或CPU架构等其他东西提供一个或多个特性。一个特性包括:

  • 的名字
  • 名称空间
  • 版本

例如,Python 3.8.2提供了一个名为python语言名称空间在版本3.8.2.在Perl中,每个发行版都为发行版中包含的所有Perl包提供特性。因此,Perl DateTime目录项的1.52版本提供了许多特性语言/ perl名称空间,包括DateTime 1.52DateTime:持续时间1.52等等。

这个增加的间接层在如何表示和解决依赖关系方面给了我们很大的灵活性。例如,将来我们可能会有多个库存项,提供“python-core”这样的特性,允许我们使用CPython构建项目,Jython,或PyPy使用不需要CPython API的Python包。或者我们可以有一个名为“OpenSSL -api”的特性LibreSSL提供,允许您在项目中在它们之间进行交换。

我们想让自己觉得这个想法很聪明,但我们直接从Debian的虚拟包系统。

PubGrub依赖关系解析算法

我们的第一个依赖求解器(我们称之为版本0,或者“V0”)非常“特别”。虽然它或多或少起了作用,但它并没有我们想要的那么高效或可预测。有时它会以令人惊讶的方式失败,它的错误消息可能相当杂乱。此外,它不支持我们想要的所有东西,比如一些复杂的条件依赖情况。但它的工作做得足够好,让我们开始获得一些牵引力,有时我们需要花大力气调整数据,以绕过求解器的怪僻或缺失的功能。

显然我们需要一些更好的东西,但从头开始设计“更好的东西”需要大量的工作。幸运的是,我们没有必要这么做。

娜塔莉透过计算机的库工具飞镖的语言,创造了一个坐在解算器她叫算法PubGrub.娜塔莉写了一篇很棒的关于PubGrub的入门文章,我们强烈推荐。还有一个发布库中的详细技术规范

PubGrub的一些属性使其成为ActiveState的绝佳选择:

  • 适应性强的-我们可以很容易地将它扩展到我们的Inventory Item -> Feature -> Feature Provider系统中,因为它的核心实现是足够抽象的,我们可以从一个Inventory Item依赖一个Feature,而不是直接在Inventory Items之间。
  • 非常高效。-当PubGrub发现冲突时,它会确定根本原因,即使这个原因在依赖链中较早。算法“记住”这一点,不会再尝试在链的根处包含依赖项。这对我们来说很重要,因为我们经常有一组非常大的需求需要解决。例如,我们的ActivePython CE发行版需要几百个Python包和Python核心。当依赖项完全解决后,最终将引入400多个包。
  • 简洁的- PubGrub可以在解决失败时轻松生成更好的错误消息。无论何时它检测到冲突,它都能够追溯冲突的根源。我们得到的错误消息是对冲突所能提供的最简单和最清晰的解释。

理解依赖关系解析错误

这是一个来自我们闪亮的新V1求解器的错误示例:

因为特性|language/perl|Test2- harness(0.001099)需要项目|language/perl|Test2- harness(0.001099)依赖于特性|language/perl|Test2::Bundle::Extended(>=0.000126),特性|language/perl|Test2- harness(0.001099)需要特性|language/perl|Test2::Bundle::Extended(>=0.000126)。因此,由于特性|language/perl|Test2::Bundle::Extended匹配>=0.000126且root依赖于特性|language/perl|Test2- harness(0.001099),版本解决失败。

这还是有点拗口,我们有计划让它更容易理解,但让我们把它一件一件地分解:

因为功能|语言/perl|Test2-Harness(0.001099)需要库存|语言/perl|Test2-Harness(0.001099)…

“Feature|language/perl|Test2-Harness”的引用来自我们的订单需求,它要求在语言/ perl命名空间名字Test2-Harness在完全版0.001099.这就是冲突开始的地方。反过来,该特性需要提供该特性的Inventory Item。这是信息的后半部分。

接下来,我们有:

这取决于特性|语言/perl|Test2::Bundle::Extended (>=0.000126)

这告诉我们Test2-Harness的0.001099版本需要一个名为Test2:包:扩展语言/ perl名称空间在任何版本大于或等于0.000126

现在我们有:

功能|语言/perl|Test2- harness(0.001099)需要功能|语言/perl|Test2::Bundle::Extended(>=0.000126)。

因为我们的需求要求在语言/ perl | Test2-Harness = = 0.001099,我们还需要语言/ perl | Test2::包::> = 0.000126.所以解算器能够知道一个要求是如何隐含另一个要求的。

包装:

所以,因为没有版本的特性|语言/perl|Test2::Bundle::Extended匹配>=0.000126…

这是简单的。它告诉我们没有提供语言/ perl | Test2::包::扩展某个版本的功能> = 0.000126在Active188bet金宝搏备用State Platform目录中。这是正确的,因为我们只有版本0.0001200.000097Test2:包:扩展目前的功能。

最后:

...和root依赖于特性|语言/perl|Test2-Harness(0.001099),版本解决失败。

解算器得出“根”依赖于语言/ perl|Test2-Harness = = 0.001099.“根”这个词只是PubGrub算法用来表示人工的“第一个需求”,它依赖于项目中的所有实际需求。我们计划改变这一点,在未来说一些更友好的东西,如“您的项目”或“项目的需求”。

总的来说,虽然错误消息仍然有些冗长,但它已经尽可能地简洁了,使我们能够轻松地帮助用户解决这类问题。相比之下,这里是旧的求解器的错误消息:

没有库存项目版本满足运行时依赖语言/perl Test2::Bundle::Extended >= 0.000126 (of requirement language/perl Test2- harness == 0.001099满足运行时依赖语言/perl Test2::Plugin::UUID >= 0.002001 (of requirement language/perl Test2- harness == 0.001099) No inventory item version满足运行时依赖语言/perl Test2::Require::Module >= 0.000126 (of requirement language/perl Test2- harness == 0.001099Test2::Tools::Subtest >= 0.000126 (of require language/perl Test2- harness == 0.001099) No inventory item version满足运行时依赖语言/perlTest2::V0 >= 0.000126 (of require language/perl Test2- harness == 0.001099)没有库存项目版本满足运行时依赖语言/perl语言/perl Test2-Harness == 0.001099)

从好的方面来说,它告诉我们每一个失踪的依赖。在负的一边,它很长。这实际上是最好的情况。在某些情况下,我们会看到相同的错误一遍又一遍地重复,这些错误变得难以理解。

顺便提一下,这个错误可能有以下几个原因:

  1. 我们还没有导入Test2-Suite Perl发行版的最新版本,而且没有一个版本提供所需的特性。
  2. 在我们导入Test2-Harness依赖项的方式上有一个错误。
  3. 在我们如何导入所提供的特性中有一个bug应该提供Test2:包:扩展特性。
  4. 在作者上传到CPAN的发行版中提供的元数据中有一个错误。

(剧透:# 1)。

ActiveState的新依赖解决器可以做的很酷的事情

我们的新解决方案还做了许多其他事情,这是我们的产品愿景的核心。它支持:

  • 对语言库之外的东西的依赖。例如,一个特定的语言包可以依赖于一个特定的操作系统内核或CPU体系结构。
  • Conflict-style依赖性。所以我们可以说,一个给定的语言包可以在任何操作系统上工作除了Windows或任何libc除了组织“。我们还可以解决两个语言包之间的冲突。
  • 条件依赖,其中依赖可以是另一个包(“只有当Python内核<= 2.7时才包括它”),构建平台的内核(“只有当Linux内核是>= 4.4.0时才包括它”),CPU架构,等等。

这些类型的功能是实现我们真正全面的愿景的关键依赖关系管理在Active188bet金宝搏备用State平台上。虽然我们已经用数据库设计来存储这些数据很长一段时间了,但V0求解器基本上忽略了这些数据。

我们真的很兴奋我们的新和改进的解决方案,并期待我们的用户尝试它时,我们推出今年第三季度。

有效的依赖管理

了解ActiveState平台如何帮助您管理依赖项:188bet金宝搏备用

  • Perl环境.让ActiveS188bet金宝搏备用tate平台不仅自动解析,还可以构建依赖项,包括链接的C库。准备好开始了吗?只需运行以下命令来安装Perl 5.32和我们的包管理器,即状态工具:

窗户

powershell -Command "& $([scriptblock]::Create((New-Object Net.WebClient).DownloadString('https://platform.activestate.com/dl/cli/install.ps1')) -activate-default ActiveState-Labs/Perl-5.32 "

Linux

——activate-default ActiveState-Labs/Perl-5.32 .sh <(curl -q https://platform.activestate.com/dl/cli/install.sh

现在你可以跑了国家安装< modulename >.了解更多关于如何使用状态工具来管理Perl环境。

  • Python环境中.准备好利用我们基于云的工具链,自动创建和激活虚拟环境了吗?只需运行以下命令来安装Python 3.9和我们的包管理器State Tool:

窗户

powershell -Command "& $([scriptblock]::Create((New-Object Net.WebClient).DownloadString('https://platform.activestate.com/dl/cli/install.ps1')) -activate-default ActiveState-Labs/Python-3.9Beta"

Linux

——activate-default ActiveState-Labs/Python-3.9Beta .sh <(curl -q https://platform.activestate.com/dl/cli/install.sh)——activate-default ActiveState-Labs/Python-3.9Beta

现在你可以跑了国家安装< packagename >了解更多关于如何使用状态工具来管理Python环境。

让我们知道你的经验ActiveState的社区论坛

推荐阅读

如何最好地管理Python依赖关系

管理依赖关系和运行时安全

戴夫Rolsky

戴夫Rolsky

Dave Rolsky在1999年开始了他的Perl开发生涯,并创建或贡献了几十个Perl CPAN模块,包括DateTime、Log::Dispatch、Moose等。最近,他还开发了《Rust》和《Go》。很久以前,他是合著者在HTML中嵌入Perl与梅森RT必需品这两本书均由奥莱利出版。在他的空闲时间,他喜欢美味的素食,阅读,电子游戏和攀岩。

评论2