При каких обстоятельствах Ruby $ LOAD_PATH будет получен от родительского процесса? - PullRequest
4 голосов
/ 06 февраля 2011

В моих сценариях с огурцом, если я вызываю rake db:schema:load в целевой папке приложения Rails, я получаю $ LOAD_PATH процесса огурца, а не собственный путь к приложению Rails Gemfile / load.Я думаю, что это очень странно.

В результате я получаю следующую ошибку:

no such file to load -- rails/all

Я не могу воспроизвести ее за пределами моего сценария с огурцом.

ruby -rubygems -e "system 'rake -T'"

работает нормально -> 'rake -T' имеет собственный $ LOAD_PATH, основанный на Gemfile;и не выдает ошибку выше.

Может кто-нибудь подумать, почему дочерний процесс (rake -T или rake db:schema:load или rails runner...; вызывается либо system, exec, %x[...] илиbacktick; будет начинаться с $ LOAD_PATH родительских процессов (из Gemfile сценария с огурцом) вместо его собственного $ LOAD_PATH (из Gemfile приложения Rails)?

Ответы [ 2 ]

1 голос
/ 06 февраля 2011

Когда вы используете упаковщик через 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").

0 голосов
/ 06 февраля 2011

Среда родительского процесса (ENV) передается в подчиненные оболочки. Либо сам огурец, то, как вы используете огурец (например, 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, без использования вложенной оболочки. Однако зависит от того, что вы пытаетесь сделать.

...