Rake というものがあります。 Ruby で記述できる make みたいなものだそうで、
task :default => [:test] task :test do ruby "test/unittest.rb" end
といった感じに書けるそうです。
なかなか面白そうだと思ったので、ちょっと触ってみようと思います。
あまり推敲していませんが、doc/rakefile.doc を訳してみたので掲載します。
なお、Rake は MITライセンスです。
まず、Rakefile のための特別なフォーマットは存在しません。 Rakefile は実行可能な Ruby のコードを含んでいます。 Ruby スクリプトとして合法な記述は全て、Rakefile でも許されています。
Rakefile のための特別な文法が存在しないことを理解したので、 Rakefile で使われる規約で、普通の Ruby プログラムではあまり見かけないも のがあります。 Rakefile はタスクやアクションを指定するために作られているので、 使われているイディオムはこの作業をサポートするためにデザインされています。
さて、Rakefile の構成はどうなっているのでしょうか。
タスクは、Rakefile 中での作業の主要な単位です。 タスクは名前(大抵はシンボルか文字列として与えられます)、 必要条件のリスト(シンボルまたは文字列として与えられます)、 アクションのリスト(ブロックとして与えられます)を 持ちます。
タスクは、+task+ メソッドを用いることで宣言されます。 +task+ メソッドは、タスクの名前を一つパラメータとして取ります。
task :name
全ての必要条件は、名前と矢印(=>)に続く [ ] で囲まれたリストによって 与えられます。
task :name => [:prereq1, :prereq2]
<b>注:<b> この文法は少し奇妙に見えるかもしれませんが、Ruby では合法です。 キーが :name で、その値が必要条件のリストであるようなハッシュを生成して います。 これは、次のように書くのと等価です。
hash = Hash.new hash[:name] = [:prereq1, :prereq2] task(hash)
タクションは、+task+ メソッドにブロックを渡すことによって定義されます。 ブロックの中には、任意の Ruby コードを置くことができます。 ブロックでは、ブロック引数を通じてタスクオブジェクトを参照することができ ます。
task :name => [:prereq1, :prereq2] do |t| # actions (may reference t) end
タスクは、複数回定義することができます。 それぞれの指定によって、既存の定義に必要条件とアクションが追加されます。 これによって、ある rakefile でアクションを指定し、 (おそらく別ファイルに生成された)他の rakefile で依存関係を指定すること ができるようになります。
例えば、次の記述は上に出てきた単一のタスク指定と等価です。
task :name task :name => [:prereq1] task :name => [:prereq2] task :name do |t| # actions end
あるタスクは、一つまたは複数のファイルからファイルを生成するために用いら れます。 もし、生成するファイルが既に存在していた場合、このタスクはスキップされます。 ファイルタスクは、ファイルを生成するタスクを指定するために用いられます。
ファイルタスクは、(+task+ メソッドの代わりに) +file+ メソッドによって宣 言されます。 さらに、ファイルタスクに名前を付けるときには大抵の場合、シンボルよりも文 字列が使われます。
次のファイルタスクは、2つのオブジェクトファイル <tt>a.o</tt> と <tt>b.o</tt> が与えられた 実行可能プログラム +prog+ を生成します。 <tt>a.o</tt> および <tt>b.o</tt> を生成するタスクは示されていません。
file "prog" => ["a.o", "b.o"] do |t| sh "cc -o #{t.name} #{t.prerequisites.join(' ')}" end
要求に応じてディレクトリを作成するのが必要であるのは一般的です。 +directory+ メソッドは、ディレクトリを作成する FileTask を作成するための 簡単な方法です。 例えば、次の宣言
directory "testdata/examples/doc"
は、次と等価です。
file "testdata" do |t| mkdir t.name end file "testdata/examples" do |t| mkdir t.name end file "testdata/examples/doc" do |t| mkdir t.name end
+directory+ メソッドには必要条件やアクションを指定できません。 しかし、これらは後から追加することができます。 例えば、次のようにやります。
directory "testdata" file "testdata" => ["otherdata"] file "testdata" do cp Dir["standard_data/*.data"], "testdata" end
ファイルが必要条件として使われ、しかしそのファイルに対する ファイルタスクが存在しない場合、 Rake は Rakefile に記述されているルールを見て タスクを合成しようとします。
"mycode.o" タスクを呼び出そうとしているものの、 このファイルのためのタスクは定義されていないとしましょう。 しかし rakefile には、次のようなルールが記述されているとします。
rule '.o' => ['.c'] do |t| sh "cc #{t.source} -c -o #{t.name}" end
このルールは、".o" で終わる任意のタスクを扱います。 これは、拡張子 ".c" のソースファイルを必要条件を持ちます。 もし Rake が "mycode.c" という名前のファイルを見つけることができた場合、 自動的に "mycode.c" から "mycode.o" をビルドするタスクが生成されます。
ソースファイル "mycode.c" が存在しなければならないことに注意してください。 Rake は(現状では)複数レベルのタスク合成を行おうとしません。
タスクがルールから生成された場合、マッチしたソースファイルに タスクの +source+ 属性が設定されます。 これによって、ソースファイルを参照するアクションを持ったルールを 書くことができます。
任意の正規表現がルールパターンとして使用できます。 加えて、ソースファイルの名前を求めるのに proc が使えます。 これにより、複雑なパターンとソースに対応できます。
次のルールは、前の例と等価です。
rule( /\.o$/ => [ proc {|task_name| task_name.sub(/\.[^.]+$/, '.c') } ]) do |t| sh "cc #{t.source} -c -o #{t.name}" end
<b>注:</b> Ruby の_気まぐれな_文法のため、
次のルールは、Java ファイルに使われます。
rule '.java' => [ proc { |tn| tn.sub(/\.class$/, '.java').sub(/^classes\//, 'src/') } ] do |t| java_compile(t.source, t.name) end
<b>注:</b> +java_compile+ は Java コンパイラを呼び出す仮のメソッドです。
("#" で始まる)標準 Ruby コメントは、Ruby コードで合法な場所では、 タスクやルールのためのコメントも含めて どこでも使うことができます。 しかしながら、"-T" オプションでタスクの説明を出したい場合は、 +desc+ コマンドを使う必要があります。
例:
desc "Create a distribution package" task :package => [ ... ] do ... end
"-T" オプション(省略しないのであれば "--tasks")は、定義されたコメントを持つ タスクのリストを出力します。 主要なタスクを記述するのに +desc+ を使えば、半自動的に Rake ファイルの概要を 生成することができます。
traken$ rake -T (in /home/.../rake) rake clean # Remove any temporary products. rake clobber # Remove any generated file. rake clobber_rdoc # Remove rdoc products rake contrib_test # Run tests for contrib_test rake default # Default Task rake install # Install the application rake lines # Count lines in the main rake file rake rdoc # Build the rdoc HTML Files rake rerdoc # Force a rebuild of the RDOC files rake test # Run tests rake testall # Run all test targets
"-T" オプションでは、説明を伴ったタスクのみが出力されます。 全てのタスクとその必要条件を得るには、"-P" (または "--prereqs")を使います。
Ruby においては、ブロックは +do+/+end+ のペアと { } のどちらでも指定することができますが、 タスクやルールのアクションを指定するときには +do+/+end+ を使うことを _強く_推奨します。 なぜならば、rakefile イディオムでは task/file/rule メソッドの括弧はよく 省略され、 { } を使った場合、あいまいさが起こるからです。
例えば、+object_files+ メソッドがプロジェクト中のオブジェクトファイルの リストを 返すとしましょう。 +object_files+ を、ルールの中の、アクションを { } で指定する必要条件とし て使ってみます。
# DON'T DO THIS! file "prog" => object_files { # Actions are expected here (but it doesn't work)! }
{ } は +do+/+end+ より優先度が高く、 ブロックは +files+ メソッドではなく +object_files+ メソッドに 関連付けられるからです。
タスクを指定する適切な方法は、次の通りです。
# THIS IS FINE file "prog" => object_files do # Actions go here end