Home About Contact
Gradle

Gradle のPlugin を書く Binary Plugins

自前のGradle Plugin をつくりそれをローカル maven レポジトリに配置、そのプラグインを別の Gradle プロジェクトから使うところまでの内容です。 試行錯誤の上、なんとなく作動するものができたので、とりあえずメモを残す。

環境

Java, Gradle のそれぞれの Version を確認:

$ java -version
openjdk version "17.0.13" 2024-10-15

$ gradle --version
Welcome to Gradle 8.13-milestone-3!

参考にしたコード中に 最新の gradle 8.13 でないと動かないところがあったので、それを使います。

Gradle プラグイン my-create-file の実装

build.gradle.kts を用意して次の内容を記述:

plugins {
    `kotlin-dsl`
    `maven-publish`
}

repositories {
    gradlePluginPortal()
}

group = "org.example"
version = "1.0.0"

gradlePlugin {
    plugins {
        create("my-create-file-plugin") {
            id = "org.example.my-create-file-plugin"
            implementationClass = "MyCreateFilePlugin"
        }
    }
}

publishing {
    repositories {
        mavenLocal()
    }
}

次にこのプラグインの実体を作成。

$ mkdir -p src/main/kotlin
$ touch src/main/kotlin/MyCreateFilePlugin.kt

MyCreateFilePlugin.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 filePath = project.layout.settingsDirectory.file("myfile.txt").asFile.path

    @OutputFile
    val myFile: File = File(filePath)

    @TaskAction
    fun action() {
        myFile.createNewFile()
        myFile.writeText(fileText.get())
    }
}

class MyCreateFilePlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.tasks.register("myCreateFileTask", CreateFileTask::class.java) {
            group = "from my create file plugin"
            description = "Create myfile.txt in the current directory"
            fileText.set("HELLO FROM MY BINARY PLUGIN")
        }
    }
}

このコードは https://github.com/gradle/gradle の ./platforms/documentation/docs/src/snippets/plugins/simple/kotlin/buildSrc/src/main/kotlin/MyCreateFileBinaryPlugin.kt を参考にしています。(そこからコピーしてクラス名を変えただけです。)

最後に settings.gradle を用意します。

rootProject.name = "my-create-file"

プロジェクト構成は次の通りです。

.
├── build.gradle.kts
├── settings.gradle
└── src
    └── main
        └── kotlin
            └── MyCreateFilePlugin.kt

あとは publishToMavenLocal タスクを実行してこのプラグインを local maven レポジトリに配置します。

$ gradle publishToMavenLocal

~/.m2/repository/org/example/my-create-file/ あたりに配置されます。

my-create-file プラグインを使う my-app プロジェクトを作成

適当なディレクトリを作成して my-app のプロジェクトルートにします。

build.gradle.kts を用意:

plugins {
    id("org.example.my-create-file-plugin") version "1.0.0"
}

repositories {
    mavenLocal()
}

ここが肝心なところなのですが settings.gradle を作成して、次の内容を記述します。

pluginManagement {
  repositories {
      mavenLocal()
      gradlePluginPortal()
  }
}

rootProject.name = "my-app" 

pluginManagment ブロックを記述して mavenLocal() を指定する必要があります。

プラグインを使う側のプロジェクトで必要なファイルは以上の2つのみです。 念のためプロジェクトの構成を確認しておきます。

.
├── build.gradle.kts
└── settings.gradle

それでは準備ができたので、 タスクの一覧を出力し、そこに myCreateFileTask が存在することを確認します。

$ gradle tasks

...

From my create file plugin tasks
--------------------------------
myCreateFileTask - Create myfile.txt in the current directory

...

myCreateFileTask を実行します。

$ gradle -q myCreateFileTask

カレントディレクトリに myfile.txt が作成されています。 内容は次の通り:

$ cat myfile.txt 
HELLO FROM MY BINARY PLUGIN

これでローカル maven レポジトリに配置した my-create-file プラグインを使うことができました。

以上です。