在什么情况下会从父进程获取 Ruby $LOAD_PATH?
在我的 Cucumber 场景中,如果我在目标 Rails 应用程序文件夹中调用 rake db:schema:load
,我会得到 Cucumber 进程的 $LOAD_PATH 而不是 Rails 应用程序自己的 Gemfile/load 路径。我觉得这很奇怪。
结果是我收到以下错误:
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...
; 由 < code>system、exec
、%x[...]
或反引号将从父进程的 $LOAD_PATH 开始(来自 cucumber 场景的 Gemfile)而不是它自己的 $LOAD_PATH (来自 Rails 应用程序的 Gemfile)?
In my cucumber scenarios, if I call rake db:schema:load
within a target Rails app folder, I get the cucumber process's $LOAD_PATH and not the Rails app's own Gemfile/load path. I think this is very weird.
The consequence is that I get the following error:
no such file to load -- rails/all
I can't reproduce it outside of my cucumber scenario.
ruby -rubygems -e "system 'rake -T'"
works normally -> the 'rake -T' has the application's own Gemfile-based $LOAD_PATH; and doesn't generate the error above.
Can anyone think why a child process (rake -T
or rake db:schema:load
or rails runner...
; invoked by either system
, exec
, %x[...]
or backtick; would start with the parent processes' $LOAD_PATH (from the cucumber scenario's Gemfile) instead of its own $LOAD_PATH (from the Rails app's Gemfile)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您使用bundle时,无论是通过
bundle exec
或require 'bundler/setup'
,它都会找到您的Gemfile,然后将其位置放入ENV["BUNDLE_GEMFILE"]中
。但是,如果已经设置,则捆绑器只会重用该值。这就是导致 Rails 应用程序使用 Cucumber 进程的 Gemfile 的原因。如果您想在不同 Gemfile 的上下文中执行某些操作,请先清除
ENV["BUNDLE_GEMFILE"]
。 Bundler 提供的方法Bundler.with_clean_env(&blk)
可能会有所帮助;它会使用加载 Bundler 之前的环境来执行您的块。当然,您也可以使用system("env -u BUNDLE_GEMFILE rake sometask")
之类的方法手动清除它。When you use bundler, either via
bundle exec
orrequire 'bundler/setup'
, it finds your Gemfile, then puts its location inENV["BUNDLE_GEMFILE"]
. However, if this is already set, then bundler just reuses the value. This is what causes your Rails app to use the cucumber process's Gemfile.If you want to execute something in the context of a different Gemfile, clear out
ENV["BUNDLE_GEMFILE"]
first. Bundler provides the methodBundler.with_clean_env(&blk)
that may be helpful; it executes your block with the environment how it was before Bundler was loaded. Of course, you can also clear it out by hand with something likesystem("env -u BUNDLE_GEMFILE rake sometask")
.父进程的环境 (
ENV
) 被传递到子 shell。 Cucumber 本身、您运行 Cucumber 的方式(例如bundle exec cucumber
)、您的场景或场景加载的代码(例如应用程序,因此捆绑器)都会扰乱您的ENV< /代码>。
RUBYLIB
、GEM_PATH
和BUNDLE_GEMFILE
等环境变量可能会对子 shell Ruby 进程可以加载的行为产生重大影响。尝试打印场景中的
ENV
变量,并将其与使用ruby -rubygems -rpp -e "pp ENV"
执行此操作时得到的结果进行比较,或者只是 < code>env 在命令行上。就其价值而言,一种可能的替代方案是直接加载并调用 rake 任务,例如,
Rake::Task['db:schema:load'].invoke
,而不使用子 shell 。不过,这取决于您想要做什么。The parent process's environment (
ENV
) is passed down to sub-shells. Either cucumber itself, how you are running cucumber (e.g.bundle exec cucumber
), your scenarios, or code the scenario loads (e.g. the app, and therefore bundler), is messing with yourENV
. Environment variables likeRUBYLIB
,GEM_PATH
, andBUNDLE_GEMFILE
can have a significant impact on what your sub-shelled Ruby processes can load / will behave.Try printing out your
ENV
variable in your scenario and comparing it to what you get when you do it withruby -rubygems -rpp -e "pp ENV"
, or justenv
on the command line.For what it's worth, a possible alternative would be to load and invoke the rake task directly, e.g.,
Rake::Task['db:schema:load'].invoke
, without using a sub-shell. Depends on what you're trying to do, though.