অনুচ্ছেদ ৩ : জ্যাকসনের YAML পার্সিং টিডিডি সহ একটি গ্রেডল প্লাগিনে ইন্টিগ্রেশন
প্রকাশিত: 25 September 2025
প্রস্তাবনা
গ্রেডল প্লাগইন ডেভেলপমেন্টে, জটিল কনফিগারেশন পরিচালনা একটি一般적인 কাজ। শект 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. কোটলিনে কনফিগারেশন মডেলিং
পার্স করার আগে, আমাদেরকে কোটলিনে আমাদের ডেটার গঠন নির্ধারণ করতে হয়। 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()`কোটলিনের বৈশিষ্ট্য সমর্থনে (যেমন বৈশিষ্টের ডিফল্ট মান)
3. Jackson-er 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 পার্সিং পরীক্ষা
এখন, আমরা পার্সিং লজিক সত্যাপন করতে টিডিড প্রয়োগ করি।
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`.
এই পরীক্ষাটি অত্যন্ত গুরুত্বপূর্ণ, কারণ এটি একটি প্রকৃত প্রকল্পে প্লাগইনের চালanut অনুকরণ করে। এটি হওয়া উচিতবায়ুরোধী, অর্থাৎ, তাকে নিজে নিজে ফাইল তৈরি করতে হবে`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কে কোনটো কোটলিন বস্তুতে পার্স করে না, তবে এটি ফাইলের উপস্থিতি এবং বিষয়বস্তুর যাচাই করে যা প্লাগইন দ্বারা পার্সের জন্য একটি অপরিহার্য पूर्वশর্ত।
5. পার্সিং প্রবাহের দৃশ্যীকরণ
নিম্নলিখিত আকৃতি YAML কনফিগারেশন পার্স করার সময় ডেটা ফ্লো এবং ইন্টার্যাকশন দেখায় :
@startuml
actor "ব্যবহারকারী Gradle" as User
participant "build.gradle.kts" as BuildScript
participant "SiteBakerPlugin" as Plugin
participant "SiteExtension" as Extension
participant "managed-jbake-context.yml" as ConfigFile
participant "parseSiteConfiguration()" as Parser
participant "SiteConfiguration (বস্তু Kotlin)" as KotlinObject
User -> BuildScript : প্লাগিনটি প্রয়োগ কর এবং DSL কনফিগার কর
BuildScript -> Plugin : apply()
Plugin -> Extension : site এক্সটেনশন তৈরি করুন এবং সংরক্ষণ করুন
User -> BuildScript : সাইট { configPath = "..." }
BuildScript -> Extension : নির্ধারণ করে configPath
Plugin -> ConfigFile : ফাইলটি পড়ে (via configPath)
ConfigFile --> Plugin : বিষয়বস্তু YAML
Plugin -> Parser : parseSiteConfiguration(yamlString)কে ফোন করুন
Parser -> KotlinObject : YAML টি SiteConfiguration অবজেক্টে মানচিত্র কর
KotlinObject --> Plugin : কনফিগার করা বস্তুটি ফেরত দেয়।
@enduml
উপসংহার
একটি TDD পদ্ধতি অনুসরণ করে, আমরা Jackson লাইব্রেরি সফলভাবে সংযুক্ত করেছি যাতে YAML কনফিগারেশন ফাইলগুলোকে Kotlin অবজেক্টে পার্স করতে পারি আমাদের Gradle প্লাগইনের মধ্যে। এই পদ্ধতিটি আমাকে অনুমতি দিয়েছে :
-
স্পষ্টভাবে মডেল করাআমাদের কোটলিন ডেটা ক্লাসের সাথে কনফিগারেশন।
-
পার্সিং যুক্তি যাচাই করুনলক্ষ্য করা ইউনিট পরীক্ষাসহ।
-
ইন্টিগ্রেশন নিশ্চিত করুনবাস্তব Gradle পরিবেশে হেরমেটিক ফাংশনাল পরীক্ষাগুলোর মাধ্যমে।
এই ভালভাবে প্রতিষ্ঠিত ভিত্তি আমাদেরকে এই কনফিগারেশনকে ভিত্তি করে কার্যকারিতা যোগ করার জন্য আপনার প্লাগইনকে বাড়ানোর জন্য একটি উচ্চ নিশ্চয়তা দেয় এবং কোডের বজায় রাখযোগ্যতা এবং দৃঢ়তাও নিশ্চিত করে। YAML পার্সিং এখন আমাদের প্লাগইনকে একটি বিশ্বস্ত এবং পরীক্ষিত কার্যকারিতা হয়ে উঠেছে।site-baker।