Apa arti bundle exec rake?

351

Apa bundle exec rake db:migrateartinya Atau bundle exec rake <command>secara umum?

Saya mengerti bahwa bundlemengurus hal-hal di dalam Gemfile. Saya tahu apa arti kata "exec". Saya mengerti bahwa rakemempertahankan semua hal berbeda yang dapat Anda lakukan, dan saya tahu itu db:migrateadalah salah satunya. Aku hanya tidak tahu apa yang dilakukan semua kata-kata ini bersama. Mengapa harus bundledigunakan untuk mengeksekusi rakeuntuk melakukan migrasi database?

JnBrymn
sumber

Jawaban:

468

bundle execadalah perintah Bundler untuk mengeksekusi skrip dalam konteks bundel saat ini (yang berasal dari Gemfile direktori Anda ). rake db:migrateadalah skrip di mana db adalah namespace dan bermigrasi adalah nama tugas yang ditentukan.

Jadi bundle exec rake db:migratejalankan skrip rake dengan perintah db:migratedalam konteks bundel saat ini.

Adapun "mengapa?" Saya akan mengutip dari halaman bundler :

Dalam beberapa kasus, menjalankan executable tanpa bundle exec dapat bekerja, jika executable kebetulan diinstal di sistem Anda dan tidak menarik permata yang bertentangan dengan bundel Anda.

Namun, ini tidak dapat diandalkan dan merupakan sumber rasa sakit yang cukup besar. Bahkan jika sepertinya berfungsi, itu mungkin tidak bekerja di masa depan atau di komputer lain.

ghoppe
sumber
7
Apakah itu berarti kita harus selalu menjalankan bundle exec, saya telah menggunakan manajer versi ruby ​​untuk menginstal ruby ​​dan ruby ​​pada rails.
Pradeep Sharma
11
@ Edmund A "bundel" adalah kata bahasa Inggris, yang berarti sekelompok hal serupa, biasanya diikat dengan rapi. Khususnya dalam pertanyaan ini, merujuk pada sekelompok Permata (pustaka kode ruby ​​mandiri.) Bundler adalah nama perangkat lunak yang kami gunakan di sini untuk mengelola Permata. Dan bundlemerupakan perintah yang digunakan oleh Bundler.
ghoppe
2
Saya memiliki kesan bahwa setiap kali kita melakukan cd ke folder dengan Gemfile, shell akan secara otomatis menggunakan versi yang ditentukan dalam Gemfile (misalnya versi Ruby). Berdasarkan asumsi itu, saya pikir rake db: migrasi akan selalu berjalan dengan baik tanpa bundel exec. CMIIW
Pahlevi Fikri Auliya
1
@PahleviFikriAuliya itu hanya benar jika Anda memiliki .ruby-gemsetfile di root proyek Anda. Ada juga .ruby-versionfile yang menetapkan versi ruby ​​Anda jika menggunakan RVM.
Catfish
1
Halaman tertaut tidak lagi menyebutkan kutipan yang Anda tentukan. Tolong perbaiki, terima kasih.
Gaurang Tandon
153

Anda menjalankan bundle execprogram. Pembuat program menulisnya ketika versi permata tertentu tersedia. Program Gemfile menentukan versi permata yang pembuatnya putuskan untuk gunakan. Artinya, skrip dibuat untuk berjalan dengan benar terhadap versi permata ini.

Gemfile seluruh sistem Anda mungkin berbeda dari Gemfile ini. Anda mungkin memiliki permata yang lebih baru atau lebih tua yang skrip ini tidak dimainkan dengan baik. Perbedaan dalam versi ini dapat memberi Anda kesalahan aneh.

bundle execmembantu Anda menghindari kesalahan ini. Itu mengeksekusi skrip menggunakan permata yang ditentukan dalam Gemfile skrip daripada Gemfile seluruh sistem. Itu mengeksekusi versi permata tertentu dengan keajaiban alias shell.

Lihat lebih lanjut di halaman manual .

Berikut ini contoh Gemfile:

source 'http://rubygems.org'

gem 'rails', '2.8.3'

Di sini, bundle execakan menjalankan skrip menggunakan rel versi 2.8.3 dan bukan beberapa versi lain yang Anda mungkin telah menginstal seluruh sistem.

Rose Perrone
sumber
9
Saya suka jawaban ini lebih baik daripada yang dipilih oleh OP: D! Jauh lebih jelas.
mauricioschneider
1
Jadi untuk menambah contoh ini: jika orang tersebut berlari rake db:migratekeluar bundle execmaka ia akan mengeksekusi menggunakan sistem Gemfile di mana orang mungkin memiliki rak di 1.5.2 (terbaru)?
Smokin Joe
jawaban yang jauh lebih baik, dengan contoh nyata.
ahnbizcad
2
Jadi bundle execgunakan "aplikasi khusus", permata lokal di Gemfile aplikasi Anda, dan bundlegunakan "permata khusus mesin", permata global jika Anda melakukannya gem install a_certain_gem. lokal vs global
ahnbizcad
Jawaban yang jauh lebih baik daripada yang dipilih.
Boon
9

Ini muncul banyak ketika gemfile.lock Anda memiliki versi berbeda dari permata yang diinstal pada mesin Anda. Anda mungkin mendapatkan peringatan setelah menjalankan rake (atau rspec atau yang lain) seperti:

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 execmemberitahu bundler untuk mengeksekusi perintah ini terlepas dari perbedaan versi. Tidak selalu ada masalah, namun, Anda mungkin mengalami masalah.

Untungnya, ada permata yang memecahkan ini: rubygems-bundler.

$ gem install rubygems-bundler

$ $ gem regenerate_binstubs

Kemudian coba rake, rspec, atau apa pun lagi.

Benjamin Dunphy
sumber
Masih merupakan solusi hebat pada tahun 2020.
Brateq
6

Mungkin harus disebutkan, bahwa ada cara untuk menghilangkan bundle exec(mereka semua dinyatakan dalam bab 3.6.1 dari Michael Hartls Ruby on Rails Tutorial buku ).

Yang paling sederhana adalah cukup menggunakan RVM versi terbaru (> = 1.11.x).

Jika Anda terbatas pada versi RVM sebelumnya, Anda selalu dapat menggunakan metode ini yang juga disebutkan oleh calasyr :

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

The bundler_stubsdirektori harus kemudian juga ditambahkan ke dalam .gitignoreberkas.

Opsi ketiga adalah menggunakan rubygems-bundlerpermata jika Anda tidak menggunakan RVM:

$ gem install rubygems-bundler
$ gem regenerate_binstubs
tschale
sumber
1

Ketika Anda langsung menjalankan tugas menyapu atau mengeksekusi file biner permata, tidak ada jaminan bahwa perintah akan berperilaku seperti yang diharapkan. Karena itu mungkin terjadi bahwa Anda sudah memiliki permata yang sama diinstal pada sistem Anda yang memiliki versi mengatakan 1.0 tetapi dalam proyek Anda, Anda memiliki versi yang lebih tinggi mengatakan 2.0. Dalam hal ini Anda tidak dapat memprediksi mana yang akan digunakan.

Untuk menegakkan versi permata yang diinginkan, Anda mengambil bantuan bundle exec perintah yang akan mengeksekusi biner dalam konteks bundel saat ini. Itu berarti ketika Anda menggunakan bundle exec, bundler memeriksa versi gem yang dikonfigurasi untuk proyek saat ini dan menggunakannya untuk melakukan tugas.

Saya juga telah menulis posting tentang itu yang juga menunjukkan bagaimana kita dapat menghindari menggunakannya dengan menggunakan rintisan bin.

Ajit Singh
sumber
1

Saya belum bundle execbanyak menggunakan , tetapi sedang menyiapkannya sekarang.

Saya memiliki contoh di mana penggaruk yang salah digunakan dan banyak waktu terbuang untuk melacak masalah. Ini membantu Anda menghindarinya.

Berikut cara mengatur RVM sehingga Anda dapat menggunakan bundle execsecara default dalam direktori proyek tertentu:

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

Calasyr
sumber
0

Ini berarti menggunakan rake yang diketahui bundler dan merupakan bagian dari Gemfile Anda atas setiap rake yang bundler tidak sadari dan jalankan tugas db: migrasi.

Omar Qureshi
sumber