背景
ruby経験0だけどbundlerとか打って環境構築した気になってるの良くない気がしたので調べてまとめてみた記事。gemってなんやねんって状態だけど雰囲気で実行しているマンです。
gemってなんだ
Rubyのライブラリのこと
Ruby のライブラリは主に RubyGems.org に gem として置かれている。cpanとかpipとかその手のイメージで良さそう。gem search -r
とかでライブラリを探したりすることもできる。Rubyのパッケージとしてのgemとパッケージ管理システムとしてのgemがあるらしくその辺はコンテキストから察するしかないみたい。
ちなみにRubyGemsを使ってgemを管理する機会は少なく、「bundler」というパッケージ管理ツールを使うのが主流らしい。perlでいうcpan使わないでcartonとかcpanm使うとかそのイメージでしょうか。
Gemfileって?
Bundler用の設定ファイル。BundlerはGemfileの記述にしたがって、gemの依存関係を示したGemfile.lockを生成する。これだけでも他の言語にもある仕組みだしなんとなく分かるけど細かく追ってみる。ちなみにbundler自体もgemの一種らしい。(gem install bundlerとかしないと使えない)
bundlerって?
『bundler』は依存関係にあるgemの依存関係やバージョンを管理してくれるgem。依存関係にあるgemもあわせてインストールする必要があったりする場合によしなにやってくれるやつ。
Usage
bundler --help Bundler commands: bundler add GEM VERSION # Add gem to Gemfile and run bundle install bundler binstubs GEM [OPTIONS] # Install the binstubs of the listed gem bundler check [OPTIONS] # Checks if the dependencies listed in Gemfile are satisfied by currently installed gems bundler config NAME [VALUE] # Retrieve or set a configuration value bundler console [GROUP] # Opens an IRB session with the bundle pre-loaded bundler doctor [OPTIONS] # Checks the bundle for common problems bundler env # Print information about the environment Bundler is running under bundler exec [OPTIONS] # Run the command in context of the bundle bundler gem NAME [OPTIONS] # Creates a skeleton for creating a rubygem bundler help [COMMAND] # Describe available commands or one specific command bundler info GEM [OPTIONS] # Show information for the given gem bundler init [OPTIONS] # Generates a Gemfile into the current working directory bundler install [OPTIONS] # Install the current environment to the system bundler issue # Learn how to report an issue in Bundler bundler licenses # Prints the license of all gems in the bundle bundler lock # Creates a lockfile without installing bundler open GEM # Opens the source directory of the given bundled gem bundler outdated GEM [OPTIONS] # List installed gems with newer versions available bundler package [OPTIONS] # Locks and then caches all of the gems into vendor/cache bundler platform [OPTIONS] # Displays platform compatibility information bundler plugin # Manage the bundler plugins bundler plugin help [COMMAND] # Describe subcommands or one specific subcommand bundler plugin install PLUGINS # Install the plugin from the source bundler pristine [GEMS...] # Restores installed gems to pristine condition bundler remove [GEM [GEM ...]] # Removes gems from the Gemfile bundler show GEM [OPTIONS] # Shows all gems that are part of the bundle, or the path to a given gem bundler update [OPTIONS] # Update the current environment bundler version # Prints the bundler's version information Options: [--no-color] # Disable colorization in output -r, [--retry=NUM] # Specify the number of times you wish to attempt network commands -V, [--verbose], [--no-verbose] # Enable verbose output mode
checkでGemfile内の依存性を現在インストールされているGemが満たしているか確認したり、
Gemfile入門
バージョン管理の基本
バージョン管理 Bundlerはただのgemインストーラではなくバージョン管理ツール*5なので、このgemコマンドは第2引数にバージョンを取れる。 gem "rails" # 最新版を入れる gem "rails", "3.0.0" # 3.0.0で固定 gem "rails", ">=3.0" # 3.0以降のバージョンに制限 gem "rails", "~>1.1" # 3.0以降4.0以前のバージョンに制限
他言語にないようなやつだと以下みたいな書き方。「3.5.2 以上,3.6.0 未満」という意味の指定になるらしい。MINORバージョンまで指定しているときは同じMAJORバージョンの中で最新の物を扱うのは確かに便利。
gem "hoge", "~> 3.5.2"
特定ブランチを使いたいとか,ローカルでちょっと変更して試したいときのGemfileの変更方法を以下に記載。
source
下記のように、:sourceオプションを利用してgemを検索してくるサイトを指定することもできる。
gem "some_internal_gem", :source => "https://gems.example.com"
git
github上のものを使う場合は以下。sshとかで認証をしておけばprivateリポジトリとかGHE上のものとかもこうやって書ける。
git "https://github.com/rails/rails.git" do gem "test1" gem "test2" end
group
groupコマンドではgemをインストールする環境を指定できる。
group :development, :test do gem "rspec-rails" gem "cucumber" end
bundle install --without test
みたいに実行することでproductionなら使わないgemを除いて環境セットアップとかが可能になる。
ローカルにあるgem
閉じたネットワークなのか古のモジュールを自分で管理してるのかみたいなケースで使えそう。
gem 'hogeee', :path => '/Users/hogeee'
Gemfile.lockとは
Gemfile.lockには依存関係にあるgemも含め、bundlerによってインストールされた全てのgemとそのgemのバージョンが記載される。lockファイルと現環境に差分があるみたいなのはどの言語でもあるあるな話なんですかね記事がありました。
--path vendor/bundleを付ける必要性は本当にあるのかの話
これ読んで面白いなーと思った。pythonならvenvは必須で使っていたけど言われてみると確かにという思いが出てきた。システムにコマンドを提供する系のgemを入れなきゃいけないケースとか以外はなるべく付けない方が良さそうなんだろうな。