Що означає граблі для виконання пакету exec?


350

Що bundle exec rake db:migrateозначає? Або просто bundle exec rake <command>загалом?

Я розумію, що bundleдбає про збереження речей у Gemfile. Я знаю, що означає слово "exec". Я розумію, що rakeпідтримує всі різні сценарії, які ви можете зробити, і я знаю, що db:migrateце одна з таких. Я просто не знаю, що всі ці слова роблять разом. Чому слід bundleвикористовувати для виконання rakeміграції бази даних?

Відповіді:


468

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

Так bundle exec rake db:migrateвиконується сценарій рейку з командою db:migrateв контексті поточного пакету.

Щодо "чому?" Я цитую на сторінці постачальника :

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

Однак це ненадійно і є джерелом значного болю. Навіть якщо це здається, що він працює, він може не працювати в майбутньому або на іншій машині.


7
Чи означає це, що ми завжди повинні виконувати пакет exec, я використовував менеджер версій ruby ​​для встановлення рубіну та рубіну на рейках.
Pradeep Sharma

11
@Edmund "Пачка" - це англійське слово, яке означає групу подібних речей, зазвичай зав'язаних акуратно. Зокрема, у цьому питанні йдеться про групу дорогоцінних каменів (самостійні бібліотеки рубінового коду.) Bundler - це назва програмного забезпечення, яке ми використовуємо тут для управління Gems. І bundleце команда, яку використовує Bundler.
ghoppe

2
У мене складається враження, що коли ми переходимо до папки з Gemfile, оболонка автоматично використовуватиме версії, вказані в Gemfile (наприклад, версія Ruby). Виходячи з цього припущення, я думав, що rake db: migrate завжди працюватиме нормально без пакетного виконання. CMIIW
Pahlevi Fikri Auliya

1
@PahleviFikriAuliya - це правда лише в тому випадку, якщо у вас є .ruby-gemsetфайл у корені проекту. Також є .ruby-versionфайл, який встановлює вашу рубінову версію, якщо ви використовуєте RVM.
Сом

1
Пов'язана сторінка більше не згадує вказану вами цитату. Виправте, дякую.
Gaurang Tandon

153

Ви працюєте bundle execна програмі. Творці програми написали це, коли були доступні певні версії дорогоцінних каменів. Програма Gemfile визначає версії дорогоцінних каменів, які творці вирішили використовувати. Тобто сценарій був створений, щоб правильно працювати проти цих версій дорогоцінних каменів.

Ваш Gemfile у всій системі може відрізнятися від цього Gemfile. У вас можуть бути новіші або старі дорогоцінні камені, з якими цей сценарій не грає добре. Ця різниця у версіях може дати вам дивні помилки.

bundle execдопомагає уникнути цих помилок. Він виконує сценарій, використовуючи дорогоцінні камені, вказані в Gemfile сценарію, а не загальносистемний Gemfile. Він виконує певні версії дорогоцінних каменів з магією псевдонімів оболонки.

Більше див на сторінці man .

Ось приклад Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

Тут bundle execвиконується сценарій, використовуючи рейки версії 2.8.3, а не якусь іншу версію, яку ви, можливо, встановили на всій системі.


9
Мені подобається ця відповідь краще, ніж обрана ОП: D! Набагато чіткіше.
mauricioschneider

1
Отже, щоб додати до цього прикладу: якщо людина просто вибігла, не rake db:migrateвиходячи з bundle execцього, вона виконала б за допомогою загальносистемного Gemfile, де може бути стійка в 1.5.2 (останнє)?
Смокін Джо

набагато краща відповідь, на конкретних прикладах.
ahnbizcad

2
Тож bundle execвикористовує локальні дорогоцінні камені у вашому Gemfile програми та bundleвикористовує "глобальні дорогоцінні камені", якщо ви це зробили gem install a_certain_gem. local vs global
ahnbizcad

Набагато краща відповідь, ніж обрана.
Бун

9

Це з’являється багато, коли ваш 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.

Попереднє завдання bundle execповідомляє постачальнику виконувати цю команду незалежно від диференціалу версії. Існує не завжди проблема, проте у вас можуть виникнути проблеми.

На щастя, існує дорогоцінний камінь, який вирішує це: rubygems-bundler.

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

Потім спробуйте ваші граблі, rspec, або що ще.


Все-таки чудове рішення у 2020 році.
Brateq

6

Напевно, слід зазначити, що існують способи пропустити bundle exec(всі вони викладені в главі 3.6.1 книги "Майкл Хартлс Рубі" про навчальний посібник "Рейки" ).

Найпростіший - просто використовувати достатньо сучасну версію 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

Якщо ви безпосередньо виконуєте завдання граблі або виконуєте будь-який двійковий файл дорогоцінного каміння, немає гарантії, що команда буде вести себе так, як очікувалося. Тому що може статися так, що у вас вже встановлено той самий дорогоцінний камінь, який має версію, скажімо, 1.0, але у вашому проекті вища версія 2.0. У цьому випадку ви не можете передбачити, який із них буде використовуватися.

Щоб застосувати потрібну версію дорогоцінного каміння, ви скористаєтесь bundle execкомандою, яка би виконувала двійковий код у контексті поточного пакету. Це означає, що при використанні bundle exec bundler перевіряє версію дорогоцінного каменю, налаштовану для поточного проекту, і використовує її для виконання завдання.

Я також написав пост про це, який також показує, як ми можемо уникнути його використання за допомогою заглушок для сміття.


1

Я мало використовував bundle exec, але зараз налаштовую.

У мене були випадки, коли використовували неправильні граблі та витрачали багато часу на відстеження проблеми. Це допомагає вам уникнути цього.

Ось як налаштувати RVM, щоб його можна було використовувати bundle execза замовчуванням у конкретному каталозі проекту:

https://thoughtbot.com/blog/use-bundlers-binstubs


0

Це означає використовувати рейки, про які знає постачальник, і є частиною вашого Gemfile над будь-якими граблями, про які не знає пакувальник, і виконайте завдання db: migrate.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.