Rakeのススメ

この記事は、 株式会社ケーシーエスキャロット アドベントカレンダー の11日目の記事です。

いい機会なので、以前 Rake タスク作成を行ったときに、試行錯誤の結果得たものをまとめてみようと思います。 少しでも 参考になれば幸いです。

Rake タスクとは

Rake タスクとは、Ruby で書く Make のようなものです。 Make だと Makefile に処理を定義していきますが、 Rake も同様に Rakefile というファイルに処理を定義します。

例えば、 Rakefile に以下のように記載すると、 sample と言うタスクが作成されます。 作成したタスクは rake -T を実行すると一覧表示されます。

desc 'sample task'
task :sample do
  puts "do sample"
end
$ rake -T
rake sample  # sample task

実行する場合は rake タスク名 で実行します。

$ rake sample
do sample

namespace の活用

タスクは namespace をつけることもできるので、ある程度タスクのまとまりが大きくなる場合などは namespace でまとめておくと良いと思います。

require 'fileutils'

namespace :workdir do
  desc 'ワークディレクトリの作成'
  task :make do
    if File.exist? 'work'
      puts "workdir already exist."
    else
      FileUtils.mkdir 'work'
    end
  end
end
$ rake -T
rake workdir:make  # ワークディレクトリの作成

引数の使い方

タスクに引数を渡すには、タスクごとに受け渡す方法と、環境変数として受け渡す方法があり、 それぞれ実装方法、実行方法が異なります。

desk '引数をタスクで定義する方法'
task :sample_1, [:str] do |task, args|
  puts "input str => #{args[:str]}"
end

desc '引数を環境変数で定義する方法'
task :sample_2 do
  puts "input str => #{ENV['INPUT_STR']}"
end
$ rake -T
rake sample_1[str]  # 引数をタスクで定義する方法
rake sample_2       # 引数を環境変数で定義する方法

$ rake sample_1['---test---']
input str => ---test---

$ rake sample_2 INPUT_STR='---test---'
input str => ---test---

タスクごとに受け渡す場合、受け取った引数は、ブロックの第2引数(上の例だと args )から取得することができます。 タスク一覧で、引数の情報を確認することができるのが便利です。

環境変数として受け渡す方法は、引数の情報を環境変数 ENV として定義します。受け渡すと言うよりは、設定すると言う感覚でしょうか。 どのタスクからでも参照可能なので、例えば一回で複数のタスクを実行させる場合には都合がいいです。

こちらは、タスクごとに定義する方法と違い、タスク一覧では引数の情報を確認することができませんので、説明文などに記載しておくと親切です。

個人的には、環境などタスク全体に関わる引数に関しては、環境変数として定義させ、それ以外はタスクごとに定義させると言うように使い分けしています。(できるだけ)

invoke と execute

他のタスクを呼び出す場合は Rake::Task#invokeRake::Task#execute は他のタスクを呼び出すときに使います。 使い方は以下になります。

desc 'invoke を使ってタスク呼び出し'
task :sample_invoke, [:str] do |task, args|
  Rake::Task['output'].invoke(args[:str])
end

desc 'execute を使ってタスク呼び出し'
task :sample_execute, [:str] do |task, args|
  Rake::Task['output'].execute(args)
end

# desc のないタスクはタスク一覧に表示されない
task :output, [:str] do |task, args|
  puts "input => #{args[:str]}"
end
$ rake sample_execute['aaa']
input => aaa

$ rake sample_execute['aaa']
input => aaa

invokeexecute も、実行時に引数を渡すことができますが、渡し方がそれぞれ異なります。 引数以外にも、以下にまとめたように挙動が異なるため、使用するケースによってどちらを使うか判断する必要があります。

invoke execute
引数 文字列 or 配列形式で渡して、渡した順番で各引数の項目と値を解釈する Rake::TaskArguments をそのまま渡す or ハッシュ形式で引数の項目と値を明示的に指定する
実行回数 1回のみ実行可能 何回でも実行可能
依存タスク 実行する 実行しない

依存タスク

依存タスクは、そのタスク実行時に必ず実行するタスクの定義です。 他のタスクを呼び出す場合はタスク実行時の好きなタイミングで呼び出せますが、依存タスクは必ずタスク実行前に呼び出されますので、タスクの前準備の処理を定義するのに向いています。

依存タスクは以下のように定義します。

desc '依存タスクサンプル'
task :sample_izon, [:str] => :header do |task, args|
  puts "input => #{args[:str]}"
end

# 依存タスク
task :header do
  puts "##########"
end
$ rake sample_izon['aaa']
##########
input => aaa

Rails で Rake タスク作ったことある人は、依存タスクの定義、見たことあるかもしれません。 そう、DB操作系のタスクを作る場合に定義する必要のある environment です。

task :hoge => :environment do
・・・
end

実はこの environment も、DB接続の準備をするタスクで、依存タスクとして定義させることで、DB操作が可能になるというわけです。

まとめ

ざざざっとまとめてみました。 Rake タスク便利なので、皆さん作って、 Ruby ライフをエンジョイしてください。