bundle-exec - Выполнить команду в контексте бандла
bundle exec [--keep-file-descriptors] command
Эта команда выполняет команду, делая все гемы, указанные в [Gemfile(5)][Gemfile(5)], доступными для require в программах на Ruby.
По сути, если вы обычно запускаете что-то вроде rspec spec/my_spec.rb и хотите использовать гемы, указанные в [Gemfile(5)][Gemfile( 5)] и установлен с помощью пакета install(1) bundle-install.1.html, вы должны запустить bundle exec rspec spec/my_spec.rb.
Обратите внимание, что bundle exec не требует, чтобы исполняемый файл был доступен в ` PATH вашей оболочки.
Exec в Ruby 2.0 начал отбрасывать нестандартные файловые дескрипторы. Когда этот флаг будет передан, exec вернется к поведению 1.9 при передаче всех файловых дескрипторов новому процессу.
Если вы используете флаг --binstubs в пакетной установке (1) bundle-install.1.html, Bundler автоматически создаст каталог (по умолчанию это app_root /bin), содержащий все исполняемые файлы, доступные из драгоценных камней в комплекте.
После использования --binstubs файл bin/rspec spec/my_spec.rb идентичен bundle exec rspec spec/my_spec.rb.
bundle exec вносит ряд изменений в среду оболочки, а затем полностью выполняет указанную вами команду.
убедитесь, что по-прежнему возможно перейти к bundle из команды, вызванной bundle exec (используя $BUNDLE_BIN_PATH)
поместите каталог, содержащий исполняемые файлы (например, rails, rspec, rackup) для вашего пакета в ` PATH
убедитесь, что если упаковщик вызывается в подоболочке, он использует тот же Gemfile (путем установки BUNDLE_GEMFILE)
добавьте -rbundler/setup в $RUBYOPT, что гарантирует, что программы Ruby, вызываемые в подоболочке, смогут видеть драгоценные камни в пакете.
Он также изменяет Rubygems:
запретить загрузку дополнительных драгоценных камней, не входящих в комплект
измените метод gem так, чтобы он был неактивным, если в комплекте есть gem, соответствующий требованиям, и вызывал Gem::LoadError, если это не так.
Определите Gem.refresh как недействующий, поскольку исходный индекс всегда замораживается при использовании сборщика, а также для предотвращения утечки гемов из системы в среду.
Переопределите Gem.bin_path, чтобы использовать драгоценные камни в комплекте, чтобы системные исполняемые файлы работали.
Добавьте все драгоценные камни в комплекте в Gem.loaded_specs.
Наконец, bundle exec также неявно изменяет Gemfile.lock, если файл блокировки и Gemfile не совпадают. Bundler нуждается в Gemfile для определения таких вещей, как группы gem, autorequire, платформы и т. д., и эта информация не хранится в файле блокировки. Gemfile и файл блокировки должны быть синхронизированы для успешной связки exec, поэтому bundle exec заранее обновляет файл блокировки.
По умолчанию при попытке связать exec с файлом с помощью ruby shebang, Bundler Kernel.load загрузит этот файл вместо использования Kernel.exec. . В подавляющем большинстве случаев это улучшение производительности. В редких случаях это может вызвать некоторые тонкие побочные эффекты (такие как зависимость от точного содержимого $0 или __FILE__), и оптимизацию можно отключить, включив параметр Параметр disable_exec_load.
Любой код Ruby, который открывает подоболочку (например, system, обратные кавычки или %x{}), будет автоматически использовать текущую среду Bundler. Если вам нужно раскошелиться на команду Ruby, которая не является частью вашего текущего пакета, используйте метод with_unbundled_env с блоком. Любые подоболочки, созданные внутри блока, получат среду, существовавшую до активации Bundler. Например, команды Homebrew запускают Ruby, но не работают внутри бандла:
Bundler.with_unbundled_env do
`brew install wget`
end
Использование with_unbundled_env также необходимо, если вы выбираете другой пакет. Любые команды Bundler, запускаемые в подоболочке, наследуют текущий Gemfile, поэтому команды, которые необходимо запускать в контексте другого пакета, также должны использовать with_unbundled_env.
Bundler.with_unbundled_env do
Dir.chdir "/other/bundler/project" do
`bundle exec ./script`
end
end
Bundler предоставляет удобные помощники, которые обертывают system и exec, и их можно использовать следующим образом:
Bundler.clean_system('brew install wget')
Bundler.clean_exec('brew install wget')
В настоящее время системе подключаемых модулей Rubygems требуются все файлы с именами rubygems_plugin.rb в пути загрузки любого установленного драгоценного камня, когда для любого кода Ruby требуется rubygems.rb . . Сюда входят исполняемые файлы, установленные в системе, такие как rails, rackup и rspec.
Поскольку плагины Rubygems могут содержать произвольный код Ruby, они обычно активируют себя или свои зависимости.
Например, гем gemcutter 0.5 зависел от json_pure. Если бы у вас была установлена эта версия gemcutter (даже если у вас также была более новая версия без этой проблемы), Rubygems активировал бы gemcutter 0.5 и json_pure
Если ваш Gemfile(5) также содержит json_pure (или гем с зависимостью от json_pure), последняя версия в вашей системе может конфликтовать с версией в вашем Gemfile(5). ) или версию снимка в файле Gemfile.lock.
Если это произойдет, упаковщик скажет:
You have already activated json_pure 1.4.6 but your Gemfile
requires json_pure 1.4.3. Consider using bundle exec.
В этой ситуации вы почти наверняка захотите удалить базовый гем с помощью проблемного плагина гем. Как правило, авторы этих плагинов (в данном случае драгоценного камня gemcutter) выпустили более новые версии, которые более тщательно подходят к своим плагинам.
Вы можете найти список всех драгоценных камней, содержащих плагины драгоценных камней, запустив
ruby -e "puts Gem.find_files('rubygems_plugin.rb')"
По крайней мере, вы должны удалить все плагины gem, кроме самой новой версии, а также удалить все плагины gem, которые вы не используете (gem uninstall gem_name).