Gradle:タスクはコードです

前のトピックで、 Gradleの概要と、Gradleの基礎となるアイデアを簡単に説明しようとしました。 ソースセットの概念とそれに関連する機能も強調されました。



ここで、Gradleが個人的にどのように私を夢中にしたかについてお話したいと思います。 タスクを操作する方法について説明します。 Gradleのタスクは、Ant Targetによく似ています。 また、用語が混乱しないように、以降のタスク(またはタスク)は常にGradleタスクを意味します。 Antのエンティティについて話している場合、これは明示的に示されます:Antタスク。



したがって、Gradleのタスクは、Groovyに基づいた特別なdsl(ドメイン固有言語)を使用して作成されます。 そして、私の意見では、このdslが提供する可能性は、antやmavenと比較してほとんど無限です。







プログラマ向けの従来の「Hello World」から始めましょう。 空のbuild.gradle



ファイルがあるとします。 私たちは書きます:



 task hello << { println 'Hello world!' }
      
      





打ち上げ



>gradle -q hello

Hello world!







ビンゴ! しかし、印象的ではありません。 他のことを試してみましょう:

 task upper << { String someString = 'mY_nAmE' println "Original: " + someString println "Upper case: " + someString.toUpperCase() 4.times { print "$it " } }
      
      





打ち上げ



>gradle -q upper

Original: mY_nAmE

Upper case: MY_NAME

0 1 2 3







つまり、タスク定義内に任意のGroovyコードが存在する場合があります 。 また、タスク自体は完全なGroovyオブジェクトです。 そしてこれは、それらを制御できるプロパティとメソッドがあることを意味します。 たとえば、新しいアクションを追加します。



より興味深い例を見てみましょう。



小さなJavaプロジェクトがあるとします。 build.gradleは次のとおりです。



 apply plugin: 'java' version = '1.0' repositories { mavenCentral() } dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.7' }
      
      





およびディレクトリ構造



 / projectAlpha
     / src
         /テスト
         /メイン
             / java
                 /私の
                     /自分の
                         /コード
                     /春
                         / db
                         /プラグイン
                         / auth




複雑なことはありません:バージョン、Maven Centralリポジトリ、コンパイルのための2つの依存関係、いくつかのパッケージ。 コマンドを実行するとき



>gradle build







projectAlpha-1.0.jar



アーカイブは、 projectAlpha/build/libs



projectAlpha-1.0.jar



でコンパイルされます。 すべてが契約に完全に準拠しています。 Mavenはまったく同じことを行います。



しかし、時間の経過とともに、要件は変化することが知られています。 例の要件を変更します。 Spring関連のコードを個別のアーカイブに収集し、単体テストクラスのある個別のjarファイルと、ソースコードのある別のjarファイルを組み立てる必要があるとします。 Gradleでは、これは次のように解決されます。



 task sourcesJar(type: Jar) { appendix = 'sources' from sourceSets.main.allJava } task testJar(type: Jar) { appendix = 'test' from sourceSets.test.classes } jar { exclude 'my/spring/**' } task springDbJar(type: Jar) { appendix = 'spring-db' from sourceSets.main.classes include 'my/spring/db/**' } task springAuthJar(type: Jar) { appendix = 'spring-auth' from sourceSets.main.classes include 'my/spring/auth/**' } task springPluginJar(type: Jar) { appendix = 'spring-plugin' from sourceSets.main.classes include 'my/spring/plugin/**' }
      
      





打ち上げ

>gradle assemble







そして私達は見る:

projectAlpha>dir /b build\libs

projectAlpha-1.0.jar

projectAlpha-sources-1.0.jar

projectAlpha-spring-auth-1.0.jar

projectAlpha-spring-db-1.0.jar

projectAlpha-spring-plugin-1.0.jar

projectAlpha-test-1.0.jar








何が起こった:



私はMavenでそれをどのように行うのだろうか?



しかし、人生は止まっておらず、私たちの要求は変わり続けています。 ある晴れた朝、Spring Foundationは、Springに関連し、habr.ruという値を持つデモ属性であるHabréで公開されているすべてのjarをマニフェストに追加することを要求しました。 奇妙に聞こえますが、まだ実装する必要があります。 追加:



 tasks.withType(Jar).matching { task -> task.archiveName.contains('spring') }.allObjects { task -> task.manifest { attributes demo: 'habr.ru' } }
      
      





実行:



projectAlpha>gradle assemble

:compileJava UP-TO-DATE

:processResources UP-TO-DATE

:classes UP-TO-DATE

:jar UP-TO-DATE

:sourcesJar UP-TO-DATE

:springAuthJar

:springDbJar

:springPluginJar

:compileTestJava UP-TO-DATE

:processTestResources UP-TO-DATE

:testClasses UP-TO-DATE

:testJar UP-TO-DATE

:assemble









多くのタスクには最新のマークが付けられていることに注意してください。 これはGradleのもう一つのハイライトです-増分アセンブリ。 しかし、彼女の別の時間について。 さて、もしあなたが怠けすぎでなく、アーカイブマニフェストの内容を見るなら、あなたはSpring関連で必要な行を見つけることができます



Manifest-Version: 1.0

demo: habr.ru







ビンゴ!



しかし、Spring Foundationの要件は変わり続けています。 そして今、あなたは各ジャーの隣に​​チェックサムを置く必要があります:)認可された清潔さは重大な問題であり、私たちは従わざるを得ません。 残念ながら、GradleはMD5計算操作をネイティブにサポートしていません。 しかし、それはAntにあります。 さて、それを使用しましょう。 最後のフラグメントを次のように変更します。



 def allSpringJars = tasks.withType(Jar).matching { task -> task.archiveName.contains('spring') } allSpringJars.allObjects { task -> configure(task) { manifest { attributes demo: 'habr.ru' } doLast { ant.checksum(file: archivePath, todir: archivePath.parentFile) } } } task springJars(dependsOn: allSpringJars)
      
      







そして今回は、不運な春関連のアーカイブのみを収集します。



projectAlpha>gradle clean springJars

:clean

:compileJava

:processResources UP-TO-DATE

:classes

:springAuthJar

:springDbJar

:springPluginJar

:springJars



BUILD SUCCESSFUL



Total time: 5.015 secs








何が起こったのか見てみましょう。

c:\Work\Gradle\tasksAreCode\projectAlpha>dir /b build\libs

projectAlpha-spring-auth-1.0.jar

projectAlpha-spring-auth-1.0.jar.MD5

projectAlpha-spring-db-1.0.jar

projectAlpha-spring-db-1.0.jar.MD5

projectAlpha-spring-plugin-1.0.jar

projectAlpha-spring-plugin-1.0.jar.MD5








タスクを完了するのに必要な労力は最小限でした。

この例で使用されている要件は、人為的で少し素朴に見えるかもしれませんが、実際に解決しなければならないタスクは驚くほど多様です。



この記事では、少量のGroovyコードの助けを借りて、変化する要件に適応し、AntまたはMavenで対処するのが困難ないくつかのタスクを実行しました。 xmlの代わりに柔軟なプログラミング言語を使用すると、手が自由になり、タスクの完了方法を決定できます。



継続する。



All Articles