Artigo 3: Integração do Jackson para o Parsing YAML com TDD em um Plugin Gradle
Publié le 25 September 2025
Introdução
No desenvolvimento de plugins Gradle, a gestão de configurações complexas é uma tarefa comum. Em vez de sobrecarregar o DSL com centenas de propriedades, costuma ser mais limpo e manutenível definir a configuração em um arquivo externo, como o YAML. Este artigo guia você através da integração da poderosa biblioteca Jackson para analisar arquivos YAML em objetos Kotlin, adotando uma abordagem TDD rigorosa para garantir a robustez do nosso plugin.site-baker.
O Contexto: Nosso Plugin `site-baker
Nosso plugin`site-baker`é projetado para automatizar a geração e a implantação de um site estático. Ele precisa ler um arquivo de configuração YAML(managed-jbake-context.yml) para obter informações como os caminhos das fontes, os destinos de implantação e os identificadores Git.
A configuração YAML que queremos analisar é assim:
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. Modelagem da Configuração em Kotlin
Antes de analisar, devemos definir a estrutura dos nossos dados em Kotlin. Jackson usará estas classes para mapear automaticamente o conteúdo 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)
A função`parseSiteConfiguration`é o nosso ponto de entrada para a desserialização. Ela utiliza`ObjectMapper`de Jackson, configurado com`YAMLFactory`para o formato YAML e`registerKotlinModule()`para o suporte às especificidades do Kotlin (como os valores padrão das propriedades).
3. Integração de Jackson no `build.gradle.kts
Para usar o Jackson, devemos adicionar as dependências necessárias no`build.gradle.kts`do nosso módulo`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
}
Utilizamos`jackson-module-kotlin`para o suporte de Kotlin e`jackson-dataformat-yaml`para a gestão do formato YAML.
4. A Abordagem TDD: Testando o parsing YAML
Agora, vamos aplicar o TDD para validar nossa lógica de análise.
4.1. Teste Unitário: Mapear o YAML para Objeto Kotlin
Começamos com um teste unitário em`SiteBakerPluginTest.kt`para verificar que a função`parseSiteConfiguration`pode transformar corretamente uma string YAML em um objeto`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)
}
Este teste lê o conteúdo do arquivo`managed-jbake-context.yml`(que deve existir para que o teste seja válido) e faz asserções sobre o objeto`SiteConfiguration`resultante. Ele valida que os valores-chave do YAML estão corretamente mapeados.
4.2. Teste Funcional: Validar a Leitura do Arquivo de Configuração
Para garantir que o plugin possa ler o arquivo de configuração via seu DSL e que a análise funcione em um ambiente Gradle real, adicionamos um teste funcional em`SiteBakerPluginFunctionalTest.kt`.
Este teste é crucial porque simula a execução do plugin em um projeto real. Deve serhermético, isto é, ele deve criar o arquivo por conta própria`managed-jbake-context.yml`com um conteúdo controlado, para garantir a reprodutibilidade e o isolamento do teste
// 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"))
}
Este teste funcional verifica que o arquivo de configuração copiado para o diretório temporário do teste contém os dados esperados. Embora este teste não faça o parsing diretamente do YAML em um objeto Kotlin, ele valida a presença do arquivo e do seu conteúdo, o que é um passo prévio essencial para o parsing pelo plugin.
5. Visualização do Fluxo de Parsing
O diagrama a seguir ilustra o fluxo de dados e as interações durante o parsing da configuração YAML :
Conclusão
Ao seguir uma abordagem TDD, integramos com sucesso a biblioteca Jackson para analisar arquivos de configuração YAML em objetos Kotlin dentro do nosso plugin Gradle. Este método nos permitiu:
-
Modelar claramentenossa configuração com classes de dados Kotlin.
-
Validar a lógica de análisecom testes unitários direcionados.
-
Garantir a integraçãonum ambiente Gradle real graças a testes funcionais herméticos.
Esta base sólida nos oferece uma grande confiança para estender nosso plugin com funcionalidades que se baseiam nessa configuração, ao mesmo tempo em que garante a manutenibilidade e a robustez do código. O parsing YAML agora é um recurso confiável e testado do nosso plugin`site-baker`.