在我的黄瓜场景中,如果我在目标Rails应用程序文件夹中调用rake db:schema:load
,我会获得黄瓜进程的$ LOAD_PATH,而不是Rails应用程序自己的Gemfile /加载路径。我觉得这很奇怪。
结果是我收到以下错误:
no such file to load -- rails/all
我无法在黄瓜情景之外重现它。
ruby -rubygems -e "system 'rake -T'"
正常工作 - > 'rake -T'有应用程序自己的基于Gemfile的$ LOAD_PATH;并且不会产生上述错误。
有人可以考虑为什么子进程(rake -T
或rake db:schema:load
或rails runner...
;由system
,exec
,%x[...]
或backtick;会从父进程'$ LOAD_PATH(来自黄瓜场景的Gemfile)开始,而不是自己的$ LOAD_PATH(来自Rails应用程序的Gemfile)?
答案 0 :(得分:1)
当您使用bundler时,通过bundle exec
或require 'bundler/setup'
,它会找到您的Gemfile,然后将其位置放在ENV["BUNDLE_GEMFILE"]
中。但是,如果已经设置了,那么bundler只会重用该值。这就是导致你的Rails应用程序使用黄瓜进程的Gemfile的原因。
如果要在其他Gemfile的上下文中执行某些操作,请先清除ENV["BUNDLE_GEMFILE"]
。 Bundler提供了可能有用的方法Bundler.with_clean_env(&blk)
;它会在Bundler加载之前用环境执行你的块。当然,您也可以手动清除它system("env -u BUNDLE_GEMFILE rake sometask")
。
答案 1 :(得分:0)
父进程的环境(ENV
)向下传递给子shell。无论是黄瓜本身,你如何运行黄瓜(例如bundle exec cucumber
),你的场景,或场景加载的代码(例如应用程序,因此捆绑者)都在弄乱你的ENV
。像RUBYLIB
,GEM_PATH
和BUNDLE_GEMFILE
这样的环境变量会对您的子外壳Ruby进程可以加载/将要执行的操作产生重大影响。
尝试在您的方案中打印出ENV
变量,并将其与使用ruby -rubygems -rpp -e "pp ENV"
或在命令行上env
执行此操作时的结果进行比较。
对于它的价值,可能的替代方案是直接加载和调用rake任务,例如Rake::Task['db:schema:load'].invoke
,而不使用子shell。不过,取决于你想要做什么。