在什么情况下从父进程获取Ruby $ LOAD_PATH?

时间:2011-02-06 06:30:25

标签: ruby-on-rails ruby rubygems cucumber bundler

在我的黄瓜场景中,如果我在目标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 -Trake db:schema:loadrails runner...;由systemexec%x[...]或backtick;会从父进程'$ LOAD_PATH(来自黄瓜场景的Gemfile)开始,而不是自己的$ LOAD_PATH(来自Rails应用程序的Gemfile)?

2 个答案:

答案 0 :(得分:1)

当您使用bundler时,通过bundle execrequire '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。像RUBYLIBGEM_PATHBUNDLE_GEMFILE这样的环境变量会对您的子外壳Ruby进程可以加载/将要执行的操作产生重大影响。

尝试在您的方案中打印出ENV变量,并将其与使用ruby -rubygems -rpp -e "pp ENV"或在命令行上env执行此操作时的结果进行比较。

对于它的价值,可能的替代方案是直接加载和调用rake任务,例如Rake::Task['db:schema:load'].invoke,而不使用子shell。不过,取决于你想要做什么。