【翻訳】Bundler 3アップグレードガイド

## はじめに

Rubyのパッケージ管理ツールであるBundlerはバージョン 3で後方互換性が失われる様々な変更点が導入される予定になっています。
そして、バージョン 3への移行を容易にするため、バージョン 2.1ではバージョン 3で使えなくなる機能を使うと警告が出ます。

これらの内容については公式リポジトリのアップグレードガイドで詳細が説明されています。

https://github.com/rubygems/rubygems/blob/master/bundler/UPGRADING.md

この記事は上記のアップグレードガイドの日本語訳です。

### 翻訳したアップグレードガイドの版について

この記事で翻訳したのは2019年10月3日に更新された以下の版です。
（翻訳時点のBundlerの最新バージョンは2.1.4）

https://github.com/rubygems/rubygems/blob/77e41a214dadeb93388b8ef23c6e333301ddd230/bundler/UPGRADING.md

今後更新される可能性もあるため、必要に応じて最新の版を参照するようにしてください。

https://github.com/rubygems/rubygems/blob/master/bundler/UPGRADING.md

**2020.1.15追記**

2020年1月14日更新の版に追従しました。

https://github.com/rubygems/rubygems/commit/5ac4fc8e61ebf298945ee6ed07c1a8b8c14c11f7

この版における主な変更点は以下のとおりです。cf. [rubygems/bundler#7561](https://github.com/rubygems/bundler/pull/7561)

- `bundle viz`コマンドの移行先となるプラグインのGitHubリポジトリへのリンクを削除（詳細未定であるため）
- 「`bundle update`コマンドを実行しても、すべてのgemがアップデートされなくなります（`--all`オプションが必要になります）」の項を削除（変更実施が延期されたため）
- 「`bundle config`コマンドに新しいサブコマンドが追加されました」の項を削除（変更実施が延期されたため）

**2022.8.23追記**

2022年8月23日更新の版に追従しました。

https://github.com/rubygems/rubygems/blob/de129db41d3b949721e3e20b9488d8aaf3927ee9/bundler/UPGRADING.md

この版における変更点は以下のとおりです。cf. [rubygems/rubygems#5864](https://github.com/rubygems/rubygems/pull/5864)

- 廃止されるコマンドインターフェイスを整理
- [rubygems/bundler#7561](https://github.com/rubygems/bundler/pull/7561)における`bundle config`の廃止内容の誤記の修正
- [rubygems/rubygems#3166](https://github.com/rubygems/rubygems/pull/3166)でのRubyGemsおよびBundlerリポジトリ統合によるURL変更対応

### おことわり

普段あまり使わない機能については、正しく翻訳できているかどうかあまり自信がありません。
もし明らかにおかしな内容を見つけたら、コメント欄や編集リクエスト等で報告してください🙏

### ライセンスについて

この記事はBundlerと同様にMITライセンスで公開します。

This document is under the MIT License.

それでは以下がアップグレードガイドの翻訳になります。

## 【翻訳】アップグレードについて

### Bundler 3について

以下で説明するのはBundler 3で導入される変更点のまとめです。なぜその変更を入れるのか、そして非推奨化のプロセスがどのようになるのかについても説明しています。非推奨になる変更点はBundler 2.1のリリース時にすべてデフォルトで表示されます。

もし非推奨警告の対応は後回しにして警告を非表示にしたい場合は、設定によってそのように変更できます。その場合は`BUNDLE_SILENCE_DEPRECATIONS`という環境変数を"true"に設定するか、`bundle config`コマンドを使って設定してください。グローバルに設定を変更したい場合は`bundle config set silence_deprecations true`コマンドを使い、ローカルの設定だけ変更したい場合は`bundle config set --local silence_deprecations true`コマンドを使います。これ以降、本ドキュメントではこの3つの設定方法がすべて有効である前提で執筆していきますが、記述するのは`bundle config set <option> <value>`の方法だけにします。

全般的な話として、これらの変更点は「新規Bundlerユーザー」のユーザー体験を改善するために行われます。ここでいう新規Bundlerユーザーとは、毎回特に決まった使い方をしておらず、これまでの使用体験から「Bundlerにはこう動いてほしい」という明確な意思も持っていないユーザーのことを指します。今回の変更点は長年Bundlerを使ってきたユーザーをイライラさせるものだと思います。その点は私たちも十分理解しています。ですので、私たちはこのプロセスをできる限りスムーズなものにしたつもりです。

非推奨化警告は、「CLIの非推奨警告」「ヘルパーの非推奨警告」「DSLの非推奨警告」「その他の非推奨警告」という4つのグループに分けられます。それぞれについて今から見ていきましょう。

#### CLIの非推奨警告

CLIではBundlerを動かすためのコマンドとオプションの集合を定義しています。このコマンドとオプションの集合に対して、私たちはさまざまな変更を導入する予定です。

* 一度設定するとそれ以後の呼び出しでその設定が記憶される`bundle install`用のフラグが非推奨となりました。

  具体的には、`bundle install`に渡す `--clean`, `--deployment`, `--frozen`, `--no-cache`, `--no-prune`, `--path`, `--shebang`, `--system`, `--without`, `--with` オプションのことになります。

  記憶されるCLIオプションはこれまで混乱とバグレポートの温床になってきました。これは初心者に限った話ではなく、経験豊富なユーザーにとっても同様です。CLIツールは全く同じ呼び出し方なのに異なる振る舞いをするべきではありません。そうなってもよいのは、そのように明示的に設定されている場合「だけ」です。それが設定の存在理由であり、ユーザーが気づかないところでこっそりと設定が変更されるべきではありません。

  この仕様変更によって影響を受けるのは、この機能に依存する「よくあるワークフロー」です。たとえば、本番環境で`bundle install --without development:test`というコマンドを実行すると、このフラグがアプリケーションの設定ファイルに保存され、それ以降は`bundle`コマンドを実行してもdevelopmentとtestのgemをありがたく無視してくれます。Bundler 3以降はこの魔法が使えなくなります。同じ挙動を維持するためには明示的な設定が必要です。設定を入れる方法は、環境変数、アプリケーションの設定、マシン全体の設定のいずれかです。たとえば、`bundle config set without development test`というコマンドを使います。（訳注：デフォルトではglobalの設定が変わってしまうので、`bundle config without 'development test' --local`のように`--local`オプションと一緒に実行するのが良さそうです）

  こうしたフラグの削除は類似のコマンドにも適用されます。たとえば、`bundle check --path`がそうです。

* `bundle install`と`bundle update`に渡す`--force`フラグは、`--redownload`にリネームされます。

  これは単なるフラグのリネームです。リネームするのは実際の挙動をよりわかりやすくするためです。このフラグは強制的にすべてのgemを再ダウンロード（redownload）するだけで、それ以外の何かを強制（force）するわけではありません。

* `bundle viz`コマンドが削除され、プラグインとして切り出されます。

  これはBundlerで唯一外部依存が発生するコマンドです。依存先はOS（`graphviz`パッケージ）とgem（`ruby-graphviz` gem）です。この依存性を排除することで開発がより容易になります。また、この機能はBundlerチームによって公式に保守されるBundlerプラグインになります。ユーザーもこのプラグインを参照すれば、独自のプラグインを作るのに役立ちます。このプラグインは従来のコアコマンドと同じコードになっていますが、唯一異なる点としてコマンド名が`bundle graph`に変わっています（でも、この方がずっとわかりやすいはずです）。ただし、このプラグインの詳細については現在検討中です。詳しくは[#7041](https://github.com/rubygems/bundler/issues/7041)をご覧ください。

* `bundle console`コマンドが削除され、`bin/console`に置きかわります。

　時間の経過とともに`bundle console`コマンドは保守するのが難しくなってきました。これは各ユーザーが自分独自の変更点を追加しようとしてくるためです。保守を容易にし、細々した議論を減らすため、`bundle console`コマンドを`bin/console`スクリプトに置き換えます。このスクリプトはgem開発時に`bundle gem`コマンドで作成され、ユーザーは自分が好きなようにこのコマンドを修正することができます。

* `bundle install`コマンドに`--binstubs`フラグを渡せなくなります。

  `--binstubs`オプションは`bundle install`コマンドから削除され、`bundle binstubs`コマンドに置きかえられました。`--binstubs`オプションはプロジェクト内のgemに存在するすべての実行可能ファイル（executables）に対してbinスタブを作成します。しかし、これはほとんど役に立ちませんでした。なぜなら大半のユーザーが使うのはbinスタブの一部だけだからです。加えて、これを使うと、使われることのない大量のファイルがソース管理システムに追加されます。こうした理由により、binスタブは個別に作成され、個別にバージョン管理されるようになります。

* `bundle inject`コマンドが非推奨になり、`bundle add`コマンドに置きかえられました。

  新しいコマンド名の方がきっとユーザーのメンタルモデルにフィットし、より広いユースケースをサポートすると思います。`bundle inject`コマンドでサポートされていたインターフェースは`bundle add`コマンドでもまったく同じように動作します。ですので、新しいコマンドに移行するのは簡単なはずです。

##### 延期された非推奨警告

以下の非推奨警告は過去に一度非推奨警告に入りましたが、Bundler 2.1.0リリース直前の時点で[rubygems/bundler#7475](https://github.com/rubygems/bundler/pull/7475)で廃止がBundler 4以降に延期になりました。

* 
`bundle update`コマンドを実行しても、すべてのgemがアップデートされなくなります（`--all`オプションが必要になります）。
（延期）

* 
`bundle config`コマンドでBundler 2.1より前に利用されていた古いサブコマンドオプション体系を受け付けなくなります。
（延期）

#### ヘルパーの非推奨警告

* 右のメソッドは非推奨になりました。`Bundler.clean_env`, `Bundler.with_clean_env`, `Bundler.clean_system`, `Bundler.clean_exec` 

  これらのヘルパーメソッドはすべて、背後で`Bundler.clean_env`メソッドを使っています。これにより実行されるブロック内ではBundlerに関連する環境は削除されます。

  ユーザーからたくさんのレポートを受け取った結果、ユーザーは通常この挙動を望まず、代わりにカレントプロセスが開始する前と同じBundler環境を使いたがっていることに私たちは気づきました。こうして生まれたのが、`Bundler.with_original_env`, `Bundler.original_system`, `Bundler.original_exec`という3つのメソッドです。これらのメソッドはすべて新しい`Bundler.original_env`メソッドを背後で使います。

  とはいえ、特定の状況下では従来の`Bundler.clean_env`の挙動が望ましいこともあるでしょう。たとえば、Railsジェネレータのテストをする場合は、`bundler`のいない環境が欲しくなると思います。このため、私たちは従来の挙動を新しく、よりわかりやすい名前で維持できるようにしました。"clean"という単語はあまりにもあいまいだからです。というわけで、私たちは `Bundler.unbundled_env`, `Bundler.with_unbundled_env`, `Bundler.unbundled_system`, `Bundler.unbundled_exec` という4つのメソッドを新たに追加しています。

* `Bundler.environment`が非推奨になり、`Bundler.load`に置き換えられました。

  どれくらいの人がこれを直接使っているのかはわかりませんが、私たちは`Bundler::Environment`クラスを削除しました。このクラスは`Bundler.environment`によってインスタンス化されるクラスです。削除した理由は`Bundler::Runtime`が同じ役割のクラスだと気づいたからです。移行期間中、`Bundler.environment`は`Bundler.load`に委譲されます。このメソッドは`Bundler::Environment`への参照を保持しています。

#### DSLの非推奨警告

Bundler DSLで発生する下記の非推奨警告は、Bundler 3で予定されている厳格なソース固定（strict source pinning）への準備を意味します。Bundler 3ではすべての依存ライブラリのsourceは厳格に定義されます。

* 複数定義されたグローバルなGemfileのsourceはサポートされなくなります。

  こんなふうに書く代わりに・・・

  ```ruby
  source "https://main_source"
  source "https://another_source"

  gem "dependency1"
  gem "dependency2"
  ```

  このように書いてください。

  ```ruby
  source "https://main_source"

  gem "dependency1"

  source "https://another_source" do
    gem "dependency2"
  end
  ```

* グローバルな`path`と`git`のソース（source）はサポートされなくなります。

  こんなふうに書く代わりに・・・

  ```ruby
  path "/my/path/with/gems"
  git "https://my_git_repo_with_gems"

  gem "dependency1"
  gem "dependency2"
  ```

  このように書いてください。

  ```ruby
  gem "dependency1", path: "/my/path/with/gems"
  gem "dependency2", git: "https://my_git_repo_with_gems"
  ```

  もしくは各ソースに対して複数のgemがあり、もっとDRYに書きたい場合はブロック記法を使ってください。

  ```ruby
  path "/my/path/with/gems" do
    # gem "dependency1"
    # ...
    # gem "dependencyn"
  end

  git "https://my_git_repo_with_gems" do
    # gem "dependency1"
    # ...
    # gem "dependencyn"
  end
  ```

#### その他の非推奨警告

* `vlad`と`capistrano`用のデプロイヘルパー（Deployment helper）は削除されました。

  `vlad`ツールは何年も活動が止まっているので自然に非推奨となりました。一方で`capistrano` 3は`capistrano-bundler` gemによってBundlerに統合されています。Capistrano 3のユーザーはきっとこれを使っているはずです。なんらかの理由でCapistrano 2を使い続けている場合は、遠慮無くBundler 2の`lib/bundler/deployment.rb`ファイルからCapistrano用のタスクをコピーして、ご自身のアプリケーションに追加してください。

  基本的に私たちはあらゆるデプロイメントシステムの統合機能を保守したくありません。この機能を削除したのはこうした理由からです。

（翻訳は以上）