rails new するとできる bin ディレクトリの役割と、それぞれの内容についてメモ程度にまとめてみました。
Rails の各種コマンドは bin ディレクトリから
rails new APP
すると出来上がる rails プロジェクトでは、ルートディレクトリに bin
ディレクトリが生成されます。
この中には、サーバを起動したり、テストをしたり、アプリケションを管理する様々なスクリプトファイルが置かれます。
$ ls bin
bundle rails rake setup spring update yarn
この文書では、これらのコマンドそれぞれの役割についてまとめてみたいと思います。
そもそも論の binstub
詳しくは rbenv/rbenv/wiki/Understanding-binstubs を見るのが良いでしょう。
binstub は実行可能なラッパースクリプトです。
複数の Rails プロジェクトをメンテナンスしていたり、その他の ruby プロジェクトを行き来していると例えば、それぞれのプロジェクトで rspec
のバージョンが違ったりして、システムにインストールしたrspec
をそのまま使うのが辛いシチュなどがざらにあります。
そこで登場するのが binstub で、要するに、プロジェクトごとに bin/rspec
みたいなラッパースクリプトを用意してラッパーの中で必要な環境を整えてから、rspec
を起動させようとします。
例えば、 Rails 4.2.8 で作ったプロジェクト foo と Rails 5.1.4 で作ったプロジェクト bar がある時、binstub 経由でそれぞれのバージョンを確認すると、次のようにいい感じにバージョンが表示されるのがわかるかと思います。
$ cd path/to/foo
$ ./bin/rails --version
Rails 4.2.8
$ cd path/to/bar
$ ./bin/rails --version
Rails 5.1.4
そんなわけで、 Rails プロジェクトでは binstub がデフォルトで作成されています。
bundle, rails, rake, spring, yarn
説明不要ですね。
それぞれ
の binstub です。
setup
Rails が用意する、「アプリケーションを初期化するスクリプト」です。
プルリクエスト を見れば意図は明白ですが、ある Rails プロジェクトをコピー・クローン・チェックアウトなどした後のセットアップをこのスクリプトに納めさせしむものです。
ですので、このスクリプトをきちんと書くことで、例えばこの2コマンドで rails プロジェクトの初期化ができるようになります。
$ git clone path/to/your/rails/project
$ cd project
$ bin/setup
# bundle install
# rake db:setup
# などが行われます。
実際のところは、デフォルトで最小限のセットアップ構成が書かれているだけです。
短いので以下にファイルを転載します。ご覧の通り、本当に最小限のスクリプトです。このスクリプトをメンテナンスすることで、プロジェクトに新しいメンバーがアサインされた際などの手間が省けます。
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
include FileUtils
# アプリケーションのルートパス
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
# このスクリプトはアプリケーションのセットアップの第一ステップとなります。
# ですので、必要なステップをこのファイルに追加していってください
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
# JavaScript の依存ライブラリを yarn を使ってインストールします
# system('bin/yarn')
# 最初に設定ファイルをコピーさせる必要あるなら、このコメントアウトを外します
# puts "\n== Copying sample files =="
# unless File.exist?('config/database.yml')
# cp 'config/database.yml.sample', 'config/database.yml'
# end
puts "\n== Preparing database =="
system! 'bin/rails db:setup'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server =="
system! 'bin/rails restart'
end
update
Rails が用意する、「アプリケーションを更新するスクリプト」です。
プルリクエスト を見れば意図は明白ですが、ある Rails プロジェクトを更新、例えば git pull origin
した後などに、変更されたすべてを更新させるスクリプトです。
ですので、このスクリプトをきちんと書くことで、例えばこの2コマンドで rails プロジェクトの更新ができるようになります。
$ git pull origin master
$ bin/update
# gem の更新
# rake db:migrate
# ログの更新
# rails のリスタート
# ...などが行われます。
このスクリプトも setup と同じく大変短いスクリプトです。面倒臭がらずにきちんとメンテナンスすることで、チーム開発に 大変役立ちます ので、ぜひ運用してください。
Scripts To Rule Them All
セットアップ方法や更新方法を1スクリプトにまとめようというのは、様々なプロジェクトでよく見られる光景です。しかしながら、どのようなスクリプトを用意すれば良いかについては、往々にして必要になってから考案されます。
GitHub 社が社内で用意している、プロジェクト管理用のスクリプトと運用方法についてまとめたのがScripts to Rule Them All | GitHub Engineering です。
GitHub社でも社内で様々なプロジェクトを開発しているようで、それらのプロジェクトを git clone
してから開発環境で立ち上げ、そして各種作業をするためのコマンドを統一することでエンジニアの負荷を下げているようです。
大抵のプロジェクトでは、エンジニアは次の4つのタスクを必ず行います。
- 開発環境の立ち上げ
- テストの実行
- CI の実行
- アプリの起動
GitHub社ではこれらの作業を標準化するために、すべてのプロジェクトで同じコマンドを用意しています。これが「Script to Rule Them All」とのことです。
彼らは具体的には7つのスクリプトを用いています。
-
script/bootstrap
: すべての依存ライブラリをインストール・更新する -
script/setup
: プロジェクトをセットアップする(クローン直後に使用する) -
script/update
: プロジェクトを更新する -
script/server
: アプリをスタートする -
script/test
: すべてのテストを実行する -
script/cibuild
: CI サーバが実行し、すべてのテストを実行する -
script/console
: コンソールを開く
このようなスクリプトをきちんと用意すれば、初めてアサインされたプロジェクトでもすぐにアプリを立ち上げられ、テストを動かせ、そしてコンソールでデータの操作ができます。
GitHub 社はこのパターンについての指針などをまとめたリポジトリをgithub/scripts-to-rule-them-allとして公開していますので、是非ご覧になってください。
bin/update を追加したプルリクエスト でも、github/scripts-to-rule-them-allについての言及があります。
なんで script ディレクトリじゃないの?
script/
が廃止され、bin/
が導入されたのは Rails 4.0 からです。
実際に導入された プルリクエストを見るとわかりますが、 binstub に合わせた為です。
direnv 使って楽するといいと思うよ
binstub のお供に最適なのが direnv です。
このツールはとても単純で、「特定のディレクトリに cd すると、設定された profile を読み込む」というツールなのですが、このツールを使って、 PATH に RAILS_ROOT/bin
を追加することで、例えば、 rails
コマンドや bundle
コマンドを自然に使えるようになります。