Rake入門:Rakefileの書き方からRailsでのカスタムタスク作成まで
はじめに
Rakeはタスクを定義して実行するためのRuby製ツールです。rake db:migrate や rake routes のようにRailsで日常的に使いますが、自分でタスクを定義してスクリプトを整理することもできます。
この記事ではRakeの基本的な使い方からカスタムタスクの作成まで解説します。
インストール
Railsプロジェクトでは依存関係として自動的に含まれます。単独で使う場合はgemでインストールします。
gem install rake
Gemfileで管理する場合:
gem 'rake'
Rakefileの基本
プロジェクトルートに Rakefile を置いてタスクを定義します。
タスクの定義
# Rakefile desc "挨拶する" task :hello do puts "Hello, World!" end
実行:
rake hello # Hello, World!
desc はタスクの説明文です。rake -T で一覧表示したときに使われます。
タスクの一覧表示
rake -T
rake hello # 挨拶する
desc のないタスクは rake -T に表示されません。rake -T -A ですべて表示できます。
依存タスク
タスクに依存関係を設定すると、実行前に指定したタスクが先に実行されます。
task :setup do puts "セットアップ中..." end task :build => :setup do puts "ビルド中..." end task :deploy => :build do puts "デプロイ中..." end
rake deploy # セットアップ中... # ビルド中... # デプロイ中...
複数の依存タスクを指定する場合は配列で書きます。
task :deploy => [:build, :test] do puts "デプロイ中..." end
namespaceでタスクをグループ化する
関連するタスクを名前空間でまとめられます。
namespace :db do desc "データベースを初期化する" task :reset do puts "DB をリセット中..." end desc "シードデータを投入する" task :seed do puts "シードデータを投入中..." end end
rake db:reset rake db:seed
namespace はネストできます。
namespace :admin do namespace :db do task :backup do puts "管理者用DBバックアップ..." end end end
rake admin:db:backup
デフォルトタスク
default タスクを定義すると rake だけで実行できます。
task :default => [:test, :lint] task :test do puts "テスト実行中..." end task :lint do puts "Lint実行中..." end
rake # テスト実行中... # Lint実行中...
引数を受け取るタスク
タスクに引数を渡すことができます。
desc "ユーザーを作成する" task :create_user, [:name, :email] do |task, args| puts "ユーザー作成: #{args[:name]} (#{args[:email]})" end
rake create_user[田中太郎,tanaka@example.com] # ユーザー作成: 田中太郎 (tanaka@example.com)
Railsでよく使うrakeタスク
Railsには多数のタスクが最初から定義されています。
# データベース関連 rake db:create # DBを作成する rake db:drop # DBを削除する rake db:migrate # マイグレーションを実行する rake db:rollback # 直前のマイグレーションを戻す rake db:seed # db/seeds.rb を実行する rake db:reset # DBを再作成してシードを実行する rake db:schema:load # schema.rb からDBを構築する # ルーティング確認 rake routes # ルーティング一覧を表示する # テスト rake test # テストを実行する rake spec # RSpecを実行する(rspec-rails導入時) # アセット rake assets:precompile # アセットをプリコンパイルする rake assets:clean # プリコンパイル済みアセットを削除する
Railsでカスタムタスクを作成する
Railsでは lib/tasks/ ディレクトリにファイルを置くとタスクとして認識されます。
# ジェネレーターで作成する場合 rails generate task maintenance cleanup
手動で作成する場合:
# lib/tasks/maintenance.rake namespace :maintenance do desc "期限切れのセッションを削除する" task cleanup: :environment do deleted = Session.where("expires_at < ?", Time.current).delete_all puts "#{deleted}件のセッションを削除しました" end desc "古いログを圧縮する" task compress_logs: :environment do Dir.glob(Rails.root.join("log/*.log")).each do |file| system("gzip #{file}") if File.size(file) > 100.megabytes end puts "ログを圧縮しました" end end
:environment を依存タスクに指定することでRailsの環境(モデルやDB接続など)が読み込まれます。
bundle exec rake maintenance:cleanup bundle exec rake maintenance:compress_logs
複数のタスクをまとめて実行する
# lib/tasks/maintenance.rake namespace :maintenance do desc "すべてのメンテナンスタスクを実行する" task all: [:cleanup, :compress_logs] task cleanup: :environment do # ... end task compress_logs: :environment do # ... end end
bundle exec rake maintenance:all
Rakefileでよく使うパターン
環境変数を受け取る
task :import do file = ENV['FILE'] or raise "FILE を指定してください" puts "#{file} をインポート中..." end
rake import FILE=data.csv
エラーハンドリング
task :deploy do sh "rsync -av dist/ user@example.com:/var/www/" rescue => e puts "デプロイに失敗しました: #{e.message}" exit 1 end
sh メソッドはシェルコマンドを実行し、失敗した場合は例外を発生させます。
まとめ
Rakefileにタスクを定義してrake <タスク名>で実行できるnamespaceで関連タスクをグループ化できる- タスク間の依存関係は
task :a => :bで定義する - Railsでは
lib/tasks/*.rakeにカスタムタスクを置き、:environmentでRails環境を読み込む rake -Tでタスク一覧を確認できる
gemのバージョン管理には「Bundler入門:Gemfile・bundle install・bundle execの使い方まとめ」を参照してください。
bundle / rake / rails コマンドの早見表は「Rails開発コマンド早見表:bundle / rake / rails の使い分けまとめ」を参照してください。
コードスタイルの自動チェックは「RuboCop導入入門:インストールから設定・git commit時の自動実行まで」を参照してください。