我需要从另一个使用Bundler + Gemfile的ruby script1.rb调用使用Bundler + Gemfile的ruby script2.rb。
我注意到script2.rb可用的Gems仅是script1.rb的。如果script1.rb调用script2.rb,则无法使用script2.rb独有的gem。当直接从bash shell调用script2.rb时,一切都可用。
我确保这不是一个ENV问题,我在两个文件中都使用了diff和辅助代码来比较它们,并进行了一些修改以使它们匹配。
File.open("script2_env.txt", 'wb') {|f| f.write(JSON.pretty_generate(ENV.to_h))}
为了确保这不是$ LOAD_PATH问题,我还确保它们匹配。
在script1.rb调用的script2.rb中,我添加了以下行以匹配script1的$ LOAD_PATH:
$:.unshift "/usr/local/Cellar/rbenv/1.1.2/rbenv.d/exec/gem-rehash"
我对问题的理解是,从script1.rb调用script2.rb时,Bundler无法正确初始化。
eval "$(rbenv init -)"
就像我的bash_profile中的一样
script1 / script1.rb:
#!/usr/bin/env ruby
cwd=Dir.pwd ; ourDir=File.dirname(__FILE__) ; Dir.chdir(ourDir)
require 'bundler' ; Bundler.setup
require "awesome_print"
ap "in script1, we have awesome_print in our GemFile"
exec("/Users/charbon/wip/script2/script2.rb")
script1 / Gemfile
source 'https://rubygems.org'
gem 'awesome_print'
script2.rb:
#!/usr/bin/env ruby
puts "we are now in script2.rb"
$:.unshift "/usr/local/Cellar/rbenv/1.1.2/rbenv.d/exec/gem-rehash"
cwd=Dir.pwd ; ourDir=File.dirname(__FILE__) ; Dir.chdir(ourDir)
#make ENV match to script1 ENV
ENV.delete('BUNDLER_ORIG_GEM_PATH')
ENV['BUNDLE_GEMFILE']=ourDir+"/Gemfile"
ENV['RBENV_DIR']=ourDir
require 'bundler' ;
Bundler.setup
require 'awesome_print'
ap "in script2, we also have awesome_print in our GemFile"
puts "but we also have colored, which is not available, this throws an erro"
require "colored"
script2 / Gemfile
source 'https://rubygems.org'
gem 'awesome_print'
gem 'colored'
结果是
/Users/charbon/wip/script1/script1.rb
"in script1, we have awesome_print in our GemFile"
we are now in script2.rb
ourDir is /Users/charbon/wip/script2
"in script2, we also have awesome_print in our GemFile"
but we also have colored, which is not available, this throws an error
/Users/charbon/wip/script2/script2.rb:19:in `require': cannot load such file -- colored (LoadError)
from /Users/charbon/wip/script2/script2.rb:19:in `<main>'
script1.rb
#!/usr/bin/env ruby
cwd=Dir.pwd ; ourDir=File.dirname(__FILE__) ; Dir.chdir(ourDir)
require 'bundler' ; Bundler.setup
require "awesome_print"
ap "in script1, we have awesome_print in our GemFile"
Bundler.with_clean_env do
Dir.chdir('/Users/charbon/wip/script2/script2.rb') do
exec("./script2.rb")
end
end
script2.rb
#!/usr/bin/env ruby
puts "we are now in script2.rb"
cwd=Dir.pwd ; ourDir=File.dirname(__FILE__) ; Dir.chdir(ourDir)
require 'bundler' ;
Bundler.setup
require 'awesome_print'
ap "in script2, we also have awesome_print in our GemFile"
puts "but we also have colored, which is not available, this throws an erro"
require "colored"
谢谢,您使我走上了正确的路。唯一需要的更改是
Bundler.with_clean_env { exec("/path/to/script2.rb") }
(之前不需要Dir.chdir)