Closed28

bundler 触ってみる

ハガユウキハガユウキ

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

https://bundler.io/guides/gemfile.html

ハガユウキハガユウキ

ほとんどのバージョン指定子(例:≥ 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 と一緒に使われる、アプリケーションの依存関係を管理するための一般的なツールです。

https://www.ruby-lang.org/ja/libraries/

ハガユウキハガユウキ

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を指定するための記述だったのか。知らんかった。

https://imaharu-blog.hatenadiary.jp/entry/2019/10/13/013046

https://qiita.com/kymmt90/items/0ab4027fb5c42857d759

ハガユウキハガユウキ

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

https://bundler.io/man/bundle-info.1.html

ハガユウキハガユウキ

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もインストールされる
https://techracho.bpsinc.jp/hachi8833/2022_11_10/121901

確かに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 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がインストールされてて依存関係も問題なかったから最新バージョンにならなかったのか。

https://qiita.com/jnchito/items/823323e276d1a90ac4a1#bundle-installでは最新バージョンがインストールされないこともある

ハガユウキハガユウキ
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バージョンを上げたか。

ハガユウキハガユウキ

Gemfileではなるべくバージョンを指定しない
Gemfile内では以下のようにしてバージョンを指定することができます。
しかし、gemはなるべく最新のものを使った方がいいです。
上の例であれば、kaminari 1.3.0や2.0.0がリリースされてもそのままではアップデートできません。
「原則として常に最新のgemを使う」という運用にするのであれば、バージョンは固定しない方が手軽にgemをバージョンアップできます。

バージョンを指定すると、bundle updateでそのバージョン内のgemしかインストールできないから、そのバージョン内より上のバージョンの最新版gemがインストールできんのか。
なので依存関係の都合でバージョン上げるとアプリケーション動かなくなるから仕方なくバージョン指定しているとか、特別な理由がない限り、バージョンは指定しない方がよさそう。

https://qiita.com/jnchito/items/823323e276d1a90ac4a1#gemfileではなるべくバージョンを指定しない

このスクラップは2日前にクローズされました