제3항: Gradle 플러그인에서 TDD를 사용한 YAML 파싱을 위한 Jackson 통합
게시: 25 September 2025
소개
Gradle 플러그인 개발에서 복잡한 구성 관리는 일반적인 작업입니다. 백 개 이상의 속성으로 DSL을 과부하 시키는 대신, 외부 파일(YAML과 같은)에 구성을 정의하는 것이 종종 더 깔끔하고 유지 관리하기 쉽습니다. 이 글에서는 강력한 Jackson 라이브러리를 통합하여 YAML 파일을 Kotlin 객체로 파싱하는 과정을 안내하며, 플러그인의 견고함을 보장하기 위해 엄격한 TDD 접근 방식을 채택합니다.site-baker.
컨텍스트 : 우리 플러그인 `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에서 데이터 구조를 정의해야 합니다. 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 라이브러리를 성공적으로 통합하여 Gradle 플러그인 내에서 YAML 구성 파일을 Kotlin 객체로 파싱했습니다. 이를 통해 우리는 다음과 같이 할 수 있게 되었습니다 :
-
명확히 모델링우리의 Kotlin 데이터 클래스를 사용한 구성.
-
파싱 로직 검증대상화된 단위 테스트와 함께.
-
통합을 보장하다실제 Gradle 환경에서 허메틱 기능 테스트를 통해
이 견고한 기반은 이 구성을 기반으로 하는 기능을 갖춘 우리 플러그인을 확장할 수 있는 큰 확신을 제공하며, 동시에 코드의 유지 관리 가능성과 안정성을 보장합니다. YAML 파싱은 이제 우리 플러그인의 신뢰할 수 있고 테스트된 기능이 되었습니다.site-baker.
관련 기사
31 May 2026
14 May 2026