परिचय

लक्ष्य दर्शक : Gradle डेवलपर्स जो मल्टी-बिल्ड प्रोजेक्ट में निर्भरताओं के प्रबंधन का सामना कर रहे हैं।

हमारे प्लगिन को बनाने की खोज में`site-baker`, हमने साफ़ और केंद्रीकृत कोड बेस बनाए रखने की कोशिश की। आधुनिक Gradle इकोसिस्टम में सर्वोत्तम प्रथाओं में से एक उसका उपयोग करना हैसंस्करणों का कैटलॉग(libs.versions.toml) निर्भरताओं को प्रबंधित करने के लिए। लेकिन जब आपका प्रोजेक्ट अधिक जटिल हो जाता है, तो क्या होता है, जैसे एककॉम्पोज़िट बनानाकहाँ एक स्वतंत्र बिल्ड (हमारा प्लगइन) को किसी अन्य में शामिल किया जाना चाहिए ?

वहाँ हमारा प्रयास अप्रत्याशित मोड़ ले लिया। हम चाहते थे कि हमारा प्लगइन`site-baker`, जो कि खुद एक Gradle प्रोजेक्ट है, हमारे मुख्य प्रोजेक्ट के समान संस्करण कैटलॉग का उपयोग करता है। यह लेख, हमारी श्रृंखला का पाँचवाँ लेख, बताता है कि हमने इस चुनौती को कैसे हल किया।

वर्ज़न कैटलॉग (libs.versions.toml) : एक अनुस्मारक

फ़ाइल`gradle/libs.versions.toml`Gradle की एक सुविधा जो आपके प्रोजेक्ट की निर्भरताओं के संस्करण और निर्देशांक को केंद्रीय रूप से व्यवस्थित करती है। इसे आमतौर पर चार खंडों में संरचित किया जाता है:

  • [versions]`परिभाषित करता संस्करण संख्याओं के लिए उपनाम (उदाहरण:`kotlin = "1.9.20").

  • [libraries]`पूरी निर्भरताओं के लिए एलियास परिभाषित करता है, ऊपर परिभाषित संस्करणों का उपयोग करके (उदाहरण:`kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }).

  • [bundles]: समूह बनाता कई पुस्तकालयों के तहत एक ही उपनाम (ex:`jackson = ["jackson-core", "jackson-databind"]`)

  • [plugins]: Gradle प्लगइन के लिए एलीयस परिभाषित करें।

एक बार परिभाषित करने पर, Gradle स्वचालित रूप से टाइप किए गए एक्सेसर्स उत्पन्न करता है, जो आपके`build.gradle.kts`अधिक पढ़ने योग्य :

dependencies {
    // Au lieu de : implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.20")
    implementation(libs.kotlin.stdlib)
}
वर्ज़न कैटलॉग का डेटा प्रवाह
@startuml
!theme plain
file "gradle/libs.versions.toml" as Toml
node "Gradle" as G
file "build.gradle.kts" as BuildScript

Toml --> G : "पढ़ा जाता है"
G --> BuildScript : "`libs` का एक्सेसर बनाता है"
BuildScript -> G : "`libs` का उपयोग निर्भरताएँ घोषित करने के लिए किया जाता है"
@enduml

2. समस्या: एक संयुक्त बिल्ड और दो अलग‑अलग दुनियाएँ

हमारी परियोजना संरचना एक हैकॉम्पोज़ाइट बनाइए. मुख्य परियोजना (thymeleaf.cheroliv.com) "प्लगइन का प्रोजेक्ट शामिल है (site-baker) कमांड के द्वारा`includeBuild("site-baker")फ़ाइल में`settings.gradle.kts.

कंपोज़िट bILD की संरचना
@startuml
!theme plain
package "मुख्य परियोजना" {
  file "settings.gradle.kts" as MainSettings
  folder "gradle" {
    file "libs.versions.toml" as MainToml
  }
}

package "Plugin `site-baker` (Build शामिल)" {
  file "settings.gradle.kts" as PluginSettings
  file "build.gradle.kts" as PluginBuild
}

MainSettings -> PluginSettings : `includeBuild("site-baker")`
PluginBuild ..> MainToml : वह ... तक पहुँचना चाहता था
note right on link: ...लेकिन नहीं कर पा सका !
@enduml

समस्या यह है कि, डिफ़ॉल्ट रूप से, एक समावेशी बिल्ड है एकअलग दुनिया. इसके पास अपनी विशिष्ट कॉन्फ़िगरेशन, अपना विशिष्ट जीवन चक्र है, और यह फ़ाइल नहीं देखता।libs.versions.toml`मुख्य बिल्ड का। हमारा`plugin/build.gradle.kts`उपयोग करने की कोशिश कर रहा था`libs.plugins.kotlin.jvm, लेकिन वस्तु`libs`इसे सही TOML फ़ाइल से उत्पन्न नहीं किया गया था, जिससे बिल्ड त्रुटियाँ उत्पन्न हुईं।

3. समाधान: निर्भरता के समाधान को साझा करें

कई शोधों के बाद, यह समाधान एक Gradle फ़ीचर होने का पता चला जो इस मामले के लिए विशेष रूप से डिज़ाइन किया गया था।dependencyResolutionManagement.

फ़ाइल में`settings.gradle.kts` du build inclus(No response)site-baker/settings.gradle.kts), हम Gradle को बता सकते हैं कि उपयोग करने के लिए संस्करण कैटलॉग कहाँ मिल सकता है।

यहाँ वह कॉन्फ़िगरेशन है जिसे हमने जोड़ दिया है।site-baker/settings.gradle.kts :

// site-baker/settings.gradle.kts

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        gradlePluginPortal()
        mavenCentral()
    }
    versionCatalogs {
        create("libs") {
            from(files("../gradle/libs.versions.toml"))
        }
    }
}

rootProject.name = "site-baker"
include("plugin")

आइए महत्वपूर्ण भाग का विश्लेषण करें:

versionCatalogs {
    create("libs") { // Crée un catalogue nommé 'libs'
        from(files("../gradle/libs.versions.toml")) // En utilisant ce fichier
    }
}
  • create("libs")`हम संस्करणों का एक कैटलॉग घोषित करते हैं जो एलियास के माध्यम से उपलब्ध होगा।`libs.

  • from(files("../gradle/libs.versions.toml"))`यह जादू है। हम Gradle को बताते हैं कि इस कैटलॉग का स्रोत निर्देशिका में स्थित TOML फ़ाइल है।`gradle du पैरेंट प्रोजेक्ट(blank)../)

इस कॉन्फ़िगरेशन के साथ, बिल्ड`site-baker`वह अब जानता है कि उसे मुख्य प्रोजेक्ट के संस्करण कैटलॉग का उपयोग करना होगा। वस्तु`libs`इसे सही तरीके से उत्पन्न किया जाता है, और निर्भरताएँ अपेक्षा के अनुसार हल हो जाती हैं।

4. निष्कर्ष : अच्छी तरह से प्रबंधित किए गए कंपोज़िट बिल्ड्स की शक्ति

यह अनुभव सीखों से भरपूर रहा। संस्करण कैटलॉग रखरखाव के लिए एक शानदार उपकरण है, लेकिन कंपोज़िट बिल्ड परिदृश्यों में उसका व्यवहार हमेशा सहज नहीं होता।

याद रखने की मुख्य बात यह है कि एक शामिल बिल्ड अभी भी एक स्वतंत्र बिल्ड है। संस्करण कैटेलॉग जैसी कॉन्फ़िगरेशन साझा करने के लिए, ग्रैडल द्वारा प्रदान की गई स्पष्ट तंत्रों का उपयोग करना आवश्यक है, जैसे ब्लॉक`dependencyResolutionManagement`में`settings.gradle.kts`.

इस समस्या का समाधान करके, हमने न केवल अपने बिन्यूक्लेड (बिल्ड) को साफ़ बनाया, बल्कि हमने अपने प्रोजेक्ट की संगति को भी मजबूत कर दिया है, यह सुनिश्चित करके कि प्लगइन और मुख्य प्रोजेक्ट अपनी निर्भरताओं के लिए एक ही सत्य का स्रोत साझा करें।

आगामी लेख में, हम अब अपने प्लगइन को अधिक जटिल कार्यों के साथ समृद्ध करना जारी रखेंगे, क्योंकि हमारा निर्भरता प्रबंधन अब मजबूत और केंद्रीकृत हो गया है।

संबंधित लेख