bundle 最初に知ること
bundler で出来ることを最初に知ることが必要
bunder はプロジェクトで使ってるgem を一覧するためのもの。
bundler は 必要なgem をインストールしてくれる
bundler は、自作ライブラリのgem化が出来る
bundler は、プロジェクトに必要なGemを「プロジェクト毎」にインストール出来る
bundler は、共有gem とプロジェクトで足りないものをインストール出来る。
つまり、bundler を使うことで、「必要なGem」の一覧を管理することが出来る。
このことにより、デプロイ先に開発元と同じgem環境を再現することができる
bundler 始め方
ディレクトリにGemFileを作成する。
もしくは、コマンドラインで bundle init とする
基本的な流れやで
sudo apt install ruby-bundler
mkdir プロジェクト cd プロジェクト bundle init bundle config set --local path 'vendor/bundle' echo gem "nokogiri" >> GemFile bundle install
なにか追加したいときは、マニュアルで編集するか
vim GemFile bundle install
または、bundle add する
bundle add sqlite3
プロジェクトの中にインストールする場合(2023-08-10追記)
bundle コマンド導入後なら、次をコピペすれば、プロジェクトごとに分離したbundler 環境を作れる。
mkdir my-project cd my-project bundle init bundle config set --local path 'vendor/bundle' bundle config set --local disable_shared_gems true bundle add sqlite3
プロジェクト内部でruby を実行するとき
bundle 経由で実行する
bundle exec ruby sample.rb
sample.rb ではrequire するだけでいい。
# in sample.rb require 'sqlite3'
つぎに GemFile の書きかた。その0。
はじめに、source を書く。
source "https://rubygems.org"
これにより、gemをどこから探すか指定することが出来る。
自作レポジトリも指定できる。
source "https://rubygems.org" source "https://takuya.example.org"
作成方法はgem generate_indexなどでググれば出てくる。
GemFile の書きかた1
GemFileには、必要なGemを書いていく。
gem "nokogiri" gem "pry" gem "sequel"
GemFile の書き方2
必要なgem ファイルは、グループ分けすることが出来る
gem "nokogiri" group :development do gem "pry" group :test do gem "shoulda" end
グループ分けしておくと、便利なことがある。
- デプロイ先で無駄なインストールしなくて便利だ
- bundle.require でグループ毎にreuqire 出来て便利。
GemFile の書き方3
バージョンを指定することが出来る
gem "nokogiri", ">= 1.4.2"
バージョン指定の方法は ruby require や gem install で用いられるものと同じだと思えばイイ。
bundler が使うファイル。
- GemFile 使う(依存する)gemの一覧
- GemFile.lock (実際に使ってる)gemとそのバージョン一覧
おもに GemFile が使われる。
GemFile.lockがBundlerで実際にインストールされたバージョンの一覧。
lock ファイルの記述を優先してインストールすることになる
lockファイルの扱い
gem file lock 記述を優先してインストールを再現される。が、、困った現象が起きた経験がある。
Bundlerが windows バイナリをOSXに入れようとしてて驚愕。OSXにCygwinのバイナリ入れたら動かんだろう?でもインストールしてた。それがlockファイル。
Windowsバイナリでトラブルったのでgemfile.lock は細かく管理したい時に用途を限ることにした。バージョンやバイナリを詳細設定するときに限る。
Windows(開発)→Linux(デプロイ)のときは、全く役に立たないし、lockは消して構わない。gemfile.lock があるせいで、lockファイルはゴミ
bundler を使ったrequie
bundle install のやり方が分かったら、次に bundler を使ったrequire を覚えておく
require 'bundler' Bundler.setup require 'nokogiri'
はい、これでOK
Gem を何処に入れるのか
bundler が良く分からない理由はコレだと思う。
- bundler にgem 環境を プロジェクト毎に作らせる
- bundler にシステム環境へgemをインストールさせる。
この2パターンがあってですね。システム環境やユーザー環境のGEM_HOMEかプロジェクト環境を選ぶことが出来るわけ。
個人で使う分には、プロジェクト環境よりシステム環境やユーザー環境利用が幾分に楽。
disable shared gems = 1
共有のgem をdisabledにして、プロジェクト内にgem 環境をゼロから作る。
bundle install vendor/bundle --disable-shared-gems
この場合、システム環境のgemは全て無視される
または、.bundle/config にかく
echo BUNDLE_DISABLE_SHARED_GEMS: '1' >> .bundle/config
これで、bundleはプロジェクト環境に全てのgemをインストールする。
BUNDLE_DISABLE_SHARED_GEMSの功罪
bundle が良く分からない現代魔法になってるのは、shared_gems にあるとおもう。
BUNDLE_DISABLE_SHARED_GEMS: '1'
システム環境のgemを使いたい時は、 BUNDLE_DISABLE_SHARED_GEMS: '1'を消す
一年くらい使っててbundle でプロジェクト毎にパッケージをインストールするのは無駄と思うようになった。
pry とか mysql2 とかいくつもインストールしてんだわ。
システムの libxml 環境変わったのに古いbundleがlib指してて反って面倒だったり。システム全体のgem 使って欲しい場面のほうが多かった。 とくに開発環境だと時間の無駄が多いので必要ない気がする。
デプロイ先なら BUNDLE_DISABLE_SHARED_GEMS: '1' をした方がいいかも。
つまり、BUNDLE_DISABLE_SHARED_GEMSがあると同じgemをいくつもインストールするので、ちょっとイラッとする。
bundleの手軽さが死ぬきがする。bundleのよさは git clone ; bundle install ; ですぐ使えることだと思うんだ。
bundle の設定
bundle/config の上書き関係
たとえば、BUNDLE_DISABLE_SHARED_GEMSの設定は次の箇所で指定される。
~/.bundle/config PROJECT/.bundle/config bundle install --disable-shared-gems
の順番で、ユーザ → プロジェクト → コマンド実行時になる。
bundle install は何処に入るのか
- bunele install は なにも設定をしなければ system のgem が使われる
- bundle install はなにも設定ををしなければ system の gem にインストールされる
- bundle install は gem listall の自動化になる。
ただし、BUNDLE_PATHが環境変数にあったり、disable-shared-gemsが指定されていればこの限りではない。
なので、油断してるとシステム環境にインストールされちゃったり、プロジェクト環境にインストールされちゃうので注意が必要
私の場合、rbenv 環境にgem がインストールされないと思って悩んでいたら
ユーザー環境にデフォルト設定が会った。 ~/.bundle/config に disable-shared-gems
が設定されていた。はぁ。。。
bundle list で bundleされた一覧を見る
rbenv やrubygems が管理してるgemに任せるのが楽だった。
takuya@~$ bundle config Settings are listed in order of priority. The top value will be used. bundle install
個人環境なら vendor/bundle 使うとかえって面倒かもね。 使わなくなったら
gem uninstall hogehoge gem cleanup
で消しちゃってもいいしrbenv環境ごとポイッ
個人のrbenv環境で使うなら、何も設定せずにbundle install 叩いてたほうが圧倒的に楽だと思った
同じファイルをいくつもシステムに持つのダルいしコンパイルオプション考えるの面倒だしさ 自分のプロジェクトってだいたい同じようなgem使ってるじゃん?大きく違うバージョンや環境でもない限り vendor 使う必要ないと思った。
gem のソースを追いかけるために、locate や mdfind して同じファイルが大量に来るのも気持ち悪い・・・
強制的にsystem に入れる方法
bundle install --system
ただ、既存のlock やconfigがあるとうまく動かない
vendor/bundle を使う方法
bundle install vendor/bundle --disable-shared-gems
これは、shared-gem(さっき言及した、システム全体gem)を拒否して、vendor/bundle にゼロからgem 空間を構築する 必要なgems の全てがvendor/bundleに入ります。
path / disable-shared-gems はワンセットになってるので消しちゃうとちょっと面倒なことに
手元の環境で、vendor/bundle 使うと、ここが不便でいや何だけど。
bundle の設定
現在のbundler の設定は bundle config で確認できる
$ bundle config Settings are listed in order of priority. The top value will be used.
bundle の設定は、プロジェクトとHOME_PATHの2つをマージして使う
~/.bundle/config PROJECT_HOME/.bundle/config
の2つのymlをマージすることになる。
たとえば、bundle install nokogiriにビルドオプションを与えたい時
bundle config --global build.nokogiri -- \ --with-xml2-dir=`brew --prefix libxml2`\ --with-xslt-dir=`brew --prefix libxslt`
とする。
全てのbundle install nokogiri に設定したいときは ~/.bundle/config に書く。
> cat ~/.bundle/config --- BUNDLE_BUILD__NOKOGIRI: "--with-xml2-dir=/usr/local/opt/libxml2 --with-xslt-dir=/usr/local/opt/libxslt"
.bundle/config の設定項目
設定項目には次のようなものがある。
- BUNDLE_PATH
- BUNDLE_FROZEN
- BUNDLE_WITHOUT
- BUNDLE_BIN
- BUNDLE_GEMFILE
- BUNDLE_SSL_CA_CERT
- BUNDLE_SSL_CLIENT_CERT
- BUNDLE_CACHE_PATH
- BUNDLE_DISABLE_MULTISOURCE
- BUNDLE_IGNORE_MESSAGES
設定は、同名の環境変数でも上書き
される。 環境変数のほうが楽かも?
環境変数を使う場合
BUNDLE_BIN="vendor/bundle/bin" bundle install
また、config を指定する時だけ、次のような読み替えが許されるっぽい
BUNDLE_PATH => path BUNDLE_BIN => bin
設定ファイルとコマンドオプションは同じ設定項目を意味する。
BUNDLE_BIN: "./bin" bundle config --global bin "./bin"
デプロイ
bundle が真価を発揮するのはここ。
bundle install --deployment
このコマンドで、GemFile.lock で指定されている必要なパッケージを取ってくる GemFile はユーザー指定 Gemfile.lock は bundle が調べて必要だと判別した全て。
ちなみに、そういうのはネットから取ってこれない場合のために
gem package
すると vendor/cache に貯めておいてくれるので git vendor/cache でもしとけばいいけど、、OS超えてまでまず動かないと思うしやらないと思う。
bundle install --deployment --path=vendor/bundle
で環境の再現ということで。
vendor/bundle に入れた場合
bundle exec nokogiri bundle exec
手元の環境で、vendor/bundle 使うと、ここが不便でいや何だけど。
その他の話題
bundle コマンドを補完したい
brew install ruby-completion brew install bundler-completion
などと、補完もいっぱいある
2023-08-10
更新。
参考資料
http://bundler.io/v0.9/bundle_install.html
https://gist.github.com/kozy4324/5719555
http://stackoverflow.com/questions/8104370/what-does-it-mean-bundle-disable-shared-gems-1
http://xxxcaqui.hatenablog.com/entry/2013/02/11/013421
http://ruby.studio-kingdom.com/bundler/gemfile
*1:HOME_PATH を --global というのはセンスが無いと思った --user にして欲しい --global は etcを期待してしまうハマった