مقدمة

الجمهور المستهدف: مطورو Gradle المتوسطون الذين يرغبون في إدارة التكوينات المعقدة.

في تطوير إضافات Gradle، إدارة التكوينات المعقدة هي مهمة شائعة. بدلاً من تحميل DSL بمئات الخصائص، غالبًا ما يكون أنظف وأكثر قابلية للصيانة تحديد التكوين في ملف خارجي، مثل YAML. هذا المقال يرشدك خلال تكامل مكتبة جاكسون القوية لتحليل ملفات YAML إلى كائنات Kotlin، باتباع نهج TDD صارم لضمان متانة برنامجنا الإضافي.site-baker.

السياق : ملحقنا `site-baker

إضافة لدينا`site-baker`تم تصميمه لأتمتة توليد ونشر موقع ثابت. يحتاج إلى قراءة ملف تكوين YAML (managed-jbake-context.yml) للحصول على معلومات مثل مسارات المصادر، وجهات النشر، ومعرّفات Git.

La configuration YAML que nous souhaitons parser ressemble à ceci :

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`من جاكسون، تم تكوينه معه`YAMLFactory`لتنسيق YAML و`registerKotlinModule()`لدعم ميزات Kotlin (مثل القيم الافتراضية للخصائص).

3. تكامل جاكسون في `build.gradle.kts

لاستخدام جاكسون، يجب أن نضيف التبعيات الضرورية في الـ`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 إلى كائن كاتلن

نبدأ باختبار وحدة في`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 :

Diagram

خاتمة

باعتماد نهج TDD، دمجنا بنجاح مكتبة Jackson لتحليل ملفات التكوين YAML وتحويلها إلى كائنات Kotlin داخل المكوّن Gradle الخاص بنا. هذه الطريقة سمحت لنا:

  • نمذج بوضوحتكويننا مع فئات البيانات Kotlin.

  • تحقق من منطق التحليلمع اختبارات الوحدة المستهدفة

  • ضمان التكاملفي بيئة Gradle حقيقية بفضل اختبارات وظيفية عازلة.

هذه القاعدة المتينة تمنحنا ثقة كبيرة لتوسيع برنامجنا الإضافي بميزات تستند إلى هذه التهيئة، مع ضمان صيانة وقوة الكود. أصبح تحليل YAML الآن ميزة موثوقة ومختبرة في برنامجنا الإضافي`site-baker`.

Articles connexes