bundle-exec - Execute um comando no contexto do bundle
bundle exec [--keep-file-descriptors] command
Este comando executa o comando, tornando todas as gems especificadas no [Gemfile(5)][Gemfile(5)] disponíveis para exigir em programas Ruby.
Essencialmente, se você normalmente executa algo como rspec spec/my_spec.rb e deseja usar as gems especificadas no [Gemfile(5)][Gemfile( 5)] e instalado via bundle install(1) bundle-install.1.html, você deve executar bundle exec rspec spec/my_spec.rb.
Observe que bundle exec não requer que um executável esteja disponível no ` PATH do shell.
Exec no Ruby 2.0 começou a descartar descritores de arquivo não padrão. Quando esse sinalizador for passado, o exec reverterá para o comportamento 1.9 de passar todos os descritores de arquivo para o novo processo.
Se você usar o sinalizador --binstubs no bundle install(1) bundle-install.1.html, o Bundler criará automaticamente um diretório (cujo padrão é app_root /bin) contendo todos os executáveis disponíveis nas gems do pacote.
Depois de usar --binstubs, bin/rspec spec/my_spec.rb é idêntico a bundle exec rspec spec/my_spec.rb.
bundle exec faz uma série de alterações no ambiente shell e, em seguida, executa o comando especificado por completo.
certifique-se de que ainda é possível desembolsar para empacotar de dentro de um comando invocado por bundle exec (usando $BUNDLE_BIN_PATH)
coloque o diretório contendo executáveis (como rails, rspec, rackup) para seu pacote em ` PATH
certifique-se de que, se o bundler for invocado no subshell, ele usará o mesmo Gemfile (configurando BUNDLE_GEMFILE)
adicione -rbundler/setup a $RUBYOPT, o que garante que os programas Ruby invocados no subshell possam ver as gems no pacote
Ele também modifica Rubygems:
proibir o carregamento de gemas adicionais que não estão no pacote
modifique o método gem para ser um no-op se uma gem correspondente aos requisitos estiver no pacote e para gerar um Gem::LoadError se não for
Defina Gem.refresh para ser um no-op, pois o índice de origem é sempre congelado ao usar o bundler e para evitar que as gems do sistema vazem para o ambiente
Substitua Gem.bin_path para usar as gems no pacote, fazendo com que os executáveis do sistema funcionem
Adicione todas as gemas do pacote em Gem.loaded_specs
Por fim, bundle exec também modifica implicitamente Gemfile.lock se o lockfile e o Gemfile não corresponderem. O Bundler precisa do Gemfile para determinar coisas como os grupos de uma gem, autorequire e plataformas, etc., e essas informações não são armazenadas no lockfile. O Gemfile e o lockfile devem ser sincronizados para empacotar exec com sucesso, então bundle exec atualiza o lockfile de antemão.
Por padrão, ao tentar empacotar exec em um arquivo com um ruby shebang, o Bundler irá Kernel.load esse arquivo em vez de usar Kernel.exec . Para a grande maioria dos casos, isso é uma melhoria de desempenho. Em alguns casos raros, isso pode causar alguns efeitos colaterais sutis (como dependência do conteúdo exato de $0 ou __FILE__) e a otimização pode ser desativada ativando o configuração disable_exec_load.
Qualquer código Ruby que abra um subshell (como system, backticks ou %x{}) usará automaticamente o ambiente Bundler atual. Se você precisar enviar um comando Ruby que não faz parte do seu pacote atual, use o método with_unbundled_env com um bloco. Quaisquer subshells criados dentro do bloco receberão o ambiente presente antes da ativação do Bundler. Por exemplo, os comandos Homebrew executam Ruby, mas não funcionam dentro de um pacote:
Bundler.with_unbundled_env do
`brew install wget`
endUsar with_unbundled_env também é necessário se você estiver investindo em um pacote diferente. Quaisquer comandos do Bundler executados em um subshell herdarão o Gemfile atual, portanto, os comandos que precisam ser executados no contexto de um pacote diferente também precisam usar with_unbundled_env.
Bundler.with_unbundled_env do
Dir.chdir "/other/bundler/project" do
`bundle exec ./script`
end
endO Bundler fornece auxiliares de conveniência que agrupam system e exec e podem ser usados assim:
Bundler.clean_system('brew install wget')
Bundler.clean_exec('brew install wget')No momento, o sistema de plugins Rubygems requer todos os arquivos nomeados rubygems_plugin.rb no caminho de carregamento de qualquer gem instalada quando qualquer código Ruby requer rubygems.rb . Isso inclui executáveis instalados no sistema, como rails, rackup e rspec.
Como os plug-ins do Rubygems podem conter código Ruby arbitrário, eles geralmente acabam ativando a si mesmos ou a suas dependências.
Por exemplo, a gem gemcutter 0.5 dependia de json_pure. Se você tivesse essa versão do gemcutter instalada (mesmo que você também tivesse uma versão mais recente sem esse problema), Rubygems ativaria gemcutter 0.5 e json_pure
Se o seu Gemfile(5) também contiver json_pure (ou uma gem com dependência de json_pure), a versão mais recente do seu sistema pode entrar em conflito com a versão do seu Gemfile(5 ) ou a versão instantânea em seu Gemfile.lock.
Se isso acontecer, o bundler dirá:
You have already activated json_pure 1.4.6 but your Gemfile
requires json_pure 1.4.3. Consider using bundle exec.Nesta situação, é quase certo que você deseja remover a gem subjacente com o plug-in de gem problemático. Em geral, os autores desses plugins (neste caso, a gem gemcutter) lançaram versões mais recentes que são mais cuidadosas em seus plugins.
Você pode encontrar uma lista de todas as gems contendo plugins de gem executando
ruby -e "puts Gem.find_files('rubygems_plugin.rb')"No mínimo, você deve remover todos, exceto a versão mais recente de cada plug-in de gem, e também remover todos os plug-ins de gem que não estiver usando (desinstalação de gem gem_name).