结合'bundler/inline'、rbenv和全局ruby设置path/gem_home

问题描述 投票:0回答:3

为了制作独立且可移植的 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...

ruby bundler rbenv
3个回答
3
投票

我们遇到了同样的问题,我发现这可以解决问题

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
以使其读取您的捆绑包配置,并正确设置路径。


0
投票

我有一个类似的问题:我想分发一个需要来自 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
模块参考并开始阅读源代码。


0
投票
老问题,但这是对我有用的最简单的事情:

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的环境中尝试这个.)

© www.soinside.com 2019 - 2024. All rights reserved.