rbenvを流し読み
注)誤ったことを書いているかもしれません。
動機
rubyで仕事してると職場でも頻繁に使うものなので、中身を理解したくなった。
version
1.1.1
ドキュメントを読んでみる
冒頭の重要そうなところをピックアップしてみます
No headaches running apps on different versions of Ruby. Just Works™ from the command line and with app servers like Pow. Override the Ruby version anytime: just set an environment variable.
異なるruby versionで動くアプリに頭痛で悩まされることがない。Powのようにコマンドラインで動かすだけ。いつでもRuby versionを上書きできる。環境変数でsetするだけだ。
Rock-solid in production. Your application's executables are its interface with ops. With rbenv and Bundler binstubs you'll never again need to cd in a cron job or Chef recipe to ensure you've selected the right runtime. The Ruby version dependency lives in one place—your app—so upgrades and rollbacks are atomic, even when you switch versions.
productionで頑丈だ。rbenvとBundler binstubsにより、cron jobの中でcdしたり、chep recipeで正しいruntimeを選択していることを保証する必要はない。Ruby versionの依存はただ一箇所、あなたのアプリに存在しているので、upgradesやrollbackはatomicはversionを切り替えるときでもatomicに行える。
One thing well. rbenv is concerned solely with switching Ruby versions. It's simple and predictable. A rich plugin ecosystem lets you tailor it to suit your needs. Compile your own Ruby versions, or use the ruby-build plugin to automate the process. Specify per-application environment variables with rbenv-vars. See more plugins on the wiki.
ecosystemがしっかりしている、ということが書いてある。
ざっくり眺める
. ├── bin ├── completions ├── libexec ├── rbenv.d │ └── exec │ └── gem-rehash ├── src └── test └── libexec
bin/
メインのロジックはここに入ってるようです。libexec
rbenv localなどに対応するファイル群。
bin/rbenv
command_path="$(command -v "rbenv-$command" || true)" if [ -z "$command_path" ]; then if [ "$command" == "shell" ]; then abort "shell integration not enabled. Run \`rbenv init' for instructions." else abort "no such command \`$command'" fi fi
rbenv-local, rbenv-init などの呼び出しはここで行っているようです。メインのロジックがここに入っているようですね。
rbenv init
を実行したときに内部で起きていることを理解すれば、大体あとはわかる気がしたので、そのあたりを中心に追ってみると良さそうです。
いきなり動作を把握するのは難しそうなので、rbenv-initのテストを読みにいきます。
@test "adds shims to PATH" { export PATH="${BATS_TEST_DIRNAME}/../libexec:/usr/bin:/bin:/usr/local/bin" run rbenv-init - bash assert_success assert_line 0 'export PATH="'${RBENV_ROOT}'/shims:${PATH}"' }
rbenv init
でshimsをPATHに追加します。
@test "outputs sh-compatible syntax" { run rbenv-init - bash assert_success assert_line ' case "$command" in' run rbenv-init - zsh assert_success assert_line ' case "$command" in' }
rbenv init
でshellに互換性のある文字列を出力します。
@test "creates shims and versions directories" { assert [ ! -d "${RBENV_ROOT}/shims" ] assert [ ! -d "${RBENV_ROOT}/versions" ] run rbenv-init - assert_success assert [ -d "${RBENV_ROOT}/shims" ] assert [ -d "${RBENV_ROOT}/versions" ] }
rbenv init
でshimsとversionsディレクトリを作成します。
rbenv-init
{ echo "# Load rbenv automatically by appending" echo "# the following to ${profile}:" echo case "$shell" in fish ) echo 'status --is-interactive; and source (rbenv init -|psub)' ;; * ) echo 'eval "$(rbenv init -)"' ;; esac echo } >&2
表示される指示をみると、.bashrc
, .bash_profile
なりに eval "$(rbenv init -)"
を書いておけ、とあります。
つまり、rbenv init -
の結果が文字列(シェルスクリプト)として返されるので、これをevalすることによって、PATHを通したりしてるみたいですね。
参考
rbenv + ruby-build はどうやって動いているのか - takatoshiono's blog
次に読みたい
Ruby
wicked_pdf, request_store, bullet, wkhtmltopdf, sidekiq, active_support, webrick, draper, jbuilder, rails/active_job, rails/spring, capistrano, omniauth, committee etc..
iOS
RxSwift, AFNetworkinig, SDWebImage, Alamofire, MBProgressHUD, Masony, SwiftyJSON, MJRefresh, CocoaLumberjack, Realm, SsnapKit, Kingfisher