導入

対象 : 中級 Gradle 開発者で、複雑な設定を管理したい人

Gradleプラグインの開発において、複雑な構成の管理は一般的な作業です。DSLに数百のプロパティを詰め込むのではなく、外部ファイル、例えばYAMLに設定を定義するほうが、すっきりしており保守しやすいことが多いです。この記事では、強力なJacksonライブラリを使ってYAMLファイルをKotlinオブジェクトにパースする統合方法を、厳格なTDDアプローチを採用してプラグインの堅牢性を確保する形でガイドします。site-baker。

1. コンテキスト: 私たちのプラグイン `site-baker

私たちのプラグイン`site-baker`は、静的サイトの生成とデプロイを自動化するように設計されています。YAML設定ファイルを読み込む必要があります (managed-jbake-context.yml) ソースのパス、デプロイ先、Gitの識別子などの情報を取得するために。

パースしたいYAML設定はこのようになります:

bake:
  srcPath: "./site/jbake"
  destDirPath: "bake"
  cname: "cheroliv.com"
pushPage:
  from: "bake"
  to: "cvs"
  repo:
    name: "trainings"
    repository: "https://github.com/pages-content/pages-content.github.io.git"
    credentials:
      username: "USERNAME"
      password: "SECRET_TOKEN"
  branch: "main"
  message: "cheroliv.com"
# ... autres configurations (pushMaquette, supabase, etc.)

2. Kotlin での設定のモデリング

パースする前に、Kotlinでデータの構造を定義する必要があります。Jacksonはこれらのクラスを使用してYAMLコンテンツを自動的にマッピングします。

// plugin/src/main/kotlin/com/cheroliv/site/baker/data/SiteConfiguration.kt
package com.cheroliv.site.baker.data

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
import com.fasterxml.jackson.module.kotlin.readValue
import com.fasterxml.jackson.module.kotlin.registerKotlinModule

fun parseSiteConfiguration(yaml: String): SiteConfiguration {
    val mapper = ObjectMapper(YAMLFactory()).registerKotlinModule()
    return mapper.readValue(yaml)
}

data class GitPushConfiguration(
    val from: String = "",
    val to: String = "",
    val repo: RepositoryConfiguration = RepositoryConfiguration(),
    val branch: String = "",
    val message: String = "",
)

data class RepositoryConfiguration(
    val name: String = "",
    val repository: String = "",
    val credentials: RepositoryCredentials = RepositoryCredentials(),
) {
    companion object {
        const val ORIGIN = "origin"
        const val CNAME = "CNAME"
        const val REMOTE = "remote"
    }
}

data class RepositoryCredentials(val username: String = "", val password: String = "")

data class SiteConfiguration(
    val bake: BakeConfiguration = BakeConfiguration(),
    val pushPage: GitPushConfiguration = GitPushConfiguration(),
    val pushMaquette: GitPushConfiguration = GitPushConfiguration(),
    val pushSource: GitPushConfiguration? = null,
    val pushTemplate: GitPushConfiguration? = null,
    val supabase: SupabaseContactFormConfig? = null
)

data class BakeConfiguration(
    val srcPath: String = "",
    val destDirPath: String = "",
    val cname: String? = null,
)

// ... (autres data classes pour Supabase, si nécessaire)

機能`parseSiteConfiguration`これはデシリアライズのエントリーポイントです。使用します`ObjectMapper`Jacksonの、設定済みの`YAMLFactory`YAMLフォーマットに対して`registerKotlinModule()`Kotlinの特殊機能のサポート(例えばプロパティのデフォルト値など)のため。

3. Jacksonの`build.gradle.kts`への統合

Jacksonを使用するには、必要な依存関係を追加する必要がありますの`build.gradle.kts`私たちのモジュールの`plugin`:

// plugin/build.gradle.kts
dependencies {
    // Jackson for YAML parsing
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.18.3")
    implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.3")

    // ... autres dépendances
}

私たちは使用します`jackson-module-kotlin`Kotlinのサポートのためにおよび`jackson-dataformat-yaml`YAML形式の管理のために。

4. TDDアプローチ:YAMLパースのテスト

今、TDDを適用してパースロジックを検証しましょう。

4.1. 単体テスト: YAMLをKotlinオブジェクトにマッピング

私たちは単体テストで始めます`SiteBakerPluginTest.kt`関数が機能しているかを確認するために`parseSiteConfiguration`YAML文字列をオブジェクトに正しく変換できます`SiteConfiguration`.

// plugin/src/test/kotlin/com/cheroliv/site/baker/SiteBakerPluginTest.kt
@Test
fun `can map configuration text to SiteConfiguration object`() {
    val yamlString = "../../managed-jbake-context.yml"
        .run(::File)
        .readText()
        .trimIndent()

    val config: SiteConfiguration = parseSiteConfiguration(yamlString)

    assertEquals("cheroliv.com", config.bake.cname)
    assertEquals("main", config.pushPage.branch)
    assertEquals("https://github.com/pages-content/pages-content.github.io.git", config.pushPage.repo.repository)
}

このテストはファイルの内容を読み込みます`managed-jbake-context.yml`(テストが有効であるために存在しなければならない)およびオブジェクトに対するアサーションを実行する`SiteConfiguration`結果として。 YAML のキーの値が正しくマッピングされていることを検証します。

4.2. 機能テスト:構成ファイルの読み取りを検証する

プラグインがそのDSLを通じて設定ファイルを読み取ることができ、実際のGradle環境でパースが機能することを確認するために、私たちは機能テストを追加します`SiteBakerPluginFunctionalTest.kt`。

このテストは重要です。なぜなら、実際のプロジェクトでのプラグインの実行をシミュレートするからです。これが必要です密閉, すなわち彼は自分でファイルを作成しなければならない`managed-jbake-context.yml`制御されたコンテンツを使用して、テストの再現性と隔離を保証します。

// plugin/src/functionalTest/kotlin/com/cheroliv/site/baker/SiteBakerPluginFunctionalTest.kt
@Test
fun `config file contains good data`(){
    val configContent = configFile.readText(UTF_8)
    // Vérifications comme dans vos commentaires
    assertTrue(configContent.contains("bake"))
    assertTrue(configContent.contains("pushPage"))
    assertTrue(configContent.contains("repository"))
}

この機能テストは、テストの一時ディレクトリにコピーされた設定ファイルに期待されるデータが含まれていることを確認します。このテストは直接 YAML を Kotlin オブジェクトにパースしませんが、ファイルとその内容の存在を検証し、これはプラグインによるパースに必要な前提条件となります。

5. パースフローの可視化

次の図は、YAML 設定のパース時のデータフローとインタラクションを示しています:

@startuml
actor "Gradle ユーザー" as User
participant "build.gradle.kts" as BuildScript
participant "SiteBakerPlugin" as Plugin
participant "サイトエクステンション" as Extension
participant "managed-jbake-context.yml" as ConfigFile
participant "parseSiteConfiguration()" as Parser
participant "SiteConfiguration ( Kotlin オブジェクト )" as KotlinObject

User -> BuildScript : Applique le plugin et configure le DSL
BuildScript -> Plugin : apply()
Plugin -> Extension : Crée et enregistre l'extension 'site'
User -> BuildScript : site { configPath = "..." }
BuildScript -> Extension : Définit configPath

Plugin -> ConfigFile : Lit le fichier (via configPath)
ConfigFile --> Plugin : Contenu YAML
Plugin -> Parser : Appelle parseSiteConfiguration(yamlString)
Parser -> KotlinObject : Mappe le YAML en objet SiteConfiguration
KotlinObject --> Plugin : Retourne l'objet configuré

@enduml

結論

TDDのアプローチを取ることで、Jacksonライブラリを使用してYAML設定ファイルをKotlinオブジェクトにパースし、Gradleプラグインに正常に組み込むことができました。この方法により、以下のことが可能になりました:

  • 明確にモデリング私たちの構成とKotlinのデータクラス。

  • パースロジックを検証する対象となる単体テストで。

  • 統合の確保実際の Gradle 環境で、密閉された機能テストにより。

この堅固な基盤により、この設定に基づく機能でプラグインを拡張する大きな自信を得られ、コードの保守性と堅牢性も確保できます。YAMLのパースは今ではプラグインの信頼性が高くテスト済みの機能となっています。site-baker。

関連記事