bundler 触ってみる

Gemfileには、Rubyコードを実行するために必要なgem依存関係を記述する
関連するコードを含むディレクトリのルートにGemfileを配置する。これは知らんかった。
Gemfileの先頭に、Gemfileに記載されたgemを含むRubyGemsソースを1行で追加する。

ほとんどのバージョン指定子(例:≥ 1.0)は自明です。指定子 ~> は特別な意味を持ち、例で示すのが最も分かりやすいでしょう。~> 2.0.3 は >= 2.0.3 および < 2.1 と同一です。~> 2.1 は >= 2.1 および < 3.0 と同一です。~> 2.2.beta は 2.2.beta.12 のようなプレリリース版に一致します。~> 0 は >= 0.0 および < 1.0 と同一です。
~>〇〇は >=〇〇 && 一番下の桁のバージョンの位が上がったバージョン未満

一部のgemをプライベートgemサーバーから取得する必要がある場合、それらのgemに対してこのデフォルトソースを上書きできます。単一のgemを含むgemサーバーの場合、そのgemに対して:sourceオプションを使用するのが最も簡単です。
gem 'my_gem', '1.0', :source => 'https://gems.example.com'

Gemfileで
ruby
を使用して必要なRubyのバージョンを指定できます。Gemfileが異なるRubyバージョンで読み込まれた場合、Bundlerは説明付きの例外を発生させます。
知らんかった。
# Gemfileに以下の行があると、BundlerはRuby 3.1.2を使います
ruby '3.1.2'
ruby -v
ruby 3.3.1 (2024-04-23 revision c56cd86388) [x86_64-darwin22]
bundle i
Your Ruby version is 3.3.1, but your Gemfile specified 3.1.2
確かにエラーは出てた。

Gemfileに書かれたrubyのバージョンをローカルと合わせてダウンロードしたらいけた。
# frozen_string_literal: true
source "https://rubygems.org"
ruby '3.3.1'
gem 'nokogiri'
ruby -v
ruby 3.3.1 (2024-04-23 revision c56cd86388) [x86_64-darwin22]
bundle i
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Fetching nokogiri 1.18.9 (x86_64-darwin)
Installing nokogiri 1.18.9 (x86_64-darwin)
WARN: Unresolved or ambiguous specs during Gem::Specification.reset:
stringio (>= 0)
Available/installed versions of this gem:
- 3.1.2
- 3.1.1
- 3.1.0
WARN: Clearing out unresolved specs. Try 'gem cleanup <gem>'
Please report a bug if this causes problems.
Bundle complete! 1 Gemfile dependency, 3 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
よくよく見るとbundle iしているときに、RubyGemsからgemのデータをインストールしているな。

ライブラリ
多くのプログラミング言語と同様に、Ruby にも幅広いサードパーティのライブラリが提供されています。
それらのほとんどは “gem” という形式で公開されています。RubyGems は (Ruby に特化した apt-get と同じようなパッケージングシステムで) ライブラリの作成や公開、インストールを助けるシステムです。Ruby のバージョン 1.9 以降 RubyGems は標準添付となっていますが、それ以前のバージョンの Ruby の場合は自分でインストールする必要があります。
Rubyではライブラリをgemという形式で公開していて、RubyGemsというシステムを通して、ライブラリの作成、公開、インストールができる、なるほど。
ライブラリを探す
Ruby のライブラリは主に RubyGems.org に gem として置かれています。直接ウェブサイトを閲覧したり、gem コマンドを使用してそれらを探すことができます。
また、他にもライブラリの配布元があります。 近年ではGitHub が ruby 関連のリポジトリとして広く使われています。 gem としては RubyGems.org に公開されますが、gem のソースコードのほとんどは GitHub 上で見ることが出来ます。
Rubyのライブラリは、RubyGems.orgにgemとして置かれているのか。
gemはRubyGems.orgに置かれていて、そのgemのソースコードはGitHub上のリポジトリで見れるのか。
RubyGemsとGitHubの関係性がわかってきた。
RubyGems.org に いくつかのガイド があります。 Bundler について調べてみるのもいいでしょう。Bundler は RubyGems と一緒に使われる、アプリケーションの依存関係を管理するための一般的なツールです。

gemコマンドでRubyGemsにアクセスしてるのか

bundle install実行したときに、bundlerがRubyGemsにアクセスするのか。納得。

git_sourceは、Rubygemsに登録されていないGemをinstallをしたいに利用します。ブランチ名も指定できます。 会社独自のGemを利用する際などに使えそうです。
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
git "rails", :github => "rails"
git_source(:stash){ |repo_name| "https://stash.corp.acme.pl/#{repo_name}.git" }
gem "rails", :stash => "forks/rails", :branch => "branch_name"
Gemfile の中で :github オプションをつけた gem について、HTTPS 経由で GitHub から取得します。
git_source は Bundler で定義されているメソッド で、引数のオプション(ここでは :github)が付いた gem の取得先 URL をブロック内で指定できます。
git_sourceは:githubオプションをつけたgemを取得する先のurlを指定するための記述だったのか。知らんかった。

bundle infoでbundlerで管理されているgemの情報を取得できる。
Chnagelogのパスも観れるの知らんかった。
bundle info nokogiri
* nokogiri (1.18.9)
Summary: Nokogiri (鋸) makes it easy and painless to work with XML and HTML from Ruby.
Homepage: https://nokogiri.org
Documentation: https://nokogiri.org/rdoc/index.html
Source Code: https://github.com/sparklemotion/nokogiri
Changelog: https://nokogiri.org/CHANGELOG.html
Bug Tracker: https://github.com/sparklemotion/nokogiri/issues
Path: /Users/yuuki_haga/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/nokogiri-1.18.9-x86_64-darwin

bundle-add - Add gem to the Gemfile and run bundle install
bundle addはgemfileにgemを追加して、さらにbundle iを実行してくれるコマンド
bundle add faker
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...
Fetching gem metadata from https://rubygems.org/...........
Resolving dependencies...
bundle addで確かにGemfileにfakerが記述されてた。
# frozen_string_literal: true
source "https://rubygems.org"
ruby '3.3.1'
gem 'nokogiri'
gem "kaminari", "~> 1.2"
gem "faker", "~> 3.5"
bundle infoも出るようになった。
bundle info faker
Could not find gem 'faker'.
↓
bundle info faker
* faker (3.5.2)
Summary: Easily generate fake data
Homepage: https://github.com/faker-ruby/faker
Documentation: https://rubydoc.info/github/faker-ruby/faker
Source Code: https://github.com/faker-ruby/faker
Changelog: https://github.com/faker-ruby/faker/blob/main/CHANGELOG.md
Bug Tracker: https://github.com/faker-ruby/faker/issues
Path: /Users/yuuki_haga/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/faker-3.5.2

依存gemのバージョンが越えると動かないことを検証する。
↓Gemfile.lock
GEM
remote: https://rubygems.org/
specs:
concurrent-ruby (1.3.5)
faker (1.0.0)
i18n (~> 0.4)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
nokogiri (1.18.9-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-musl)
racc (~> 1.4)
racc (1.8.1)
PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
faker (= 1.0)
nokogiri
RUBY VERSION
ruby 3.3.1p55
BUNDLED WITH
2.5.20
↓ Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
ruby '3.3.1'
gem 'nokogiri'
gem 'faker', '1.0'

# frozen_string_literal: true
source "https://rubygems.org"
ruby '3.3.1'
gem 'nokogiri'
gem 'faker', '1.0'
gem 'i18n', '1.14.7'
bundle i
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Could not find compatible versions
Because faker >= 0.9.1, < 1.1.0 depends on i18n ~> 0.4
and Gemfile depends on faker = 1.0,
i18n ~> 0.4 is required.
So, because Gemfile depends on i18n = 1.14.7,
version solving has failed.
互換性のあるバージョンが見つかりませんでした
faker >= 0.9.1, < 1.1.0 は i18n ~> 0.4 に依存しており、
Gemfile は faker = 1.0 に依存しているため、
i18n ~> 0.4 が必要です。
しかし、Gemfile は i18n = 1.14.7 に依存しているため、
バージョンの解決に失敗しました。
上のケースだと、i18nをバージョン1.14.7でインストールしようとしているが、fakerが依存している18nで使える最大バージョンが0.9であるため、このエラーが出てる。

# frozen_string_literal: true
source "https://rubygems.org"
ruby '3.3.1'
gem 'nokogiri'
gem 'faker', '1.0'
gem 'i18n', '0.9'
これだとうまくいく。
bundle i
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Fetching i18n 0.9.0 (was 0.9.5)
Installing i18n 0.9.0 (was 0.9.5)
WARN: Unresolved or ambiguous specs during Gem::Specification.reset:
stringio (>= 0)
Available/installed versions of this gem:
- 3.1.2
- 3.1.1
- 3.1.0
WARN: Clearing out unresolved specs. Try 'gem cleanup <gem>'
Please report a bug if this causes problems.
Bundle complete! 3 Gemfile dependencies, 6 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
GEM
remote: https://rubygems.org/
specs:
concurrent-ruby (1.3.5)
faker (1.0.0)
i18n (~> 0.4)
i18n (0.9.0)
concurrent-ruby (~> 1.0)
nokogiri (1.18.9-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-musl)
racc (~> 1.4)
racc (1.8.1)
PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
faker (= 1.0)
i18n (= 0.9)
nokogiri
RUBY VERSION
ruby 3.3.1p55
BUNDLED WITH
2.5.20

当たり前だけど、これだとうまくいかない
# frozen_string_literal: true
source "https://rubygems.org"
ruby '3.3.1'
gem 'nokogiri'
gem 'faker', '1.0'
gem 'i18n', '1.0'
bundle i
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Could not find compatible versions
Because faker >= 0.9.1, < 1.1.0 depends on i18n ~> 0.4
and Gemfile depends on faker = 1.0,
i18n ~> 0.4 is required.
So, because Gemfile depends on i18n = 1.0,
version solving has failed

bundle iで、依存gemもインストールされる
確かにbundle infoで見れるしな。
bundle info i18n
* i18n (0.9.0)
Summary: New wave Internationalization support for Ruby
Homepage: http://github.com/svenfuchs/i18n
Path: /Users/yuuki_haga/.rbenv/versions/3.3.1/lib/ruby/gems/3.3.0/gems/i18n-0.9.0
Reverse Dependencies:
faker (1.0.0) depends on i18n (~> 0.4)

bundle execを使うと、Gemfile.lockで指定されたバージョンのgemで実行できる。

bundle updateは依存関係を越えない程度でgemをupdateするのか。
bundle updateをgem指定しないで打つと全部のgemをupdateして依存関係とか考えないでupdateしちゃうから、そこは注意。
bundle update i18n
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Resolving dependencies...
Using i18n 0.9.5 (was 0.9.0)
Bundle updated!
bundle update faker
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Resolving dependencies...
Bundler attempted to update faker but its version stayed the same
Bundle updated!
bundle update i18n
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Resolving dependencies...
Bundler attempted to update i18n but its version stayed the same
Bundle updated!

faker、バージョン固定でやってたけど、~>にしてbundle iしたが、バージョン更新されてなかったな。
# frozen_string_literal: true
source "https://rubygems.org"
ruby '3.3.1'
gem 'nokogiri'
gem 'faker', "~> 1.0"
bundle i
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Bundle complete! 2 Gemfile dependencies, 6 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
GEM
remote: https://rubygems.org/
specs:
concurrent-ruby (1.3.5)
faker (1.0.0)
i18n (~> 0.4)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
nokogiri (1.18.9-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-musl)
racc (~> 1.4)
racc (1.8.1)
PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
faker (~> 1.0)
nokogiri
RUBY VERSION
ruby 3.3.1p55
BUNDLED WITH
2.5.20

しかし、ローカルマシンにすでに同じgemがインストールされていて、そのバージョンが他のgemとの依存関係的にも問題がない場合は、インストール済みのgemがそのまま使われるため、最新バージョンにならないことがあります。
これか。ローカルマシンにすでにgemがインストールされてて依存関係も問題なかったから最新バージョンにならなかったのか。

bundle updateしたらfakerが1.0が1.9とかになるはず。

bundle update faker
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Resolving dependencies...
Using i18n 1.14.7 (was 0.9.5)
Using faker 1.9.6 (was 1.0.0)
Bundle updated!
やっぱバージョン上がってた。依存gemのi18nもバージョン上がってるな。
GEM
remote: https://rubygems.org/
specs:
concurrent-ruby (1.3.5)
faker (1.9.6)
i18n (>= 0.7)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
nokogiri (1.18.9-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-musl)
racc (~> 1.4)
racc (1.8.1)
PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
faker (~> 1.0)
nokogiri
RUBY VERSION
ruby 3.3.1p55
BUNDLED WITH
2.5.20

fakerを1.0に戻して、もういちどGemfileで ~> fakerにして、i18nを0.4固定にしたらどうなるか

GEM
remote: https://rubygems.org/
specs:
concurrent-ruby (1.3.5)
faker (1.0.0)
i18n (~> 0.4)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
nokogiri (1.18.9-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-musl)
racc (~> 1.4)
racc (1.8.1)
PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
faker (= 1.0)
nokogiri
RUBY VERSION
ruby 3.3.1p55
BUNDLED WITH
2.5.20
↓
# frozen_string_literal: true
source "https://rubygems.org"
ruby '3.3.1'
gem 'nokogiri'
gem 'faker', "~> 1.0"
gem 'i18n', '0.4'
↓
bundle update faker
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Resolving dependencies...
Fetching i18n 0.4.0 (was 0.9.5)
Installing i18n 0.4.0 (was 0.9.5)
Fetching faker 1.0.1 (was 1.0.0)
Installing faker 1.0.1 (was 1.0.0)
WARN: Unresolved or ambiguous specs during Gem::Specification.reset:
stringio (>= 0)
Available/installed versions of this gem:
- 3.1.2
- 3.1.1
- 3.1.0
WARN: Clearing out unresolved specs. Try 'gem cleanup <gem>'
Please report a bug if this causes problems.
Bundle updated!
↓
GEM
remote: https://rubygems.org/
specs:
faker (1.0.1)
i18n (~> 0.4)
i18n (0.4.0)
nokogiri (1.18.9-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-musl)
racc (~> 1.4)
racc (1.8.1)
PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
faker (~> 1.0)
i18n (= 0.4)
nokogiri
RUBY VERSION
ruby 3.3.1p55
BUNDLED WITH
2.5.20

bundle update fakerを実行して
依存gemのバージョン制約は守りつつ、上げられる最大バージョンまでfakerバージョンを上げたか。

bundle updateでもrubygemsにリクエストしてるな。

Gemfileではなるべくバージョンを指定しない
Gemfile内では以下のようにしてバージョンを指定することができます。
しかし、gemはなるべく最新のものを使った方がいいです。
上の例であれば、kaminari 1.3.0や2.0.0がリリースされてもそのままではアップデートできません。
「原則として常に最新のgemを使う」という運用にするのであれば、バージョンは固定しない方が手軽にgemをバージョンアップできます。
バージョンを指定すると、bundle updateでそのバージョン内のgemしかインストールできないから、そのバージョン内より上のバージョンの最新版gemがインストールできんのか。
なので依存関係の都合でバージョン上げるとアプリケーション動かなくなるから仕方なくバージョン指定しているとか、特別な理由がない限り、バージョンは指定しない方がよさそう。

bundlerのよくわかってないところ理解したのでクローズ