Gradleのタスクの実行制御についてメモ
またまたGradleネタです。Gradleであるタスクを実行する場合のみに、依存関係にあるタスクの前に処理を割り込ませたい、というのをどう定義するか?というのでちょっと悩んでいたのでメモ。
Antなら、callタスクを使って別のタスクを呼び出すことができるので、例えば以下のように書ける。これをGradleだとどう書くのか?
<target name="dist"> <echo message="dist"/> </target> <target name="release"> ... (ここで前処理) <antcall target="dist" /> ... (ここで後処理) </target>
一応、非公開APIながらGradleではタスクに対してexecute()を呼び出せばタスクを実行できるのだが、これだとそのタスク単体しか呼ばれないようだ。コマンドラインからそのタスクを実行した時のように、そのタスクの依存関係までみて実行はしてくれない? 例えば、以下のように定義できるのだが...
task compile << { println "compile" } task dist(dependsOn: compile) << { println "dist" } task release << { println "Before process" tasks.dist.execute() println "After process" }
これでreleaeタスクを実行しても、distタスクが依存するcompileタスクまで実行してくれない。
# gradle release :release Before process dist After process BUILD SUCCESSFUL
というわけでどうするのがいいかなーとGradleのユーザガイドを眺めていると、使えそうな仕組みがあった。
以下のように、gradle.taskGraph.whenReadyのクロージャでGradleのconfiguration phase後に処理をフックすることができるのだ。これを使えば、releaesタスクが実行されるときにだけdistタスクに前処理をdoFirstクロージャで追加することができる。
task compile << { println "compile" } task dist(dependsOn: compile) << { println "dist" } task release(dependsOn: dist) << { println "After process" } gradle.taskGraph.whenReady {taskGraph -> if (taskGraph.hasTask(release)) { dist.doFirst { println "Before process" } } }
実行結果は以下の通り。ちゃんと、依存関係のあるcompileも先に実行されつつ、distタスクの前に追加した処理が実行され、distタスク完了後にreleaseタスクが呼ばれるようになった。
gradle release :compile compile :dist Before process dist :release After process BUILD SUCCESSFUL
ただ、もうちょっとスマートに書く方法ないのかなぁ。。。