Что такое пакетные грабли exec? - PullRequest
336 голосов
/ 06 июля 2011

Что означает bundle exec rake db:migrate? Или просто bundle exec rake <command> в целом?

Я понимаю, что bundle заботится о сохранении вещей в Gemfile. Я знаю, что означает слово «exec». Я понимаю, что rake поддерживает все различные сценарии, которые вы можете сделать, и я знаю, что db:migrate является одним из них. Я просто не знаю, что все эти слова делают вместе. Почему bundle должен использоваться для выполнения rake для выполнения миграции базы данных?

Ответы [ 7 ]

451 голосов
/ 06 июля 2011

bundle exec - это команда Bundler для выполнения сценария в контексте текущего пакета (из сценария Gemfile вашего каталога). rake db:migrate - это сценарий, где db - это пространство имен, а migrate - это определенное имя задачи.

Итак, bundle exec rake db:migrate выполняет скрипт rake с командой db:migrate в контексте текущего пакета.

Что касается "почему?" Я приведу цитату со страницы :

В некоторых случаях запуск исполняемых файлов без bundle exec может работать, если исполняемый файл установлен в вашей системе и не содержит никаких драгоценных камней, конфликтующих с вашим комплектом.

Однако это ненадежно и является источником значительной боли. Даже если он выглядит так, как будто он работает, он может не работать в будущем или на другом компьютере.

143 голосов
/ 25 апреля 2013

Вы запускаете bundle exec в программе.Создатели программы написали это, когда были доступны определенные версии драгоценных камней.Программа Gemfile указывает версии драгоценных камней, которые решили использовать создатели.То есть скрипт был создан для правильной работы с этими версиями гемов.

Ваш общесистемный Gemfile может отличаться от этого Gemfile.У вас могут быть новые или более старые драгоценные камни, с которыми этот сценарий не играет хорошоЭто различие в версиях может привести к странным ошибкам.

Bundle exec поможет вам избежать этих ошибок.Он выполняет скрипт, используя гемы, указанные в Gemfile скрипта, а не общесистемный Gemfile.Он выполняет определенные версии драгоценных камней с помощью магии псевдонимов оболочки.

Подробнее о на странице man .

Вот пример Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

Здесь bundle exec будет выполнять скрипт с использованием rails версии 2.8.3, а не какой-либо другой версии, которую вы, возможно, установили для всей системы.

7 голосов
/ 15 мая 2014

Это часто встречается, когда на вашем компьютере установлены различные версии gemfile.lock. Вы можете получить предупреждение после запуска рейка (или rspec или других), таких как:

You have already activated rake 10.3.1, but your Gemfile requires rake 10.1.0. Prepending "bundle exec" to your command may solve this.

Prepending bundle exec указывает программе-исполнителю выполнить эту команду независимо от разницы версий. Проблема не всегда есть, однако вы можете столкнуться с проблемами.

К счастью, существует гем, который решает это: rubygems-bundler.

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

Тогда попробуйте снова свои грабли, rspec или что-то еще.

6 голосов
/ 14 мая 2014

Вероятно, следует упомянуть, что есть способы опустить bundle exec (все они изложены в главе 3.6.1 книги Майкла Хартла Ruby on Rails ).

Самое простое - просто использовать достаточно актуальную версию RVM (> = 1.11.x).

Если вы ограничены более ранней версией RVM, вы всегда можете использовать этот метод, также упомянутый calasyr :

$ rvm get head && rvm reload
$ chmod +x $rvm_path/hooks/after_cd_bundler
$ bundle install --binstubs=./bundler_stubs

Затем следует также добавить каталог bundler_stubs в файл .gitignore.

Третий вариант - использовать камень rubygems-bundler, если вы не используете RVM:

$ gem install rubygems-bundler
$ gem regenerate_binstubs
1 голос
/ 20 мая 2018

Когда вы напрямую запускаете задачу rake или запускаете какой-либо двоичный файл гема, нет гарантии, что команда будет работать так, как ожидается. Может случиться так, что в вашей системе уже установлен тот же самый гем с версией 1.0, но в вашем проекте более поздняя версия 2.0. В этом случае вы не можете предсказать, какой из них будет использоваться.

Для принудительного исполнения желаемой версии гема вы воспользуетесь командой bundle exec, которая выполнит двоичный файл в контексте текущего пакета. Это означает, что когда вы используете bundle exec, bundler проверяет версию gem, настроенную для текущего проекта, и использует ее для выполнения задачи.

Я также написал сообщение об этом, которое также показывает, как мы можем избежать его использования с помощью заглушек бин.

1 голос
/ 29 января 2013

Я не очень много использовал bundle exec, но сейчас настраиваю.

У меня были случаи, когда использовался неправильный рейк, и много времени тратилось на поиск проблемы. Это поможет вам избежать этого.

Вот как настроить rvm, чтобы вы могли использовать bundle exec по умолчанию в определенной директории проекта:

http://robots.thoughtbot.com/post/15346721484/use-bundlers-binstubs

0 голосов
/ 06 июля 2011

Это означает использование rake, о котором знает сборщик, и который является частью вашего Gemfile, по сравнению с любыми граблями, о которых не знает упаковщик, и запускайте задачу db: migrate.

...