こんにちは。寺岡です。
この記事は TECHSCORE Advent Calendar 2014 の 23 日目の記事です。
今日はGradleのちょっとしたTIPをお届けします。
Gradleとは
GradleはJava(JVM)環境におけるビルドシステムで、JavaやGroovy、Scalaなどのビルドに利用することができます。
AntやMavenと違いXMLベースの設定ではなくgroovyのDSLで記述できることが特徴で、最近ではSpring FrameworkやAndroidアプリの標準ビルドツールとして利用されています。
Gradleについて詳しく知りたい方は、素晴らしい日本語ドキュメントがあるので読んでみると良いでしょう。
Gradleのデフォルトタスク
Gradleではデフォルトタスクを定義することができます。
Antでいうデフォルトターゲットのような機能で、引数を省略してgradleコマンドを実行した際のタスクを定義します。
例えばgradle コマンドで gradle clean build を実行したい場合、build.gradleに以下の一行を追加します。
1 |
defaultTasks 'clean', 'build' |
デフォルトタスクとして開発時に良く使う一連のタスクを定義しておくと便利です。
デフォルトタスクに名前をつけたい
上記で定義したデフォルトタスクには名前がありません。
GUIのツールや自作の外部スクリプトでタスクを実行する際に、引数を省略できない場合が稀にあるかもしれません。
筆者の場合、Eclipseのプラグインでデフォルトタスクを実行する方法が分らず困った経験があります。
こんな時、gradle default のようにデフォルトタスクをタスク化して名前をつけられると便利ですね。
defaultという名前のタスクの依存関係に、clean、buildタスクを追加して実行してみます。
1 2 3 4 |
task('default') { dependsOn 'clean' dependsOn 'build' } |
では試してみましょう。
1 2 3 4 5 6 |
$ gradle default :build :clean :default BUILD SUCCESSFUL |
おや、buildタスクが先に実行されてしまいました。
これでは折角buildタスクで作ったファイルが、cleanタスクによって綺麗さっぱり消されてしまいます。
これは、Gradleのタスクは依存関係に追加した順ではなく、タスク名順で実行されてしまうためです。
タスクの実行順を制御するshouldRunAfter
Gradleではタスクの実行順を制御するために、shouldRunAfterメソッドを利用することができます。
buildタスクのshouldRunAfterメソッドの引数に、先に実行してほしいcleanタスクを与えてみましょう。
1 |
build.shouldRunAfter clean |
では実行してみます。
1 2 3 4 5 6 |
$ gradle default :clean :build :default BUILD SUCCESSFUL |
上手くいきましたね。
自動化してみる
せっかくdefaultTasksを設定しているのにいちいちタスクを定義するのは面倒です。
設定を二重で持つことになり、片方だけ修正してしまうという悲劇も予想されます。
面倒は悪です。
二重設定は罪です。
完膚なきまでに駆逐せねばなりません。
というわけで、defaultという名前で実行できるデフォルトタスクを自動定義するスクリプトを作ってみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
allprojects { afterEvaluate { project -> if (project.defaultTasks) { project.task('default', group: 'default', description: "Execute ${project.path} default tasks ${project.defaultTasks.collect{ project.path + ':' + it}}") { project.defaultTasks.each { project.tasks['default'].dependsOn it } } project.defaultTasks.collect{tasks.getByPath(it)}.reverse().inject(project.tasks['default']) { after, before -> after.shouldRunAfter before before } } } } |
上記のコードをbuild.gradleにコピペしておくと、defaultという名前で一連のデフォルトタスクを実行するタスクを作ってくれます。
サブプロジェクトにも対応しているのでご安心を。
副作用としてデフォルトタスクの実行時以外も実行順が制御されることになりますが、大抵の場合実用上問題はないでしょう。
え、コピペも悪だろって?……ごもっとも。