Gradle:より良い構築方法

Javaプラットフォームを使用するプロジェクトは(そしてそれだけではなく)ビルドツールなしではできません(「Hello、world!」でない限り)。 遅かれ早かれ、手作業で配布キットを作成するのは退屈です。 はい。また、プロジェクトで複数の異なるIDEを使用している場合は、コンソールからコンパイルすると便利です。 そして、配布キットを作成する前に、彼の名前にバージョン番号を記載しておくといいでしょう。 そして、単体テストを実行するために-ケントベックが本を書くのは無意味ではありません。 そして、地平線上には継続的な統合が迫っています。 そして、CIサーバーにそれをすべて自分で行う方法を教えることは素晴らしいことです。 つまり、多くのタスクがあります。

タスクがあれば、解決策があります。 ほとんどの開発者は少なくとも一度は思うが、Antに直面した。 多くの人がMavenを使用しています。 あまり一般的ではない他のツール:GAnt、Buildrなどがあります。それぞれに独自のプラスとマイナスのセットがありますが、今日は新しいものを紹介します。 グラドル


Gradleは 、Ant、Maven、Ivyのすべての利点を組み合わせようとしています。 そして、 Groovyで何が起こったのかを説明します。 これで、バッチスクリプト、javaおよびxml構成ファイルを横断する代わりに、Groovyダイアレクトで数行のコードを書くだけで生活を楽しむことができます。 方言は、アセンブリ、テスト、展開、エクスポート、および思い浮かぶ可能性のある他のプロジェクト活動を記述するために特別に設計されています。

なぜなら Gradleは実行中のJVMで実行され、Antタスクライブラリ、Apache Ivy依存関係管理ツール、およびその他の既存のツール(TestNG、JUnit、Surefire、Emmaなど)を正常に使用します。 原則として、jvmで実行されているツールをアセンブリに簡単に統合できます。 さらに、Gradleで使用されているGroovy方言により、完全に自由に行動できます。 完全に完了しました。 条件式が必要ですか? お願い! サイクルが必要ですか? どういたしまして! ファイルを読み書きしますか? ネットワークで作業しますか? その場で独自のタスクを生成しますか? 何でも! そして、不気味なxml-constructsではなく、通常の人間のプログラミング言語で。

興味深い機能:適切に構成されたGradleプロジェクトは、Gradleがインストールされていないユーザーのマシンでビルドできます。 必要なのは、ソースツリーに4つのファイル(Gradleが生成する)を配置することだけです:Win / * nix用の2つの実行可能ファイル、1つの設定ファイル、小さなjar。 〜20Kbでのみ。 その後、Webにアクセスできる任意のマシンでプロジェクトを組み立てることができます。 スクリプト自体がGradleの正しいバージョンのダウンロード、ビルドのセットアップおよび開始を処理します。

Gradleへの移行は非常に簡単です。 たとえば、maven2アセンブリをGradleアセンブリに自動的に変換できます(構成された依存関係、アーティファクト、バージョン、およびサブプロジェクトを保持しながら)。 そして、移行はすでに始まっています。 現在、このツールは、 GrailsSpring SecurityHibernate Core 、さらにはGAntのプロジェクトでも使用されています(正直なところ、GAntはGradleを使用して構築されています!)。

称賛され、今行動で実証する必要があります。

最初に、「javaのビルド」の使用方法を示すテンプレートJavaプロジェクトを作成しましょう。 その後、ファイル構造に自動化された一連の統合テストを追加して、Gradleが「慣習」の使用にどれだけの自由度を提供するかを示すことで、少し変更を試みます。 この例では、ソースファイルについて意図的に言及していません。 それらのポイントではありません。

プロジェクト構造があると仮定します(すでに1000回見たことがあります)。

 /プロジェクト
    / src
       /メイン
          / java
          /リソース
       /テスト
          / java
          /リソース


プロジェクトディレクトリに空のbuild.gradleファイルを作成します。 そこに1行書きます:

apply plugin:'java' 


gradle buildコマンドを実行し、取得します:

>gradle build
:compileJava
:processResources
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build

BUILD SUCCESSFUL

Total time: 4.116 secs


コンソールには、Antターゲットの類似物である一連のタスク(Gradle Tasks)の実行が表示されます。 / project / buildディレクトリには、コンパイルされたクラス(jarにきちんとパッケージ化されたクラスを含む)、テスト実行レポート、およびその他のビルド結果があります。

これはすべて、Mavenを使用する多くのプロジェクト参加者が慣れているものと違いはありません。 同じディレクトリ、同じpom.xml(build.gradleのみと呼ばれます)。 しかし、急いで腐ったトマトを暴き出し、Gradleの興味深い機能の1つを紹介させてください。

統合テストを追加します。 それらに対して個別のディレクトリブランチを作成します。

 /プロジェクト
    / src
       /メイン
       /テスト
       / integTest
          / java
          /リソース


build.gradleに次のコードを追加します。
 sourceSets { integTest } 


Gradleソースセットに関しては、コンパイルして一緒に実行する必要がある一連のファイルとリソース。 上記のスニペットは、integTestという名前の新しいソースセットを定義しています。 デフォルトでは、ソースとリソースはそれぞれ/project/src/< source set>/javaおよび/project/src/< source set>/resourcesから取得されます。 最初に接続したJavaプラグインは、 maintest 2つの標準ソースセットを定義します。

3つの新しいタスクが自動的に生成されます。コンパイル(compileIntegTestJava)、リソース処理(processIntegTestResource)、およびそれらを組み合わせたintegTestClassesです。 実行してみましょう:

>gradle integTestClasses
:compileIntegTestJava
:processIntegTestResources
:integTestClasses

BUILD SUCCESSFUL

Total time: 1.675 secs


2行の価格で、3つの新しいタスクを取得し、プロジェクトアセンブリに新しいカタログを追加しました。 しかし、これらのテストを書くとすぐに、メインプロジェクトのすべての依存関係、さらにはコンパイルされたクラスも必要になることがわかります。
質問はありません。

 configurations { integTestCompile { extendsFrom compile } } sourceSets { integTest{ compileClasspath = sourceSets.main.classes + configurations.integTestCompile } } 


Congfigurationsブロックは、 依存関係の構成を記述します 。 各構成は、Mavenアーティファクト、ローカルファイルのセットなどを結合できます。新しい構成は、既存の構成から継承できます。 この場合、依存関係構成を継承して、 compile構成から統合テストをcompileます。 この構成は、 mainをコンパイルするための標準です(プラグインによって定義されます)

sourceSets.main.classes + configurations.integTestCompileは、ファイルセットの結合を示します。 main.classes mainアセンブリ中に受信した* .classファイルが置かれるディレクトリ。

おそらく、ビルドするとき、JUnitは役に立ちます。 そして、これらのテストを実行するのもいいでしょう。 依存関係のもう1つの構成について説明しましょう。

 configurations { integTestCompile { extendsFrom compile } integTestRuntime { extendsFrom integTestCompile, runtime } } repositories { mavenCentral() } dependencies { integTestCompile "junit:junit:4.8.1" } sourceSets { integTest{ compileClasspath = sourceSets.main.classes + configurations.integTestCompile runtimeClasspath = classes + sourceSets.main.classes + configurations.integTestRuntime } } task integrationTest(type: Test) { testClassesDir = sourceSets.integTest.classesDir classpath = sourceSets.integTest.runtimeClasspath } 


Repositoriesブロックは、Maven Central(および選択した他のリポジトリ)を接続します。 dependenciesブロックにより、構成にアーティファクト依存関係が追加されます。 runtimeClasspath = classes + sourceSets.main.classes + configurations.integTestRuntimeintegTest.classesmain.classes 、およびintegTestRuntimeファイルruntimeClasspath = classes + sourceSets.main.classes + configurations.integTestRuntime結合します。

テストを実行するために、タスクを作成する必要がありました。 しかし、それは難しくありませんでした。テストをどこから取得し、どのクラスパスで実行するかを示すだけで十分でした。 「なに」 「どのように」Gradleは自分で決定します。

これで準備ができました:

>gradle clean integrationTest
:clean
:compileJava
:processResources
:classes
:compileIntegTestJava
:processIntegTestResources UP-TO-DATE
:integTestClasses
:integrationTest

BUILD SUCCESSFUL

Total time: 4.195 secs


Gradleは、統合テストを収集する前に、 integTest.compileClasspath依存関係をmain.classesし、ソースセットmainをコンパイルしたことに注意してください!

その結果、プロジェクトの標準構成を組み立て、それを完全に簡単に拡張し、継承を使用してサブタスク間の依存関係スキームを説明することができました。 これはすべて、シンプルで完全に読み取り可能な言語の助けを借りて行われます。

まだ語られていないこと:タスクの操作、インクリメンタルビルド、サブプロジェクトの操作、Mavenリポジトリの操作、Antとの統合、標準プラグイン、initスクリプトなどについて。 しかし、これについては、おそらく、他の記事で。

Source: https://habr.com/ru/post/J107085/


All Articles