Rakeとdry run
Rakeに-n
オプションを指定するとdry runできる。ただ、dry runと言ってもタスクの実行予定が表示されるだけなので、いまいち使いどころがない。
$ cat Rakefile
task :example do
sh 'ls', '-ld', '1'
end
$ rake -n example
** Invoke example (first_time)
** Execute (dry run) example
ところで、Rakeが提供するsh
メソッドや、Rakeが拡張しているmkdir
などのFileUtils由来のメソッドは、nowrite
の値により動作を変える。
とはいうものの、nowrite
の値はrake
コマンドの-n
オプションに従って設定される。上述の通り-n
オプションを指定するとタスクが実行されなくなるため、タスク定義の上ではnowrite
そのものにはあまり意味がない。
$ cat Rakefile
task :example do
p nowrite ? 'nowrite' : 'write'
end
$ rake
"write"
$ rake -n
** Invoke example (first_time)
** Execute (dry run) example
ただしnowrite
メソッドに引数としてtrue
またはfalse
を指定すると、nowrite
の値を変更できる。また、その際にブロックが与えられると、そのブロック内でのみnowrite
の値を変えることができる。
たとえば以下の内容のRakefileを作る。
task :example do
sh 'ls', '-ld', '1'
nowrite(true) do
sh 'ls', '-ld', '2'
end
sh 'ls', '-ld', '3'
end
rake
コマンドを実行すると、次のようにls -ld 2
だけが実行されないのが分かる。
$ rake example -f r
ls -ld 1
-rw-r--r-- 1 akira 501 0 1 14 13:44 1
ls -ld 2
ls -ld 3
-rw-r--r-- 1 akira 501 0 1 14 13:44 3
これを利用して、次のようなタスク定義をすると、Rakeによるコマンド実行内容を知ることが可能となる。
task :example do
sh 'ls', '-ld', '1'
end
task :dry_run do
nowrite(true) { Rake::Task[:example].invoke }
end
タスクdry_run
はnowrite(true)
の中でタスクexample
を実行しているので、タスクexample
内での実行内容を表示するだけで終了する。
$ rake dry_run
ls -ld 1
$ rake example
ls -ld 1
-rw-r--r-- 1 akira 501 0 1 14 13:44 1
同じようなことを他のタスクでも行いたければ、以下のようなdry_run
メソッドを用意しておくとよいかもしれない。
def dry_run(task = nil)
verbose(true) do
nowrite(true) do
return yield unless task
Rake::Task[task.scope.path].invoke
end
end
end
namespace :example do
task :dry_run do |t|
dry_run(t)
end
end
dry_run
メソッドは、与えられたタスクの名前からネームスペース(scope)を取得し、その名前と同じ名前のタスクをnowrite(true)
の中で実行する。
verbose
はnowrite
とよくにたメソッドで、rake
コマンドの-v
オプションまたは-q
オプションに従った値を返す。nowrite
と同じように引数にtrue
またはfalse
をとり、その値を変更できる。ここでは、dry runのためのタスク実行で、実行内容を常に表示させるために使っている。
なお、verbose
については少し注意を要する。rake
コマンドに-v
オプションも-q
オプションも指定しないとき、verbose
の値はObjectオブジェクトになる。このため、以下のコードは予想と違った結果になるかもしれない。
task :verbose do
puts 'verbose' if verbose
end
実行結果は次の通りとなる。
$ rake verbose -v
verbose
$ rake verbose -q
$ rake verbose
verbose
verbose
のデフォルトの値が、なぜObjectオブジェクトなのかは分からないが、-v
オプションが指定されたときだけメッセージを表示する、といったときには次のようにする。
task :verbose do
puts 'verbose' if verbose == true
end