Rake入門:Rakefileの書き方からRailsでのカスタムタスク作成まで

スポンサーリンク

Rake入門:Rakefileの書き方からRailsでのカスタムタスク作成まで

はじめに

Rakeはタスクを定義して実行するためのRuby製ツールです。rake db:migraterake 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時の自動実行まで」を参照してください。