Gemのパッケージ管理ツール「Bundler」のセットアップ&操作方法

## 「Bundler」とは？

Gemのパッケージ管理ツールです。
Bundlerを使うことで、プロジェクトごとにバージョンを指定してGemを使うことができるようになります。

## 環境

- RubyGems：2.7.1
- Bundler：2.0.1

## RubyGemsの更新

まずはRubyGemsを更新します。
更新方法は[こちら](https://qiita.com/uhooi/items/1134b0f784028412cb83#rubygemsの更新)に記載しています。

## rbenvのセットアップ

rubyのバージョン管理ツールであるrbenvを導入すると、既存の環境を変更せずにBundlerをセットアップできます。

rbenvのセットアップについては以下の記事をご参照ください。
https://qiita.com/uhooi/items/3ff6f2747036189f649b

## Bundlerのセットアップ

RubyGemsからインストールします。

```shell-session
$ gem install bundler
```

2021/03/27, 追記
Ruby `2.6.0` あたりから標準でBundlerがインストールされるようになりました。
Bundlerのバージョンを切り替える方法がわからなかったので、基本的にはそのまま使うのがいいと思います。

https://twitter.com/_bannzai_/status/1375772717975171073?s=20

## Gemのセットアップ

### カレントフォルダの変更

まずはプロジェクトのルートフォルダに移動します。

```shell-session
$ cd {プロジェクトのルートフォルダ}
```

### Gemfileの編集

プロジェクトのルートフォルダに移動して `bundle init` を実行すると、 `Gemfile` という拡張子なしのファイルが作成されます。

Gemfileのフォーマットは以下の通りで、使いたいライブラリを記述します。

```ruby:Gemfile
source 'https://rubygems.org'
gem '{パッケージ名}'
…
```

`source 'https://rubygems.org'` はおまじないです。
記述しないとCI/CD環境などで以下のエラーが発生します。

```shell-session
$ bundle install
Your Gemfile has no gem server sources. If you need gems that are not already on
your machine, add a line like this to your Gemfile:
source 'https://rubygems.org'
Your bundle is locked to CFPropertyList (2.3.6), but that version could not be
found in any of the sources listed in your Gemfile. If you haven't changed
sources, that means the author of CFPropertyList (2.3.6) has removed it. You'll
need to update your bundle to a version other than CFPropertyList (2.3.6) that
hasn't been removed in order to install.
```

例：
slatherをインストールします。

```ruby:Gemfile
source 'https://rubygems.org'
gem 'slather'
```

### パッケージのインストール

以下のコマンドを実行します。

```bash
$ bundle install
```

インストールが完了するとGemfile.lockというファイルが作成されます。
こちらのファイルには実際にインストールしたパッケージのバージョンが記述されています。

Gemfile.lockが存在するときに `bundle install` を実行すると、基本的には __Gemfileを見ずにGemfile.lockのみを見てパッケージをインストール__ します。
Gemfile.lockは更新されません。

しかし、GemfileとGemfile.lockに矛盾がある場合、Gemfile.lockを更新してからパッケージをインストールします。

開発者同士でパッケージのバージョンを合わせるときに使います。

### ライブラリの更新

`bundle update` を実行すると、Gemfileに記述した全てのパッケージがGemfileに従って更新されます。

```shell-session
$ bundle update
```

Gemfile.lockも更新されます。

### `bundle install` と `bundle update` の違い

`bundle install` と `bundle update` の違いの詳細については、[scivolaさんのコメント](https://qiita.com/uhooi/items/4abf8c282ae23a259e4f#comment-37ac1b576e0e00720083)が非常にわかりやすいので、こちらを参照してもらえればと思います。
この場を借りてお礼申し上げます:bow:

## Bundlerのバージョンアップ

RubyGemsからバージョンアップします。

```shell-session
$ gem update bundler
```

## Gemの実行方法

コマンドの先頭に `bundle exec` を付けて実行します。
付けないとプロジェクト外でインストールされたコマンドが実行されます。

例：
slatherを実行します。

```shell-session
$ bundle exec slather
```

## おわりに

これでプロジェクトごとに異なるバージョンのGemが使えるようになります！
CI/CD環境で特定のバージョンのGemをインストールしたいときにも使えるので、非常に便利なツールです。

## 参考リンク

- [Bundler: The best way to manage a Ruby application's gems](https://bundler.io/)
- [bundle install と bundle updateの違いについて - Qiita](https://qiita.com/lasershow/items/1a048d03ddaaba98171e)
- [bundler、bundle execについて　※自分用メモ - Qiita](https://qiita.com/dawn_628/items/1821d4eef22b9f45eea8)
- [MacにHomeBrew,rbenv,bundlerをインストールする - Qiita](https://qiita.com/shinkuFencer/items/3679cfd966f6a61ccd1b)