简体   繁体   中英

Under what circumstances would a Ruby $LOAD_PATH be acquired from a parent process?

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)?

When you use bundler, either via bundle exec or require 'bundler/setup' , it finds your Gemfile, then puts its location in ENV["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 method Bundler.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 like system("env -u BUNDLE_GEMFILE rake sometask") .

The parent process's environment ( ENV ) is passed down to sub-shells. Either cucumber itself, how you are running cucumber (eg bundle exec cucumber ), your scenarios, or code the scenario loads (eg the app, and therefore bundler), is messing with your ENV . Environment variables like RUBYLIB , GEM_PATH , and BUNDLE_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 with ruby -rubygems -rpp -e "pp ENV" , or just env on the command line.

For what it's worth, a possible alternative would be to load and invoke the rake task directly, eg, Rake::Task['db:schema:load'].invoke , without using a sub-shell. Depends on what you're trying to do, though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM