Co oznacza pakiet Rake Exec?


350

Co bundle exec rake db:migrateznaczy A może bundle exec rake <command>w ogóle?

Rozumiem, że bundledba o utrzymanie rzeczy w Gemfile. Wiem, co znaczy słowo „exec”. Rozumiem, że rakezachowuje wszystkie różne skrypty rzeczy, które możesz zrobić, i wiem, że db:migrateto jedna z nich. Po prostu nie wiem, co te wszystkie słowa razem robią. Dlaczego powinienem bundlezostać użyty do wykonania rakemigracji bazy danych?

Odpowiedzi:


468

bundle execto komenda Bundlera do wykonania skryptu w kontekście bieżącego pakietu (tego z pliku Gemfile katalogu ). rake db:migrateto skrypt, w którym db jest przestrzenią nazw, a migracja to zdefiniowana nazwa zadania.

bundle exec rake db:migrateWykonuje więc skrypt rake z poleceniem db:migratew kontekście bieżącego pakietu.

Co do „dlaczego?” Zacytuję ze strony pakietu :

W niektórych przypadkach uruchomienie plików wykonywalnych bez bundle execmoże działać, jeśli plik wykonywalny zostanie zainstalowany w systemie i nie pobierze żadnych klejnotów, które kolidują z twoim pakietem.

Jest to jednak niewiarygodne i jest źródłem znacznego bólu. Nawet jeśli wygląda na to, że działa, może nie działać w przyszłości lub na innym komputerze.


7
Czy to oznacza, że ​​zawsze powinniśmy uruchamiać exec pakietu, użyłem menedżera wersji Ruby, aby zainstalować Ruby i Ruby na szynach.
Pradeep Sharma

11
@Edmund „Pakiet” to angielskie słowo, które oznacza grupę podobnych rzeczy, zwykle starannie związanych. W szczególności w tym pytaniu odnosi się do grupy Gems (samodzielnych bibliotek ruby). Bundler to nazwa oprogramowania, którego używamy tutaj do zarządzania Gems. I bundleto jest polecenie, które jest używane przez Bundler.
ghoppe

2
Mam wrażenie, że ilekroć przejdziemy do folderu z Gemfile, powłoka automatycznie użyje wersji określonych w Gemfile (np. Wersja Ruby). Opierając się na tym założeniu, pomyślałem, że rake db: migrate zawsze będzie działał dobrze bez pakietu exec. CMIIW
Pahlevi Fikri Auliya

1
@PahleviFikriAuliya jest to prawdą tylko wtedy, gdy masz .ruby-gemsetplik w katalogu głównym projektu. Istnieje również .ruby-versionplik, który ustawia twoją wersję ruby, jeśli używasz RVM.
Sum

1
Połączona strona nie wspomina już o podanym przez Ciebie wycenie. Napraw, dziękuję.
Gaurang Tandon

153

Używasz bundle execprogramu. Twórcy programu napisali go, gdy dostępne były niektóre wersje klejnotów. Program Gemfile określa wersje klejnotów, których twórcy postanowili użyć. Oznacza to, że skrypt został poprawnie uruchomiony w przypadku tych wersji klejnotów.

Twój system Gemfile może różnić się od tego Gemfile. Możesz mieć nowsze lub starsze klejnoty, z którymi ten skrypt nie gra się dobrze. Ta różnica w wersjach może powodować dziwne błędy.

bundle execpomaga uniknąć tych błędów. Wykonuje skrypt przy użyciu klejnotów określonych w pliku Gemfile skryptu, a nie w ogólnodostępnym pliku Gemfile. Wykonuje niektóre wersje klejnotów za pomocą magii aliasów powłoki.

Zobacz więcej na stronie man .

Oto przykład Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

Tutaj bundle execwykonałby skrypt przy użyciu szyny w wersji 2.8.3, a nie jakiejkolwiek innej wersji, którą mogłeś zainstalować w całym systemie.


9
Podoba mi się ta odpowiedź bardziej niż wybrana przez OP: D! Znacznie jaśniej.
mauricioschneider

1
Dodajmy więc do tego przykładu: jeśli osoba po prostu ucieknie rake db:migrate, bundle execa następnie uruchomi się przy użyciu ogólnosystemowego pliku Gemfile, w którym można mieć stelaż w wersji 1.5.2 (najnowszej)?
Smokin Joe

znacznie lepsza odpowiedź, z konkretnymi przykładami.
ahnbizcad

2
Więc bundle execużywa „specyficznych dla aplikacji”, lokalnych klejnotów w twoim pliku Gem aplikacji i bundleużywa „specyficznych dla maszyny”, globalnych klejnotów, jeśli tak zrobiłeś gem install a_certain_gem. local vs global
ahnbizcad

Znacznie lepsza odpowiedź niż wybrana.
Boon,

9

To pojawia się bardzo często, gdy twój gemfile.lock ma różne wersje klejnotów zainstalowane na twoim komputerze. Możesz otrzymać ostrzeżenie po uruchomieniu prowizji (lub rspec lub innych), takich jak:

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.

Poprzedzenie bundle execopowiada Bundler do wykonania tego polecenia, niezależnie od różnicy wersji. Nie zawsze jest problem, jednak mogą wystąpić problemy.

Na szczęście istnieje klejnot, który rozwiązuje ten problem: pakiet pakietowy rubygems.

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

Następnie wypróbuj ponownie swój rake, rspec lub cokolwiek innego.


Nadal świetne rozwiązanie w 2020 roku.
Brateq

6

Prawdopodobnie należy wspomnieć, że istnieją sposoby, aby je pominąć bundle exec(wszystkie są wymienione w rozdziale 3.6.1 podręcznika Michaela Hartlsa Ruby on Rails ).

Najprościej jest po prostu użyć wystarczająco aktualnej wersji RVM (> = 1.11.x).

Jeśli jesteś ograniczony do wcześniejszej wersji RVM, zawsze możesz użyć tej metody wspomnianej również przez calasyr :

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

bundler_stubsKatalog powinien następnie zostać dodane do .gitignorepliku.

Trzecią opcją jest użycie rubygems-bundlerklejnotu, jeśli nie używasz RVM:

$ gem install rubygems-bundler
$ gem regenerate_binstubs

1

Gdy bezpośrednio uruchomisz zadanie prowizji lub wykonasz dowolny plik binarny klejnotu, nie ma gwarancji, że polecenie będzie działało zgodnie z oczekiwaniami. Ponieważ może się zdarzyć, że masz już ten sam klejnot w swoim systemie, który ma wersję powiedzieć 1.0, ale w swoim projekcie masz wyższą wersję powiedz 2.0. W takim przypadku nie można przewidzieć, który zostanie użyty.

Aby wymusić pożądaną wersję klejnotów, skorzystaj z bundle execpolecenia, które uruchomiłoby plik binarny w kontekście bieżącego pakietu. Oznacza to, że gdy używasz exec pakietu, bundler sprawdza wersję klejnotu skonfigurowaną dla bieżącego projektu i używa go do wykonania zadania.

Napisałem też o tym post , który pokazuje, jak możemy uniknąć używania go za pomocą kodów pośredniczących.


1

Nie używałem bundle execdużo, ale jestem ustawienie go teraz.

Miałem przypadki, w których użyto niewłaściwej prowizji i traciłem dużo czasu na śledzenie problemu. To pomaga ci tego uniknąć.

Oto jak skonfigurować RVM, abyś mógł bundle execdomyślnie korzystać z niego w określonym katalogu projektu:

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


0

Oznacza to użycie prowizji, o której pakujący jest świadomy i jest częścią pliku Gemfile, w stosunku do prowizji, o której nie jest świadomy, i uruchomienie zadania db: migracja.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.