Open38

Gradleユーザーガイドメモ

ta.toshiota.toshio

Gradleの基本

https://docs.gradle.org/current/userguide/gradle_basics.html

内容一覧

  • Gradleの基本概念
  • Gradleプロジェクト構造
  • Gradleの呼び出し方法

Gradleは、ビルドスクリプトに基づいて、ソフトウェアのビルド、テスト、デプロイを自動化します。


Gradleの基本概念

プロジェクト

Gradleプロジェクトは、アプリケーションやライブラリのようなビルド可能なソフトウェアの単位を指します。

  • シングルプロジェクトビルド: 1つのプロジェクト(ルートプロジェクト)のみを含みます。
  • マルチプロジェクトビルド: 1つのルートプロジェクトと、任意の数のサブプロジェクトを含みます。

ビルドスクリプト

ビルドスクリプトは、Gradleにプロジェクトをビルドするための手順を詳細に説明します。
各プロジェクトは、1つ以上のビルドスクリプトを含むことができます。

依存関係管理

依存関係管理とは、プロジェクトが必要とする外部リソースを宣言・解決する自動化技術です。
通常、各プロジェクトにはGradleがビルド中に解決する外部依存関係が含まれます。

タスク

タスクは、コードのコンパイルやテストの実行など、基本的な作業単位を指します。
各プロジェクトには、ビルドスクリプトやプラグイン内で定義された1つ以上のタスクが含まれます。

プラグイン

プラグインは、Gradleの機能を拡張し、タスクをプロジェクトに追加するために使用されます。


Gradleプロジェクト構造

多くの開発者は、既存のプロジェクトを通じて初めてGradleを触れることになります。
プロジェクトのルートディレクトリにgradlewgradlew.batファイルがある場合、そのプロジェクトがGradleを使用している明確な指標となります。

Gradleプロジェクトの一般的な構造は以下の通りです:

project
├── gradle                              
│   ├── libs.versions.toml              
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew                             
├── gradlew.bat                         
├── settings.gradle(.kts)               
├── subproject-a
│   ├── build.gradle(.kts)              
│   └── src                             
└── subproject-b
    ├── build.gradle(.kts)              
    └── src                             

構造の説明

  • gradleディレクトリ: Wrapperファイルなどを格納します。
  • libs.versions.toml: 依存関係管理用のバージョンカタログ。
  • Gradleラッパースクリプト: gradlewgradlew.bat
  • settings.gradle(.kts): ルートプロジェクト名やサブプロジェクトを定義します。
  • サブプロジェクトのビルドスクリプト: build.gradle(.kts)
  • ソースコードおよび追加ファイル: 各プロジェクトに関連。

Gradleの呼び出し方法

IDEからの呼び出し

Gradleは、多くのIDE(Android Studio、IntelliJ IDEA、Visual Studio Code、Eclipse、NetBeansなど)に組み込まれています。
IDE内でアプリをビルド、クリーン、または実行するとき、Gradleが自動的に呼び出されます。
使用するIDEのマニュアルを参照して、Gradleの使い方や設定方法を確認することをお勧めします。

コマンドラインからの呼び出し

Gradleは、インストール後、コマンドラインから呼び出すことができます。

例:

$ gradle build

ただし、ほとんどのプロジェクトではインストールされたGradleではなく、Gradle Wrapperを使用します。


Gradle Wrapper

Gradle Wrapperは、宣言されたバージョンのGradleを呼び出すスクリプトで、Gradleビルドを実行する推奨方法です。
プロジェクトのルートディレクトリにgradlewgradlew.batとして配置されています。

使用例

  • Linux/OSXでの実行:

    $ ./gradlew build
    
  • Windowsでの実行:

    $ gradlew.bat build
    

ご不明点があればお気軽にお知らせください!

ta.toshiota.toshio

Gradle Wrapper Basics

https://docs.gradle.org/current/userguide/gradle_wrapper_basics.html

Gradleビルドを実行する推奨方法は、Gradle Wrapperを使用することです。

gradle basic 2

Wrapper スクリプトは、宣言されたGradleのバージョンを呼び出し、必要に応じて事前にダウンロードします。

Wrapperのワークフロー

Gradle Wrapperは、gradlew または gradlew.bat ファイルとして利用できます。

Wrapperの利点

  • プロジェクトで特定のGradleバージョンを標準化できる。
  • 異なるユーザー間で同じGradleバージョンを提供できる。
  • 異なる実行環境(IDEやCIサーバーなど)に同じGradleバージョンを提供できる。

Gradle Wrapperの使用方法

Gradle Wrapperを使用することで、ビルドの実行を信頼性が高く、制御された、標準化されたものにすることが推奨されます。

オペレーティングシステムに応じて、gradlew または gradlew.batgradle コマンドの代わりに使用します。

一般的なGradleコマンド例

$ gradle build

LinuxやOSXでのWrapperの実行例

$ ./gradlew build

Windows PowerShellでのWrapperの実行例

$ .\gradlew.bat build

Wrapperのあるディレクトリでコマンドを実行します。別のディレクトリでコマンドを実行する場合は、Wrapperへの相対パスを指定する必要があります。

$ ../gradlew build

WindowsでのWrapper使用例(コンソール出力)

$ gradlew.bat build

Downloading https://services.gradle.org/distributions/gradle-5.0-all.zip
.....................................................................................
Unzipping C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-all\ac27o8rbd0ic8ih41or9l32mv\gradle-5.0-all.zip to C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-al\ac27o8rbd0ic8ih41or9l32mv
Set executable permissions for: C:\Documents and Settings\Claudia\.gradle\wrapper\dists\gradle-5.0-all\ac27o8rbd0ic8ih41or9l32mv\gradle-5.0\bin\gradle

BUILD SUCCESSFUL in 12s
1 actionable task: 1 executed

Wrapperファイルの理解

以下のファイルがGradle Wrapperの一部です:

.
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar  
│       └── gradle-wrapper.properties   
├── gradlew 
└── gradlew.bat 

ファイル説明

  • gradle-wrapper.jar:
    小さなJARファイルで、Gradle Wrapperコードが含まれています。プロジェクトに必要なGradleのバージョンがインストールされていない場合、このファイルがダウンロードとインストールを行います。

  • gradle-wrapper.properties:
    Gradle Wrapperの設定ファイルで、GradleをダウンロードするURLや配布形式(ZIPまたはTARBALL)が含まれています。

  • gradlew:
    Unix系システム用のシェルスクリプトで、gradle-wrapper.jarをラップしてGradleタスクを実行します。手動でGradleをインストールする必要がありません。

  • gradlew.bat:
    Windows用のバッチスクリプトで、gradlewと同様の機能をWindows環境で提供します。

注意点

これらのファイルを手動で編集しないでください。
プロジェクトのGradleバージョンを確認または更新したい場合は、コマンドラインを使用します。

バージョン確認および更新コマンド例

$ ./gradlew --version
$ ./gradlew wrapper --gradle-version 7.2
$ gradlew.bat --version
$ gradlew.bat wrapper --gradle-version 7.2

詳しくはGradle Wrapperのリファレンスを参照してください。

ta.toshiota.toshio

Command-Line Interface Basics

https://docs.gradle.org/current/userguide/command_line_interface_basics.html

コマンドラインインターフェース(CLI)は、IDE外でGradleと対話するための主な方法です。

gradle basic 2

Gradle Wrapperの使用が強く推奨されます。

以下の例では、gradle の代わりに、macOS/Linuxでは ./gradlew、Windowsでは gradlew.bat を使用してください。


コマンドラインでのGradleの実行構造

Gradleコマンドの構造は以下の形式に従います:

gradle [taskName...] [--option-name...]
  • オプションはタスク名の前後どちらにも指定可能です。
  • 複数のタスクを指定する場合は、スペースで区切ります。

例:

gradle [--option-name...] [taskName1 taskName2...] [--option-name...]
  • 値を受け取るオプションは、オプション名と値の間に=を入れるか省略できます。ただし、=を使用するのが推奨されます。

例:

gradle [...] --console=plain
  • 動作を有効にするオプションには、否定形を指定する --no- オプションもあります。

例:

gradle [...] --build-cache
gradle [...] --no-build-cache
  • 長形式オプションの多くは短形式のオプションも提供しています。

例:

gradle --help
gradle -h

コマンドラインでの使用方法

以下のセクションでは、Gradleコマンドラインインターフェースの使用方法を説明します。一部のプラグインは独自のコマンドラインオプションを追加する場合があります。


タスクの実行

ルートプロジェクトで taskName というタスクを実行するには、次のコマンドを入力します:

$ gradle :taskName

これにより、単一の taskName とその依存関係が実行されます。


タスクのオプションを指定する

タスクにオプションを渡すには、タスク名の後に -- を付けてオプション名を指定します:

$ gradle taskName --exampleOption=exampleValue

詳細は、Gradleコマンドラインインターフェースリファレンスを参照してください。

ta.toshiota.toshio

設定ファイルの基本

https://docs.gradle.org/current/userguide/settings_file_basics.html

内容一覧

設定ファイルは、すべてのGradleプロジェクトのエントリポイントです。

gradle basic 3

設定ファイルの主な目的は、ビルドにサブプロジェクトを追加することです。

Gradleは、シングルプロジェクトビルドとマルチプロジェクトビルドの両方をサポートします。

  • シングルプロジェクトビルドでは、設定ファイルは任意です。
  • マルチプロジェクトビルドでは、設定ファイルが必須であり、すべてのサブプロジェクトを宣言します。

設定スクリプト

設定ファイルはスクリプトであり、以下のいずれかの形式で記述されます:

  • Groovyで記述されたsettings.gradleファイル
  • Kotlinで記述されたsettings.gradle.ktsファイル

Gradleスクリプトで使用できる言語は、Groovy DSLKotlin DSLのみです。

設定ファイルは通常、プロジェクトのルートディレクトリに配置されます。

以下は設定ファイルの例とその内容の説明です:


例:Kotlin DSLの場合

rootProject.name = "root-project"   // プロジェクト名を定義

include("sub-project-a")            // サブプロジェクトを追加
include("sub-project-b")
include("sub-project-c")
説明
rootProject.name プロジェクト名を定義します。
include サブプロジェクトを追加します。

1. プロジェクト名を定義

設定ファイルでは、プロジェクト名を定義します:

rootProject.name = "root-project"

ビルドごとにルートプロジェクトは1つだけ存在します。


2. サブプロジェクトを追加

設定ファイルでは、必要に応じてサブプロジェクトを含めることでプロジェクトの構造を定義します:

include("app")
include("business-logic")
include("data-model")

さらに詳しい情報は、設定ファイルの記述ページを参照してください。

ta.toshiota.toshio

ビルドファイルの基本

https://docs.gradle.org/current/userguide/build_file_basics.html

内容一覧

ビルドスクリプトは通常、ビルド構成、タスク、プラグインを記述します。

gradle basic 4

すべてのGradleビルドには、少なくとも1つのビルドスクリプトが含まれます。

ビルドファイルでは、次の2種類の依存関係を追加できます:

  1. Gradleやビルドスクリプトが依存するライブラリやプラグイン。
  2. プロジェクトのソースコードが依存するライブラリ。

ビルドスクリプト

ビルドスクリプトは、Groovyで記述されたbuild.gradleファイル、またはKotlinで記述されたbuild.gradle.ktsファイルです。

Gradleスクリプトで使用できる言語は、Groovy DSLKotlin DSLのみです。

以下は、ビルドスクリプトの例とその内容の説明です:


例:Kotlin DSLの場合

plugins {
    id("application")               // プラグインを追加
}

application {
    mainClass = "com.example.Main"  // メインクラスを指定
}
説明
plugins プラグインを追加します。
application 慣例プロパティを使用します。

1. プラグインを追加する

プラグインはGradleの機能を拡張し、プロジェクトにタスクを追加できます。
ビルドにプラグインを追加する操作はプラグインの適用と呼ばれ、追加機能を利用可能にします。

例:

plugins {
    id("application")
}
  • applicationプラグイン: 実行可能なJVMアプリケーションを作成するためのプラグインです。
  • このプラグインを適用すると、暗黙的に**javaプラグイン**も適用されます。
    • javaプラグイン: Javaコンパイル、テスト、およびバンドル機能をプロジェクトに追加します。

2. 慣例プロパティを使用する

プラグインはプロジェクトにタスクを追加するだけでなく、プロパティやメソッドも追加します。

  • applicationプラグインは、アプリケーションのパッケージングや配布を行うタスク(例:runタスク)を定義します。
  • また、Javaアプリケーションのメインクラスを宣言する方法を提供します。これはコードを実行するために必要です。

例:

application {
    mainClass = "com.example.Main"
}
  • 上記の例では、プログラムの実行が開始されるメインクラスがcom.example.Mainであることを指定しています。

さらに詳しい情報は、ビルドスクリプトの記述ページを参照してください。

ta.toshiota.toshio

依存関係管理の基本

https://docs.gradle.org/current/userguide/dependency_management_basics.html

内容一覧

Gradleには依存関係管理のための組み込みサポートがあります。

gradle basic 7

依存関係管理は、プロジェクトが必要とする外部リソースを宣言し解決するための自動化技術です。
Gradleのビルドスクリプトでは、プロジェクトをビルドする過程で必要な外部依存関係(JAR、プラグイン、ライブラリ、ソースコードなど)を定義します。


バージョンカタログ

バージョンカタログを使用すると、libs.versions.tomlファイルに依存関係の宣言を集中管理できます。

  • カタログにより、サブプロジェクト間での依存関係やバージョン設定の共有が簡単になります。
  • 大規模プロジェクトでは、チームがライブラリやプラグインのバージョンを統一するのに役立ちます。

バージョンカタログの構成

バージョンカタログには通常、次の4つのセクションが含まれます:

  1. [versions]:プラグインやライブラリが参照するバージョン番号を宣言します。
  2. [libraries]:ビルドファイルで使用するライブラリを定義します。
  3. [bundles]:依存関係のセットを定義します。
  4. [plugins]:プラグインを定義します。

例:

[versions]
androidGradlePlugin = "7.4.1"
mockito = "2.16.0"

[libraries]
googleMaterial = { group = "com.google.android.material", name = "material", version = "1.1.0-alpha05" }
mockitoCore = { module = "org.mockito:mockito-core", version.ref = "mockito" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "androidGradlePlugin" }
  • このファイルはgradleディレクトリ内に配置され、GradleやIDEが自動的に利用します。
  • バージョンカタログファイルはソース管理システムに登録する必要があります:gradle/libs.versions.toml

依存関係の宣言

プロジェクトに依存関係を追加するには、build.gradle(.kts)ファイルのdependenciesブロック内で依存関係を指定します。

例:以下のbuild.gradle.ktsファイルは、前述のバージョンカタログを使用してプラグインと2つの依存関係をプロジェクトに追加します。

plugins {
   alias(libs.plugins.androidApplication)  
}

dependencies {
    // リモートバイナリへの依存関係(コードのコンパイルと実行に使用)
    implementation(libs.googleMaterial)    

    // リモートバイナリへの依存関係(テストコードのコンパイルと実行に使用)
    testImplementation(libs.mockitoCore)   
}

説明

  • Androidプラグイン:
    Androidアプリをビルドするための特定の機能を追加します。
  • Materialライブラリ:
    AndroidアプリのUIを作成するためのMaterial Designコンポーネントを提供します。このライブラリはKotlinのソースコードをコンパイル・実行する際に使用されます。
  • Mockitoライブラリ:
    Javaコードをテストするためのモックフレームワークです。このライブラリはテストコードをコンパイル・実行する際に使用されます。

依存関係はGradleで**構成(configuration)**ごとに分類されます。

  • materialライブラリはimplementation構成に追加され、本番コードのコンパイルと実行に使用されます。
  • mockito-coreライブラリはtestImplementation構成に追加され、テストコードのコンパイルと実行に使用されます。

プロジェクト依存関係の表示

依存関係ツリーを表示するには、ターミナルで以下のコマンドを実行します:

$ ./gradlew :app:dependencies

> Task :app:dependencies

------------------------------------------------------------
Project ':app'
------------------------------------------------------------

implementation - Implementation only dependencies for source set 'main'. (n)
\--- com.google.android.material:material:1.1.0-alpha05 (n)

testImplementation - Implementation only dependencies for source set 'test'. (n)
\--- org.mockito:mockito-core:2.16.0 (n)

...

詳細は、依存関係管理の章を参照してください。

ta.toshiota.toshio

タスクの基本

https://docs.gradle.org/current/userguide/task_basics.html

内容一覧

タスクは、クラスのコンパイル、JARの作成、Javadocの生成、リポジトリへのアーカイブ公開など、ビルドが実行する独立した作業単位を表します。

gradle basic 5

Gradleのbuildタスクは、gradleコマンドまたはGradle Wrapper(./gradlewまたはgradlew.bat)を使用してプロジェクトディレクトリで実行します。

例:

$ ./gradlew build

利用可能なタスク

プロジェクトで利用可能なすべてのタスクは、Gradleプラグインとビルドスクリプトから提供されます。

以下のコマンドでプロジェクト内のすべての利用可能なタスクを一覧表示できます:

$ ./gradlew tasks

タスクの例

  • アプリケーションタスク

    run - このプロジェクトをJVMアプリケーションとして実行します。
    
  • ビルドタスク

    assemble - このプロジェクトの出力をアセンブルします。
    build - このプロジェクトをアセンブルし、テストします。
    
  • ドキュメンテーションタスク

    javadoc - メインソースコードのJavadoc APIドキュメントを生成します。
    
  • その他のタスク

    compileJava - メインのJavaソースコードをコンパイルします。
    

タスクの実行

たとえば、runタスクを実行するには、以下のコマンドを使用します:

$ ./gradlew run

> Task :app:compileJava
> Task :app:processResources NO-SOURCE
> Task :app:classes

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 904ms
2 actionable tasks: 2 executed

上記のJavaプロジェクトの例では、runタスクの出力として、コンソールにHello Worldが表示されます。


タスクの依存関係

多くの場合、あるタスクは別のタスクを先に実行する必要があります。

例:buildタスク

Gradleがbuildタスクを実行するには、最初にJavaコードをコンパイルする必要があります。そのため、buildタスクはcompileJavaタスクに依存しています。

これにより、compileJavaタスクがbuildタスクの前に実行されます:

$ ./gradlew build

> Task :app:compileJava
> Task :app:processResources NO-SOURCE
> Task :app:classes
> Task :app:jar
> Task :app:startScripts
> Task :app:distTar
> Task :app:distZip
> Task :app:assemble
> Task :app:compileTestJava
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses
> Task :app:test
> Task :app:check
> Task :app:build

BUILD SUCCESSFUL in 764ms
7 actionable tasks: 7 executed

タスク依存関係の定義

ビルドスクリプトでタスクの依存関係を定義することも可能です。Gradleはこれに基づいてタスクの実行順序を自動的に決定します。

詳細は、タスク開発の章を参照してください。

ta.toshiota.toshio

プラグインの基本

https://docs.gradle.org/current/userguide/plugin_basics.html

内容一覧

Gradleはプラグインシステムに基づいて構築されています。Gradle自体は、高度な依存関係解決エンジンなどの基盤を提供し、それ以外の機能はすべてプラグインから提供されます。

プラグインは、Gradleのビルドシステムに追加機能を提供するソフトウェアの一部です。

gradle basic 6

プラグインは、新しいタスク、設定、またはその他のビルド関連の機能を追加するためにビルドスクリプトに適用できます。

プラグインの例

  • Javaライブラリプラグインjava-library
    Javaライブラリを定義してビルドするために使用します。compileJavaタスクでJavaソースコードをコンパイルし、javadocタスクでJavadocを生成し、jarタスクでコンパイル済みクラスをJARファイルにパッケージ化します。

  • Google Services Gradleプラグインcom.google.gms:google-services
    Google APIやFirebaseサービスをAndroidアプリケーションに有効化します。

  • Gradle Bintrayプラグインcom.jfrog.bintray
    アーティファクトをBintrayに公開するためのプラグインです。


プラグインの配布方法

プラグインは、次の3つの方法で配布されます:

  1. コアプラグイン
    Gradleが開発・保守しているコアプラグイン

  2. コミュニティプラグイン
    GradleのコミュニティがGradle Plugin Portalを通じて共有するプラグイン。

  3. ローカルプラグイン
    Gradle APIを使用して、ユーザーがカスタムプラグインを作成できます。


プラグインの適用

プロジェクトにプラグインを適用すると、プラグインがプロジェクトの機能を拡張します。
ビルドスクリプトでプラグインを適用するには、プラグインID(グローバルに一意な識別子)とバージョンを指定します。

plugins {
    id("プラグインID") version "プラグインバージョン"
}

1. コアプラグイン

コアプラグインは、Gradleの配布に含まれているプラグイン群で、プロジェクトのビルドと管理に必要な基本機能を提供します。

例:コアプラグイン

  • java: Javaプロジェクトのビルドをサポート。
  • groovy: Groovyソースファイルのコンパイルとテストをサポート。
  • ear: エンタープライズアプリケーション用のEARファイルのビルドをサポート。

コアプラグインはバージョン指定が不要で、短い名前(例:java)を使って適用できます。

plugins {
    id("java")
}

2. コミュニティプラグイン

コミュニティプラグインは、Gradleコミュニティによって開発されたプラグインで、特定のユースケースや技術に特化した機能を提供します。

例:Spring Boot Gradleプラグイン

  • 実行可能なJARまたはWARアーカイブをパッケージ化し、Spring Boot Javaアプリケーションを実行します。

適用方法:

plugins {
    id("org.springframework.boot") version "3.1.5"
}

コミュニティプラグインはGradle Plugin Portalで公開されており、他のユーザーが簡単に発見して使用できます。


3. ローカルプラグイン

ローカルプラグインは、特定のプロジェクトや組織内で使用するために開発されたカスタムプラグインです。
これらのプラグインは公開されず、プロジェクト固有のニーズに合わせて設計されています。

ローカルプラグインの作成手順

  1. プラグインクラスを定義する
    Plugin<Project>インターフェースを実装する新しいクラスを作成します。

    class HelloPlugin : Plugin<Project> {
        override fun apply(project: Project) {
            val helloTask = project.tasks.register("hello") {
                doLast {
                    println("Hello, Gradle!")
                }
            }
        }
    }
    
  2. プラグインをビルドし公開する(オプション)
    プラグインコードを含むJARファイルを生成し、ローカルまたはリモートリポジトリに公開します。

    plugins {
        `maven-publish`
    }
    
    publishing {
        publications {
            create<MavenPublication>("mavenJava") {
                from(components["java"])
            }
        }
        repositories {
            mavenLocal()
        }
    }
    
  3. プラグインを適用する
    ビルドファイル内のplugins{}ブロックでプラグインIDとバージョンを指定します。

    plugins {
        id("com.example.hello") version "1.0"
    }
    

詳細については、プラグイン開発の章を参照してください。

ta.toshiota.toshio

Gradleのインクリメンタルビルドとビルドキャッシュ

https://docs.gradle.org/current/userguide/gradle_optimizations.html

内容一覧

Gradleは、インクリメンタルビルドビルドキャッシュという2つの主要機能を使用してビルド時間を短縮します。

gradle basic 8


インクリメンタルビルド

インクリメンタルビルドは、前回のビルド以降に入力が変更されていないタスクを実行せずにスキップする仕組みです。同じ出力を再生成するだけのタスクを再実行する必要はありません。

動作の仕組み

  • タスクの入力と出力を定義する必要があります。
  • ビルド時にGradleが入力や出力が変更されたかどうかを判断します。
    • 変更があればタスクを実行します。
    • 変更がなければタスクの実行をスキップします。

インクリメンタルビルドの確認

インクリメンタルビルドは常に有効になっていますが、その動作を確認する最適な方法は詳細モード(verbose mode)を有効にすることです。このモードでは、ビルド中に各タスクの状態がラベル付きで表示されます。

例:

$ ./gradlew compileJava --console=verbose

> Task :buildSrc:generateExternalPluginSpecBuilders UP-TO-DATE
> Task :list:compileJava UP-TO-DATE
> Task :utilities:compileJava UP-TO-DATE
> Task :app:compileJava UP-TO-DATE

BUILD SUCCESSFUL in 374ms
12 actionable tasks: 12 up-to-date
  • UP-TO-DATE: タスクが以前に実行されており、変更がないことを示します。

詳細モードの永続的な有効化

gradle.propertiesファイルに次を追加します:

org.gradle.console=verbose

ビルドキャッシュ

インクリメンタルビルドは、変更されていない作業をスキップする優れた最適化方法です。ただし、例えば次のようなケースではどうでしょうか?

  • 開発者が数週間前に作成された別のブランチに切り替える場合、以前にビルドしたファイルであっても再ビルドされる可能性があります。

このような場合、ビルドキャッシュが役立ちます。

ビルドキャッシュの仕組み

  • ビルドキャッシュは、以前のビルド結果を保存し、必要に応じてそれを復元します。
  • 時間とコストがかかるプロセスを再実行せずに済みます。

キャッシュ利用の例

以下のコマンドでビルドキャッシュを有効にします:

$ ./gradlew compileJava --build-cache

> Task :list:compileJava FROM-CACHE
> Task :utilities:compileJava FROM-CACHE
> Task :app:compileJava FROM-CACHE

BUILD SUCCESSFUL in 364ms
12 actionable tasks: 3 from cache, 9 up-to-date
  • FROM-CACHE: タスクがキャッシュから復元されたことを示します。

キャッシュがローカルディレクトリに再構築された後の次回の実行では、タスクはUP-TO-DATEとしてマークされ、FROM-CACHEとは表示されません。


ビルドキャッシュの利点

  • ビルドの高速化: チーム間でビルドやテストの未変更の出力を共有および再利用できます。
  • 効率的なリソース利用: 新しいコード変更に影響を受けないバイナリの再ビルドを防ぎます。

詳細については、ビルドキャッシュの章を参照してください。

ta.toshiota.toshio

ビルドスキャン (Build Scans)

https://docs.gradle.org/current/userguide/build_scans.html

内容一覧

ビルドスキャンの使用方法を学ぶ

ビルドスキャンは、ビルド実行時に収集されたメタデータの表現です。

gradle basic 1


ビルドスキャンとは

Gradleはビルドのメタデータを収集し、それをビルドスキャンサービスに送信します。このサービスは、収集したメタデータを分析・共有可能な情報に変換します。

build scan 1

ビルドスキャンの活用例

  • トラブルシューティング: ビルドエラーの原因を特定する際に役立ちます。
  • コラボレーション: チームメンバーとビルド情報を共有して効率的に作業を進められます。
  • パフォーマンス最適化: ビルド時間やタスクの実行状況を可視化して、ボトルネックを発見できます。

たとえば、エラーメッセージをコピー&ペーストしたり、環境の詳細を説明する代わりに、最新のビルドスキャンへのリンクを共有できます。これにより、Stack Overflow、Slack、Gradleフォーラムなどでの質問が簡単になります。

build scan 2


ビルドスキャンの有効化

ビルドスキャンを有効にするには、Gradleコマンドに--scanオプションを追加します:

 ./gradlew build --scan

この機能を使用するには、ビルドスキャンの利用規約に同意を求められる場合があります。

さらに詳しくは、ビルドスキャンのページをご覧ください。

ta.toshiota.toshio

Part 1: プロジェクトの初期化

https://docs.gradle.org/current/userguide/part1_gradle_init.html

目次


このセクションでは以下を学びます:

  • 新しいGradleプロジェクトの初期化
  • プロジェクトのビルド
  • Gradleのプロジェクト構造の確認
  • IntelliJ IDEAでプロジェクトを開く
  • Gradleファイルとビルドスクリプトの調査
  • Gradle Wrapperの理解

ステップ 0. 始める前に

  1. **Gradleのインストール**が必要です。
  2. **IntelliJ IDEA**をインストールします。Community Edition(無料版)がおすすめです。

ステップ 1. プロジェクトの初期化

  1. Gradleがインストールされているか確認します:
$ gradle

インストールされていない場合は、インストールセクションを参照してください。

  1. 新しいディレクトリを作成し移動します:
$ mkdir tutorial
$ cd tutorial
  1. gradle initコマンドでJavaアプリケーションを生成します:
$ gradle init --type java-application --dsl kotlin

プロンプトが表示された場合は、デフォルトの選択肢を使用してください。

  1. 生成されたプロジェクト構造:
.
├── .gradle                 
├── gradle                  
│   ├── libs.versions.toml  
│   └── wrapper
├── gradlew                 
├── gradlew.bat             
├── settings.gradle.kts     
├── app                     
│   ├── build.gradle.kts
│   └── src

ステップ 2. Gradle Wrapperの理解

Gradle Wrapperは、特定のGradleバージョンを宣言してダウンロード・実行するスクリプトです。

  • macOS/Linuxではgradlew
  • Windowsではgradlew.bat

これにより、システムにGradleを直接インストールせずともビルドが可能です。


ステップ 3. Gradle Wrapperの実行

Gradle Wrapperを使用してプロジェクトをビルドします:

$ ./gradlew build

Windowsの場合:

$ .\gradlew.bat build

ステップ 4. Gradleのプロジェクト構造の理解

Gradleプロジェクトの基本構造:

  1. settings.gradle(.kts): ルートプロジェクトの設定を定義。
  2. ルートプロジェクト: プロジェクト全体を表すディレクトリ。
  3. サブプロジェクト: 個々のアプリケーションやライブラリを定義するディレクトリ。

ステップ 5. GradleファイルをIDEで表示する

settings.gradle(.kts)ファイルをダブルクリックし、IntelliJ IDEAでプロジェクトを開きます。


ステップ 6. 設定ファイルの理解

settings.gradle(.kts)ファイルは以下のように見えます:

plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}

rootProject.name = "tutorial"
include("app")
  • rootProject.name: ルートプロジェクトの名前を指定。
  • include: サブプロジェクトを追加。

ステップ 7. ビルドスクリプトの理解

サブプロジェクトappbuild.gradle.ktsファイル:

plugins {
    application
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(libs.junit.jupiter)
    implementation(libs.guava)
}

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(11))
    }
}

application {
    mainClass.set("running.tutorial.kotlin.App")
}

tasks.named<Test>("test") {
    useJUnitPlatform()
}
  • plugins: アプリケーションや依存関係の管理に必要なプラグインを指定。
  • dependencies: テストライブラリやアプリケーションで使用するライブラリを指定。

次のセクションではビルドスクリプトの詳細を掘り下げます。

ta.toshiota.toshio

パート2: Gradleタスクの実行

https://docs.gradle.org/current/userguide/part2_gradle_tasks.html

目次


このセクションでは以下を学びます:

  • 利用可能なタスクの確認
  • タスクを実行し結果を確認
  • タスクの仕組みを理解
  • タスク間の依存関係を探る

ステップ 0. 始める前に

  • パート1でJavaアプリを初期化した状態から開始します。

ステップ 1. 利用可能なタスクの確認

  1. タスクの一覧を表示する:

    プロジェクトのルートディレクトリ(tutorial)で以下のコマンドを実行します:

    $ ./gradlew tasks
    
  2. 出力例:

    Application tasks
    -----------------
    run - このプロジェクトをJVMアプリケーションとして実行します。
    
    Build tasks
    -----------
    assemble - このプロジェクトの出力を構築します。
    build - このプロジェクトを構築およびテストします。
    
    Documentation tasks
    -------------------
    javadoc - メインソースコード用のJavadoc APIドキュメントを生成します。
    
    Other tasks
    -----------
    compileJava - メインのJavaソースコードをコンパイルします。
    

    タスクは、コンパイル、ファイルの移動、JARファイルの作成、Javadocの生成、リポジトリへの公開など、さまざまな作業単位を表します。

  3. サブプロジェクトのタスクだけを確認する場合:

    $ ./gradlew :app:tasks
    

ステップ 2. タスクの理解

Gradleには多くの組み込みタスクがあり、これらを使用してビルドスクリプトを拡張できます。

例として、以下はCopyタスクを使用して、sourceディレクトリの.warファイルをtargetディレクトリにコピーするタスクです:

tasks.register<Copy>("copyTask") {
    from("source")
    into("target")
    include("*.war")
}

代表的な組み込みタスク:

  • Copy - ファイルのコピー
  • Delete - ファイルやディレクトリの削除
  • Exec - 任意のOSコマンドの実行
  • Zip - ファイルの圧縮

ステップ 3. タスク間の依存関係の理解

タスクの実行順序は、明示的または暗黙的な依存関係によって決定されます。

明示的な依存関係の例:

tasks.register("hello") {
    doLast {
        println("Hello!")
    }
}

tasks.register("greet") {
    doLast {
        println("How are you?")
    }
    dependsOn("hello")
}

実行順序:

  1. helloタスクが先に実行されて「Hello!」が出力されます。
  2. 続いてgreetタスクが実行されて「How are you?」が出力されます。

ステップ 4. IDEでのタスクの確認

IntelliJ IDEAでプロジェクトを開き、右側の「Gradle」ペインを確認します:

タスクペイン


ステップ 5. IDEでのタスクの実行

  1. 「Gradle」ペインからタスクをダブルクリックで実行:

    例:tutorial > app > build > build

  2. 実行結果の確認:

    BUILD SUCCESSFUL in 966ms
    7 actionable tasks: 7 executed
    

ステップ 6. ターミナルでのタスクの実行

  1. buildタスクを実行:

    $ ./gradlew build
    

    出力例:

    > Task :app:compileJava
    > Task :app:processResources
    > Task :app:classes
    > Task :app:jar
    ...
    > Task :app:build
    
    BUILD SUCCESSFUL in 764ms
    
  2. runタスクを実行:

    $ ./gradlew run
    

    出力例:

    > Task :app:run
    Hello World!
    
    BUILD SUCCESSFUL in 325ms
    

    このrunタスクは、App.javaのコードを実行し、以下のコードに基づいて「Hello World!」を出力します:

    public class App {
        public String getGreeting() {
            return "Hello World!";
        }
        public static void main(String[] args) {
            System.out.println(new App().getGreeting());
        }
    }
    

これでGradleタスクの基本的な操作方法を学びました!

ta.toshiota.toshio

パート3: 依存関係管理

https://docs.gradle.org/current/userguide/part3_gradle_dep_man.html

目次


このセクションで学ぶこと:

  • プロジェクト依存関係の理解
  • プロジェクト依存関係の検査
  • ビルドスキャンを使用して依存関係を分析
  • プロジェクト依存関係の更新
  • 伝播的依存関係の理解
  • バージョンカタログの追加

ステップ 0. 始める前に

  1. パート1でJavaアプリを初期化済み。
  2. パート2でいくつかのタスクを実行済み。

ステップ 1. バージョンカタログの理解

バージョンカタログは、プロジェクトのすべての直接依存関係を中央で宣言するための仕組みです。

以下はgradle/libs.versions.tomlに生成される例です:

[versions]
guava = "32.1.2-jre"
junit-jupiter = "5.10.0"

[libraries]
guava = { module = "com.google.guava:guava", version.ref = "guava" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }

これをサブプロジェクトのビルドファイルで参照する:

dependencies {
    implementation(libs.guava)
    testImplementation(libs.junit.jupiter)
}

バージョンカタログのメリット:

  • Gradleが型安全なアクセサを生成し、IDEでの補完機能が利用可能。
  • 依存関係のバージョンを中央で管理可能。

ステップ 2. プロジェクト依存関係の理解

以下はプロジェクトのbuild.gradle.ktsの例です:

repositories {
    // 依存関係解決にMaven Centralを使用
    mavenCentral()
}

dependencies {
    // テストでJUnit Jupiterを使用
    testImplementation(libs.junit.jupiter)

    // テストランタイムでJUnitランチャーを使用
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")

    // アプリケーションでGuavaを使用
    implementation(libs.guava)
}

主要な概念:

  • リポジトリ - 依存関係のソース(例:mavenCentral()
  • 依存関係 - libs.guava(例:com.google.guava:guava:32.1.2-jre

依存関係の構造:

項目 説明
グループ 組織の識別子 com.google.guava
名前 依存関係の識別子 guava
バージョン インポートするバージョン 32.1.2-jre

ステップ 3. 伝播的依存関係の理解

伝播的依存関係とは、依存関係がさらに依存するライブラリです。

例として、guavafailureaccessというライブラリに依存しています。この場合、failureaccessは伝播的依存関係です。


ステップ 4. プロジェクト依存関係の確認

以下のコマンドで依存関係ツリーを表示:

$ ./gradlew :app:dependencies

出力例:

compileClasspath - Compile classpath for source set 'main'.
\--- com.google.guava:guava:32.1.2-jre
     +--- com.google.guava:failureaccess:1.0.1
     +--- com.google.j2objc:j2objc-annotations:2.8
...

guavafailureaccessなどに依存していることが分かります。


ステップ 5. ビルドスキャンで依存関係を確認

以下のコマンドでビルドスキャンを有効化:

$ ./gradlew build --scan

リンクが提供され、ビルドスキャンにアクセス可能:

ビルドスキャン結果

依存関係タブでcompileClasspathruntimeClasspathを展開し、guavajunitの伝播的依存関係を確認できます。


ステップ 6. プロジェクト依存関係の更新

例:guavaのバージョンを30.0-jreに変更:

[versions]
guava = "30.0-jre"

./gradlew :app:dependenciesで更新内容を確認:

\--- com.google.guava:guava:30.0-jre
     +--- com.google.guava:failureaccess:1.0.1
     +--- com.google.errorprone:error_prone_annotations:2.3.4
...

ステップ 7. Javaアプリの実行

最後にrunタスクを実行:

$ ./gradlew run

出力例:

> Task :app:run
Hello World!

これでGradleの依存関係管理の基本を学びました!

ta.toshiota.toshio

パート4: Gradleプラグインの適用

https://docs.gradle.org/current/userguide/part4_gradle_plugins.html

目次


このセクションで学ぶこと:

  • プラグインの適用
  • プラグインの設定
  • プラグインの使用
  • 他のプラグインの探索

ステップ 0. 始める前に

  1. パート1でJavaアプリを初期化しました。
  2. パート2でいくつかのタスクを実行しました。
  3. パート3で依存関係管理について学びました。

ステップ 1. プラグインの理解

プラグインは、ビルドロジックを整理および再利用するための主要な方法です。また、カスタムタスクをパッケージ化したコードとして配布することもできます。

プラグインの役割:

  • プロジェクトにタスクを追加(例:コンパイル、テスト)。
  • Gradleモデルを拡張(例:新しいDSL要素を追加)。
  • 規約に従ってプロジェクトを設定(例:デフォルトタスクの追加や標準の設定適用)。
  • 組織のリポジトリや標準を適用。
  • 既存の型に新しいプロパティやメソッドを追加。

ステップ 2. プラグインの適用

現在のプロジェクトには、Gradleにバンドルされているアプリケーションプラグインが適用されています:

plugins {
    application
}

次に、Gradleが提供するMaven Publish Pluginを適用します。このプラグインは、ビルド成果物をApache Mavenリポジトリに公開する機能を提供します。また、ローカルMavenリポジトリへの公開も可能です。

プラグインを適用するには、以下のようにbuild.gradle(.kts)に追加します:

plugins {
    application
    id("maven-publish")
}

新しいタスクの確認:

以下のコマンドを実行して、新しいタスクが追加されているか確認します:

$ ./gradlew :app:tasks

出力例:

Publishing tasks
----------------
publish - プロジェクトで生成されたすべての成果物を公開します。
publishToMavenLocal - プロジェクトで生成されたMaven成果物をローカルMavenキャッシュに公開します。

ステップ 3. プラグインの設定

build.gradle(.kts)に公開情報を追加します:

publishing {
    publications {
        create<MavenPublication>("maven") {
            groupId = "com.gradle.tutorial"
            artifactId = "tutorial"
            version = "1.0"

            from(components["java"])
        }
    }
}

再度タスクを確認すると、さらに新しいタスクが追加されています:

Publishing tasks
----------------
generateMetadataFileForMavenPublication - Maven公開用のGradleメタデータファイルを生成。
generatePomFileForMavenPublication - Maven公開用のPOMファイルを生成。
publishMavenPublicationToMavenLocal - Maven公開成果物をローカルMavenリポジトリに公開。

ステップ 4. プラグインの使用

以下のコマンドでpublishToMavenLocalタスクを実行します:

$ ./gradlew :app:publishToMavenLocal

出力例:

BUILD SUCCESSFUL in 331ms

このタスクは、公開するためのPOMファイルと成果物を生成し、ローカルMavenリポジトリに配置します。

成果物は、通常以下のディレクトリに配置されます:

/Users/[username]/.m2/repository/com/gradle/tutorial/tutorial/1.0

POMファイルの内容例:

<project>
  <groupId>com.gradle.tutorial</groupId>
  <artifactId>tutorial</artifactId>
  <version>1.0</version>
</project>

ステップ 5. プラグインの探索

プラグインは、Gradleの機能を拡張し、ビルドロジックをカスタマイズします。

プラグインの種類:

  1. コアプラグイン - Gradleが提供する公式プラグイン。
  2. コミュニティプラグイン - GradleコミュニティがGradle Plugin Portalで共有。
  3. カスタムプラグイン - ユーザーや組織が独自に作成したプラグイン。

Gradleは、ビルドロジックを整理するためにコンベンションプラグインの使用を推奨しています。たとえば、コードカバレッジ用のプラグインをプロジェクト全体で使用する場合に便利です。


これで、Gradleプラグインの適用と設定について学びました!

ta.toshiota.toshio

パート5: インクリメンタルビルドの探索

目次

Gradleによるインクリメンタルビルドとビルドキャッシュの学習 >


このセクションで学ぶこと:

  • Gradleプロパティの使用
  • インクリメンタルビルドの理解
  • タスクの実行結果ラベルの確認

ステップ 0. 始める前に

  1. パート1でJavaアプリを初期化しました。
  2. パート2でいくつかのタスクを実行しました。
  3. パート3で依存関係管理について学びました。
  4. パート4でアプリにプラグインを適用しました。

ステップ 1. インクリメンタルビルドの理解

Gradleはビルドを最適化するためにさまざまな方法を使用します。その一つがインクリメンタルビルドです。

インクリメンタルビルドとは、前回のビルド以降に入力が変更されていないタスクの実行を避けることで、必要のない処理を省略するビルドです。

インクリメンタルビルドを機能させるには、タスクがその入力と出力を定義している必要があります。ビルド時にGradleはこれらが変更されたかを判断し、変更があればタスクを実行し、変更がなければ実行をスキップします。


ステップ 2. Gradleプロパティの更新

インクリメンタルビルドを確認しやすくするために、コンソール出力を詳細モード(verbose)に切り替えます。

アプリのトップレベルフォルダ(tutorial)にgradle.propertiesファイルを作成します:

$ touch gradle.properties

以下を追加して、ファイルの内容を次のようにします:

gradle.properties

org.gradle.console=verbose

ステップ 3. インクリメンタルビルドの分析

cleanタスクを実行した後、buildタスクを実行します:

$ ./gradlew :app:clean :app:build

> Task :app:clean
> Task :app:compileJava
> Task :app:processResources NO-SOURCE
> Task :app:classes
> Task :app:jar
> Task :app:startScripts
> Task :app:distTar
> Task :app:distZip
> Task :app:assemble
> Task :app:compileTestJava
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses
> Task :app:test
> Task :app:check
> Task :app:build

BUILD SUCCESSFUL in 1s
8 actionable tasks: 8 executed

Gradleはアプリをビルドするために必要なすべてのタスクを呼び出しました。

次に、もう一度buildタスクを実行してインクリメンタルビルドの最適化を確認します:

$ ./gradlew :app:build

> Task :app:compileJava UP-TO-DATE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar UP-TO-DATE
> Task :app:startScripts UP-TO-DATE
> Task :app:distTar UP-TO-DATE
> Task :app:distZip UP-TO-DATE
> Task :app:assemble UP-TO-DATE
> Task :app:compileTestJava UP-TO-DATE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test UP-TO-DATE
> Task :app:check UP-TO-DATE
> Task :app:build UP-TO-DATE

BUILD SUCCESSFUL in 409ms
7 actionable tasks: 7 up-to-date

ほとんどのタスクにUP-TO-DATEのラベルが表示されます。これは、入力と出力に変更がなく、一部のタスクが再実行されなかったことを意味します。


ステップ 4. 実行結果ラベルの理解

詳細モードが有効な場合、開発者は以下の4つのラベルを使用してタスクの実行結果を確認できます:

ラベル 説明
UP-TO-DATE タスクがすでに実行され、変更がない(インクリメンタルビルド機能)。
SKIPPED タスクが明示的に実行を防がれた場合。
FROM-CACHE ビルドキャッシュから以前のビルド結果がローカルディレクトリに復元されたタスク(キャッシュ機能)。
NO-SOURCE 必要な入力が利用できず、タスクが実行されなかった場合。

ラベルがない場合、そのタスクはGradleによって新たに実行されたことを示します。

次のセクションではFROM-CACHEラベルについて詳しく説明します。


これでインクリメンタルビルドについての基本を理解できました!

ta.toshiota.toshio

パート6: Gradleビルドキャッシュの有効化

https://docs.gradle.org/current/userguide/part6_gradle_caching.html

目次

Gradleによるインクリメンタルビルドとビルドキャッシュの学習 >


このセクションで学ぶこと:

  • ローカルビルドキャッシュを有効にする
  • キャッシュの仕組みを理解する
  • リモートビルドキャッシュについて学ぶ

ステップ 0. 始める前に

  1. パート1でJavaアプリを初期化しました。
  2. パート2でいくつかのタスクを実行しました。
  3. パート3で依存関係管理について学びました。
  4. パート4でアプリにプラグインを適用しました。
  5. パート5でインクリメンタルビルドについて学びました。

ステップ 1. キャッシュの理解

インクリメンタルビルドは、変更されていない作業をスキップする最適化の一つです。ただし、開発者が先週作成したブランチに切り替えた場合など、すでにビルドされたファイルを再度ビルドする必要が生じることがあります。

ここでビルドキャッシュが役立ちます。キャッシュは以前のビルド結果を保存し、すでにローカルでビルドされた内容を再構築する必要を大幅に削減します。

まず、ローカルビルドキャッシュをアプリで有効にします。


ステップ 2. ローカルビルドキャッシュの有効化

cleanタスクを実行した後、buildタスクを実行します:

$ ./gradlew :app:clean :app:build
> Task :app:clean
> Task :app:compileJava
> Task :app:processResources NO-SOURCE
> Task :app:classes
> Task :app:jar
> Task :app:startScripts
> Task :app:distTar
> Task :app:distZip
> Task :app:assemble
> Task :app:compileTestJava
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses
> Task :app:test
> Task :app:check
> Task :app:build

BUILD SUCCESSFUL in 1s
8 actionable tasks: 8 executed

次に、gradle.propertiesファイルに以下を追加してローカルビルドキャッシュを有効にします:

gradle.properties

org.gradle.console=verbose
org.gradle.caching=true

ステップ 3. ローカルビルドキャッシュの使用

buildタスクを実行してローカルビルドキャッシュを初期化します:

$ ./gradlew :app:build
> Task :app:compileJava UP-TO-DATE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar UP-TO-DATE
> Task :app:startScripts UP-TO-DATE
> Task :app:distTar UP-TO-DATE
> Task :app:distZip UP-TO-DATE
> Task :app:assemble UP-TO-DATE
> Task :app:compileTestJava UP-TO-DATE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test UP-TO-DATE
> Task :app:check UP-TO-DATE
> Task :app:build UP-TO-DATE

BUILD SUCCESSFUL in 409ms
7 actionable tasks: 7 up-to-date

Gradleは何も変更がないことを検知し、タスクをスキップしました。ただし、バックグラウンドではローカルキャッシュが初期化されました。

次に、cleanbuildを再度実行します:

$ ./gradlew :app:clean :app:build
> Task :app:clean
> Task :app:compileJava FROM-CACHE
> Task :app:processResources NO-SOURCE
> Task :app:classes UP-TO-DATE
> Task :app:jar
> Task :app:startScripts
> Task :app:distTar
> Task :app:distZip
> Task :app:assemble
> Task :app:compileTestJava FROM-CACHE
> Task :app:processTestResources NO-SOURCE
> Task :app:testClasses UP-TO-DATE
> Task :app:test FROM-CACHE
> Task :app:check UP-TO-DATE
> Task :app:build

BUILD SUCCESSFUL in 525ms
8 actionable tasks: 5 executed, 3 from cache

Gradleは以下のようにタスクの結果を表示します:

  • FROM-CACHE - タスクがローカルビルドキャッシュから取得されました。
  • UP-TO-DATE - インクリメンタルビルドによってタスクが再実行されませんでした。

ステップ 4. リモートキャッシュの理解

ローカルキャッシュに加えて、Gradleは複数の開発者が利用できるリモートビルドキャッシュもサポートしています。

リモートキャッシュは、リモートビルド間でタスク出力を共有し、ビルド時間を短縮するためのものです。

ローカルおよびリモートキャッシュの両方が有効な場合、Gradleはまずローカルキャッシュを確認し、結果が見つからない場合にリモートキャッシュから取得します。

リモートキャッシュを試すには、Gradleが提供する無料のDockerイメージを使用できます。商用利用にはDevelocityが推奨されます。


これでGradleのビルドキャッシュの仕組みを理解できました!

ta.toshiota.toshio

パート7: Gradleの参照資料の活用

https://docs.gradle.org/current/userguide/part7_gradle_refs.html

目次

このセクションで学ぶこと:

  • Gradleの参照資料を学ぶ
  • チュートリアルを終了する

始める前に

  1. パート1でJavaアプリを初期化しました。
  2. パート2でいくつかのタスクを実行しました。
  3. パート3で依存関係管理について学びました。
  4. パート4でアプリにプラグインを適用しました。
  5. パート5でインクリメンタルビルドについて学びました。
  6. パート6でローカルキャッシュを有効化しました。

ステップ1. Gradleの参照資料

Gradleを使う際には、以下の参照資料が役立ちます:

Gradle APIやDSLのリファレンス

プラグインの検索

Gradleのリリース情報

Gradleのサポートリソース


ステップ2. 次のステップ

次のステップとして、Gradleのユーザーマニュアルの各セクションを一通り読むことをお勧めします。


これでGradleチュートリアルが完了しました。引き続きGradleの学習を進めてください!

ta.toshiota.toshio

https://docs.gradle.org/current/userguide/getting_started_dev.html

はじめに

目次

Gradleの開発者向け入門を学ぶ   >

カスタムビルドロジックを構成し独自のプラグインを作成する準備が整ったビルドエンジニアは、ここから始めてください。

Gradleビルドをエンジニアリングするためのステップ:

  1. ビルドの基本章を読む。
  2. チュートリアルでハンズオン形式を学ぶ。

1. Gradleビルドの基本を作成する

このセクションでは、ビルドを構成し、タスクを作成し、プラグインを書く方法を迅速に理解するためのGradleの基本を解説します。

トレーニングレベル: 中級
所要時間: 約35分

内容

  1. Gradleディレクトリの構造
  2. マルチプロジェクトビルド
  3. Gradleビルドのライフサイクル
  4. 設定ファイルの書き方
  5. ビルドスクリプトの書き方
  6. タスクの使用方法
  7. タスクの作成方法
  8. プラグインの使用方法
  9. プラグインの作成方法

2. Gradleビルド作成チュートリアル

このチュートリアルでは、Gradleの初期化からシンプルなスクリプトプラグインを作成するところまでを学びます。事前の経験は必要ありませんが、JavaやKotlinの基本知識があると役立ちます。

Gradleのインストールがまだの場合は、インストールセクションを参照してください。

トレーニングレベル: 中級
所要時間: 約65分

内容

  1. プロジェクトの初期化
  2. ビルドライフサイクルの理解
  3. マルチプロジェクトビルド
  4. 設定ファイルの作成
  5. ビルドスクリプトの作成
  6. タスクの作成
  7. プラグインの作成

これでGradleの基礎からカスタム構成への準備が整いました。引き続き学習を進め、Gradleの活用スキルを高めてください!

ta.toshiota.toshio

Gradleディレクトリ

目次

Gradleは、作業を実行および管理するために以下の2つの主要なディレクトリを使用します:

  1. Gradleユーザーホームディレクトリ
  2. プロジェクトルートディレクトリ

author gradle 2


Gradle ディレクトリ構造の概要

提供された情報源 "Gradle Directories" から、Gradle の主要なディレクトリ構造と重要な概念をまとめます。

Gradle が使用する主なディレクトリ

Gradle は、主に2つのディレクトリを使用して動作します。

Gradle ユーザーホームディレクトリ (~/.gradle または C:\Users<USERNAME>.gradle)

  • グローバルな設定プロパティ、初期化スクリプト、キャッシュ、ログファイルを保存します。
  • 環境変数 GRADLE_USER_HOME で設定できます。
  • Gradle のインストールディレクトリである GRADLE_HOME とは異なります。
├── caches (1)
│ ├── 4.8 (2)
│ ├── 4.9 (2)
│ ├── ⋮
│ ├── jars-3 (3)
│ └── modules-2 (3)
├── daemon (4)
│ ├── ⋮
│ ├── 4.8
│ └── 4.9
├── init.d (5)
│ └── my-setup.gradle
├── jdks (6)
│ ├── ⋮
│ └── jdk-14.0.2+12
├── wrapper
│ └── dists (7)
│ ├── ⋮
│ ├── gradle-4.8-bin
│ ├── gradle-4.9-all
│ └── gradle-4.9-bin
└── gradle.properties (8)
  • (1) グローバルキャッシュディレクトリ(プロジェクト固有ではないものすべて)
  • (2) バージョン固有のキャッシュ(例:増分ビルドのサポート)
  • (3) 共有キャッシュ(例:依存関係の成果物)
  • (4) Gradle デーモンのレジストリとログ
  • (5) グローバル初期化スクリプト
  • (6) ツールチェーンサポートによってダウンロードされた JDK
  • (7) Gradle Wrapper によってダウンロードされたディストリビューション
  • (8) グローバル Gradle 設定プロパティ

プロジェクトルートディレクトリ

  • プロジェクトのすべてのソースファイルが含まれます。
  • .gradle や build などの Gradle が生成するファイルとディレクトリ、および Gradle 設定ディレクトリ gradle も含まれます。
  • gradle ディレクトリは通常ソース管理にチェックインされますが、 build と .gradle ディレクトリには、ビルドの出力、キャッシュ、および Gradle が増分ビルドなどの機能をサポートするために使用するその他の一時ファイルが含まれます。
├── .gradle (1)
│ ├── 4.8 (2)
│ ├── 4.9 (2)
│ └── ⋮
├─ build (3)
├── radle│ └── wrapper (4)
├── gradle.properties (5)
├── gradlew (6)
├── gradlew.bat (6)
├── settings.gradle.kts (7)
├── subproject-one (8)
| └── build.gradle.kts (9)
├── subproject-two (8)
| └── build.gradle.kts (9)
└── ⋮
  • (1) Gradle によって生成されたプロジェクト固有のキャッシュディレクトリ
  • (2) バージョン固有のキャッシュ(例:増分ビルドのサポート)
  • (3) このプロジェクトのビルドディレクトリ。Gradle はすべてのビルド成果物をここに生成します。
  • (4) Gradle Wrapper の JAR ファイルと設定が含まれています。
  • (5) プロジェクト固有の Gradle 設定プロパティ。
  • (6) Gradle Wrapper を使用してビルドを実行するためのスクリプト。
  • (7) サブプロジェクトのリストが定義されているプロジェクトの設定ファイル。
  • (8) 通常、プロジェクトは1つ以上のサブプロジェクトに編成されます。
  • (9) 各サブプロジェクトには独自の Gradle ビルドスクリプトがあります。

重要なポイント

  • Gradle は、グローバルとプロジェクトレベルの両方で設定とキャッシュを管理します。
  • 異なる Gradle バージョンは、互いに干渉することなく共存できます。
  • Gradle Wrapper は、プロジェクトのビルドに必要な Gradle ディストリビューションを自動的にダウンロードします。

さらなる学習

Gradle Directories リファレンスを参照して、詳細を学ぶことができます。 また、マルチプロジェクトビルドの構造化方法を学ぶことも推奨されます。

ta.toshiota.toshio

https://docs.gradle.org/current/userguide/intro_multi_project_builds.html

マルチプロジェクトビルドの基本

目次

Gradleはマルチプロジェクトビルドをサポートしています。

gradle basic 9

小規模なプロジェクトやモノリシックアプリケーションでは、1つのビルドファイルとソースツリーを持つことが一般的ですが、プロジェクトを複数の小さなモジュールに分割するケースが増えています。「相互依存」という言葉が重要で、多くの場合、複数のモジュールを単一のビルドで連携させる必要があります。

Gradleは、このようなシナリオを「マルチプロジェクトビルド」を通じてサポートします。この構成は、マルチモジュールプロジェクトと呼ばれることもあります。Gradleでは、モジュールを「サブプロジェクト」と呼びます。

マルチプロジェクトビルドは、1つのルートプロジェクトと1つ以上のサブプロジェクトで構成されます。


マルチプロジェクト構造

以下は、3つのサブプロジェクトを持つマルチプロジェクトビルドの構造を表しています。

multi project structure

ディレクトリ構造は以下のようになります:

├── .gradle
│   └── ⋮
├── gradle
│   ├── libs.versions.toml
│   └── wrapper
├── gradlew
├── gradlew.bat
├── settings.gradle.kts 
├── sub-project-1
│   └── build.gradle.kts    
├── sub-project-2
│   └── build.gradle.kts    
└── sub-project-3
    └── build.gradle.kts    
settings.gradle.kts すべてのサブプロジェクトを含める必要があります。
各サブプロジェクト 自身の build.gradle.kts ファイルを持つ必要があります。

マルチプロジェクト標準

Gradleコミュニティでは、マルチプロジェクトビルド構造に2つの標準があります:

  1. buildSrc を使ったマルチプロジェクトビルド
    Gradleプロジェクトルートにある buildSrc は、ビルドロジックを含むサブプロジェクトのようなディレクトリです。

  2. コンポジットビルド
    他のビルドを含むビルドで、build-logic ディレクトリが再利用可能なビルドロジックを含む構造です。

multi project standards


1. buildSrc を使ったマルチプロジェクトビルド

マルチプロジェクトビルドを使用すると、多くのモジュールを持つプロジェクトを整理し、それらのモジュール間の依存関係を結び、共通のビルドロジックを簡単に共有できます。

例として、以下のようなモジュールを持つビルドがあります:

  • mobile-app
  • web-app
  • api
  • lib
  • documentation

構造は次のようになります:

.
├── gradle
├── gradlew
├── settings.gradle.kts
├── buildSrc
│   ├── build.gradle.kts
│   └── src/main/kotlin/shared-build-conventions.gradle.kts
├── mobile-app
│   └── build.gradle.kts
├── web-app
│   └── build.gradle.kts
├── api
│   └── build.gradle.kts
├── lib
│   └── build.gradle.kts
└── documentation
    └── build.gradle.kts

この場合、web-appmobile-applib に依存しています。そのため、Gradleが web-appmobile-app をビルドするには、まず lib をビルドする必要があります。

ルートの settings.gradle.kts ファイルは次のようになります:

include("mobile-app", "web-app", "api", "lib", "documentation")

サブプロジェクト(モジュール)が含まれる順番は問題ではない。

buildSrc ディレクトリはGradleによって自動的に認識されます。共通の設定や、カスタムタスクやプラグインなどの命令型ビルドロジックを定義・管理する場所として適しています。

buildSrc 内の build.gradle(.kts) ファイルは、特別なサブプロジェクトとしてビルドに自動的に含まれます。たとえば、buildSrc/src/main/java 内のコードは、ルートビルドスクリプトのクラスパスに含まれ、ビルド内の任意のサブプロジェクト(例: web-app, mobile-app, lib など)で利用可能になります。

サブプロジェクト間の依存関係の宣言方法については、サブプロジェクト間のビルドロジックの共有 を参照してください。

2. コンポジットビルド (Composite Builds)

コンポジットビルド(included builds とも呼ばれる)は、ビルド間でロジックを共有する場合(サブプロジェクトではなく)、または共有ビルドロジック(例: コンベンションプラグイン)へのアクセスを分離する場合に最適です。

以下の例を見てみましょう。buildSrc のロジックはプラグインを含むプロジェクトに変換され、ルートプロジェクトのビルドから独立して作業および公開できるようになりました。

プラグインは build-logic という名前のビルドに移動され、ビルドスクリプトと設定ファイルが含まれます:

.
├── gradle
├── gradlew
├── settings.gradle.kts
├── build-logic
│   ├── settings.gradle.kts
│   └── conventions
│       ├── build.gradle.kts
│       └── src/main/kotlin/shared-build-conventions.gradle.kts
├── mobile-app
│   └── build.gradle.kts
├── web-app
│   └── build.gradle.kts
├── api
│   └── build.gradle.kts
├── lib
│   └── build.gradle.kts
└── documentation
    └── build.gradle.kts

build-logicがルートプロジェクトのサブディレクトリにあることは関係ない。 必要であれば、このフォルダはルート・プロジェクトの外側に置くこともできる。

ルートの設定ファイルは、build-logic ビルド全体 を含めます:

settings.gradle.kts

pluginManagement {
    includeBuild("build-logic")
}
include("mobile-app", "web-app", "api", "lib", "documentation")

includeBuild を使用した コンポジットビルドの作成方法 を参照してください。


マルチプロジェクトのパス

プロジェクトのパスは以下の形式を持ちます:先頭にルートプロジェクトを示すコロンが付きます(オプション)。ルートプロジェクト(:)は唯一、名前で指定されないプロジェクトです。

プロジェクトパスの残りの部分は、コロンで区切られたプロジェクト名のシーケンスで、次のプロジェクトが前のプロジェクトのサブプロジェクトであることを表します:

:sub-project-1

gradle projects を実行するとプロジェクトパスが表示されます:

------------------------------------------------------------
Root project 'project'
------------------------------------------------------------

Root project 'project'
+--- Project ':sub-project-1'
\--- Project ':sub-project-2'

プロジェクトパスは通常、ファイルシステムのレイアウトを反映しますが、例外もあります。特に コンポジットビルド では例外が見られます。


プロジェクト構造の特定

gradle projects コマンドを使用してプロジェクト構造を特定できます。

以下は、マルチプロジェクトビルドの例です:

$ gradle -q projects

Projects:

------------------------------------------------------------
Root project 'multiproject'
------------------------------------------------------------

Root project 'multiproject'
+--- Project ':api'
+--- Project ':services'
|    +--- Project ':services:shared'
|    \--- Project ':services:webservice'
\--- Project ':shared'

プロジェクトのタスク一覧を確認するには、gradle <project-path>:tasks を実行します。例:gradle :api:tasks

マルチプロジェクトビルドでは実行可能なタスクの集合体を構成します。違いとして、どのプロジェクトのタスクを実行するかを制御できます。

以下のセクションでは、マルチプロジェクトビルドでタスクを実行する2つの方法について説明します。


タスクを名前で実行する

gradle test コマンドは、現在の作業ディレクトリに相対して存在するすべてのサブプロジェクトで test タスクを実行します。

  • ルートプロジェクトディレクトリから実行すると、test タスクが apisharedservices:sharedservices:webservice で実行されます。
  • services プロジェクトディレクトリから実行すると、services:sharedservices:webservice のタスクのみが実行されます。

Gradleの基本ルールは「この名前を持つすべてのタスクを階層下で実行する」というものです。さらに、「指定された名前のタスクが存在しない場合、エラーを報告する」動作になります。

helpやdependenciesのようないくつかのタスクセレクタは、画面に表示される情報量を減らすために、すべてのサブプロジェクトではなく、呼び出されたプロジェクト上でのみタスクを実行します。


完全修飾名でタスクを実行する

完全修飾名を使用して特定のサブプロジェクトの特定タスクを実行できます。例:gradle :services:webservice:build は、webservice サブプロジェクトの build タスクを実行します。

タスクの完全修飾名は、その プロジェクトパス とタスク名を組み合わせたものです。

特定のサブプロジェクトに存在するタスクを確認するには、tasks タスクを使用します。例:gradle :services:webservice:tasks


マルチプロジェクトのビルドとテスト

build タスクは通常、単一のプロジェクトをコンパイル、テスト、確認するために使用されます。

マルチプロジェクトビルドでは、これらのタスクを複数のプロジェクトにまたがって実行する必要がある場合があります。このような場合、buildNeeded および buildDependents タスクが役立ちます。

この例 では、:services:person-service プロジェクトは :api および :shared プロジェクトに依存しています。また、:api プロジェクトは :shared プロジェクトにも依存しています。

例えば、:api プロジェクトで作業しており、clean を実行した後にまだプロジェクト全体をビルドしていないと仮定します。この場合、必要なサポート用JARファイルのみをビルドし、変更した部分のコード品質とユニットテストを実行したい場合があります。

その場合、build タスクを実行します:

$ gradle :api:build
> Task :shared:compileJava
> Task :shared:processResources
> Task :shared:classes
> Task :shared:jar
> Task :api:compileJava
> Task :api:processResources
> Task :api:classes
> Task :api:jar
> Task :api:assemble
> Task :api:compileTestJava
> Task :api:processTestResources
> Task :api:testClasses
> Task :api:test
> Task :api:check
> Task :api:build

BUILD SUCCESSFUL in 0s

バージョン管理システムからソースコードの最新バージョンを取得した場合、:api が依存する他のプロジェクトに変更が含まれている可能性があります。この場合、依存しているすべてのプロジェクトをビルドしてテストする必要があります。

buildNeeded タスクは、testRuntime 構成におけるプロジェクト依存関係からすべてのプロジェクトをビルドし、テストします:

$ gradle :api:buildNeeded
> Task :shared:compileJava
> Task :shared:processResources
> Task :shared:classes
> Task :shared:jar
> Task :api:compileJava
> Task :api:processResources
> Task :api:classes
> Task :api:jar
> Task :api:assemble
> Task :api:compileTestJava
> Task :api:processTestResources
> Task :api:testClasses
> Task :api:test
> Task :api:check
> Task :api:build
> Task :shared:assemble
> Task :shared:compileTestJava
> Task :shared:processTestResources
> Task :shared:testClasses
> Task :shared:test
> Task :shared:check
> Task :shared:build
> Task :shared:buildNeeded
> Task :api:buildNeeded

BUILD SUCCESSFUL in 0s

:api プロジェクトの一部をリファクタリングし、それが他のプロジェクトで使用されている場合、:api プロジェクトのみをテストするのでは不十分です。:api プロジェクトに依存しているすべてのプロジェクトをテストする必要があります。

buildDependents タスクは、指定されたプロジェクトにプロジェクト依存関係(testRuntime 構成)を持つすべてのプロジェクトをテストします:

$ gradle :api:buildDependents
> Task :shared:compileJava
> Task :shared:processResources
> Task :shared:classes
> Task :shared:jar
> Task :api:compileJava
> Task :api:processResources
> Task :api:classes
> Task :api:jar
> Task :api:assemble
> Task :api:compileTestJava
> Task :api:processTestResources
> Task :api:testClasses
> Task :api:test
> Task :api:check
> Task :api:build
> Task :services:person-service:compileJava
> Task :services:person-service:processResources
> Task :services:person-service:classes
> Task :services:person-service:jar
> Task :services:person-service:assemble
> Task :services:person-service:compileTestJava
> Task :services:person-service:processTestResources
> Task :services:person-service:testClasses
> Task :services:person-service:test
> Task :services:person-service:check
> Task :services:person-service:build
> Task :services:person-service:buildDependents
> Task :api:buildDependents

BUILD SUCCESSFUL in 0s

最後に、すべてのプロジェクトでビルドとテストを実行することが可能です。ルートプロジェクトフォルダ内で任意のタスクを実行すると、同じ名前のタスクがすべての子プロジェクトでも実行されます。

すべてのプロジェクトをビルドしてテストするには、gradle build を実行できます。

詳しくは ビルド構造化の章 を参照してください。

ta.toshiota.toshio

https://docs.gradle.org/current/userguide/build_lifecycle.html#build_lifecycle

ビルドライフサイクル

目次

ビルドの作成者として、タスクを定義し、それらの依存関係を指定します。Gradle は、これらの依存関係によって指定された順序でタスクを実行することを保証します。

ビルドスクリプトとプラグインが、タスクの依存関係グラフを設定します。

例えば、プロジェクトに buildassemblecreateDocs というタスクが含まれている場合、ビルドスクリプトを設定して、buildassemblecreateDocs の順に実行するようにできます。


タスクグラフ

Gradle は、タスクを実行する前に タスクグラフを構築します。

ビルド内のすべてのプロジェクトにおいて、タスクは 有向非巡回グラフ (Directed Acyclic Graph) (DAG) を形成します。

以下はタスクグラフの例です。依存関係は矢印で表されています:

タスクDAGの例

プラグインとビルドスクリプトは、タスク依存関係のメカニズム注釈付きの入力/出力 を介してタスクグラフに貢献します。


ビルドフェーズ

Gradle のビルドは3つの明確なフェーズで構成されています。

Gradleのライフサイクル

Gradle はこれらのフェーズを順番に実行します:

フェーズ1: 初期化

  • settings.gradle(.kts) ファイルを検出。
  • Settings インスタンスを作成。
  • 設定ファイルを評価し、ビルドを構成するプロジェクト(および含まれるビルド)を特定。
  • 各プロジェクトの Project インスタンスを作成。

フェーズ2: 設定

  • すべてのプロジェクトのビルドスクリプト(build.gradle(.kts))を評価。
  • 指定されたタスクのタスクグラフを作成。

フェーズ3: 実行

  • 選択されたタスクをスケジュールおよび実行。
  • タスク間の依存関係に基づいて実行順序を決定。
  • タスクの実行は並列で行うことも可能。

ビルドライフサイクルの例


以下は、各ビルドフェーズに対応する設定およびビルドファイルの部分を示す例です:

settings.gradle.kts

rootProject.name = "basic"
println("これは初期化フェーズで実行されます。")

build.gradle.kts

println("これは設定フェーズで実行されます。")

tasks.register("configured") {
    println("これは設定フェーズでも実行されます(:configured タスクがビルドで使用されているため)。")
}

tasks.register("test") {
    doLast {
        println("これは実行フェーズで実行されます。")
    }
}

tasks.register("testBoth") {
    doFirst {
        println("これは実行フェーズの最初に実行されます。")
    }
    doLast {
        println("これは実行フェーズの最後に実行されます。")
    }
    println("これは設定フェーズでも実行されます(:testBoth タスクがビルドで使用されているため)。")
}

以下のコマンドは、上記で指定された test および testBoth タスクを実行します。Gradle は指定されたタスクとその依存関係のみを設定するため、configured タスクは設定されません:

> gradle test testBoth
これは初期化フェーズで実行されます。

> Configure project :
これは設定フェーズで実行されます。
これは設定フェーズでも実行されます(:testBoth タスクがビルドで使用されているため)。

> Task :test
これは実行フェーズで実行されます。

> Task :testBoth
これは実行フェーズの最初に実行されます。
これは実行フェーズの最後に実行されます。

BUILD SUCCESSFUL in 0s
2 actionable tasks: 2 executed

フェーズ1: 初期化

初期化フェーズ では、Gradle がビルドに参加するプロジェクト(ルートおよびサブプロジェクト)と含まれるビルドを検出します。

まず、settings.gradle(.kts) ファイルを評価し、Settings オブジェクトをインスタンス化します。その後、各プロジェクトの Project インスタンスを作成します。


フェーズ2: 設定

設定フェーズ では、初期化フェーズで検出されたプロジェクトにタスクやその他のプロパティを追加します。


フェーズ3: 実行

実行フェーズ では、Gradle がタスクを実行します。

設定フェーズで生成されたタスク実行グラフを使用して、どのタスクを実行するかを決定します。

ta.toshiota.toshio

https://docs.gradle.org/current/userguide/writing_settings_files.html

設定ファイルの記述

目次

設定ファイルは、すべてのGradleビルドのエントリポイントです。

author gradle 7

Gradleビルドライフサイクルの初期段階(初期化フェーズ)では、プロジェクトのルートディレクトリ内で設定ファイルを検索します。

settings.gradle(.kts)が見つかると、GradleはSettingsオブジェクトをインスタンス化します。

このSettingsオブジェクトの目的の1つは、ビルドに含めるすべてのプロジェクトを宣言できるようにすることです。


設定スクリプト

設定スクリプトは、Groovy形式のsettings.gradleファイルまたはKotlin形式のsettings.gradle.ktsファイルです。

Gradleがビルド用にプロジェクトを組み立てる前に、Settingsインスタンスを作成し、そのインスタンスに対して設定ファイルを実行します。

Settings

設定スクリプトが実行されると、このSettingsオブジェクトが設定されます。したがって、設定ファイルSettingsオブジェクトを定義します。

Settingsインスタンスとsettings.gradle(.kts)ファイルは1対1の対応関係があります。

Settingsオブジェクト

SettingsオブジェクトはGradle APIの一部です。

  • Groovy DSLのSettingsオブジェクトのドキュメントはこちら
  • Kotlin DSLのSettingsオブジェクトのドキュメントはこちら

多くのトップレベルプロパティやブロックがSettings APIの一部です。

例えば、Settings.rootProjectプロパティを使用して、設定スクリプト内でルートプロジェクト名を設定できます:

settings.rootProject.name = "application"

通常は以下のように短縮されます:

Kotlin

rootProject.name = "application"

標準Settingsプロパティ

Settingsオブジェクトは設定スクリプト内で使用できる標準プロパティを公開します。

主なプロパティの例:

プロパティ名 説明
buildCache ビルドキャッシュの設定
plugins 適用されたプラグインのコンテナ
rootDir ビルドのルートディレクトリ
rootProject ビルドのルートプロジェクト
settings このSettingsオブジェクトを返す

主なメソッドの例:

メソッド名 説明
include() 指定したプロジェクトをビルドに追加
includeBuild() 指定されたパスのビルドをコンポジットビルドに含める

設定スクリプトの構造

設定スクリプトは、Gradle APIへの一連のメソッド呼び出しで構成されます。GroovyやKotlin言語の特殊なショートカットである{ …​ }をよく使用します。

単純に言えば、plugins { }ブロックは次のようなメソッド呼び出しを短縮したものです:

plugins(function() {
    id("plugin")
})

スクリプト内の各コード行は、Gradle APIの呼び出しを表します。

以下は設定スクリプトの例です:

Kotlin

pluginManagement {
    repositories {
        gradlePluginPortal()
    }
}

plugins {   
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}

rootProject.name = "simple-project"

dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
}

include("sub-project-a")     
include("sub-project-b")
include("sub-project-c")

各ブロックの解説

1. プラグインの場所を定義する

設定ファイルでは、pluginManagementブロックを使用してビルド用のプラグインのバージョンとリポジトリを管理できます。このブロックは、プロジェクトで使用するプラグインと、それらを解決するリポジトリを定義する方法を提供します。

Kotlin または Groovy

settings.gradle.kts

pluginManagement {  
    repositories {
        gradlePluginPortal()
    }
}

2. 設定プラグインを適用する

設定ファイルでは、プロジェクトの設定を構成するために必要なプラグインを適用できます。以下の例では、一般的なDevelocityプラグインToolchain Resolverプラグインを使用しています。

設定ファイル内で適用されるプラグインは、Settingsオブジェクトのみに影響します。

Kotlin または Groovy

settings.gradle.kts

plugins {   
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}

3. ルートプロジェクト名を定義する

設定ファイルでは、rootProject.name プロパティを使用してプロジェクト名を定義します。

Kotlin または Groovy

settings.gradle.kts

rootProject.name = "simple-project"     

ビルドごとにルートプロジェクトは1つだけです。


4. 依存関係解決戦略を定義する

設定ファイルでは、プロジェクト全体の依存関係解決のためのルールや設定を定義できます。これにより、依存関係解決を一元管理しカスタマイズできます。

Kotlin または Groovy

settings.gradle.kts

dependencyResolutionManagement {    
    repositories {
        mavenCentral()
    }
}

このセクションでバージョンカタログを含めることもできます。


5. サブプロジェクトをビルドに追加する

設定ファイルでは、includeステートメントを使用してすべてのサブプロジェクトを追加することで、プロジェクトの構造を定義します。

Kotlin または Groovy

settings.gradle.kts

include("sub-project-a")     
include("sub-project-b")
include("sub-project-c")

また、includeBuildを使用して、ビルド全体を含めることもできます。

設定ファイルスクリプティング

GroovyやKotlinの完全な機能を活用してスクリプトを記述できます。

たとえば、ディレクトリを自動的に検出してサブプロジェクトを追加することも可能です:

rootDir.listFiles()
    .filter { it.isDirectory && File(it, "build.gradle.kts").exists() }
    .forEach {
        include(it.name)
    }

このようなロジックは通常、プラグインとして開発するのが推奨されます。

設定ファイルスクリプティング

Settingsオブジェクトには、ビルドを構成するために使用できる多くのプロパティやメソッドが用意されています。

多くのGradleスクリプトは通常、GroovyやKotlinの簡潔な構文で記述されますが、設定スクリプト内のすべての項目は本質的にGradle API内のSettingsオブジェクトのメソッドを呼び出しています。

include("app")

は実際には次のように展開されます:

settings.include("app")

さらに、GroovyやKotlin言語のフル機能を活用することが可能です。

例えば、includeを何度も使用してサブプロジェクトを追加する代わりに、プロジェクトルートフォルダ内のディレクトリ一覧を反復処理して自動的に追加することができます。

rootDir.listFiles().filter { it.isDirectory && (new File(it, "build.gradle.kts").exists()) }.forEach {
    include(it.name)
}
この種のロジックはプラグインとして開発するべきです。
ta.toshiota.toshio

閑話休題

settings.gradle.kts

pluginManagement {  
    repositories {
        gradlePluginPortal()
    }
}

plugins {   
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}

rootProject.name = "simple-project"     

dependencyResolutionManagement {    
    repositories {
        mavenCentral()
    }
}

include("sub-project-a")     
include("sub-project-b")
include("sub-project-c")

以下は、settings.gradle.ktsファイルに記述されたコードの詳細な解説です。


1. プラグイン管理 (pluginManagement ブロック)

pluginManagement {  
    repositories {
        gradlePluginPortal()
    }
}
  • pluginManagement ブロックは、ビルドで使用するプラグインのバージョンと、それらを解決するリポジトリを管理します。
  • repositories ブロックでは、Gradleプラグインを解決するリポジトリを指定しています。
    • gradlePluginPortal() は、Gradleが公式に提供するプラグインリポジトリを指します。

この部分は、どこからプラグインを取得するかを定義しています。


2. プラグイン適用 (plugins ブロック)

plugins {   
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}
  • plugins ブロックは、設定ファイルに適用するプラグインを指定します。
  • id("org.gradle.toolchains.foojay-resolver-convention") は、Toolchain Resolverプラグインを適用します。
    • このプラグインは、プロジェクトのための適切なJavaツールチェーンを解決するための設定を簡単に行うために使用されます。
  • version "0.8.0" は、このプラグインのバージョンを指定しています。

3. ルートプロジェクト名の定義

rootProject.name = "simple-project"
  • rootProject.name は、ビルドのルートプロジェクト(最上位プロジェクト)の名前を定義します。
  • この例では、ルートプロジェクトの名前が "simple-project" に設定されています。

4. 依存関係解決管理 (dependencyResolutionManagement ブロック)

dependencyResolutionManagement {    
    repositories {
        mavenCentral()
    }
}
  • dependencyResolutionManagement ブロックは、依存関係の解決戦略を定義します。
  • repositories ブロックでは、依存関係を解決するリポジトリを指定しています。
    • mavenCentral() は、Maven Centralリポジトリを指します。多くのオープンソースライブラリがホストされているリポジトリです。

この部分により、プロジェクトの依存関係がMaven Centralから解決されることを指定しています。


5. サブプロジェクトの定義

include("sub-project-a")     
include("sub-project-b")
include("sub-project-c")
  • include メソッドは、ビルドに含めるサブプロジェクトを指定します。
    • "sub-project-a", "sub-project-b", "sub-project-c" は、それぞれのサブプロジェクトの名前です。
    • これらはルートプロジェクトのサブディレクトリとして存在し、各ディレクトリにはbuild.gradle.ktsまたはbuild.gradleが配置されている必要があります。

この部分により、これらのサブプロジェクトがビルドの一部として認識され、ルートプロジェクトの一部として扱われます。


全体の目的

このsettings.gradle.ktsファイルは、Gradleビルドの設定を行い、以下を定義しています:

  1. プラグインのリポジトリとバージョンを管理(pluginManagement)。
  2. 設定用プラグインの適用(plugins)。
  3. ルートプロジェクト名の定義(rootProject.name)。
  4. 依存関係を解決するリポジトリの指定(dependencyResolutionManagement)。
  5. ビルドに含めるサブプロジェクトの指定(include)。

この設定により、Gradleは指定された構造でプロジェクトをビルドし、依存関係やツールチェーンを適切に解決できます。

ta.toshiota.toshio

以下に日本語訳を提供します。


ビルドスクリプトの記述

目次

Gradleビルドライフサイクルの初期化フェーズでは、プロジェクトルートディレクトリに含まれるルートプロジェクトとサブプロジェクトを設定ファイルを使用して見つけます。

author gradle 6

その後、設定ファイルに含まれる各プロジェクトに対して、GradleはProjectインスタンスを作成します。

次に、設定ファイルで指定された各プロジェクトに対応するビルドスクリプトファイルを検索し、構成フェーズで使用します。


ビルドスクリプト

すべてのGradleビルドは、1つまたは複数のプロジェクトで構成されます。これには、_ルートプロジェクト_と_サブプロジェクト_が含まれます。

プロジェクトは通常、ビルドが必要なソフトウェアコンポーネント(ライブラリやアプリケーションなど)に対応します。例えば、ライブラリJAR、Webアプリケーション、または他のプロジェクトによって生成されたJARから構成されるZIPディストリビューションを表すことがあります。

一方で、アプリケーションをステージングまたは本番環境にデプロイするなどの作業を表す場合もあります。

GradleスクリプトはGroovy DSLまたはKotlin DSL(ドメイン固有言語)で記述されます。

ビルドスクリプトプロジェクトを構成し、Project型のオブジェクトに関連付けられます。

Build

ビルドスクリプトが実行されると、Projectが構成されます。

ビルドスクリプトは、Groovy形式の*.gradleファイル、またはKotlin形式の*.gradle.ktsファイルです。

_ビルドスクリプト_はProjectオブジェクトとその子を構成します。

Projectオブジェクト

ProjectオブジェクトはGradle APIの一部です:

  • Groovy DSLのProjectオブジェクトのドキュメントはこちら
  • Kotlin DSLのProjectオブジェクトのドキュメントはこちら

ビルドスクリプト内の多くのトップレベルプロパティやブロックは、Project APIの一部です。

例えば、次のビルドスクリプトでは、Project.nameプロパティを使用してプロジェクトの名前を出力します:

Kotlin

build.gradle.kts

println(name)
println(project.name)
$ gradle -q check
project-api
project-api

どちらのprintlnステートメントも同じプロパティを出力します。

  • 最初の行はProjectオブジェクトのnameプロパティを直接参照しています。
  • 2番目の行は、ビルドスクリプトで利用可能なprojectプロパティを使用してProjectオブジェクトを参照しています。

標準的なプロジェクトプロパティ

Projectオブジェクトはビルドスクリプト内で使用できる標準的なプロパティを公開します。

以下に、一般的なプロパティの例を示します:

プロパティ名 説明
name String プロジェクトディレクトリの名前
path String プロジェクトの完全修飾名
description String プロジェクトの説明
dependencies DependencyHandler プロジェクトの依存関係ハンドラー
repositories RepositoryHandler プロジェクトのリポジトリハンドラー
layout ProjectLayout プロジェクトの重要な場所にアクセスするためのオブジェクト
group Object プロジェクトのグループ
version Object プロジェクトのバージョン

以下に、一般的なメソッドの例を示します:

メソッド名 説明
uri() このプロジェクトのディレクトリを基準にしたURIへのファイルパスを解決
task() 指定した名前でタスクを作成し、プロジェクトに追加

ビルドスクリプトの構造

ビルドスクリプトは、GroovyやKotlinの特別なオブジェクト{ …​ }で構成されます。このオブジェクトは、Kotlinではラムダ、Groovyではクロージャと呼ばれます。

単純に言えば、plugins { }ブロックはメソッド呼び出しの短縮形であり、KotlinラムダオブジェクトやGroovyクロージャオブジェクトを引数として渡しています。

以下のコード:

plugins {  
    id("plugin")
}

は実際には次のように展開されます:

plugins(function() {
    id("plugin")
})

ブロックはGradle APIのメソッドにマッピングされています。

関数内のコードは、Kotlinのラムダ内ではreceiver、Groovyのクロージャ内ではdelegateと呼ばれるthisオブジェクトに対して実行されます。Gradleは適切なthisオブジェクトを判断し、対応する正しいメソッドを呼び出します。例えば、id("plugin")メソッド呼び出しのthisオブジェクトはPluginDependenciesSpec型です。

ビルドスクリプトはDSL上に構築されたGradle API呼び出しで構成されています。Gradleはスクリプトを上から順に1行ずつ実行します。


以下に例を示し、詳細を解説します:

Kotlin

build.gradle.kts

plugins {   
    id("application")
}

repositories {  
    mavenCentral()
}

dependencies {  
    testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.3")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
    implementation("com.google.guava:guava:32.1.1-jre")
}

application {   
    mainClass = "com.example.Main"
}

tasks.named<Test>("test") { 
    useJUnitPlatform()
}

tasks.named<Javadoc>("javadoc").configure {
    exclude("app/Internal*.java")
    exclude("app/internal/*")
}

tasks.register<Zip>("zip-reports") {
    from("Reports/")
    include("*")
    archiveFileName.set("Reports.zip")
    destinationDirectory.set(file("/dir"))
}

1. ビルドにプラグインを適用する

プラグインはGradleを拡張するために使用されます。また、プロジェクト設定をモジュール化し再利用するためにも利用されます。

プラグインは、PluginDependenciesSpecプラグインスクリプトブロックを使用して適用されます。

以下は推奨される記述方法の例です:

Kotlin

build.gradle.kts

plugins {   
    id("application")
}

この例では、Gradleに含まれるapplicationプラグインを適用しています。このプラグインは、プロジェクトをJavaアプリケーションとして記述します。


2. 依存関係を見つける場所を定義する

プロジェクトには通常、多くの依存関係が必要です。これらの依存関係には、プラグイン、ライブラリ、またはビルドを成功させるためにGradleがダウンロードする必要があるコンポーネントが含まれます。

ビルドスクリプトは、Gradleに依存関係のバイナリがどこにあるかを知らせるものです。複数の場所を指定することができます。

Kotlin

build.gradle.kts

repositories {  
    mavenCentral()
}

この例では、guavaライブラリやJetBrains Kotlinプラグイン(org.jetbrains.kotlin.jvm)は、Maven Centralリポジトリからダウンロードされます。


3. 依存関係を追加する

プロジェクトには通常、その作業を実行するために必要な多くの依存関係があります。これらの依存関係は、プロジェクトのソースコードにインポートされる事前コンパイル済みのクラスライブラリであることが多いです。

依存関係は設定を介して管理され、リポジトリから取得されます。

依存関係を管理するには、Project.getDependencies()メソッドで取得したDependencyHandlerを使用します。リポジトリを管理するには、Project.getRepositories()メソッドで取得したRepositoryHandlerを使用します。

Kotlin

build.gradle.kts

dependencies {  
    testImplementation("org.junit.jupiter:junit-jupiter-engine:5.9.3")
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
    implementation("com.google.guava:guava:32.1.1-jre")
}

この例では、アプリケーションコードでGoogleのguavaライブラリを使用しています。Guavaは、コレクション、キャッシュ、プリミティブサポート、並行処理、共通アノテーション、文字列処理、I/O、およびバリデーション用のユーティリティメソッドを提供します。


4. プロパティを設定する

プラグインは、拡張機能を使用してプロジェクトにプロパティやメソッドを追加できます。

Projectオブジェクトには、適用されたプラグインの設定やプロパティを格納するためのExtensionContainerオブジェクトが関連付けられています。

以下の例では、applicationプラグインがapplicationプロパティを追加しており、これを使用してJavaアプリケーションのメインクラスを指定しています:

Kotlin

build.gradle.kts

application {   
    mainClass = "com.example.Main"
}

5. タスクを登録および構成する

タスクは基本的な作業を実行するもので、クラスのコンパイル、ユニットテストの実行、WARファイルの圧縮などが含まれます。

タスクは通常、プラグインによって定義されますが、ビルドスクリプト内でタスクを登録または構成する必要がある場合もあります。

タスクの登録

タスクをプロジェクトに追加するには、TaskContainer.register(java.lang.String)メソッドを使用します。

Kotlin

build.gradle.kts

tasks.register<Zip>("zip-reports") {
    from("Reports/")
    include("*")
    archiveFileName.set("Reports.zip")
    destinationDirectory.set(file("/dir"))
}

TaskContainer.create(java.lang.String)メソッドも使用できますが、非推奨です。

tasks.create<Zip>("zip-reports") { }
register()の使用は、タスク構成の回避を可能にするため、create()より推奨されます。

タスクの構成

タスクを検索して構成するには、TaskCollection.named(java.lang.String)メソッドを使用します。

Kotlin

build.gradle.kts

tasks.named<Test>("test") { 
    useJUnitPlatform()
}

以下の例では、Javadocタスクを構成して、JavaコードからHTMLドキュメントを自動生成するようにしています:

Kotlin

build.gradle.kts

tasks.named<Javadoc>("javadoc").configure {
    exclude("app/Internal*.java")
    exclude("app/internal/*")
}

ビルドスクリプティング

ビルドスクリプトは、0個以上のステートメントおよびスクリプトブロックで構成されます:

println(project.layout.projectDirectory);

ステートメントには、メソッド呼び出し、プロパティの代入、ローカル変数の定義が含まれます:

version = "1.0.0.GA"

スクリプトブロックは、クロージャやラムダを引数として取るメソッド呼び出しです:

configurations {
}

クロージャ/ラムダ内のコードは、delegateまたはreceiverオブジェクトを構成します:

repositories {
    google()
}

ビルドスクリプトはGroovyまたはKotlinのスクリプトでもあります。

Kotlin

build.gradle.kts

tasks.register("upper") {
    doLast {
        val someString = "mY_nAmE"
        println("Original: $someString")
        println("Upper case: ${someString.toUpperCase()}")
    }
}
$ gradle -q upper
Original: mY_nAmE
Upper case: MY_NAME

スクリプト内には、メソッドやクラスの定義など、GroovyまたはKotlinスクリプトで許可される要素を含めることができます。

Kotlin

build.gradle.kts

tasks.register("count") {
    doLast {
        repeat(4) { print("$it ") }
    }
}
$ gradle -q count
0 1 2 3

柔軟なタスク登録

GroovyまたはKotlinの言語機能を使用して、ループ内で複数のタスクを登録することができます:

Kotlin

build.gradle.kts

repeat(4) { counter ->
    tasks.register("task$counter") {
        doLast {
            println("I'm task number $counter")
        }
    }
}
$ gradle -q task1
I'm task number 1

Gradleの型

Gradleでは、プロパティ、およびプロバイダーがビルドロジックを管理および構成するための基盤となります:

  • : Gradleは、ビルドコンポーネント(TaskConfigurationFileなど)を表す型を定義しています。これらの型を拡張して、カスタムタスクやドメインオブジェクトを作成できます。
  • プロパティ: Gradleプロパティ(Property<T>ListProperty<T>SetProperty<T>など)は、ビルド構成に使用されます。これらは遅延評価をサポートし、柔軟性とパフォーマンスを向上させます。
  • プロバイダー: Provider<T>は、遅延的に計算または取得される値を表します。プロバイダーはプロパティと一緒に使用されることが多く、値の計算を必要な時点まで遅らせることができます。

詳細については、Gradleの型についての理解をご覧ください。


変数の宣言

ビルドスクリプトでは、次の2種類の変数を宣言できます:

  1. ローカル変数
  2. 追加プロパティ

ローカル変数

ローカル変数は、Kotlinのvalキーワードを使用して宣言します。ローカル変数は、宣言されたスコープ内でのみ可視です。これは、基盤となるKotlin言語の機能です。

Kotlin

build.gradle.kts

val dest = "dest"

tasks.register<Copy>("copy") {
    from("source")
    into(dest)
}

この例では、ローカル変数dest"dest"ディレクトリを指しています。この変数はcopyタスク内で使用されています。


追加プロパティ

Gradleの拡張オブジェクト(プロジェクト、タスク、ソースセットなど)は、ユーザー定義のプロパティを保持することができます。

追加プロパティは、オブジェクトのextraプロパティを通じて追加、読み取り、設定できます。また、Kotlinのデリゲートプロパティby extraを使用してアクセスすることも可能です。

Kotlin

build.gradle.kts

plugins {
    id("java-library")
}

val springVersion by extra("3.1.0.RELEASE")
val emailNotification by extra { "build@master.org" }

sourceSets.all { extra["purpose"] = null }

sourceSets {
    main {
        extra["purpose"] = "production"
    }
    test {
        extra["purpose"] = "test"
    }
    create("plugin") {
        extra["purpose"] = "production"
    }
}

tasks.register("printProperties") {
    val springVersion = springVersion
    val emailNotification = emailNotification
    val productionSourceSets = provider {
        sourceSets.matching { it.extra["purpose"] == "production" }.map { it.name }
    }
    doLast {
        println(springVersion)
        println(emailNotification)
        productionSourceSets.get().forEach { println(it) }
    }
}
$ gradle -q printProperties
3.1.0.RELEASE
build@master.org
main
plugin

この例では、extra を使用してプロジェクトオブジェクトに2つの追加プロパティを追加しています。さらに、この例では、extra["purpose"]null を設定することで、各ソースセットに purpose という名前のプロパティを追加しています。追加されたプロパティは、extra を介して読み書きが可能です。

Gradleでは、プロパティを追加するために特別な構文が必要です。これは、存在しないプロパティをスクリプト内で設定しようとした場合に、すぐにエラーを検出できるようにするためです。この仕組みにより、所有するオブジェクトのどこからでも追加プロパティにアクセスすることが可能です。そのため、追加プロパティのスコープはローカル変数よりも広くなります。また、サブプロジェクトは親プロジェクトの追加プロパティにアクセスすることができます。

詳細については、ExtraPropertiesExtensionをご覧ください。


任意のオブジェクトを構成する

次の例では、任意のオブジェクトを構成する方法を示しています:

Kotlin

build.gradle.kts

class UserInfo(
    var name: String? = null,
    var email: String? = null
)

tasks.register("greet") {
    val user = UserInfo().apply {
        name = "Isaac Newton"
        email = "isaac@newton.me"
    }
    doLast {
        println(user.name)
        println(user.email)
    }
}
$ gradle -q greet
Isaac Newton
isaac@newton.me

このスクリプトでは、次を行っています:

  1. UserInfoクラスを定義し、nameemailプロパティを持つオブジェクトを作成。
  2. タスクgreetを登録し、UserInfoオブジェクトを構成してdoLastブロック内で使用。

クロージャデリゲート

Groovyのクロージャにはdelegateオブジェクトがあります。Groovyは、このデリゲートを使用して、非ローカル変数やクロージャパラメータへの変数・メソッド参照を検索します。Gradleは、このデリゲートを構成クロージャに使用し、デリゲートオブジェクトを構成対象のオブジェクトに設定します。

Groovy

build.gradle

dependencies {
    assert delegate == project.dependencies
    testImplementation('junit:junit:4.13')
    delegate.testImplementation('junit:junit:4.13')
}

この例では、dependenciesクロージャのデリゲートはproject.dependenciesオブジェクトを指します。


デフォルトインポート

ビルドスクリプトを簡潔にするために、Gradleはスクリプトに自動的にいくつかのインポート文を追加します。

その結果、throw new org.gradle.api.tasks.StopExecutionException()と記述する代わりに、throw new StopExecutionException()と記述できます。

Gradleは、各スクリプトに次のインポートを暗黙的に追加します:

詳細はこちら https://docs.gradle.org/current/userguide/writing_build_scripts.html#script-default-imports

ta.toshiota.toshio

閑話休題

Gradleのtasks.namedtasks.registerは、どちらもタスクを操作するために使用しますが、目的や動作に違いがあります。


tasks.register

  • 目的: 新しいタスクを登録する。
  • 動作:
    1. タスクがまだ存在しない場合に、新しいタスクを作成して登録します。
    2. タスクの登録は即座に行われますが、構成(configuration)は遅延され、タスクが必要になるまで実行されません(構成回避)。
  • 戻り値: TaskProvider<T>(タスクへの遅延参照)。
  • 主な用途: 新しいタスクを作成し、必要な設定を適用する場合に使用します。

tasks.register<Test>("customTest") {
    useJUnitPlatform()
}
  • タスクcustomTestがまだ存在しない場合に作成されます。
  • useJUnitPlatform()のような構成は、タスクが実行される直前まで遅延されます。

tasks.named

  • 目的: 既存のタスクを取得して操作する。
  • 動作:
    1. 指定した名前のタスクがすでに登録済みである場合に、そのタスクを取得します。
    2. 取得したタスクに対して設定や変更を加えることができます。
    3. タスクが未登録の場合、エラーになります(登録されていないタスクを操作しようとした場合に失敗)。
  • 戻り値: TaskProvider<T>(タスクへの遅延参照)。
  • 主な用途: すでに存在するタスクをカスタマイズまたは再構成する場合に使用します。

tasks.named<Test>("test") {
    useJUnitPlatform()
}
  • Gradleのデフォルトタスクtestが対象。
  • すでに登録済みのタスクtestに対してuseJUnitPlatform()を適用します。

違いの比較

特徴 tasks.register tasks.named
目的 新しいタスクを登録する。 既存のタスクを取得して操作する。
動作対象 未登録のタスクを新規作成し登録。 登録済みのタスクのみを操作可能。
タスクの存在チェック 必要なし。自動的に作成される。 対象タスクが存在しない場合、エラー。
戻り値 TaskProvider<T>(遅延参照) TaskProvider<T>(遅延参照)
主な用途 新しいカスタムタスクを作成。 既存タスクの設定変更や再構成。
エラーの可能性 タスクが登録されるためエラーにならない。 タスクが未登録の場合、エラーになる。

選択の基準

  • 新しいタスクを作成する場合は、tasks.registerを使用。
  • 既存のタスクを操作する場合は、tasks.namedを使用。

実用的な例

新しいタスクの登録

tasks.register<Zip>("zipReports") {
    from("Reports/")
    archiveFileName.set("Reports.zip")
    destinationDirectory.set(file("build/reports"))
}

既存タスクの再構成

tasks.named<Zip>("zipReports") {
    exclude("*.tmp") // 特定のファイルを除外
}
  • zipReportsがすでにregisterなどで登録されている場合に再構成を行います。
  • zipReportsが未登録の場合、このスクリプトはエラーになります。

まとめ

  • register: 新しいタスクを定義する。
  • named: 既存タスクを取得して変更する。

どちらも遅延参照(TaskProvider)を利用しており、タスク構成の効率化やパフォーマンス向上に寄与します。

ta.toshiota.toshio

閑話休題

sourceSetsとは

sourceSets は Gradle のビルドスクリプトで使用される ソースコードの構成を定義するオブジェクト です。主に、プロジェクト内で使用されるコードのグループ(ディレクトリ構造や依存関係)を指定するために使われます。


基本的な概要

Gradle プロジェクトには、デフォルトでいくつかの ソースセット が用意されています。それぞれのソースセットには、以下のような構成要素が含まれます:

  • ソースコード(java など)
  • リソース(resources など)
  • 依存関係
  • 出力ディレクトリ

デフォルトのソースセット

Gradle で java プラグインを適用すると、以下のソースセットが自動的に作成されます。

1. main ソースセット

  • アプリケーションやライブラリの 本番コード を含む。
  • デフォルトのソースディレクトリ:
    • ソースコード:src/main/java
    • リソース:src/main/resources

2. test ソースセット

  • アプリケーションやライブラリの テストコード を含む。
  • デフォルトのソースディレクトリ:
    • ソースコード:src/test/java
    • リソース:src/test/resources

sourceSets のプロパティとカスタマイズ

sourceSets オブジェクトを使用して、ソースセットをカスタマイズできます。

プロパティ

  • java: Java ソースコードのパスを定義する。
  • resources: リソースファイルのパスを定義する。
  • compileClasspath: コンパイル時のクラスパス。
  • runtimeClasspath: 実行時のクラスパス。

カスタマイズの例

ソースセットのカスタマイズ

sourceSets {
    main {
        java.srcDir("src/main/kotlin") // Kotlin ソースコードを追加
        resources.srcDir("src/main/config") // リソースディレクトリを変更
    }
    test {
        java.srcDir("src/test/kotlin") // テストコードも Kotlin に対応
    }
}

新しいソースセットを作成

新しいソースセットを作成することで、特定の用途に応じたコードグループを追加できます。

sourceSets {
    create("integrationTest") {
        java.srcDir("src/integrationTest/java")
        resources.srcDir("src/integrationTest/resources")
        compileClasspath += sourceSets["main"].output // 本番コードをクラスパスに含む
        runtimeClasspath += sourceSets["main"].output
    }
}

この例では、integrationTest という新しいソースセットを追加しています。このソースセットは統合テストのために使用されます。


sourceSets の使用例

タスクで使用

sourceSets を利用して、特定のソースセットに基づいて処理を実行できます。

tasks.register("printSourceSets") {
    doLast {
        sourceSets.forEach { sourceSet ->
            println("SourceSet: ${sourceSet.name}")
            println("Java Source Directories: ${sourceSet.java.srcDirs}")
            println("Resource Directories: ${sourceSet.resources.srcDirs}")
        }
    }
}

このタスクを実行すると、すべてのソースセットの情報が出力されます。


まとめ

  • sourceSets はソースコードやリソースの構成を定義するためのもの。
  • maintest がデフォルトで用意されており、カスタマイズや追加が可能。
  • プロジェクトの構成や用途に応じて柔軟に設定できるため、大規模なプロジェクトや特定の要件を持つプロジェクトで特に便利です。
ta.toshiota.toshio

https://docs.gradle.org/current/userguide/tutorial_using_tasks.html#tutorial_using_tasks

タスクの使用


目次


Gradle でプロジェクトに対して行う作業は、1つまたは複数の タスク によって定義されます。

author gradle 5

タスクは、ビルドが実行する独立した作業単位を表します。これには、クラスのコンパイル、JAR の作成、Javadoc の生成、リポジトリへのアーカイブの公開などが含まれます。

例えば、コマンドラインで ./gradlew build を実行すると、Gradle は build タスクおよびそれが依存しているタスクを実行します。


利用可能なタスクの一覧表示

Gradle はプロジェクトに対していくつかのデフォルトタスクを提供しており、./gradlew tasks コマンドを実行することで一覧表示できます:

> Task :tasks

------------------------------------------------------------
Tasks runnable from root project 'myTutorial'
------------------------------------------------------------

Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'myTutorial'.
...

タスクは ビルドスクリプト または プラグイン から提供されます。

例えば、プロジェクトに application プラグインを適用すると、追加のタスクが利用可能になります:

plugins {
    id("application")
}

その後に ./gradlew tasks を実行すると以下のように表示されます:

> Task :tasks

------------------------------------------------------------
Tasks runnable from project ':app'
------------------------------------------------------------

Application tasks
-----------------
run - Runs this project as a JVM application

Build tasks
-----------
assemble - Assembles the outputs of this project.
build - Assembles and tests this project.

Documentation tasks
-------------------
javadoc - Generates Javadoc API documentation for the main source code.

Other tasks
-----------
compileJava - Compiles main Java source.

...

これらのタスク(例えば assemblebuildrun など)は、開発者にとって馴染みのあるものが多いでしょう。


タスクの分類

実行可能なタスクには、以下の2種類があります:

  1. 実行可能タスク (Actionable tasks)

    • 実際に作業を行うタスク(例:compileJava)。
  2. ライフサイクルタスク (Lifecycle tasks)

    • アクションを持たず、他のタスクに依存するタスク(例:assemblebuild)。

通常、ライフサイクルタスクは複数の実行可能タスクに依存しており、それらをまとめて実行するために使用されます。


タスクの登録とアクション

以下はシンプルな "Hello World" タスクの例です:

tasks.register("hello") {
    doLast {
        println("Hello world!")
    }
}

この例では、ビルドスクリプトで TaskContainer API を使用して hello タスクを登録し、そのタスクにアクションを追加しています。

利用可能なタスクを一覧表示すると、hello タスクが表示されます:

$ ./gradlew app:tasks --all

Other tasks
-----------
hello

./gradlew hello コマンドでタスクを実行すると:

Hello world!

Gradle が hello タスクを実行すると、指定されたアクション(println("Hello world!"))が実行されます。


タスクのグループと説明

以下のようにタスクに 説明 を追加し、特定の グループ に割り当てることができます:

tasks.register("hello") {
    group = "Custom"
    description = "A lovely greeting task."
    doLast {
        println("Hello world!")
    }
}

./gradlew tasks を実行すると:

Custom tasks
------------------
hello - A lovely greeting task.

タスクの詳細情報を表示するには、help --task <task-name> を使用します:

$ ./gradlew help --task hello

> Task :help
Detailed task information for hello

Path
:app:hello

Type
Task (org.gradle.api.Task)

Description
A lovely greeting task.

Group
Custom

タスクの依存関係

タスクは他のタスクに依存させることができます:

tasks.register("hello") {
    doLast {
        println("Hello world!")
    }
}
tasks.register("intro") {
    dependsOn("hello")
    doLast {
        println("I'm Gradle")
    }
}

この場合、./gradlew intro を実行すると:

Hello world!
I'm Gradle

依存関係は、依存するタスクが定義される前に記述しても問題ありません:

tasks.register("taskX") {
    dependsOn("taskY")
    doLast {
        println("taskX")
    }
}
tasks.register("taskY") {
    doLast {
        println("taskY")
    }
}

./gradlew taskX を実行すると:

taskY
taskX

タスクの設定

登録されたタスクは、TaskProvider API を使用してさらに設定することが可能です。これにより、タスクの依存関係を動的に追加したり、既存のタスクの振る舞いを変更できます。

依存関係を動的に追加する例

以下は、複数のタスクを動的に作成し、特定のタスクに依存関係を追加する例です:

repeat(4) { counter ->
    tasks.register("task$counter") {
        doLast {
            println("I'm task number $counter")
        }
    }
}

tasks.named("task0") {
    dependsOn("task2", "task3")
}

./gradlew task0 を実行すると、task0 の実行前に task2task3 が実行されます:

I'm task number 2
I'm task number 3
I'm task number 0

既存タスクの動作を追加する例

doFirst および doLast を使用して、既存タスクの実行順序を変更できます。

tasks.register("hello") {
    doLast {
        println("Hello Earth")
    }
}

tasks.named("hello") {
    doFirst {
        println("Hello Venus")
    }
    doLast {
        println("Hello Mars")
    }
    doLast {
        println("Hello Jupiter")
    }
}

./gradlew hello を実行すると、以下の順序でアクションが実行されます:

Hello Venus
Hello Earth
Hello Mars
Hello Jupiter
  • doFirst:アクションリストの先頭に追加。
  • doLast:アクションリストの末尾に追加。

プラグインが追加したタスクを設定

named メソッドを使用して、プラグインが追加したタスクを設定することも可能です:

tasks.named("dokkaHtml") {
    outputDirectory.set(buildDir)
}

このコードは、dokkaHtml タスクの出力ディレクトリを buildDir に設定します。


タスクの種類

Gradle タスクは、Task のサブクラスです。独自のタスクを作成するには、DefaultTask クラスを拡張します。

以下は、HelloTask クラスを作成してタスクとして登録する例です:

// DefaultTask クラスを拡張して HelloTask を作成
abstract class HelloTask : DefaultTask() {
    @TaskAction
    fun hello() {
        println("hello from HelloTask")
    }
}

// HelloTask 型のタスクを登録
tasks.register<HelloTask>("hello") {
    group = "Custom tasks"
    description = "A lovely greeting task."
}

./gradlew hello を実行すると:

hello from HelloTask

help --task hello を実行してタスクの詳細を確認すると、タスクの型が HelloTask であることが分かります。

Type
HelloTask (Build_gradle$HelloTask)

組み込みタスクの種類

Gradle は、一般的なタスクを実行するための組み込みタスクタイプを多く提供しています。例えば、ファイルのコピーや削除などです。

コピータスクの例

以下の例では、Copy タスクを使用して .war ファイルをコピーします:

tasks.register<Copy>("copyTask") {
    from("source")
    into("target")
    include("*.war")
}

利用可能な組み込みタスクの例

Gradle は以下のような多くのタスクタイプを提供しています:

  • GroovyDoc
  • Zip
  • Jar
  • JacocoReport
  • Sign
  • Delete

これらは Gradle DSL ドキュメント で確認できます。


これで、タスクの種類と設定についての説明は以上です。さらなる詳細が必要であれば、Gradle の公式ドキュメントをご参照ください!

ta.toshiota.toshio

https://docs.gradle.org/current/userguide/writing_tasks.html#writing_tasks

タスクの作成

目次

Gradleのタスクは、DefaultTaskを拡張することで作成されます。

ただし、汎用的なDefaultTask自体には、Gradleのアクションは含まれていません。ユーザーがGradleの機能やビルドスクリプトを拡張するには、以下のいずれかを使用する必要があります。

  1. 組み込みタスク - GradleにはCopyJarZipDeleteなどのユーティリティタスクが用意されています。
  2. カスタムタスク - ユーザーはDefaultTaskをサブクラス化することで独自のタスクタイプを作成できます。

タスクを作成する

最も簡単かつ迅速なカスタムタスクの作成方法は、ビルドスクリプト内で作成することです。

タスクを作成するには、DefaultTaskクラスを継承し、@TaskActionハンドラーを実装します。

Kotlin``Groovy

build.gradle.kts

abstract class CreateFileTask : DefaultTask() {
    @TaskAction
    fun action() {
        val file = File("myfile.txt")
        file.createNewFile()
        file.writeText("HELLO FROM MY TASK")
    }
}

このCreateFileTaskは、簡単な一連のアクションを実行します。まず、「myfile.txt」という名前のファイルをプロジェクトのメインディレクトリに作成し、その後にテキストを書き込みます。


タスクを登録する

タスクは、ビルドスクリプト内でTaskContainer.register()メソッドを使用して登録され、その後ビルドロジックで使用できるようになります。

Kotlin``Groovy

build.gradle.kts

abstract class CreateFileTask : DefaultTask() {
    @TaskAction
    fun action() {
        val file = File("myfile.txt")
        file.createNewFile()
        file.writeText("HELLO FROM MY TASK")
    }
}

tasks.register<CreateFileTask>("createFileTask")

タスクグループと説明

タスクのgroupdescriptionプロパティを設定することで、タスクの使用方法をユーザーが理解しやすくなります。

Kotlin``Groovy

build.gradle.kts

abstract class CreateFileTask : DefaultTask() {
    @TaskAction
    fun action() {
        val file = File("myfile.txt")
        file.createNewFile()
        file.writeText("HELLO FROM MY TASK")
    }
}

tasks.register<CreateFileTask>("createFileTask") {
    group = "custom"
    description = "Create myfile.txt in the current directory"
}

タスクがグループに追加されると、そのタスクはリスト表示時に確認できます。


タスクの入力と出力

タスクが有用な作業を行うためには、通常いくつかの入力を必要とし、タスクの実行結果として出力を生成します。

Kotlin``Groovy

build.gradle.kts

abstract class CreateAFileTask : DefaultTask() {
    @get:Input
    abstract val fileText: Property<String>

    @Input
    val fileName = "myfile.txt"

    @OutputFile
    val myFile: File = File(fileName)

    @TaskAction
    fun action() {
        myFile.createNewFile()
        myFile.writeText(fileText.get())
    }
}

タスクを設定する

タスクは、ビルドスクリプト内でTaskCollection.named()メソッドを使用して設定することができます。

次の例では、CreateAFileTaskクラスを使用して、ファイル内のテキストを設定可能にしています。

Kotlin``Groovy

build.gradle.kts

abstract class CreateAFileTask : DefaultTask() {
    @get:Input
    abstract val fileText: Property<String>

    @Input
    val fileName = "myfile.txt"

    @OutputFile
    val myFile: File = File(fileName)

    @TaskAction
    fun action() {
        myFile.createNewFile()
        myFile.writeText(fileText.get())
    }
}

tasks.register<CreateAFileTask>("createAFileTask") {
    group = "custom"
    description = "Create myfile.txt in the current directory"
    fileText.convention("HELLO FROM THE CREATE FILE TASK METHOD") // 規定値を設定
}

tasks.named<CreateAFileTask>("createAFileTask") {
    fileText.set("HELLO FROM THE NAMED METHOD") // カスタムメッセージで上書き
}

タスクが実行されると次のようになります。

$ ./gradlew createAFileTask

> Configure project :app

> Task :app:createAFileTask

BUILD SUCCESSFUL in 5s
2 actionable tasks: 1 executed, 1 up-to-date

この結果、myfile.txtというテキストファイルがプロジェクトのルートフォルダに作成されます。

myfile.txt

HELLO FROM THE NAMED METHOD

より詳しい情報は、Gradleタスクの開発に関する章をご参照ください。

ta.toshiota.toshio

https://docs.gradle.org/current/userguide/plugins.html#sec:plugin_management

プラグインの使用

目次

Gradle の多くの機能はプラグインによって提供されます。これには、Gradle に付属しているコアプラグイン、Gradle コミュニティによるサードパーティプラグイン、そしてビルド内で定義されたスクリプトプラグインが含まれます。

プラグインは新しいタスク (例: JavaCompile)、ドメインオブジェクト (例: SourceSet)、規約 (例: Java ソースを src/main/java に配置) を導入し、コアまたは他のプラグインオブジェクトを拡張します。

Gradle のプラグインは、共通のビルドタスクを自動化し、外部ツールやサービスと統合し、プロジェクトの特定のニーズに合わせてビルドプロセスを調整するために不可欠です。また、ビルドロジックを整理するための主要なメカニズムとしても機能します。


プラグインの利点

ビルドスクリプト内に多くのタスクを書いたり、設定ブロックを複製したりすると、スクリプトが散らかってしまう可能性があります。プラグインは、ビルドスクリプト内にロジックを直接追加する場合と比較して、いくつかの利点を提供します。

  • 再利用性を促進: プロジェクト間で同様のロジックを複製する必要が減少します。
  • モジュール性を強化: ビルドスクリプトをよりモジュール化し整理します。
  • ロジックをカプセル化: 宣言的なビルドスクリプトを可能にし、命令型ロジックを分離します。

プラグインの配布

Gradle や Gradle コミュニティから提供されるプラグインを活用したり、自分でプラグインを作成したりできます。

プラグインは以下の 3 つの方法で利用可能です:

  1. コアプラグイン: Gradle が開発・保守している コアプラグイン
  2. コミュニティプラグイン: Maven や Gradle Plugin Portal などのリモートリポジトリで共有されている Gradle プラグイン。
  3. カスタムプラグイン: API を使用して作成されたプラグイン。

プラグインの種類

プラグインは以下の形式で実装されます:

1. スクリプトプラグイン

スクリプトプラグインは Groovy DSL または Kotlin DSL スクリプトであり、apply from: 構文を使用して Gradle ビルドスクリプトに直接適用されます。これらはビルドプロセスをカスタマイズするためにインラインで適用されますが、推奨されません。しかし、操作方法を理解することは重要です。

build.gradle.kts

// プラグインを定義する
class HelloWorldPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.tasks.register("helloWorld") {
            group = "Example"
            description = "Prints 'Hello, World!' to the console"
            doLast {
                println("Hello, World!")
            }
        }
    }
}

// プラグインを適用する
apply<HelloWorldPlugin>()

2. 事前コンパイルスクリプトプラグイン

事前コンパイルスクリプトプラグインは、Groovy DSL または Kotlin DSL スクリプトで記述され、Java クラスファイルとしてコンパイルされ、一部のライブラリにパッケージ化されます。これらはバイナリ Gradle プラグインとして利用され、plugins {} ブロックを使用してプロジェクトに適用されます。

plugin/src/main/kotlin/my-plugin.gradle.kts

// このスクリプトは自動的に `my-plugin` プラグインとして公開されます
tasks {
    register("myCopyTask", Copy::class) {
        group = "sample"
        from("build.gradle.kts")
        into("build/copy")
    }
}

consumer/build.gradle.kts

// プラグインを適用する
plugins {
    id("my-plugin") version "1.0"
}

3. BuildSrc とコンベンションプラグイン

これらは、事前コンパイルプラグインとバイナリプラグインのハイブリッドであり、プロジェクト間で複雑なロジックを再利用し、ビルドロジックの整理を改善する方法を提供します。

buildSrc/src/main/kotlin/shared-build-conventions.gradle.kts

plugins {
    java
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
    implementation("com.google.guava:guava:30.1.1-jre")
}

tasks.named<Test>("test") {
    useJUnitPlatform()
}

tasks.register<Copy>("backupTestXml") {
    from("build/test-results/test")
    into("/tmp/results/")
    exclude("binary/**")
}

app/build.gradle.kts

plugins {
    application
    id("shared-build-conventions")
}

4. バイナリプラグイン

バイナリプラグインは、通常 Java または Kotlin DSL を用いて記述されるコンパイル済みのプラグインであり、JAR ファイルとしてパッケージ化されます。これらは plugins {} ブロックを使用してプロジェクトに適用されます。スクリプトプラグインや事前コンパイルスクリプトプラグインと比較して、より良いパフォーマンスと保守性を提供します。

// プラグインを定義 (plugin/src/main/kotlin/plugin/MyPlugin.kt)
class MyPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.run {
            tasks {
                register("myCopyTask", Copy::class) {
                    group = "sample"
                    from("build.gradle.kts")
                    into("build/copy")
                }
            }
        }
    }
}
// プラグインを適用 (consumer/build.gradle.kts)
plugins {
    id("my-plugin") version "1.0"
}

バイナリプラグインスクリプトプラグイン の違いは、共有方法と実行方法にあります:

  • バイナリプラグイン: バイトコードにコンパイルされ、そのバイトコードが共有されます。
  • スクリプトプラグイン: ソースコードとして共有され、使用時にコンパイルされます。

バイナリプラグインは、Java、Kotlin、Groovy など JVM バイトコードを生成する任意の言語で記述可能です。一方で、スクリプトプラグインは Kotlin DSL または Groovy DSL でしか記述できません。

また、事前コンパイルスクリプトプラグイン は中間的な存在です。これはスクリプトプラグインのように Kotlin DSL または Groovy DSL で記述されますが、バイナリプラグインのようにバイトコードとしてコンパイルされて共有されます。

プラグインはしばしば、スクリプトプラグインとして書き始めます (記述が容易なため)。その後、そのコードがより価値を持つにつれて、簡単にテスト可能で、複数のプロジェクトや組織で共有できるバイナリプラグインへと移行します。


プラグインの使用方法

Gradle がプラグインに含まれるビルドロジックを使用するためには、以下の 2 つのステップを実行する必要があります。

  1. 解決 (Resolve)
    プラグインが含まれる正しいバージョンの JAR を見つけ、スクリプトクラスパスに追加します。一度プラグインが解決されると、その API をビルドスクリプト内で使用できます。スクリプトプラグインは自己解決型であり、適用時に指定されたファイルパスや URL から解決されます。Gradle 配布物の一部であるコアバイナリプラグインは自動的に解決されます。

  2. 適用 (Apply)
    プラグインの apply(T) メソッドをプロジェクトに対して実行します。

plugins DSL を使用することで、プラグインの解決と適用を 1 つのステップで行うことを推奨します。


プラグインの解決

Gradle は、コアプラグイン (例: JavaPlugin, GroovyPlugin, MavenPublishPlugin など) を Gradle 配布物の一部として提供しています。これにより、コアプラグインは自動的に解決されます。

コアプラグインは、ビルドスクリプト内でプラグイン名を指定して適用できます:

plugins {
    id("java")
}

非コアプラグイン は解決されなければ使用できません。非コアプラグインは、ビルドファイル内で固有の ID とバージョンを指定する必要があります。

plugins {
    id("org.springframework.boot") version "3.3.1"
}

さらに、非コアプラグインを解決するには、プラグインの場所を設定ファイルで指定する必要があります。

// settings.gradle.kts
pluginManagement {
    repositories {
        gradlePluginPortal()
    }
}

以下に、プラグインを解決し適用する際の考慮事項を示します:

# タスク 使用する構文
1 プロジェクトにプラグインを適用 ビルドファイル内の plugins ブロック plugins { id("org.barfuin.gradle.taskinfo") version "2.1.0" }
2 複数のサブプロジェクトにプラグインを適用 ルートビルドファイルの subprojects または allprojects ブロック 推奨されない subprojects { plugins.apply("org.barfuin.gradle.taskinfo") }
3 サブプロジェクトに適用するカスタムプラグインを定義 buildSrc ディレクトリ内のコンベンションプラグイン 推奨 plugins { id("shared-build-conventions") }
4 ビルドスクリプト自体で必要なプラグインを適用 buildscript ブロックを使用 レガシー buildscript { dependencies { classpath("org.example:plugin:1.0") } }
5 スクリプトプラグインを適用 レガシーな apply() メソッド 推奨されない apply<MyCustomPlugin>()

1. plugins{} ブロックを使用したプラグインの適用

plugins DSL は、プラグイン依存関係を宣言するための簡潔で便利な方法を提供します。

以下は plugins ブロックの例です:

plugins {
    application                                     // 名前で指定
    java                                            // 名前で指定
    id("java")                                      // ID で指定 - 推奨
    id("org.jetbrains.kotlin.jvm") version "1.9.0" // ID で指定 - 推奨
}

Gradle のコアプラグインは、java のような短い名前を使用して適用できます:

plugins {
    java
}

コミュニティプラグインやカスタムプラグインなどのコア以外のバイナリプラグインでは、プラグイン ID とバージョンを完全に指定する必要があります:

plugins {
    id("org.springframework.boot") version "3.3.1"
}

プラグイン DSL の使用についての詳細は、PluginDependenciesSpec を参照してください。


プラグイン DSL の制限事項

plugins DSL は、ユーザーにとって便利な構文と、使用されるプラグインを Gradle が迅速に特定する機能を提供します。これにより、Gradle は以下を実現できます:

  • プラグインクラスのロードと再利用の最適化。
  • ビルドスクリプト内でのプロパティや値の詳細情報をエディタに提供。

しかしながら、DSL は静的に定義される必要があります。

制約された構文

plugins {} ブロックは、任意のコードをサポートしません。この構文は、冪等性 (毎回同じ結果を生成) を保ち、副作用がないようにする必要があります。

構文の形式は次のとおりです:

plugins {
    id("plugin id")                              // コア Gradle プラグイン、またはスクリプトクラスパス内のプラグイン
    id("plugin id") version "plugin version"    // 解決が必要なバイナリ Gradle プラグイン
}

plugins {} ブロックは、ビルドスクリプトのトップレベル文である必要があります。他の構造体 (例: if 文や for ループ) の内部にネストすることはできません。


2. 複数のサブプロジェクトにプラグインを適用する (subprojects または allprojects)

マルチプロジェクトビルドでは、ビルド内のサブプロジェクトの一部またはすべてにプラグインを適用したい場合があります。ただし、root プロジェクトには適用したくない場合があります。

以下のように、ルートプロジェクトの plugins {} ブロックで apply false を使用すると、プラグインが現在のプロジェクトに適用されないように指定できます。その後、サブプロジェクトのビルドスクリプトでプラグインを適用できます。

設定例:

// settings.gradle.kts
include("hello-a")
include("hello-b")
include("goodbye-c")
// build.gradle.kts
plugins {
    // 現在のプロジェクトには適用されない
    id("com.example.hello") version "1.0.0" apply false
    id("com.example.goodbye") version "1.0.0" apply false
}

allprojects {
    // 全てのプロジェクト (ルートプロジェクト含む) に共通プラグインを適用
    plugins.apply("java")
}

subprojects {
    // ルートプロジェクトを除く全てのサブプロジェクトに適用
    plugins.apply("java-library")
}

サブプロジェクトのビルドスクリプト例:

// hello-a/build.gradle.kts
plugins {
    id("com.example.hello")
}
// hello-b/build.gradle.kts
plugins {
    id("com.example.hello")
}
// goodbye-c/build.gradle.kts
plugins {
    id("com.example.goodbye")
}

3. buildSrc ディレクトリからのコンベンションプラグイン適用

buildSrc は、Gradle プロジェクトルートに存在するオプションのディレクトリであり、メインプロジェクトのビルドロジック (プラグインなど) を含みます。buildSrc ディレクトリ内のプラグインは、ID を定義している限り適用できます。

プラグイン定義例 (buildSrc/build.gradle.kts):

plugins {
    `java-gradle-plugin`
}

gradlePlugin {
    plugins {
        create("myPlugins") {
            id = "my-plugin"
            implementationClass = "my.MyPlugin"
        }
    }
}

プラグインの適用:

// build.gradle.kts
plugins {
    id("my-plugin")
}

4. buildscript{} ブロックを使用したプラグインの適用

ビルドスクリプト自体で必要なライブラリやプラグインを定義する場合、buildscript ブロックを使用します。この方法は、Gradle の最新バージョンではあまり一般的ではありませんが、非標準的なプラグインリポジトリやライブラリの依存関係を扱う場合に使用されます。

// build.gradle.kts
buildscript {
    repositories {
        maven {
            url = uri("https://plugins.gradle.org/m2/")
        }
        mavenCentral()
    }
    dependencies {
        classpath("org.yaml:snakeyaml:1.19")
        classpath("com.gradleup.shadow:shadow-gradle-plugin:8.3.4")
    }
}

// プラグインの適用
apply(plugin = "com.gradleup.shadow")

4. buildscript{} ブロックを使用したプラグインの適用

ビルドスクリプト自体で必要なプラグインやライブラリを定義する場合、buildscript ブロックを使用します。buildscript ブロックは、これらの依存関係をどこで見つけるか (リポジトリ) と、それらのクラスパス依存関係を指定します。

このアプローチは、最新の Gradle バージョンでは一般的ではありません。plugins {} ブロックの使用が推奨されますが、非標準のプラグインリポジトリやライブラリ依存関係を扱う必要がある場合は依然として有用です。

// build.gradle.kts
import org.yaml.snakeyaml.Yaml
import java.io.File

buildscript {
    repositories {
        maven {
            url = uri("https://plugins.gradle.org/m2/")
        }
        mavenCentral()  // プラグインを取得するリポジトリ
    }
    dependencies {
        classpath("org.yaml:snakeyaml:1.19") // クラスパス依存関係
        classpath("com.gradleup.shadow:shadow-gradle-plugin:8.3.4") // プラグイン依存関係
    }
}

// Shadow プラグインを適用
apply(plugin = "com.gradleup.shadow")

// ライブラリの使用
val yamlContent = """
        name: Project
    """.trimIndent()
val yaml = Yaml()
val data: Map<String, Any> = yaml.load(yamlContent)
println(data)

5. レガシーな apply() メソッドを使用したスクリプトプラグインの適用

スクリプトプラグインはアドホックなプラグインであり、通常は同じビルドスクリプト内で記述され、適用されます。これは レガシーな適用方法 を使用して適用されます。

Kotlin および Groovy の例

build.gradle.kts

class MyPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        println("Plugin ${this.javaClass.simpleName} applied on ${project.name}")
    }
}

apply<MyPlugin>()

この例では、MyPlugin クラスが Plugin インターフェースを実装しており、apply メソッドでプロジェクトに対する処理を定義しています。apply<MyPlugin>() を使用して、このプラグインを現在のビルドスクリプトに適用します。

ta.toshiota.toshio

続き

https://docs.gradle.org/current/userguide/plugins.html#sec:plugin_management

プラグイン管理 (Plugin Management)

pluginManagement{} ブロックは、プラグイン解決用のリポジトリを設定し、ビルドスクリプトで適用されるプラグインのバージョン制約を定義するために使用されます。

pluginManagement{} ブロックは settings.gradle(.kts) ファイルで使用できます。このブロックはファイル内の最初のブロックでなければなりません。

Kotlin/Groovy

settings.gradle.kts

pluginManagement {
    plugins {
    }
    resolutionStrategy {
    }
    repositories {
    }
}
rootProject.name = "plugin-management"

このブロックは 初期化スクリプト 内でも使用できます。

Kotlin/Groovy

init.gradle.kts

settingsEvaluated {
    pluginManagement {
        plugins {
        }
        resolutionStrategy {
        }
        repositories {
        }
    }
}

カスタムプラグインリポジトリ

デフォルトでは、plugins{} DSL は Gradle Plugin Portal からプラグインを解決します。

多くのビルド作成者は、プラグインを非公開の Maven や Ivy リポジトリから解決したいと考えています。これには、プロプライエタリな実装の詳細を含める場合や、使用可能なプラグインを制御したい場合が含まれます。

カスタムプラグインリポジトリを指定するには、pluginManagement{} 内で repositories{} ブロックを使用します。

Kotlin/Groovy

settings.gradle.kts

pluginManagement {
    repositories {
        maven(url = file("./maven-repo"))
        gradlePluginPortal()
        ivy(url = file("./ivy-repo"))
    }
}

この設定では、Gradle がプラグインを解決する際、まず ../maven-repo にある Maven リポジトリを確認し、その後 Maven リポジトリに見つからない場合は Gradle Plugin Portal を確認します。Gradle Plugin Portal を検索したくない場合は、gradlePluginPortal() 行を省略してください。最後に ../ivy-repo にある Ivy リポジトリを確認します。


プラグインバージョン管理

pluginManagement{} 内の plugins{} ブロックを使用することで、ビルドで使用されるすべてのプラグインのバージョンを一箇所で定義できます。その後、プラグインを plugins{} ブロックを通じて任意のビルドスクリプトに ID で適用できます。

この方法でプラグインバージョンを設定する利点は、pluginManagement.plugins{} がビルドスクリプトの plugins{} ブロックと同じ 制約された構文 を持たないことです。これにより、プラグインバージョンを gradle.properties から取得したり、他のメカニズムを通じて読み込むことが可能です。

例: pluginManagement を通じたプラグインバージョンの管理

Kotlin/Groovy

settings.gradle.kts

pluginManagement {
  val helloPluginVersion: String by settings
  plugins {
    id("com.example.hello") version "${helloPluginVersion}"
  }
}

build.gradle.kts

plugins {
    id("com.example.hello")
}

gradle.properties

helloPluginVersion=1.0.0

プラグインバージョンは gradle.properties から読み込まれ、settings スクリプトで構成されます。これにより、プラグインを任意のプロジェクトにバージョンを指定せずに追加することが可能になります。


プラグイン解決ルール

プラグイン解決ルールを使用することで、plugins{} ブロックで行われるプラグインリクエストを変更できます。例えば、リクエストされたバージョンを変更したり、実装アーティファクトの座標を明示的に指定することができます。

解決ルールを追加するには、pluginManagement{} 内で resolutionStrategy{} を使用します。

Kotlin/Groovy

settings.gradle.kts

pluginManagement {
    resolutionStrategy {
        eachPlugin {
            if (requested.id.namespace == "com.example") {
                useModule("com.example:sample-plugins:1.0.0")
            }
        }
    }
    repositories {
        maven {
            url = uri("./maven-repo")
        }
        gradlePluginPortal()
        ivy {
            url = uri("./ivy-repo")
        }
    }
}

この例では、Gradle に対して特定のプラグイン ID に対して指定されたモジュールを使用するよう指示しています。

カスタム Maven および Ivy プラグインリポジトリには、プラグインマーカーアーティファクト と、プラグインを実装するアーティファクトが含まれている必要があります。プラグインをカスタムリポジトリに公開する方法については、Gradle Plugin Development Plugin を参照してください。


プラグインマーカーアーティファクト

plugins{} DSL ブロックでは、グローバルに一意なプラグイン ID (id) とバージョン (version) プロパティを使用してプラグインを宣言できます。このため、Gradle はプラグイン実装アーティファクトの座標を検索する必要があります。

Gradle は以下の形式のプラグインマーカーアーティファクトを検索します:

plugin.id:plugin.id.gradle.plugin:plugin.version

このマーカーには、実際のプラグイン実装への依存関係が必要です。このマーカーの発行は java-gradle-plugin によって自動化されています。

例: プラグインの公開

Kotlin/Groovy

build.gradle.kts

plugins {
    `java-gradle-plugin`
    `maven-publish`
    `ivy-publish`
}

group = "com.example"
version = "1.0.0"

gradlePlugin {
    plugins {
        create("hello") {
            id = "com.example.hello"
            implementationClass = "com.example.hello.HelloPlugin"
        }
        create("goodbye") {
            id = "com.example.goodbye"
            implementationClass = "com.example.goodbye.GoodbyePlugin"
        }
    }
}

publishing {
    repositories {
        maven {
            url = uri(layout.buildDirectory.dir("maven-repo"))
        }
        ivy {
            url = uri(layout.buildDirectory.dir("ivy-repo"))
        }
    }
}

サンプルディレクトリ内で gradle publish を実行すると、次のような Maven リポジトリレイアウトが作成されます (Ivy レイアウトも同様)。

plugin markers

レガシープラグイン適用 (Legacy Plugin Application)

plugins DSL の導入により、レガシーなプラグイン適用方法を使用する理由はほとんどなくなりました。しかし、plugins DSL を使用できない制約がある場合のために、この方法を記載します。

Kotlin/Groovy

build.gradle.kts

apply(plugin = "java")

プラグインは プラグイン ID を使用して適用することができます。上記の例では、短い名前 "java" を使用して JavaPlugin を適用しています。

プラグイン ID を使用する代わりに、プラグインのクラスを直接指定して適用することも可能です。

Kotlin/Groovy

build.gradle.kts

apply<JavaPlugin>()

上記の例で使用されている JavaPlugin シンボルは、JavaPlugin クラス を指します。このクラスは org.gradle.api.plugins パッケージに含まれており、すべてのビルドスクリプトで自動的にインポートされます (デフォルトインポート を参照)。

さらに、Kotlin ではクラスリテラルを指定する際に ::class サフィックスを使用する必要があります (Java の .class に相当)。

また、apply メソッドを使用してビルドファイル全体を取り込むことも可能です。

Kotlin/Groovy

build.gradle.kts

apply(from = "other.gradle.kts")

この例では、other.gradle.kts に記述されたすべてのスクリプトが現在のビルドスクリプトに適用されます。


バージョンカタログの使用 (Using a Version Catalog)

プロジェクトがバージョンカタログを使用している場合、プラグインを適用する際にエイリアスを通じて参照することができます。

以下は単純なバージョンカタログの例です:

libs.versions.toml

[versions]
groovy = "3.0.5"
checkstyle = "8.37"

[libraries]
groovy-core = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
groovy-json = { module = "org.codehaus.groovy:groovy-json", version.ref = "groovy" }
groovy-nio = { module = "org.codehaus.groovy:groovy-nio", version.ref = "groovy" }
commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version = { strictly = "[3.8, 4.0[", prefer="3.9" } }

[bundles]
groovy = ["groovy-core", "groovy-json", "groovy-nio"]

[plugins]
versions = { id = "com.github.ben-manes.versions", version = "0.45.0" }

上記のようにバージョンカタログを定義した場合、ビルドスクリプトで次のようにプラグインを適用できます。

Kotlin/Groovy

build.gradle.kts

plugins {
    `java-library`
    alias(libs.plugins.versions)
}

この例では、Gradle がカタログアイテムに対する型安全なアクセサを生成します。

ta.toshiota.toshio

閑話休題

buildSrc/build.gradle.kts

plugins {
    `java-gradle-plugin`
}

gradlePlugin {
    plugins {
        create("myPlugins") {
            id = "my-plugin"
            implementationClass = "my.MyPlugin"
        }
    }
}

build.gradle.kts

plugins {
    id("my-plugin")
}

このコードでは、Gradle プロジェクト内で独自のカスタムプラグインを定義し、それをプロジェクト内で適用する方法を示しています。それぞれの役割を以下で詳しく解説します。


1. buildSrc ディレクトリの役割

  • buildSrc は Gradle プロジェクトの特別なディレクトリであり、このディレクトリ内のコードはプロジェクト全体で自動的にビルドされ、利用可能になります。
  • buildSrc に配置したプラグインは、他のプロジェクトモジュールで追加の設定なしに利用可能です。

2. buildSrc/build.gradle.kts の内容

以下は buildSrc 内でカスタムプラグインを定義するためのスクリプトです。

プラグイン設定

plugins {
    `java-gradle-plugin`
}
  • java-gradle-plugin:
    • Gradle プラグインを作成するための専用のプラグインです。
    • これにより、Gradle プラグインを簡単に定義・構成し、利用できるようになります。

カスタムプラグインの作成

gradlePlugin {
    plugins {
        create("myPlugins") {
            id = "my-plugin"
            implementationClass = "my.MyPlugin"
        }
    }
}
  • gradlePlugin ブロック:
    • ここでカスタムプラグインを定義します。
    • create("myPlugins"):
      • このプラグイン定義の名前 (内部的な識別用)。
      • 他のプロジェクトから直接参照する必要はありません。
    • id = "my-plugin":
      • プラグインの公開 ID。これを使って他のモジュールやプロジェクトでプラグインを適用します。
    • implementationClass = "my.MyPlugin":
      • プラグインの実装クラス。このクラスは buildSrc 内に定義される必要があります。

例: 実装クラス MyPlugin の内容

以下のようなクラスが buildSrc/src/main/kotlin/my/MyPlugin.kt に定義されている必要があります。

package my

import org.gradle.api.Plugin
import org.gradle.api.Project

class MyPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        // プラグインが適用されたときの処理をここに記述
        println("MyPlugin applied to ${project.name}")
    }
}
  • このクラスは Plugin<Project> インターフェースを実装し、apply メソッドを定義しています。
  • apply メソッドには、プラグインが適用されたときに実行されるカスタムロジックを記述します。

3. プラグインの適用

次に、定義したプラグインを他のプロジェクトで使用します。

// build.gradle.kts
plugins {
    id("my-plugin")
}
  • id("my-plugin"):
    • buildSrcgradlePlugin ブロックで指定した id ("my-plugin") を使ってプラグインを適用します。
    • プラグイン適用時、implementationClass で指定されたクラス (my.MyPlugin) が自動的に呼び出されます。

4. プラグイン適用の動作

プラグインを適用すると、以下の動作が行われます:

  1. buildSrc ディレクトリが自動的にビルドされ、my.MyPlugin クラスが Gradle のプラグインとして認識されます。
  2. id("my-plugin") を使ってプラグインを適用すると、my.MyPluginapply メソッドが実行されます。
  3. apply メソッド内で定義されたカスタムロジック (例えば、タスクの登録、プロパティの設定など) が適用されます。

5. 実現できること

この設定により、以下のことが可能になります:

  1. カスタムロジックのカプセル化:
    • プラグインにプロジェクト固有のビルド設定やタスクをまとめることで、複数のプロジェクトで再利用可能な設定を一元管理できます。
  2. ビルドスクリプトの簡素化:
    • ビルドスクリプトで複雑なロジックを記述する必要がなくなり、シンプルにプラグインを適用するだけで済みます。
  3. 一貫性のある設定:
    • すべてのプロジェクトに対して共通の設定を簡単に適用し、一貫性を保つことができます。

まとめ

  • buildSrc を使用することで、Gradle プロジェクト内でカスタムプラグインを作成し、他のモジュールに簡単に適用できます。
  • my.MyPlugin のようなカスタムクラスを通じて、特定のタスクやビルド設定を一元管理できます。
  • プラグイン ID (my-plugin) を指定するだけで適用できるため、再利用性が高まり、ビルドスクリプトの保守性も向上します。
ta.toshiota.toshio

閑話休題

plugins {
    java
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
    implementation("com.google.guava:guava:30.1.1-jre")
}

tasks.named<Test>("test") {
    useJUnitPlatform()
}

tasks.register<Copy>("backupTestXml") {
    from("build/test-results/test")
    into("/tmp/results/")
    exclude("binary/**")
}

この設定を適用することで、以下のことができるようになります。


1. Javaプロジェクトのサポート

plugins { java } を指定しているため、この設定を適用するとプロジェクトが Java プロジェクトとして扱われます。これにより、以下のような Java プロジェクト特有の機能が有効になります:

  • Java コンパイルタスク (compileJava) の追加
  • テストタスク (test) の自動生成
  • src/main/java および src/test/java ディレクトリをデフォルトのソースセットとして認識

2. Maven Central からの依存関係解決

repositories { mavenCentral() } を設定することで、依存関係を Maven Central リポジトリ から解決できるようになります。この設定により、Gradle が外部ライブラリやモジュールを自動的に取得します。


3. 共通の依存関係の適用

dependencies ブロックにより、以下の依存関係がプロジェクト全体に適用されます:

  • テスト用依存関係:
    testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
    → JUnit 5 (Jupiter) を使用したユニットテストが実行可能になります。

  • 実装用依存関係:
    implementation("com.google.guava:guava:30.1.1-jre")
    → Google Guava ライブラリが利用可能になり、データ構造、コレクションユーティリティなどの便利な機能が使えます。


4. JUnit 5 (Jupiter) プラットフォームの使用

以下の設定により、JUnit 5 のテストプラットフォームが有効になります:

tasks.named<Test>("test") {
    useJUnitPlatform()
}

これにより、test タスク実行時に JUnit 5 を使用してテストを実行するよう設定されます。


5. カスタムタスク backupTestXml の登録

以下のカスタムタスクが登録されます:

tasks.register<Copy>("backupTestXml") {
    from("build/test-results/test")
    into("/tmp/results/")
    exclude("binary/**")
}
  • 目的: テスト結果 (build/test-results/test ディレクトリ内のファイル) を /tmp/results/ にコピーする。
  • 動作:
    • binary ディレクトリ内のファイルは除外。
    • テスト結果を別の場所にバックアップする用途で使用。

このタスクを使用することで、CI/CD パイプラインやデバッグ用にテスト結果を保存・活用することが可能です。


まとめ: この設定でできること

  1. Java プロジェクトの基本設定が自動的に有効化
  2. Maven Central リポジトリから外部ライブラリを取得可能
  3. JUnit 5 を使用したテストの実行
  4. Google Guava ライブラリを利用可能
  5. テスト結果をバックアップするカスタムタスクの使用

これにより、プロジェクト全体に基本的なビルド、テスト、および依存関係管理の仕組みが適用され、開発作業が効率化されます。

backupTestXml タスクは現在 buildSrcshared-build-conventions プラグインに定義されています。そのため、別のモジュールからこのタスクを利用するには、以下の手順を実行する必要があります。


1. 別モジュールに shared-build-conventions プラグインを適用

backupTestXml タスクは shared-build-conventions に含まれているため、別モジュールでこのプラグインを適用する必要があります。

例えば、app モジュールで利用したい場合、app/build.gradle.kts で以下のようにプラグインを適用します:

plugins {
    id("shared-build-conventions")
}

これにより、shared-build-conventions で定義されているすべての設定やタスク (backupTestXml を含む) が app モジュール内で利用可能になります。


2. backupTestXml タスクの利用

プラグインを適用した後は、backupTestXml タスクをそのまま呼び出して使用できます。

コマンドラインで実行する場合

Gradle コマンドでタスクを直接実行できます:

./gradlew :app:backupTestXml

ビルドスクリプト内で使用する場合

ビルドスクリプト内で backupTestXml を他のタスクに依存させたり、カスタマイズすることも可能です。例えば:

tasks.named("build") {
    dependsOn("backupTestXml") // `build` タスクの実行時に `backupTestXml` を実行
}

3. backupTestXml タスクの動作をカスタマイズ

別モジュールで backupTestXml タスクの挙動をカスタマイズしたい場合、tasks.named を使用して設定を追加できます。

例: コピー先ディレクトリを変更

tasks.named<Copy>("backupTestXml") {
    into("/custom/results/") // コピー先をカスタマイズ
}

4. shared-build-conventions プラグインが適用されていない場合の対策

もし shared-build-conventions プラグインを適用せずに backupTestXml タスクを使用したい場合、タスクをモジュール固有に再定義する必要があります。

タスクを再定義する例:

app/build.gradle.kts 内に以下を追加します:

tasks.register<Copy>("backupTestXml") {
    from("build/test-results/test")
    into("/tmp/results/")
    exclude("binary/**")
}

ただし、この方法ではタスク定義が分散し、shared-build-conventions の再利用性が損なわれるため、可能であればプラグインを適用する形を推奨します。


まとめ

  • 利用手順:
    1. 別モジュールで shared-build-conventions プラグインを適用。
    2. タスクをコマンドラインまたはビルドスクリプト内で呼び出す。
  • カスタマイズ:
    • 必要に応じてタスクの設定 (例: コピー先) を変更可能。

これにより、他のモジュールでも簡単に backupTestXml タスクを利用することができます。

ta.toshiota.toshio

閑話休題

build.gradle.kts

plugins {
    `java-gradle-plugin`
    `maven-publish`
    `ivy-publish`
}

group = "com.example"
version = "1.0.0"

gradlePlugin {
    plugins {
        create("hello") {
            id = "com.example.hello"
            implementationClass = "com.example.hello.HelloPlugin"
        }
        create("goodbye") {
            id = "com.example.goodbye"
            implementationClass = "com.example.goodbye.GoodbyePlugin"
        }
    }
}

publishing {
    repositories {
        maven {
            url = uri(layout.buildDirectory.dir("maven-repo"))
        }
        ivy {
            url = uri(layout.buildDirectory.dir("ivy-repo"))
        }
    }
}

このスクリプトでは、Gradle を使用して複数のカスタムプラグイン (hellogoodbye) を定義し、それらを Maven リポジトリおよび Ivy リポジトリに公開する方法を示しています。それぞれの設定を詳しく解説します。


1. plugins ブロック

plugins {
    `java-gradle-plugin` // Gradle プラグイン作成用プラグイン
    `maven-publish`      // Maven リポジトリへの公開を可能にするプラグイン
    `ivy-publish`        // Ivy リポジトリへの公開を可能にするプラグイン
}
  • java-gradle-plugin:

    • Gradle プラグインを作成・構成するための機能を提供します。
    • このプラグインを適用することで、gradlePlugin ブロックを使用してプラグインを定義できます。
  • maven-publish:

    • プラグインやアーティファクトを Maven リポジトリに公開するためのサポートを提供します。
  • ivy-publish:

    • プラグインやアーティファクトを Ivy リポジトリに公開するためのサポートを提供します。

2. グループとバージョンの定義

group = "com.example"
version = "1.0.0"
  • group:

    • プロジェクトやアーティファクトを一意に識別するための名前空間 (パッケージ名のような役割)。
    • Maven や Ivy リポジトリでアーティファクトの識別に使用されます。
  • version:

    • アーティファクトのバージョンを指定します。
    • Maven や Ivy で公開される際、このバージョン番号が使用されます。

3. gradlePlugin ブロック

gradlePlugin {
    plugins {
        create("hello") {
            id = "com.example.hello"
            implementationClass = "com.example.hello.HelloPlugin"
        }
        create("goodbye") {
            id = "com.example.goodbye"
            implementationClass = "com.example.goodbye.GoodbyePlugin"
        }
    }
}
  • gradlePlugin ブロック:
    • ここでカスタム Gradle プラグインを定義します。

create("hello")

  • id = "com.example.hello":

    • プラグインの一意の識別子 (ID)。この ID を使用してプラグインを適用します。
    • 例: plugins { id("com.example.hello") }
  • implementationClass = "com.example.hello.HelloPlugin":

    • プラグインのロジックを実装するクラスを指定します。
    • 例: HelloPlugin クラスには Plugin<Project> インターフェースを実装した apply メソッドが定義されている必要があります。

create("goodbye")

  • 同様に、com.example.goodbye という ID を持つ別のプラグインを定義しています。
  • このプラグインのロジックは com.example.goodbye.GoodbyePlugin クラスに実装されます。

4. publishing ブロック

publishing {
    repositories {
        maven {
            url = uri(layout.buildDirectory.dir("maven-repo"))
        }
        ivy {
            url = uri(layout.buildDirectory.dir("ivy-repo"))
        }
    }
}
  • publishing ブロック:
    • プラグインやアーティファクトをリポジトリに公開する設定を記述します。

maven

  • プラグインやアーティファクトを Maven リポジトリに公開します。
  • url:
    • この例では、ビルドディレクトリ内の maven-repo フォルダに公開されます。

ivy

  • プラグインやアーティファクトを Ivy リポジトリに公開します。
  • url:
    • この例では、ビルドディレクトリ内の ivy-repo フォルダに公開されます。

5. プラグインの公開手順

このスクリプトに基づいて、カスタムプラグインを Maven または Ivy リポジトリに公開するには、以下のコマンドを実行します:

./gradlew publish
  • このコマンドを実行すると、以下が行われます:
    1. プラグイン (hellogoodbye) の JAR ファイルが作成されます。
    2. Maven リポジトリ (build/maven-repo) と Ivy リポジトリ (build/ivy-repo) にプラグインが公開されます。

6. 公開されたプラグインの適用

公開されたプラグインは、以下のように他のプロジェクトで適用可能です:

plugins {
    id("com.example.hello") version "1.0.0"
}

まとめ

このスクリプトにより以下が可能になります:

  1. 複数のカスタム Gradle プラグイン (hellogoodbye) を定義
  2. Maven リポジトリと Ivy リポジトリにプラグインを公開
  3. 他のプロジェクトでプラグインを簡単に適用

これにより、複数のプロジェクト間でプラグインを再利用しやすくなり、ビルド設定の一貫性を保つことができます。

ta.toshiota.toshio

https://docs.gradle.org/current/userguide/writing_plugins.html#writing_plugins

プラグインの作成

内容

Gradle または Gradle コミュニティがプロジェクトの必要とする特定の機能を提供していない場合、自作のカスタムプラグインを作成することが解決策となる可能性があります。

また、サブプロジェクト間でビルドロジックを重複して記述しており、より良い整理方法が必要な場合は、コンベンションプラグインが役立ちます。

スクリプトプラグイン

プラグインとは、Plugin インターフェースを実装するクラスのことです。たとえば、以下は「Hello World」プラグインの例です:

Kotlin``Groovy

build.gradle.kts

abstract class SamplePlugin : Plugin<Project> { 
    override fun apply(project: Project) {  
        project.tasks.register("ScriptPlugin") {
            doLast {
                println("Hello world from the build file!")
            }
        }
    }
}

apply<SamplePlugin>()
org.gradle.api.Plugin インターフェースを拡張します。
apply メソッドをオーバーライドします。
プロジェクトにプラグインを apply します。

1. org.gradle.api.Plugin インターフェースを拡張する

Plugin インターフェースを拡張するクラスを作成します:

Kotlin``Groovy

build.gradle.kts

abstract class SamplePlugin : Plugin<Project> {
}

2. apply メソッドをオーバーライドする

apply() メソッド内にタスクやその他のロジックを追加します:

Kotlin``Groovy

build.gradle.kts

override fun apply(project: Project) {

}

3. プロジェクトにプラグインを apply する

プロジェクトに SamplePlugin が適用されると、Gradle は定義された fun apply() {} メソッドを呼び出します。これにより、プロジェクトに ScriptPlugin タスクが追加されます:

Kotlin``Groovy

build.gradle.kts

apply<SamplePlugin>()

これは単純な「Hello World」の例であり、ベストプラクティスを反映しているわけではありません。

スクリプトプラグインは 推奨されません

プラグイン開発のベストプラクティスは、コンベンションプラグインまたはバイナリプラグインを作成することです。

事前コンパイル済みスクリプトプラグイン

事前コンパイル済みスクリプトプラグインは、迅速なプロトタイピングや実験を行うための簡単な方法を提供します。これにより、Groovy または Kotlin DSL を使用して *.gradle(.kts) スクリプトファイルとしてビルドロジックをパッケージ化できます。これらのスクリプトは、src/main/groovysrc/main/kotlin などの特定のディレクトリに配置されます。

適用するには、スクリプトファイル名(.gradle を除く)から導出された ID を使用します。ファイル自体がプラグインとみなされるため、事前コンパイル済みスクリプトでは Plugin インターフェースをサブクラス化する必要はありません。

以下は、次のようなディレクトリ構造の例です:

.
└── buildSrc
    ├── build.gradle.kts
    └── src
       └── main
          └── kotlin
             └── my-create-file-plugin.gradle.kts

my-create-file-plugin.gradle.kts ファイルには以下のコードが含まれます:

Kotlin``Groovy

buildSrc/src/main/kotlin/my-create-file-plugin.gradle.kts

abstract class CreateFileTask : DefaultTask() {
    @get:Input
    abstract val fileText: Property<String>

    @Input
    val fileName = "myfile.txt"

    @OutputFile
    val myFile: File = File(fileName)

    @TaskAction
    fun action() {
        myFile.createNewFile()
        myFile.writeText(fileText.get())
    }
}

tasks.register<CreateFileTask>("createMyFileTaskInConventionPlugin") {
    group = "from my convention plugin"
    description = "Create myfile.txt in the current directory"
    fileText.set("HELLO FROM MY CONVENTION PLUGIN")
}

この事前コンパイル済みスクリプトプラグインは、任意のサブプロジェクトの build.gradle(.kts) ファイルで適用できます:

Kotlin``Groovy

build.gradle.kts

plugins {
    id("my-create-file-plugin")  // 事前コンパイル済みコンベンションプラグインを適用
    `kotlin-dsl`
}

これにより、プラグインから createFileTask タスクがサブプロジェクトで利用可能になります。

バイナリプラグイン

バイナリプラグインは、コンパイル済みの言語で実装され、JAR ファイルとしてパッケージ化されたプラグインです。これらはソースからコンパイルされるのではなく、依存関係として解決されます。

ほとんどの場合、コンベンションプラグインは頻繁に更新される必要はありません。各開発者が開発プロセスの一環としてプラグインのビルドを実行するのは非効率であり、代わりにバイナリ依存関係として配布できます。

上記の例のコンベンションプラグインをバイナリプラグインに更新する方法は2通りあります。

  1. コンポジットビルド を使用する:

    settings.gradle.kts

    includeBuild("my-plugin")
    
  2. プラグインを パブリッシュする

    build.gradle.kts

    plugins {
        id("com.gradle.plugin.my-plugin") version "1.0.0"
    }
    

ここでは2番目の方法を採用します。このプラグインは Kotlin で書き直され、MyCreateFileBinaryPlugin.kt と呼ばれています。依然として buildSrc に保存されています:

buildSrc/src/main/kotlin/MyCreateFileBinaryPlugin.kt

import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import java.io.File

abstract class CreateFileTask : DefaultTask() {
    @get:Input
    abstract val fileText: Property<String>

    @Input
    val fileName = project.rootDir.toString() + "/myfile.txt"

    @OutputFile
    val myFile: File = File(fileName)

    @TaskAction
    fun action() {
        myFile.createNewFile()
        myFile.writeText(fileText.get())
    }
}

class MyCreateFileBinaryPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.tasks.register("createFileTaskFromBinaryPlugin", CreateFileTask::class.java) {
            group = "from my binary plugin"
            description = "Create myfile.txt in the current directory"
            fileText.set("HELLO FROM MY BINARY PLUGIN")
        }
    }
}

プラグインは、gradlePlugin {} ブロックを使用して id を付与し、パブリッシュすることができます。これによりルートプロジェクトで参照できるようになります:

Kotlin``Groovy

buildSrc/build.gradle.kts

group = "com.example"
version = "1.0.0"

gradlePlugin {
    plugins {
        create("my-binary-plugin") {
            id = "com.example.my-binary-plugin"
            implementationClass = "MyCreateFileBinaryPlugin"
        }
    }
}

publishing {
    repositories {
        mavenLocal()
    }
}

その後、ビルドファイルでプラグインを適用できます:

Kotlin``Groovy

build.gradle.kts

plugins {
    id("my-create-file-plugin")  // 事前コンパイル済みコンベンションプラグインを適用
    id("com.example.my-binary-plugin") // バイナリプラグインを適用
    `kotlin-dsl`
}

詳細については、プラグイン開発の章 を参照してください。

ta.toshiota.toshio

https://docs.gradle.org/current/userguide/part1_gradle_init_project.html

Part 1: プロジェクトの初期化

目次

Gradle の基本を学ぶために、まず Gradle を使って Java アプリケーションを作成します。

このセクションで行うこと:

  • Java プロジェクトの初期化
  • ディレクトリ構成の確認
  • Java アプリケーションの実行
  • Build Scan の生成
  • アプリケーションをアーカイブとしてバンドル

ステップ 0. 始める前に

  1. Gradle をインストール していることを確認してください。
  2. IntelliJ IDEA をインストールしてください(無料版の Community Edition で問題ありません)。

ステップ 1. プロジェクトの初期化

authoring-tutorial という新しいディレクトリを作成し、移動します。

$ mkdir authoring-tutorial
$ cd authoring-tutorial

gradle init コマンドを使用して Java アプリケーションを生成します。

$ gradle init --type java-application --dsl kotlin

追加のプロンプトが表示された場合は、デフォルトの設定を選択してください。

注: 本チュートリアルの例は macOS をベースとしています。


ステップ 2. ディレクトリ構成の理解

Gradle init の実行後、ディレクトリ構成は次のようになります。

.
├── gradle                              
    ├── libs.versions.toml              
│   └── wrapper
├── gradlew                             
├── gradlew.bat                         
├── settings.gradle.kts                 
└── app
    ├── build.gradle.kts                
    └── src
        ├── main
        │   └── java                    
        │       └── demo
        │           └── App.java
        └── test
            └── java                    
                └── demo
                    └── AppTest.java
ディレクトリ / ファイル 説明
gradle/wrapper Gradle Wrapper のファイルを含むディレクトリ
gradlew, gradlew.bat Gradle Wrapper の起動スクリプト
settings.gradle.kts ビルドの名前やサブプロジェクトを定義するファイル
app/build.gradle.kts app サブプロジェクトのビルドスクリプト
app/src/main/java app サブプロジェクトの Java ソースフォルダ
app/src/test/java app サブプロジェクトのテスト用 Java ソースフォルダ

ステップ 3. Gradle ファイルの確認

settings.gradle.kts ファイルには次のような行があります。

rootProject.name = "authoring-tutorial"
include("app")
  • rootProject.name はプロジェクトの名前を設定します。
  • include("app") は、サブプロジェクト app を含めることを指定します。

app/build.gradle.kts の内容:

plugins {
    id("application")
}

repositories {
    mavenCentral()
}

dependencies {
    testImplementation(libs.junit.jupiter)
    testRuntimeOnly("org.junit.platform:junit-platform-launcher")
    implementation(libs.guava)
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(11)
    }
}

application {
    mainClass = "org.example.App"
}

tasks.named<Test>("test") {
    useJUnitPlatform()
}

ステップ 4. コードの確認

メインクラス App.java のコード:

package authoring.tutorial;

public class App {
    public String getGreeting() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        System.out.println(new App().getGreeting());
    }
}

テストクラス AppTest.java のコード:

package authoring.tutorial;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class AppTest {
    @Test void appHasAGreeting() {
        App classUnderTest = new App();
        assertNotNull(classUnderTest.getGreeting(), "app should have a greeting");
    }
}

ステップ 5. アプリの実行

application プラグインを適用すると、run タスクを使用してアプリケーションを実行できます。

$ ./gradlew run

出力例:

> Task :app:run
Hello World!

BUILD SUCCESSFUL in 998ms
2 actionable tasks: 2 executed

ステップ 6. アプリのバンドル

アプリをパッケージ化するには、次のコマンドを実行します。

$ ./gradlew build

成功すると、app/build/distributions/.tar.zip のアーカイブが作成されます。


ステップ 6. Build Scan の公開

Build Scan を公開するには、--scan オプションを指定してビルドを実行します。

$ ./gradlew build --scan

出力例:

Publishing a build scan to scans.gradle.com requires accepting the Gradle Terms of Service defined at https://gradle.com/terms-of-service. Do you accept these terms? [yes, no] yes

Publishing build scan...
https://gradle.com/s/link

リンクをクリックすると、タスクの実行状況や依存関係の情報を確認できます。