管理 ruby​​ gem 的冲突版本

发布于 2024-10-09 21:07:49 字数 618 浏览 0 评论 0原文

我正在构建一个加载用户提供的 ruby​​ 代码的框架。它基本上是一个插件机制。我希望用户提供 ruby​​ 代码以便能够需要自己的 gem。我打算让“插件”包包含一个包含 gem 的供应商目录。

如何加载插件所需的 gem,而不使其与我的框架的 gem 冲突?例如,如果我的框架使用treetop版本1.3.0,并且插件使用treetop 1.4.2,我希望每个框架都使用其指定的版本。

同样,有没有办法防止插件相互冲突?

我研究过 gem_plugin、_why 的沙箱和其他一些工具。但我没有看到任何专门处理这种情况的库 - 我认为它以前已经完成过。

我还研究了 Bundler 的内部结构,了解它如何管理 gem 版本。如果需要的话,我准备做一些相当复杂的事情。但我仍然不确定如何去做。

我在如何实现这一点上也有很大的自由。因此,如果您认为我找错了对象,请直言不讳。

感谢您的任何建议。

旁注:在编写本文时,我突然想到我需要类似于 Java servlet 容器中的类加载器的东西。 WAR 文件可以包含 jar 文件,并且 Web 应用程序的类加载器将优先选择那些位于全局类路径上的 jar 文件。 ruby 有什么方法可以分段 ruby​​“类路径”(即 load_path、require 等)?

I am building a framework that loads user provided ruby code. It is basically a plugin mechanism. I want the user provide ruby code to be able to require gems of its own. I intend to have the "plugin" package include a vendor directory with the gems.

How can I load gems that are required by the plugin without having them conflict with my framework's gems? For example, if my framework uses treetop version 1.3.0, and a plugin uses treetop 1.4.2 I want each to work with their specified version.

Likewise, is there a way to prevent plugins from conflicting with each other?

I have looked at gem_plugin, _why's sandbox, and some other tools. But I don't see any library that specifically handles this case - I assume its been done before.

I have also looked at the internals of Bundler to see how it manages gem versions. I am prepared to do some pretty complex stuff if need be. But I am still uncertain of how to go about it.

I also have a lot of freedom in how I implement this. So if you think I am barking up the wrong tree, please say so.

Thanks for any advice.

SIDE NOTE: It occurred to me while writing this that I need something similar to the Classloaders in a Java servlet container. A WAR file can include jar files, and the web application's class loader will prefer those over the jars that are on the global classpath. Is there any way in ruby to segment the ruby "classpath" (i.e. load_path, require, etc)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

廻憶裏菂餘溫 2024-10-16 21:07:49

坦率地说,您不能同时加载同一个 gem 的两个版本。

Bundler 在查看所有必需的 gem 并找到各种重叠依赖关系的解决方案方面做得很好,但即便如此,它也仅限于一次只能加载一个版本的 gem。

这导致插件开发人员必须不断更新以支持依赖 gem 中所做的任何更改,以避免出现您所描述的情况。

(不要让我开始谈论各种竞争性 JSON 实现所导致的混乱,以及当您有多个 gem 依赖项都需要不同的依赖项时您必须经历的痛苦。)

To be blunt, you can't have two versions of the same gem loaded at the same time.

Bundler does a good (ish) job of looking through all of the required gems and finding a solution to the various overlapping dependencies, but even so it is limited to only loading one version of a gem at a time.

This leads to plugin developers constantly having to update to support any changes that are made in dependent gems in order to avoid just the situation you describe.

(Don't get me started on the screw up that results from the various competing JSON implementations and the pain you have to go through when you have several gem dependencies all requiring different ones.)

习惯成性 2024-10-16 21:07:49

恭敬地不同意上面的答案。这是我的做法:

ruby -S gem list my_gem

`*** LOCAL GEMS ***
my_gem (1.0.1, 1.0.0, 0.0.2)
`

ruby -S gem lock my_gem-1.0.0 > locklist.rb

它将特定版本的依赖项列表生成到 locklist 中,

require 'rubygems'
gem 'my_gem', '= 1.0.0'
gem 'gem_base', '= 1.0.0'
gem 'rest-client', '= 1.7.2'
gem 'savon', '= 1.1.0'
gem 'addressable', '= 2.3.6'
gem 'mime-types', '= 1.25.1'
gem 'netrc', '= 0.11.0'

现在您可以执行 load('locklist.rb') 它将加载特定版本的 gem 及其依赖项。看,妈,没有 Bundler。

Respectfully disagree with the answer above. Here is how I do it:

ruby -S gem list my_gem

`*** LOCAL GEMS ***
my_gem (1.0.1, 1.0.0, 0.0.2)
`

ruby -S gem lock my_gem-1.0.0 > locklist.rb

which generates list of dependencies for a specific version into locklist

require 'rubygems'
gem 'my_gem', '= 1.0.0'
gem 'gem_base', '= 1.0.0'
gem 'rest-client', '= 1.7.2'
gem 'savon', '= 1.1.0'
gem 'addressable', '= 2.3.6'
gem 'mime-types', '= 1.25.1'
gem 'netrc', '= 0.11.0'

now you can do load('locklist.rb') which will load a specific version of a gem along with its dependencies. Look ma, no Bundler.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文