Bzlmod की मदद से एक्सटर्नल डिपेंडेंसी मैनेज करें

अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है किसी समस्या की शिकायत करें सोर्स देखें रात · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bzlmod नए एक्सटर्नल डिपेंडेंसी सिस्टम का कोडनेम है बेज़ल 5.0 में पेश किया गया. इसे उन समस्याओं को हल करने के लिए शुरू किया गया था जो पुराना सिस्टम, जिसे बेहतर तरीके से ठीक नहीं किया जा सकता था; देखें ओरिजनल डिज़ाइन दस्तावेज़ का प्रॉब्लम स्टेटमेंट सेक्शन देखें.

Bazz 5.0 में, Bzlmod डिफ़ॉल्ट रूप से चालू नहीं होता है; फ़्लैग नीचे दी गई चीज़ों को लेने के लिए, --experimental_enable_bzlmod तय करना ज़रूरी है इफ़ेक्ट. जैसा कि फ़्लैग के नाम से पता चलता है, फ़िलहाल यह सुविधा एक्सपेरिमेंट के तौर पर उपलब्ध है; जब तक सुविधा आधिकारिक तौर पर लॉन्च नहीं हो जाती, तब तक एपीआई और उसके व्यवहार में बदलाव हो सकता है.

अपने प्रोजेक्ट को Bzlmod पर माइग्रेट करने के लिए, Bzlmod माइग्रेशन गाइड में दी गई जानकारी देखें. Bzlmod इस्तेमाल के उदाहरण देखने के लिए, उदाहरण रिपॉज़िटरी (डेटा स्टोर करने की जगह) में भी देखें.

बेज़ल मॉड्यूल्स

पुराना WORKSPACE-आधारित एक्सटर्नल डिपेंडेंसी सिस्टम इसके बीच में है डेटा स्टोर करने की जगहें (या डेटा स्टोर करने की जगहें), जिन्हें डेटा स्टोर करने के लिए बनाए गए नियमों (या रेपो नियम) के ज़रिए बनाया जाता है. इस नए सिस्टम में, रेपो अब भी एक अहम कॉन्सेप्ट है, लेकिन मॉड्यूल डिपेंडेंसी की कोर यूनिट.

मॉड्यूल एक Basel प्रोजेक्ट है. इसके कई वर्शन हो सकते हैं, जिनमें से हर एक के लिए जिसमें से उस मॉड्यूल के बारे में मेटाडेटा पब्लिश होता है जिस पर वह निर्भर करता है. यह है यह अन्य डिपेंडेंसी मैनेजमेंट सिस्टम में मौजूद कॉन्सेप्ट से मिलता-जुलता है: Maven आर्टफ़ैक्ट, एक एनपीएम पैकेज, कार्गो क्रेट, गो मॉड्यूल वगैरह

मॉड्यूल, name और version पेयर का इस्तेमाल करके, सिर्फ़ अपनी डिपेंडेंसी के बारे में बताता है, में खास यूआरएल की जगह WORKSPACE में मौजूद यूआरएल डालें. इसके बाद डिपेंडेंसी Baज़ल रजिस्ट्री; डिफ़ॉल्ट रूप से, Babel Central Registry. आपके फ़ाइल फ़ोल्डर में, हर तो वह एक रेपो में बदल जाता है.

MODULE.bazel

हर मॉड्यूल के हर वर्शन में एक MODULE.bazel फ़ाइल होती है, जो यह बताती है कि डिपेंडेंसी और अन्य मेटाडेटा. यहां एक सामान्य उदाहरण दिया गया है:

module(
    name = "my-module",
    version = "1.0",
)

bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")

MODULE.bazel फ़ाइल, वर्कस्पेस डायरेक्ट्री के रूट में होनी चाहिए (WORKSPACE फ़ाइल के बगल में). WORKSPACE फ़ाइल के उलट, आपको इसकी ज़रूरत नहीं है आपकी ट्रांज़िव डिपेंडेंसी के बारे में बताने के लिए; इसके बजाय, आपको केवल direct डिपेंडेंसी और आपकी डिपेंडेंसी की MODULE.bazel फ़ाइलें को अपने-आप ट्रांज़िटिव डिपेंडेंसी खोजने के लिए प्रोसेस किया जाता है.

MODULE.bazel फ़ाइल, BUILD फ़ाइलों जैसी है, क्योंकि यह किसी भी फ़ाइल के साथ काम नहीं करती कंट्रोल फ़्लो का तरीका; साथ ही यह load स्टेटमेंट के लिए मना करता है. डायरेक्टिव MODULE.bazel फ़ाइलों का इस्तेमाल किया जा सकता है:

  • module, मेटाडेटा की जानकारी देने के लिए मौजूदा मॉड्यूल के बारे में जानकारी, जिसमें उसका नाम, वर्शन वगैरह शामिल हैं;
  • bazel_dep, डायरेक्ट बताने के लिए अन्य Baze मॉड्यूल की डिपेंडेंसी;
  • ओवरराइड करता है, जिनका उपयोग केवल रूट मॉड्यूल द्वारा किया जा सकता है (यानी, जिसे एक डिपेंडेंसी के रूप में इस्तेमाल किया जा रहा है) कुछ डायरेक्ट या ट्रांज़िटिव डिपेंडेंसी:
  • मॉड्यूल एक्सटेंशन से जुड़े निर्देश:

वर्शन का फ़ॉर्मैट

बेज़ल का नेटवर्क काफ़ी अलग है. यहां अलग-अलग प्रोजेक्ट में वर्शन बनाने के लिए अलग-अलग स्कीम का इस्तेमाल किया जाता है. कॉन्टेंट बनाने अब तक SemVer सबसे लोकप्रिय है, लेकिन कुछ प्रोजेक्ट पर काम करने के लिए, अब्सील, वर्शन तारीख के हिसाब से हों, जैसे कि 20210324.2).

इस वजह से, Bzlmod SemVer स्पेसिफ़िकेशन का ज़्यादा आसान वर्शन इस्तेमाल करता है. कॉन्टेंट बनाने अंतरों में शामिल हैं:

  • SemVer का कहना है कि "रिलीज़" वर्शन के हिस्से के तौर पर, सेगमेंट: MAJOR.MINOR.PATCH. Basel में, इस ज़रूरत को ढीला कर दिया गया है, इसलिए कितने भी सेगमेंट की अनुमति हो.
  • SemVer में, "रिलीज़" के हर सेगमेंट भाग में केवल अंक होने चाहिए. Baज़ल में, इसे ढीला किया गया, ताकि अक्षर और तुलना करने की सुविधा का इस्तेमाल किया जा सके सिमेंटिक्स "आइडेंटिफ़ायर" से मेल खाता है "प्रीरिलीज़" में .
  • इसके अलावा, मेजर, माइनर, और पैच वर्शन में होने वाले बदलावों की वजह से लागू नहीं किया जाता. (हालांकि, इसके लिए कंपैटबिलिटी लेवल देखें हम पुराने सिस्टम के साथ काम करने की सुविधा को कैसे दिखाते हैं.

SemVer का कोई भी मान्य वर्शन, Basel मॉड्यूल का एक मान्य वर्शन है. इसके अलावा, दो SemVer के वर्शन a और b एक ही होल्ड की होने पर a < b की तुलना करते हैं की तुलना बेज़ेल मॉड्यूल वर्शन से की है.

वर्शन का रिज़ॉल्यूशन

वर्शन वाली डिपेंडेंसी में डायमंड डिपेंडेंसी की समस्या मुख्य है मैनेजमेंट स्पेस मान लें कि आपके पास नीचे दिया गया डिपेंडेंसी ग्राफ़ है:

       A 1.0
      /     \
   B 1.0    C 1.1
     |        |
   D 1.0    D 1.1

D का कौनसा वर्शन इस्तेमाल करना चाहिए? इस प्रश्न का समाधान करने के लिए, Bzlmod द्वारा कम से कम वर्शन चुनना (MVS) एल्गोरिदम को Go मॉड्यूल सिस्टम में लॉन्च किया गया. MVS का मानना है कि सभी नए मॉड्यूल के वर्शन पुराने सिस्टम के साथ काम करते हैं. इसलिए, इनमें से सबसे ऊंचे किसी भी आश्रित द्वारा निर्दिष्ट किया गया वर्शन (हमारे उदाहरण में D 1.1). इसे "मिनिमल" कहा जाता है क्योंकि यहां D 1.1 बहुत कम वर्शन है जो हमारी ज़रूरतों को पूरा कर सकता है; भले ही, D 1.2 या नया वर्शन मौजूद हो, हम उन्हें नहीं चुनते. इसमें एक अतिरिक्त फ़ायदा है यह ज़रूरी है कि चुना गया वर्शन हाई-फ़िडेलिटी हो और फिर से बनाया जा सके.

वर्शन रिज़ॉल्यूशन को आपकी मशीन पर स्थानीय तौर पर किया जाता है, रजिस्ट्री के ज़रिए नहीं.

कंपैटिबिलिटी लेवल

ध्यान दें कि पुराने सिस्टम के साथ काम करने की सुविधा के बारे में MVS का यह अनुमान संभव है, क्योंकि किसी मॉड्यूल के पुराने वर्शन के साथ काम न करने वाले वर्शन को एक अलग मॉड्यूल मान लेता है. SemVer के हिसाब से, इसका मतलब है कि A 1.x और A 2.x को अलग-अलग मॉड्यूल माना जाता है, और रिज़ॉल्व की गई डिपेंडेंसी ग्राफ़ में एक साथ रह सकता है. यही वजह है कि ऐसा इसलिए हो सकता है, क्योंकि मेजर वर्शन को शुरू करें, ताकि कोई कंपाइल-टाइम या लिंकिंग-टाइम कॉन्फ़्लिक्ट न हों.

Basel में, हम ऐसी कोई गारंटी नहीं देते. इसलिए, हमें "प्रमुखता" को बताने का एक तरीका चाहिए वर्शन" नंबर डालें, ताकि पुराने सिस्टम के साथ काम न करने वाले वर्शन का पता लगाया जा सके. यह नंबर इसे कंपैटबिलिटी लेवल कहा जाता है. इसे हर मॉड्यूल के वर्शन के ज़रिए, इसके module() डायरेक्टिव. यह जानकारी मिलने के बाद, हम गड़बड़ी की सूचना जब हमें पता चलता है कि एक ही मॉड्यूल के अलग-अलग वर्शन के साथ काम करने वाले वर्शन लेवल रिज़ॉल्व की गई डिपेंडेंसी ग्राफ़ में मौजूद हैं.

डेटा स्टोर करने की जगह के नाम

Basel में, हर बाहरी डिपेंडेंसी का एक रिपॉज़िटरी नाम होता है. कभी-कभी, एक जैसा डिपेंडेंसी का इस्तेमाल अलग-अलग रिपॉज़िटरी के नामों के ज़रिए किया जा सकता है (उदाहरण के लिए, दोनों @io_bazel_skylib और @bazel_skylib का मतलब Baaz skylib) या इससे पहले रिपॉज़िटरी के नाम का इस्तेमाल अलग-अलग प्रोजेक्ट में अलग-अलग डिपेंडेंसी के लिए किया जा सकता है.

Bzlmod में, डेटा स्टोर करने की जगहें, Baze मॉड्यूल की मदद से जनरेट की जा सकती हैं और मॉड्यूल एक्सटेंशन. डेटा स्टोर करने की जगह के नाम से जुड़े विवादों को हल करने के लिए, हम डेटा स्टोर करने की जगह की जानकारी को मैप करने को अपना रहे हैं नए सिस्टम में मौजूद है. यहां दो ज़रूरी कॉन्सेप्ट दिए गए हैं:

  • डेटा स्टोर करने की कैननिकल जगह का नाम: हर यूआरएल के लिए, दुनिया भर में यूनीक रिपॉज़िटरी का नाम डेटा स्टोर करने की जगह. इस डायरेक्ट्री का नाम, डेटा स्टोर करने की जगह में होगा.
    इसे इस तरह बनाया जाता है (चेतावनी: कैननिकल नाम का फ़ॉर्मैट यह है यह वह एपीआई नहीं है जिस पर आपको निर्भर रहना चाहिए, इसमें किसी भी समय बदलाव हो सकता है):

    • बेज़ेल मॉड्यूल रिपोज़ के लिए: module_name~version
      (उदाहरण. @bazel_skylib~1.0.3)
    • मॉड्यूल एक्सटेंशन डेटा को स्टोर करने की सुविधा के लिए: module_name~version~extension_name~repo_name
      (उदाहरण. @rules_cc~0.0.1~cc_configure~local_config_cc)
  • एपरेंट रिपॉज़िटरी का नाम: रिपॉज़िटरी का नाम BUILD और डेटा स्टोर करने की जगह के अंदर .bzl फ़ाइलें. एक ही डिपेंडेंसी के लिए अलग-अलग ऑब्जेक्ट हो सकते हैं अलग-अलग जगह पर रखते हैं.
    यह इस तरह से तय होता है:

    • Baज़ल मॉड्यूल रिपोज़ के लिए: module_name डिफ़ॉल्ट या repo_name विशेषता से तय किया गया नाम bazel_dep.
    • मॉड्यूल एक्सटेंशन डेटा स्टोर करने की सुविधा के लिए: रिपॉज़िटरी का नाम इसके ज़रिए जोड़ा गया use_repo.

हर रिपॉज़िटरी में उसकी डायरेक्ट डिपेंडेंसी का रिपॉज़िटरी मैपिंग डिक्शनरी होती है, जो कि रिपॉज़िटरी के नाम से लेकर कैननिकल रिपॉज़िटरी के नाम तक का मैप है. हम रिपॉज़िटरी मैपिंग का इस्तेमाल करके, रिपॉज़िटरी का नाम बनाते समय लेबल. ध्यान दें कि कैननिकल रिपॉज़िटरी के नामों में कोई अंतर नहीं होता है. साथ ही, MODULE.bazel को पार्स करके, साफ़ तौर पर स्टोर किए गए डेटा स्टोर के नामों के इस्तेमाल का पता लगाया जा सकता है फ़ाइल डाउनलोड की जाती है, इसलिए विवादों को प्रभावित किए बिना आसानी से पकड़ा और हल किया जा सकता है अन्य डिपेंडेंसी.

सख्त डेप

डिपेंडेंसी के नए स्पेसिफ़िकेशन के फ़ॉर्मैट की मदद से, हम ज़्यादा सख्त जांच करते हैं. तय सीमा में खास तौर पर, अब हम यह लागू करते हैं कि मॉड्यूल सिर्फ़ डायरेक्ट डिपेंडेंसी. इससे, अनजाने में होने वाली और डीबग करने में मुश्किल आने वाली गड़बड़ियों से बचा जा सकता है जब ट्रांज़िटिव डिपेंडेंसी ग्राफ़ में कुछ बदलता है.

इसके आधार पर सख्त निर्देश लागू किए गए हैं डेटा स्टोर करने की जगह की मैपिंग के बारे में ज़्यादा जानें. मूल रूप से, हर रेपो की रिपॉज़िटरी मैपिंग में इसकी सभी डायरेक्ट डिपेंडेंसी होती हैं, किसी भी डेटा स्टोर करने की अन्य जगह नहीं दिखती. हर रिपॉज़िटरी के लिए दिखने वाली डिपेंडेंसी इस तरह तय किया जाता है:

  • बेज़ल मॉड्यूल रेपो, MODULE.bazel फ़ाइल में पेश किए गए सभी रेपो देख सकता है bazel_dep से और use_repo.
  • मॉड्यूल एक्सटेंशन रेपो, मॉड्यूल की दिखने वाली उन सभी डिपेंडेंसी को देख सकता है जो एक्सटेंशन के साथ-साथ इस मॉड्यूल से जनरेट किए गए दूसरे सभी डेटा संग्रह स्थान देता है एक्सटेंशन चुनें.

रजिस्ट्री

Bzlmod ने Baज़ेन से अपनी जानकारी मांगकर, डिपेंडेंसी का पता लगाया रजिस्ट्री होती हैं. Basel रजिस्ट्री, Basel मॉड्यूल का एक डेटाबेस है. सिर्फ़ रजिस्ट्री का एक मौजूदा फ़ॉर्मैट इंडेक्स रजिस्ट्री है, जो कोई लोकल डायरेक्ट्री या खास फ़ॉर्मैट का पालन करने वाला स्टैटिक एचटीटीपी सर्वर. इस आने वाले समय में, हम सिंगल-मॉड्यूल रजिस्ट्री के लिए सपोर्ट जोड़ने की योजना बना रहे हैं, जो कि git repos में, प्रोजेक्ट का सोर्स और इतिहास शामिल होता है.

इंडेक्स रजिस्ट्री

इंडेक्स रजिस्ट्री, एक लोकल डायरेक्ट्री या स्टैटिक एचटीटीपी सर्वर होता है, जिसमें मॉड्यूल की सूची के बारे में जानकारी. इसमें उनका होम पेज, मेंटेनर, हर वर्शन की MODULE.bazel फ़ाइल और हर वर्शन के सोर्स को फ़ेच करने का तरीका वर्शन है. खास तौर पर, इसे सोर्स संग्रह को दिखाने की ज़रूरत नहीं होती.

इंडेक्स रजिस्ट्री को इस फ़ॉर्मैट का पालन करना होगा:

  • /bazel_registry.json: एक JSON फ़ाइल जिसमें रजिस्ट्री के लिए मेटाडेटा शामिल होता है, जैसे कि:
    • mirrors, सोर्स संग्रहों के लिए इस्तेमाल होने वाले मिरर की सूची तय करता है.
    • module_base_path, मॉड्यूल के लिए बुनियादी पाथ तय करता है source.json फ़ाइल में local_repository टाइप.
  • /modules: एक डायरेक्ट्री, जिसमें हर मॉड्यूल की सबडायरेक्ट्री होती है रजिस्ट्री.
  • /modules/$MODULE: एक डायरेक्ट्री, जिसमें हर वर्शन की सबडायरेक्ट्री होती हैं और साथ ही नीचे दी गई फ़ाइल की:
    • metadata.json: एक JSON फ़ाइल जिसमें मॉड्यूल के बारे में जानकारी होती है, इसमें ये फ़ील्ड शामिल होंगे:
      • homepage: प्रोजेक्ट के होम पेज का यूआरएल.
      • maintainers: JSON ऑब्जेक्ट की एक सूची, जो कि हर ऑब्जेक्ट से जुड़ी है रजिस्ट्री में मॉड्यूल के मेंटेनर की जानकारी. ध्यान दें कि यह आवश्यक रूप से लेखकों के प्रोजेक्ट.
      • versions: यहां मिलने वाले इस मॉड्यूल के सभी वर्शन की सूची इस रजिस्ट्री को डाउनलोड करें.
      • yanked_versions: इस मॉड्यूल के यंक किए गए वर्शन की सूची. यह फ़िलहाल, उपलब्ध नहीं है. हालांकि, आने वाले समय में, येंक किए गए वर्शन स्किप कर दिया गया है या कोई गड़बड़ी हुई है.
  • /modules/$MODULE/$VERSION: नीचे दी गई फ़ाइलों वाली एक डायरेक्ट्री:
    • MODULE.bazel: इस मॉड्यूल वर्शन की MODULE.bazel फ़ाइल.
    • source.json: एक JSON फ़ाइल जिसमें, इस मॉड्यूल वर्शन का सोर्स.
      • डिफ़ॉल्ट टाइप "संग्रह" है इसमें ये फ़ील्ड शामिल होंगे:
        • url: सोर्स संग्रह का यूआरएल.
        • integrity: सबरिसॉर्स इंटेग्रिटी चेकसम.
        • strip_prefix: एक्सट्रैक्ट करते समय स्ट्रिप करने के लिए डायरेक्ट्री प्रीफ़िक्स स्रोत संग्रह.
        • patches: स्ट्रिंग की सूची, जिसमें हर एक में पैच फ़ाइल का नाम होता है एक्सट्रैक्ट किए गए संग्रह पर लागू होता है. पैच फ़ाइलें इसके नीचे मौजूद होती हैं: /modules/$MODULE/$VERSION/patches डायरेक्ट्री.
        • patch_strip: Unix पैच के --strip आर्ग्युमेंट के जैसा ही.
      • इन फ़ील्ड के साथ लोकल पाथ का इस्तेमाल करने के लिए, टाइप को बदला जा सकता है:
        • type: local_path
        • path: डेटा स्टोर करने की जगह का लोकल पाथ, इस तरह से कैलकुलेट किया जाता है:
          • अगर पाथ एक ऐब्सलूट पाथ है, तो उसे उसी तरह इस्तेमाल किया जाएगा जैसा वह है.
          • अगर पाथ एक रिलेटिव पाथ है और module_base_path एक ऐब्सलूट पाथ है, तो पाथ का समाधान <module_base_path>/<path> तक हुआ है
          • अगर पाथ और module_base_path, दोनों मिलते-जुलते पाथ हैं, तो पाथ <registry_path>/<module_base_path>/<path> तक का समाधान किया गया. रजिस्ट्री को स्थानीय तौर पर होस्ट किया जाना चाहिए और --registry=file://<registry_path> के ज़रिए इस्तेमाल किया जाना चाहिए. ऐसा न करने पर, Basel एक गड़बड़ी दिखाएगा.
    • patches/: पैच फ़ाइलों वाली एक वैकल्पिक डायरेक्ट्री, जिसका इस्तेमाल सिर्फ़ तब किया जाता है, जब source.json में "संग्रह" हो टाइप करें.

बेज़ल सेंट्रल रजिस्ट्री

Basel Central Registry (BCR) एक इंडेक्स रजिस्ट्री है. यह इस जगह पर मौजूद है: bcr.bazel.build. इसका कॉन्टेंट GitHub रेपो का इस्तेमाल होता है bazelbuild/bazel-central-registry.

बीसीआर का रखरखाव बेज़ल समुदाय करता है; योगदान देने वाले लोग, सबमिट कर सकते हैं पुल करने के अनुरोध शामिल हैं. यहां जाएं: Basel Central Registry की नीतियां और प्रक्रियाएं.

सामान्य इंडेक्स रजिस्ट्री के फ़ॉर्मैट का पालन करने के अलावा, बीसीआर को हर मॉड्यूल वर्शन के लिए एक presubmit.yml फ़ाइल (/modules/$MODULE/$VERSION/presubmit.yml). यह फ़ाइल कुछ ज़रूरी एलिमेंट के बारे में बताती है ऐसे टारगेट बनाएं और टेस्ट करें जिनका इस्तेमाल करके, इस बात की सटीक जांच की जा सके कि इसका इस्तेमाल किया जाता है. साथ ही, इसका इस्तेमाल बीसीआर की सीआई पाइपलाइन करती हैं, ताकि इंटरऑपरेबिलिटी (दूसरे सिस्टम के साथ काम करना) पक्का किया जा सके और बीसीआर के मॉड्यूल के बीच में.

रजिस्ट्री चुनी जा रही हैं

दोहराए जा सकने वाले बेज़ल फ़्लैग --registry का इस्तेमाल, रजिस्ट्री से मॉड्यूल का अनुरोध करने की अनुमति मिलती है, ताकि आप फ़ेच करने के लिए अपना प्रोजेक्ट सेट अप कर सकें ये आपके डोमेन, तीसरे पक्ष या इंटरनल रजिस्ट्री से डिपेंडेंसी होती हैं. पहले की रजिस्ट्री लेने पर प्राथमिकता. सुविधा के लिए, आप इसमें --registry फ़्लैग की सूची आपके प्रोजेक्ट की .bazelrc फ़ाइल.

मॉड्यूल एक्सटेंशन

मॉड्यूल एक्सटेंशन की मदद से, इनपुट डेटा को पढ़कर मॉड्यूल सिस्टम को बढ़ाया जा सकता है डिपेंडेंसी ग्राफ़ के मॉड्यूल से, समाधान के लिए ज़रूरी लॉजिक परफ़ॉर्म किया जा रहा है डिपेंडेंसी और आखिर में रेपो नियमों को कॉल करके रेपो बनाना. वे मिलते-जुलते हैं आज के WORKSPACE मैक्रो के साथ काम कर रहे हैं, लेकिन मॉड्यूल और ट्रांज़िटिव डिपेंडेंसी.

मॉड्यूल एक्सटेंशन, .bzl फ़ाइलों में रेपो नियमों की तरह या WORKSPACE मैक्रो. इन्हें सीधे तौर पर शुरू नहीं किया जाता; इसके बजाय, हर मॉड्यूल से पढ़ने के लिए एक्सटेंशन के लिए टैग कहे जाने वाले डेटा के हिस्से तय करें. इसके बाद, मॉड्यूल के बाद वर्शन रिज़ॉल्यूशन हो गया और मॉड्यूल एक्सटेंशन चलाए जा रहे हैं. हर एक्सटेंशन चलाया जा रहा है मॉड्यूल रिज़ॉल्यूशन के बाद एक बार (किसी भी बिल्ड के असल में होने से पहले) और इससे संबंधित सभी टैग को पूरे डिपेंडेंसी ग्राफ़ में पढ़ा जा सकता है.

          [ A 1.1                ]
          [   * maven.dep(X 2.1) ]
          [   * maven.pom(...)   ]
              /              \
   bazel_dep /                \ bazel_dep
            /                  \
[ B 1.2                ]     [ C 1.0                ]
[   * maven.dep(X 1.2) ]     [   * maven.dep(X 2.1) ]
[   * maven.dep(Y 1.3) ]     [   * cargo.dep(P 1.1) ]
            \                  /
   bazel_dep \                / bazel_dep
              \              /
          [ D 1.4                ]
          [   * maven.dep(Z 1.4) ]
          [   * cargo.dep(Q 1.1) ]

ऊपर दिए गए डिपेंडेंसी ग्राफ़ के उदाहरण में, A 1.1 और B 1.2 वगैरह Basel मॉड्यूल हैं; हर फ़ाइल को MODULE.bazel फ़ाइल माना जा सकता है. हर मॉड्यूल से कुछ मॉड्यूल एक्सटेंशन के लिए टैग; यहां कुछ एक्सटेंशन "maven" के लिए बताए गए हैं, और कुछ "कार्गो" के लिए तय किए गए हैं. जब इस डिपेंडेंसी ग्राफ़ को अंतिम रूप दिया जाता है (इसके लिए उदाहरण, शायद B 1.2 के पास D 1.3 पर bazel_dep मौजूद है, लेकिन यह इस पर अपग्रेड हो गया है: C की वजह से D 1.4), एक्सटेंशन "maven" चलाया जाता है और यह उन सभी maven.* टैग, उसमें दी गई जानकारी का इस्तेमाल करके, तय करते हैं कि कौनसे डेटा स्टोर करने हैं. इसी तरह "कार्गो" के लिए एक्सटेंशन चुनें.

एक्सटेंशन का इस्तेमाल

एक्सटेंशन, Baze मॉड्यूल में खुद होस्ट किए जाते हैं. इसलिए, किसी एक्सटेंशन का इस्तेमाल करने के लिए आपके मॉड्यूल के लिए, आपको पहले उस मॉड्यूल पर एक bazel_dep जोड़ना होगा और फिर कॉल करना होगा use_extension बिल्ट-इन का इस्तेमाल किया जा सकता है. नीचे दिए गए उदाहरण पर विचार करें, किसी काल्पनिक "मेवन" का इस्तेमाल करने के लिए एक MODULE.bazel फ़ाइल rules_jvm_external मॉड्यूल:

bazel_dep(name = "rules_jvm_external", version = "1.0")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

एक्सटेंशन को दायरे में लाने के बाद, आप dot-सिंटैक्स का इस्तेमाल करके, उसके लिए टैग सेट करें. ध्यान दें कि टैग को संबंधित टैग क्लास (एक्सटेंशन की परिभाषा देखें नीचे दिया गया है). यहां एक उदाहरण दिया गया है, जिसमें कुछ maven.dep और maven.pom टैग के बारे में बताया गया है.

maven.dep(coord="org.junit:junit:3.0")
maven.dep(coord="com.google.guava:guava:1.2")
maven.pom(pom_xml="//:pom.xml")

अगर एक्सटेंशन ऐसे रिपो जनरेट करता है जिन्हें आपको अपने मॉड्यूल में इस्तेमाल करना है, तो use_repo डायरेक्टिव के तौर पर उन्हें. ऐसा इसलिए ज़रूरी है, ताकि डिपार्टमेंट की सख्त शर्त को पूरा किया जा सके और स्थानीय रेपो नाम से बचा जा सके विवाद.

use_repo(
    maven,
    "org_junit_junit",
    guava="com_google_guava_guava",
)

किसी एक्सटेंशन के ज़रिए जनरेट किए गए डेटा संग्रह स्थान उसके API का हिस्सा होते हैं, इसलिए आप जिन टैग से आपको यह पता होना चाहिए कि "मेवन" एक्सटेंशन एक रेपो को "org_junit_junit" कहा जाता है और एक रेपो को "com_google_guava_guava" कहा जाता है. के साथ use_repo, आपके पास अपने मॉड्यूल के दायरे में वैकल्पिक तौर पर उनका नाम बदलने का विकल्प है, जैसे कि "गुआवा" यहां.

एक्सटेंशन की परिभाषा

मॉड्यूल एक्सटेंशन, रेपो नियमों की तरह ही परिभाषित किए जाते हैं. इनके लिए, module_extension फ़ंक्शन का इस्तेमाल करें. दोनों का एक लागू फ़ंक्शन होता है; हालांकि, रेपो नियमों में कई एट्रिब्यूट, मॉड्यूल एक्सटेंशन में कई tag_class हैं, जिनमें से हर एक में एट्रिब्यूट की संख्या. टैग क्लास, इसके इस्तेमाल किए जाने वाले टैग के लिए स्कीमा तय करती हैं एक्सटेंशन चुनें. उसके बाद, हमारा वह काल्पनिक उदाहरण "मावन" है एक्सटेंशन ऊपर दिया गया है:

# @rules_jvm_external//:extensions.bzl
maven_dep = tag_class(attrs = {"coord": attr.string()})
maven_pom = tag_class(attrs = {"pom_xml": attr.label()})
maven = module_extension(
    implementation=_maven_impl,
    tag_classes={"dep": maven_dep, "pom": maven_pom},
)

इन एलानों से यह साफ़ तौर पर पता चलता है कि maven.dep और maven.pom टैग और इसके लिए, ऊपर बताए गए एट्रिब्यूट स्कीमा का इस्तेमाल करें.

लागू करने का फ़ंक्शन किसी WORKSPACE मैक्रो के जैसा ही होता है, अंतर को छोड़कर एक module_ctx ऑब्जेक्ट मिलता है, जो डिपेंडेंसी ग्राफ़ और सभी ज़रूरी टैग का ऐक्सेस. लागू करना फ़ंक्शन को रेपो जनरेट करने के लिए रेपो नियमों को कॉल करना चाहिए:

# @rules_jvm_external//:extensions.bzl
load("//:repo_rules.bzl", "maven_single_jar")
def _maven_impl(ctx):
  coords = []
  for mod in ctx.modules:
    coords += [dep.coord for dep in mod.tags.dep]
  output = ctx.execute(["coursier", "resolve", coords])  # hypothetical call
  repo_attrs = process_coursier(output)
  [maven_single_jar(**attrs) for attrs in repo_attrs]

ऊपर दिए गए उदाहरण में, हमने डिपेंडेंसी ग्राफ़ के सभी मॉड्यूल देखे हैं (ctx.modules), इनमें से हर एक bazel_module ऑब्जेक्ट जिसका tags फ़ील्ड है मॉड्यूल में सभी maven.* टैग दिखाता है. इसके बाद, हम सीएलआई यूटिलिटी का इस्तेमाल करते हैं Maven से संपर्क करने और समस्या को हल करने की प्रोसेस के बारे में सलाह. आखिर में, हम जिससे कई रिपो बन जाते हैं. इन नतीजों के लिए, वे काल्पनिक maven_single_jar रेपो नियम के हिसाब से होना चाहिए.