はじめに
bin/seupファイル理解のための備忘録です。
そもそもbin/ディレクトリとは
Railsのアプリ開発時に使用する、実行コマンドを格納しているディレクトリのこと。
bin/setup
#!/usr/bin/env ruby
require "fileutils"
# path to your application root.
APP_ROOT = File.expand_path("..", __dir__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
FileUtils.chdir APP_ROOT do
# This script is a way to set up or update your development environment automatically.
# This script is idempotent, so that you can run it at any time and get an expectable outcome.
# Add necessary setup steps to this file.
puts "== Installing dependencies =="
system! "gem install bundler --conservative"
system("bundle check") || system!("bundle install")
# puts "\n== Copying sample files =="
# unless File.exist?("config/database.yml")
# FileUtils.cp "config/database.yml.sample", "config/database.yml"
# end
puts "\n== Preparing database =="
system! "bin/rails db:prepare"
# To avoid error https://github.com/rails/rails/issues/46845
system! "bin/rails db:environment:set RAILS_ENV=test"
puts "\n== Removing old logs and tempfiles =="
system! "bin/rails log:clear tmp:clear"
puts "\n== Restarting application server =="
system! "bin/rails restart"
end
Railsガイドによると、
これはアプリケーションの初期設定時に設定を自動化するためのコードの置き場所となります。
./bin/setup
は実行可能なファイルで、開発に必要な処理をまとめて実行できます。
#!の意味
スクリプトファイルの先頭に、#!
があるとUNIXはその後に続くコマンドを実行する。
#!
は「シェバング」(shebang)と呼ばれ、起動するインタプリタを指定できる。
つまり#!/usr/bin/env ruby
はrubyの形式でファイルを実行するための命令。
require "fileutils"
FileUtilsモジュールを使用するために"fileutils"ライブラリを読み込んでいる。
APP_ROOT = File.expand_path("..", __dir__)
- File.expand_path
「第2引数で指定したディレクトリ」を相対パスの基準にする
__dir__はファイルのディレクトリを指す。
つまりどのディレクトリからこのソースファイルを実行しても、/binの一つ上の階層(=アプリのルートディレクトリ)で実行されるようになる。
def system!(*args)
引数に渡されたコマンドを実行し、コマンドが失敗した場合にはプログラムをエラーメッセージ付きで終了する。
system(*args) || abort("\n== Command #{args} failed ==")
system変数の使い方
system(command, options={}) #commandを文字列で指定する
abortの使い方
abort(message)
FileUtils.chdir APP_ROOT do
- FileUtils.chdir
カレントディレクトリを変更 - FileUtils.chdir APP_ROOT do
カレントディレクトリをアプリのルートパスに変更してブロックを実行する。
ブロックを抜けた後は元のディレクトリに戻る。
system! "gem install bundler --conservative"
例えばgemをインストールする際は依存している他のgemもインストールされたりするが、--conservative
オプションによってコマンドで指定したgemのみを対象にできる。
system("bundle check") || system!("bundle install")
-
system("bundle check")
Gemfile内の依存性を現在インストールされているGemが満たしているか確認する。
参考 - system!("bundle install")
依存性に問題があればgemをインストールする。
unless File.exist?("config/database.yml") ~
config/database.yml
がなければ、
system! "bin/rails db:prepare"
DBが存在しない場合
- DBを作成する
- schema.rbを参考にしてテーブルを作成
-
rails db:seed
を実行する
DBが存在する場合
-
rails db:migrate
を実行する
db:setup
との違い
db:setup
は、DBが元々存在する場合にschema.rbを参考にテーブルを作成し直し、db:seed
を実行する
system! "bin/rails db:environment:set RAILS_ENV=test"
rails db:prepareをすると、テストデータベースにar_internal_metadataテーブルの「key:environment, value:development」を保存する。
つまり、テストDBがdevelopment環境として保存されてしまっているため、rails test
する時などテストDBを使用したい時にエラーが出る。
それを修正するためのコマンド。
- ar_internal_metadata
環境情報を保持するテーブル。自動的に作成される。
Rails5から追加され、DBを誤って削除してしまうことを防止するためのテーブル。
environmentがproductionの時に、以下のタスクを実行すると例外が発生する。
・db:drop
・db:drop:all
・db:purge
・db:purge:all
・db:purge:test
・db:schema:load
タスクを実行したい時
DISABLE_DATABASE_ENVIRONMENT_CHECK=1 rails db:drop
監視する環境を任意に変更したい時
ActiveRecord::Base.protected_environments = %w(production staging)
system! "bin/rails log:clear tmp:clear"
- logディレクトリ以下にあるすべての*.logファイルを0バイトに切り詰める
- tmpディレクトリからキャッシュ、ソケット、スクリーンショットファイルをクリア
system! "bin/rails restart"
- アプリを再起動する
参考サイト
・【Rails】binとは何か
Rails の /bin/setup にある db:prepare はなにをするのか
linux上で動作するスクリプト先頭行に書く「#!…」行の意味は?
Rails5でDBに自動生成されるテーブル、"ar_internal_metadata" とは何なのか
Rails 5に入ったDB破壊系taskの防止処理について
RubyのFile.expand_path('相対パス', FILE)の意味