LoginSignup
0

【Gradle】gradleから値を埋め込んだファイルを生成し、ソースとして扱う【Kotlin】

Last updated at Posted at 2023-06-11

やりたいこと

ビルド時にgradleから値を埋め込んだKotlinファイルを生成し、それをソースとして扱います。

実際に生成したかったのは、以下のようなファイルです。
文字列で設定されている"2.15.2-beta0"などの値はgradleから埋め込んだものです。

KogeraVersion.kt
package io.github.projectmapk.jackson.module.kogera

import com.fasterxml.jackson.core.Version
import com.fasterxml.jackson.core.util.VersionUtil

public val kogeraVersion: Version = VersionUtil.parseVersion("2.15.2-beta0", "io.github.projectmapk", "jackson-module-kogera")

やり方

これから紹介する方法は以下の方法を参考に独自の改修を加えたものです。
自分はこの辺りに詳しくないため、より良いやり方などご存じでしたらコメント頂けると嬉しいです。

成果物(build.gradle.kts)は以下の通りです。
移行の解説は、この成果物からの抜粋をベースに行います。

1. ファイルを生成するタスクを定義する

まず、以下のようにしてファイルを生成するタスクを定義します。

build.gradle.kts(抜粋)
val generatedSrcPath = "$buildDir/generated/kotlin"

/* 略 */

tasks {
    // Task to generate version file
    val generateKogeraVersion by registering(Copy::class) {
        val packageStr = "$groupStr.jackson.module.kogera"

        from(
            resources.text.fromString(
                """
package $packageStr

import com.fasterxml.jackson.core.Version
import com.fasterxml.jackson.core.util.VersionUtil

public val kogeraVersion: Version = VersionUtil.parseVersion("$version", "$groupStr", "${rootProject.name}")

                """.trimIndent()
            )
        ) {
            rename { "KogeraVersion.kt" }
        }

        into(file("$generatedSrcPath/${packageStr.replace(".", "/")}"))
    }

    /* 略 */
}

generateKogeraVersionとしている部分はタスクの名前で、ここには任意の名前を付けられます。

resources.text.fromStringの中身は生成結果となる文字列です。
ここでgradleタスクのスコープに定義された値を読み取り、埋め込んでいます。

renameに設定した値がファイル名、intoに設定した値が生成先ディレクトリとなります。
生成先ディレクトリに関しては、基本的にbuild/generatedの下とすることがお勧めです。
サンプルコードではbuild/generated/kotlinの下としていますが、既存で生成を行っている場合そのディレクトリに合わせるのも手です。

ここまで設定したタスクを実行することで、ファイル生成を行えます。

2. 生成したファイルをソースに加える

1で生成したファイルは、そのままではKotlin上でソースとして扱われません(既にソースとして認識されているディレクトリへ生成した場合を除く)。
そこで、以下のようにしてソースに加える必要が有ります。

build.gradle.kts(抜粋)
val generatedSrcPath = "$buildDir/generated/kotlin"

/* 略 */

kotlin {
    /* 略 */

    sourceSets["main"].apply {
        kotlin.srcDir(generatedSrcPath)
    }
}

3. ビルドに連動して自動生成する

以下のように、1で定義したタスクをcompileKotlinの依存に追加することで、ビルドの前に自動実行することが出来ます。

build.gradle.kts(抜粋)
tasks {
    /* 略 */

    compileKotlin {
        dependsOn.add(generateKogeraVersion)

        /* 略 */
    }

    /* 略 */
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0