buildSrcを使用してGradleに追加のロジックを実装する

ZeroTurnaround RebelLabsブログのMadis Pinkからの興味深い投稿。 誰かが深夜に目を覚まし、「Gradleの全員が知っておくべき機能は何か?」-これがbuildSrc



と自信を持って答えてbuildSrc



。 これはリポジトリ内の特別な魔法のGradleプロジェクトで、すべてのbuild.gradle



ファイルからライブラリとしてアクセスできます。







以下に説明するアプローチにより、便利なJVM言語でコードを記述し、ビルドスクリプトで結果を直接使用できます。 ボーナスとして、これらのスクリプトで特に注意が必要な瞬間を含む単体テストをカバーできます。 猫へようこそ!







こんにちは 世界 buildSrc!



この機能の接続は簡単です。 プロジェクトのルートにbuildSrc



というディレクトリを作成します( settings.gradle



同じディレクトリに):







 mkdir buildSrc
      
      





java



プラグインとgroovy



プラグインの両方がこのプロジェクトに同時に適用されます。 したがって、さらに標準ディレクトリsrc/main/java



を作成し、そこにコードを追加し始めます。







 mkdir -p buildSrc/src/main/java
      
      





これで、プロジェクトをIDEと同buildSrc



、焼きたてのbuildSrc



プロジェクトに新しいJavaクラスを作成できます。







 package myapp.gradle; public class Fun { public static void sayHello() { System.out.println("Hello from buildSrc!"); } }
      
      





最後のステップFun.sayHello



ます: build.gradle



ファイルからFun.sayHello



メソッドを呼び出します。 ルートプロジェクトで簡単なhello



タスクを作成して、排気を見てみましょう。







 import myapp.gradle.Fun task hello { doLast { Fun.sayHello() } } $ ./gradlew hello > Task :hello Hello from buildSrc! BUILD SUCCESSFUL in 0s 1 actionable task: 1 executed
      
      





以上です。 sayHello



メソッドは、通常のJavaメソッドです。 build.gradle



ファイルはJVMアプリケーションとして機能するため、他のJavaメソッドと同様にGroovyから呼び出すことができます。







独自のタスクを作成します



コードを再利用するのは良いことですが、 doLast {}



からのこのゴミはすべて、新しいタスクを作成するときにdoLast {}



見えます。 buildSrc



を使用すると、代わりに特別なタスククラスを作成して、ゴミを捨てることができます。 Gradleタスクは、次のようなJavaクラスです。









別のタスクでFun.sayHello



メソッドをリファクタリングしましょう:







 package myapp.gradle; import org.gradle.api.DefaultTask; import org.gradle.api.tasks.TaskAction; public class HelloTask extends DefaultTask { @TaskAction public void run() { System.out.println("Hello from task " + getPath() + "!"); } }
      
      





Gradleスクリプトからこのタスクを使用する場所はありません。







 import myapp.gradle.HelloTask task hello(type: HelloTask) $ ./gradlew hello > Task :hello Hello from task :hello! BUILD SUCCESSFUL in 0s 1 actionable task: 1 executed
      
      





タスクを完全なプラグインに変える



大規模なプロジェクトでは、接続の複雑なグラフに埋め込まれた多数のタスクを定義する必要があります。 この場合、独自のプラグインを作成することは理にかなっています。 このプラグインは、必要なタスクをすべて作成し、それらを結合する必要があります。







 package myapp.gradle; import org.gradle.api.Plugin; import org.gradle.api.Project; public class MyPlugin implements Plugin<Project> { @Override public void apply(Project project) { project.getTasks().create("hello", HelloTask.class); } }
      
      





現在、タスクを直接使用することはできませんが、この特別なプラグインをアセンブリファイルに直接接続します。







 apply plugin: myapp.gradle.MyPlugin
      
      





はい、動作します!







 $ ./gradlew hello > Task :hello Hello from task :hello! BUILD SUCCESSFUL in 1s 1 actionable task: 1 executed
      
      





これで、サブプロジェクトで使用できるプラグインが手動で作成されました。 もちろん、画面にテキストを印刷する上記の例は、自作のプラグインを使用してプロジェクトに配置できるものの想像を絶するほど小さな部分です。 プラグインをより深く理解したい場合は、 Gradle Summit 2017のこれらのレポートを強くお勧めします。









最後まで読んだ人のためのボーナス: buildSrc



依存関係管理



午後、このノートの著者はJRebel for Androidプロジェクトの開発者です。 これは、IDE用のプラグイン、Gradleプラグイン、Androidアプリケーション、および通常のJava SEアプリケーションで構成される開発者向けのツールです。 これらすべてのアーティファクトを収集するために、90以上のサブプロジェクトで構成される大規模なGradleプロジェクトがあります。 これらすべてのサブプロジェクトには、 commons-io



slf4j-api



など、多くの類似した依存関係があります。 org.slf4j:slf4j-api:1.7.25



度もorg.slf4j:slf4j-api:1.7.25



度もコンパイルする必要がある場合、通常のハウスキーピングのように、すぐに迷惑になります。 これらの依存関係の正しいバージョンを推測する場合も同じです。







通常、プロジェクトルートでext {}



ブロックを直接使用して管理することをお勧めします。 例は、StackOverflowに対するこの回答にあります。 このアプローチの裏側は、IDEがオートコンプリートとコードナビゲーションから外れることです。







Deps.java



内のDeps.java



ファイルで文字列定数として依存関係を定義する、別の方法で行った。 IDEのこのアプローチでは、オートコンプリートとナビゲーションが機能します! 小さなAndroidプロジェクトの例でどのように見えるか見てみましょう。







 package myapp.gradle; public class Deps { public static final String androidPlugin = "com.android.tools.build:gradle:3.0.0-beta6"; public static final String kotlinVersion = "1.1.50"; public static final String kotlinPlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:" + kotlinVersion; public static final String kotlinRuntime = "org.jetbrains.kotlin:kotlin-stdlib-jre7:" + kotlinVersion; public static final String appCompat = "com.android.support:appcompat-v7:26.1.0"; public static final String constraintLayout = "com.android.support.constraint:constraint-layout:1.0.2"; public static final String junit = "junit:junit:4.12"; }
      
      





これで、次のようにbuild.gradle



ファイル内でそれらを参照できます。













buildSrc



にビルド構成をbuildSrc



すると、少し間違っている、または何かを感じます。 しかし、このアプローチの利点ははるかに重要です。







buildSrc



フォーカスを使用しbuildSrc



か? コメントを書いてください! さらに、作者はTwitter @madispを介して連絡を取り 、不快な質問をすべてすることできます。 この投稿のすべての例は、GitHubで入手できます







この投稿は、ZeroTurnaroundおよび著者であるMadis Pinkの許可を得て公開されています。 ZeroTurnaroundの従業員は、多くの場合 JUG.ruグループの会議プログラム委員会出席し、会議で講演者として行動し 、しばしば単にゲストとして来ます。 また、2018年4月6〜7日に開催される JPointにHabrの読者を招待します。








All Articles