为了制作独立且可移植的 ruby 脚本,我正在使用
bundler/inline
。
我提供此脚本的服务器非常具体,它们有 rbenv (因此我们可以回滚/使用多个 ruby 版本),并且安装某些 gem(备份 gem)需要花费时间。我们使用全局 ruby 安装。
导致非 root 用户执行带有“bundle/inline”的脚本并抛出错误:
Your user account isn't allowed to install to the system Rubygems.
You can cancel this installation and run:
bundle install --path vendor/bundle
to install the gems into ./vendor/bundle/, or you can enter your password
and install the bundled gems to Rubygems using sudo.
遗憾的是,捆绑器/内联没有选项将此作为参数。
所以我尝试通过设置捆绑路径来解决这个问题:
bundle config path ~/.gem/ruby/2.3.0/
,但这不起作用。 (我检查过,配置已正确保存)
设置
GEM_HOME=~/.gem/ruby/2.3.0/
有效。 (Ruby gems 在这种情况下支持两个 gem home,所以这实际上工作得很好)。唯一的问题是我需要做一些簿记,以保持该环境变量与 rbenv 激活的 ruby 的次要版本一致。我无法从我的 ruby 脚本中设置此 ENV,我可以在其中根据当前版本轻松计算此版本:
version_used_for_gem_home = RUBY_VERSION.gsub /\.\d+$/, '.0'
ENV['GEM_HOME'] = "/var/lib/postgresql/.gem/ruby/#{version_used_for_gem_home}/"
require 'bundler/inline'
有没有更好的解决方案,不需要我做任何记账?我希望有一些 rbenv 钩子可以用来修改路径/gem home...
我们遇到了同样的问题,我发现这可以解决问题
require 'bundler/inline'
require 'bundler'
Bundler.configure # where the magic happens
# passing true here does the install; in real scripts we
# pass a boolean based on a --install flag.
gemfile(true) do
...gems go here...
end
您需要显式调用
Bundler.configure
以使其读取您的捆绑包配置,并正确设置路径。
我有一个类似的问题:我想分发一个需要来自 rubygems 的非默认 gem 的文件,并且应该以非 root 用户身份运行。
幸运的是,虽然
bunder/inline
缺乏 API 到了令人烦恼的地步,但通过要求 bundler
(如 @bazzargh 推荐),我们可以获得更多 API。请注意,这不是一个方便或有记录的 API (*),但您可以让事情正常工作。
我的解决方案如下所示:
require 'bundler/inline'
require 'bundler'
Bundler.configure_gem_home_and_path "#{ENV['HOME']}/.cache/my-app-bundle"
gemfile do
source 'https://rubygems.org'
gem 'my-gem'
end
备注:
~/.cache/my-app-bundle
是我想要捆绑程序安装 gem 的地方。gemfile(true)
,所以bundler install
进程仅运行一次符文(如果缺少任何宝石)并且不产生任何输出。这就是我需要的 CLI,但是 YMMV。*) 想知道如何操作
Bundler
?前往 ruby-lang.org 上的 烦人无用的 Bundler
模块参考并开始阅读源代码。
Gem.paths = { "GEM_HOME" => Gem.user_dir }
require "bundler/inline"
Gem.paths=
采用类似
ENV
的对象。如果你还有其他 Gem 相关的环境变量想要生效,你可能需要:
Gem.paths = ENV.merge({ "GEM_HOME" => Gem.user_dir })`
require "bundler/inline"
(bazzargh的答案和Guss的答案对我来说都失败了Could not locate Gemfile or .bundle/ directory (Bundler::GemfileNotFound)
。也许自从答案发布后Bundler已经改变了,或者他们正在Bundler能够找到Gemfile的环境中尝试这个.)