今更だけど、Gradleをちゃんと勉強しよう - Task同士の協調

今度のJava女子部の勉強会でGradleの講師をさせていただくことになりました。
それほど高度な内容は扱わないのですが、入門レベルの復習をされたい方はご参加いただくとよいかもしれません。
で、その勉強会の中でGradleのタスク同士が強調するようなサンプルを作っていた所、謎いタスクが出来上がりました。

ベースとなっているタスクは単なるじゃんけんです。ユーザーがrps(Rock-Paper-Scissors)の値を入力して、Gradle側もrps(Rock-Paper-Scissors)の値を決定して比べているだけです。
まあ、それだけだったら、面白くもなんともないのですが、そのタスクの結果を受けて、Gradleが負けた(ユーザーが勝った)時に、JVM系モダンビルドツールの他の四天王(sbt、Leiningen、Maven)がお決まりの四天王ネタを言ってくれるタスクを用意します。
なお、ユーザーが負けたり、あいこだったりする場合は、他の四天王の面々は無言です。

仕様と実装
簡単にタスクの仕様を書くとこんな感じです。
rpsタスク- ユーザーが
rpsというプロパティを設定して起動した場合、その値からじゃんけんの値を取り出す(ない場合や、特定できない場合はグーになる) - cpu側はランダムでrpsの値を決定する
- それらを比較結果(
WIN、DRAW、LOSE)をresultというフィールドに設定する
- ユーザーが
jvmタスクrpsタスクに依存するrpsタスクが実行され、rpsタスクのresultの値がLOSEの場合にのみ実行される- 四天王ネタを表示する
rpsタスクのベースになるタスクのクラスはこんな感じです。
class RpsCompTask extends DefaultTask { CompResult result @TaskAction void comp() { // ユーザーの手とCPUの手を決定 -> 省略 // 比較結果をresultに保存する result = cpu.comp(user) // 結果を表示する -> 省略 } }
タスク実行制御
jvmタスクの方の実行制御ですが、これはTaskのonlyIfメソッドを用いて制御します。
onlyIfに渡されるClosureがtrueを返す時にタスクは実行され、falseを返すときにタスクはスキップされます。
task rps(type: RpsCompTask) task jvm(dependsOn: 'rps') { group = 'JVM系モダンビルドツール最強決定戦' description = 'JVM系モダンビルドツール四天王が何か言いたそうにこちらを見ている' onlyIf { // rpsタスクが実行されて、その結果がLOSEの場合のみ実行 tasks.rps.didWork && tasks.rps.result == CompResult.LOSE } doLast { logger.lifecycle "sbt : Gradleが負けたようだな…" logger.lifecycle "Leiningen: ククク…奴はJVM系モダンビルドツール四天王の中でも最弱" logger.lifecycle "Maven : ユーザーごときに負けるとはJVM系モダンビルドツールの面汚しよ…" } }
このような形で依存タスクの実行結果に基いて次のタスクの実行制御が可能になります。
応用
例えば、Dockerファイルなどをまとめてパッケージングするタスクは、JaCoCoのテストカバレージで分岐、行とも70%に満たない場合には行わないという形にするなどの応用ができるでしょう。