Basel मॉड्यूल एक Basel प्रोजेक्ट है. इसके कई वर्शन हो सकते हैं, जिनमें से हर एक जो दूसरे मॉड्यूल के बारे में मेटाडेटा पब्लिश करता है. यह, डिपेंडेंसी मैनेजमेंट के अन्य सिस्टम में मौजूद कॉन्सेप्ट से मिलता-जुलता है. जैसे, Maven आर्टफ़ैक्ट, npm पैकेज, Go मॉड्यूल या Cargo क्रेट.
किसी मॉड्यूल के repo रूट में 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
फ़ाइलों में उपलब्ध डायरेक्टिव की पूरी सूची देखें.
मॉड्यूल रिज़ॉल्यूशन निष्पादित करने के लिए, Baज़र, रूट मॉड्यूल के
MODULE.bazel
फ़ाइल का इस्तेमाल करता है और फिर बार-बार किसी डिपेंडेंसी की
Basel रजिस्ट्री से तब तक फ़ाइल MODULE.bazel
पूरा डिपेंडेंसी ग्राफ़ खोजता है.
डिफ़ॉल्ट रूप से, Basel हर मॉड्यूल का एक वर्शन चुनता है इस्तेमाल करें. Baze, हर मॉड्यूल के बारे में रेपो की जानकारी देता है और रजिस्ट्री से सलाह लेता है ताकि हर स्टोर को साफ़ तौर पर बताया जाए.
वर्शन का फ़ॉर्मैट
बेज़ल का नेटवर्क काफ़ी अलग है. प्रोजेक्ट में अलग-अलग तरह के वर्शन बनाने के तरीकों का इस्तेमाल किया जाता है. अब तक SemVer सबसे लोकप्रिय है. हालांकि, Abseil जैसी अलग-अलग स्कीम का इस्तेमाल करने वाले लोकप्रिय प्रोजेक्ट भी हैं. इनके वर्शन, तारीख पर आधारित होते हैं, जैसे कि 20210324.2
).
इस वजह से, Bzlmod SemVer स्पेसिफ़िकेशन का ज़्यादा आसान वर्शन इस्तेमाल करता है. कॉन्टेंट बनाने अंतरों में शामिल हैं:
- SemVer के मुताबिक, वर्शन के "रिलीज़" हिस्से में तीन सेगमेंट होने चाहिए:
MAJOR.MINOR.PATCH
. Basel में, इस ज़रूरत को ढीला कर दिया गया है, इसलिए कितने भी सेगमेंट की अनुमति हो. - SemVer में, "रिलीज़" के हर सेगमेंट भाग में केवल अंक होने चाहिए. Bazel में, अक्षरों को भी शामिल करने के लिए इस शर्त को कम किया गया है. साथ ही, तुलना के सेमेटिक्स, "प्री-रिलीज़" वाले हिस्से में मौजूद "आइडेंटिफ़ायर" से मैच करते हैं.
- इसके अलावा, मेजर, माइनर, और पैच वर्शन में होने वाली बढ़ोतरी के सेमेटिक्स लागू नहीं किए जाते. हालांकि, इसके लिए कंपैटबिलिटी लेवल देखें हम पुराने सिस्टम के साथ काम करने की सुविधा को कैसे दिखाते हैं.
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
या इसके बाद की नई ऐसेट मौजूद होने पर भी, हम उन्हें नहीं चुनते. एमवीएस का इस्तेमाल करने से, वर्शन चुनने की ऐसी प्रोसेस बनती है जो हाई-फ़िडेलिटी और फिर से बनाई जा सकने वाली होती है.
यांक किए गए वर्शन
अगर किसी वर्शन से बचना चाहिए, तो रजिस्ट्री इसे यां किया गया के तौर पर एलान कर सकती है
(जैसे, सुरक्षा से जुड़े जोखिम की आशंकाओं की वजह से). किसी मॉड्यूल के हटाए गए वर्शन को चुनने पर, Bazel गड़बड़ी का मैसेज दिखाता है. इस गड़बड़ी को ठीक करने के लिए, किसी ऐसे नए वर्शन पर अपग्रेड करें जिसे हटाया नहीं गया है या हटाए गए वर्शन को अनुमति देने के लिए, --allow_yanked_versions
फ़्लैग का इस्तेमाल करें.
काम करने का लेवल
Go में, पुराने सिस्टम के साथ काम करने की सुविधा के बारे में MVS का अनुमान इसलिए काम करता है, क्योंकि यह
किसी मॉड्यूल के पिछले वर्शन का, एक अलग मॉड्यूल के तौर पर काम न करना. SemVer के हिसाब से, इसका मतलब है कि A 1.x
और A 2.x
को अलग-अलग मॉड्यूल माना जाता है. साथ ही, ये दोनों एक साथ, डिपेंडेंसी ग्राफ़ में मौजूद हो सकते हैं. यही वजह है कि
मैं पैकेज पाथ में मेजर वर्शन को कोड में बदल रहा था
कंपाइल-टाइम या लिंकिंग-टाइम के विवाद.
हालांकि, Bazel ऐसी कोई गारंटी नहीं दे सकता. इसलिए, पुराने वर्शन के साथ काम न करने वाले वर्शन का पता लगाने के लिए, उसे "मुख्य वर्शन" के नंबर की ज़रूरत होती है. इस नंबर को काम करने का लेवल कहा जाता है. यह हर मॉड्यूल के वर्शन के module()
डायरेक्टिव में बताया जाता है. इस जानकारी की मदद से, Basel को गड़बड़ी का मैसेज मिल सकता है.
यह पता लगाता है कि अलग-अलग लेवल के साथ एक ही मॉड्यूल के वर्शन का इस्तेमाल किया गया है या नहीं
रिज़ॉल्व की गई डिपेंडेंसी ग्राफ़ में मौजूद हो.
ओवरराइड
Basel के काम करने के तरीके में बदलाव करने के लिए, MODULE.bazel
फ़ाइल में बदलावों के बारे में बताएं
मॉड्यूल रिज़ॉल्यूशन. सिर्फ़ रूट मॉड्यूल के बदलाव लागू होते हैं — अगर किसी मॉड्यूल का इस्तेमाल डिपेंडेंसी के तौर पर किया जाता है, तो उसके बदलावों को अनदेखा कर दिया जाता है.
हर बदलाव, किसी खास मॉड्यूल के नाम के लिए तय किया जाता है. इससे डिपेंडेंसी ग्राफ़ में उसके सभी वर्शन पर असर पड़ता है. हालांकि, सिर्फ़ रूट मॉड्यूल के ओवरराइड की वजह से ये ट्रांज़िटिव डिपेंडेंसी के लिए हो सकते हैं, जो रूट मॉड्यूल में नहीं निर्भर करता है.
एक वर्शन को ओवरराइड करना
single_version_override
का इस्तेमाल कई कामों के लिए किया जाता है:
version
एट्रिब्यूट की मदद से, किसी खास डिपेंडेंसी को किसी खास समयावधि पर पिन किया जा सकता है इस बात पर ध्यान दिए बिना कि डिपेंडेंसी के कौनसे वर्शन का अनुरोध किया गया है डिपेंडेंसी ग्राफ़.registry
एट्रिब्यूट की मदद से, इस डिपेंडेंसी को ज़बरदस्ती किसी विशिष्ट रजिस्ट्री, सामान्य रजिस्ट्री का पालन करने के बजाय चुना गया प्रोसेस.patch*
एट्रिब्यूट की मदद से, डाउनलोड किए गए मॉड्यूल पर लागू करने के लिए पैच का एक सेट तय किया जा सकता है.
ये सभी एट्रिब्यूट ज़रूरी नहीं हैं. इन्हें एक-दूसरे के साथ मिलाया और मैच किया जा सकता है.
एक से ज़्यादा वर्शन ओवरराइड करना
multiple_version_override
को एक ही मॉड्यूल के कई वर्शन को एक साथ रहने की अनुमति देने के लिए
रिज़ॉल्व की गई डिपेंडेंसी ग्राफ़.
आप मॉड्यूल के लिए अनुमति वाले वर्शन की एक खास सूची बना सकते हैं, जिसमें ये सभी समाधान, समाधान से पहले डिपेंडेंसी ग्राफ़ में मौजूद होने चाहिए — यह भी ज़रूरी है some ट्रांज़िटिव डिपेंडेंसी, हर अनुमति वाले वर्शन के हिसाब से तय होती है. समस्या हल होने के बाद, मॉड्यूल के सिर्फ़ वे वर्शन बचे रहते हैं जिनके इस्तेमाल की अनुमति है. साथ ही, Bazel मॉड्यूल के अन्य वर्शन को, काम करने के एक ही लेवल पर, अनुमति वाले सबसे नज़दीकी वर्शन पर अपग्रेड कर देता है. अगर काम करने के एक ही लेवल पर, अनुमति वाला कोई ज़्यादा वर्शन मौजूद नहीं है, तो Bazel गड़बड़ी का मैसेज दिखाता है.
उदाहरण के लिए, अगर 1.1
, 1.3
, 1.5
, 1.7
, और 2.0
वर्शन
समाधान से पहले डिपेंडेंसी ग्राफ़ और मेजर वर्शन के साथ काम करने की सुविधा
स्तर:
- एक से ज़्यादा वर्शन ओवरराइड करने से
1.3
,1.7
, और2.0
नतीजे मिलेंगे1.1
को1.3
पर अपग्रेड किया जा रहा है.1.5
को1.7
और अन्य सदस्यताओं में अपग्रेड किया जा रहा है वर्शन में कोई बदलाव नहीं हुआ है. - एक से ज़्यादा वर्शन ओवरराइड करने से
1.5
और2.0
की वजह से गड़बड़ी होती है, जैसे कि1.7
पर अपग्रेड करने के लिए, पुराने वर्शन के साथ काम करने के उसी लेवल का कोई नया वर्शन नहीं है. 1.9
और2.0
को अनुमति देने वाले कई वर्शन के बदलाव से गड़बड़ी होती है, क्योंकि रिज़ॉल्यूशन से पहले1.9
, डिपेंडेंसी ग्राफ़ में मौजूद नहीं होता.
इसके अलावा, उपयोगकर्ता registry
का इस्तेमाल करके भी रजिस्ट्री को बदल सकते हैं
विशेषता के आधार पर जोड़ा जा सकता है. यह सुविधा, सिंगल-वर्शन के बदलावों की तरह ही है.
गैर-रजिस्ट्री बदलावों की जानकारी
रजिस्ट्रेशन के अलावा किसी और तरीके से बदलाव करने पर, वर्शन रिज़ॉल्यूशन से मॉड्यूल पूरी तरह हट जाता है. Bazel, MODULE.bazel
फ़ाइलों का अनुरोध किसी रजिस्ट्री से नहीं करता, बल्कि खुद रिपॉज़िटरी से करता है.
बेज़ल, बिना रजिस्ट्रेशन वाले इन बदलावों के साथ काम करता है:
ऐसे रिपॉज़िटरी तय करना जो Bazel मॉड्यूल को दिखाते नहीं हैं
bazel_dep
की मदद से, ऐसे रिपॉज़िटरी तय किए जा सकते हैं जो अन्य Bazel मॉड्यूल दिखाते हैं.
कभी-कभी ऐसे रेपो को बनाने की ज़रूरत होती है जो बेज़ल का प्रतिनिधित्व नहीं करता
module; उदाहरण के लिए, ऐसी फ़ाइल जिसमें एक सामान्य JSON फ़ाइल हो, जिसे डेटा के तौर पर पढ़ा जा सके.
इस मामले में, use_repo_rule
डायरेक्टिव का इस्तेमाल करके, सीधे तौर पर किसी रिपॉज़िटरी को तय किया जा सकता है. इसके लिए, रिपॉज़िटरी नियम को लागू करना होगा. यह रिपॉज़िटरी सिर्फ़ उस मॉड्यूल को दिखेगी जिसमें इसे तय किया गया है.
हुड के तहत, इसे मॉड्यूल जैसे ही तरीके का इस्तेमाल करके लागू किया जाता है एक्सटेंशन की मदद से, आप ज़्यादा जानकारी के साथ डेटा स्टोर करने की जगह तय कर सकते हैं ज़रूरत के हिसाब से इस्तेमाल किया जा सकता है.
डेटा स्टोर करने की जगहों के नाम और डिपार्टमेंट
किसी मॉड्यूल के सीधे डिपेंडेंट को बैकअप करने वाले किसी रिपॉज़िटरी का सामान्य नाम, डिफ़ॉल्ट रूप से मॉड्यूल के नाम पर सेट होता है. ऐसा तब तक होता है, जब तक कि bazel_dep
डायरेक्टिव के repo_name
एट्रिब्यूट में कोई दूसरा नाम न दिया गया हो. ध्यान दें कि इसका मतलब है कि कोई मॉड्यूल सिर्फ़ अपनी डायरेक्ट डिपेंडेंसी ढूंढ सकता है. यह
ट्रांज़िटिव डिपेंडेंसी.
उस रेपो का कैननिकल नाम जो
मॉड्यूल या तो module_name+version
(उदाहरण के लिए, bazel_skylib+1.0.3
) या module_name+
(उदाहरण के लिए, bazel_features+
) है. यह इस बात पर निर्भर करता है कि
पूरे डिपेंडेंसी ग्राफ़ में मॉड्यूल के कई वर्शन (देखें
multiple_version_override
).
ध्यान दें कि कैननिकल नाम का फ़ॉर्मैट ऐसा एपीआई नहीं है जिस पर आपको निर्भर रहना चाहिए और
इसमें किसी भी समय बदलाव किया जा सकता है. कैननिकल नाम को हार्ड-कोड करने के बजाय,
सीधे Bazel से इसे पाने के लिए, काम करने वाले तरीके का इस्तेमाल करें:
* BUILD और .bzl
फ़ाइलों में, Label
इंस्टेंस पर
Label.repo_name
का इस्तेमाल करें. यह इंस्टेंस, रिपॉज़िटरी के नाम से दी गई लेबल स्ट्रिंग से बनाया जाता है. उदाहरण के लिए,
Label("@bazel_skylib").repo_name
.
* रनफ़ाइलें खोजते समय,
$(rlocationpath ...)
या @bazel_tools//tools/{bash,cpp,java}/runfiles
में मौजूद रनफ़ाइल लाइब्रेरी में से किसी एक का इस्तेमाल करें. इसके अलावा, नियमों का सेट rules_foo
के लिए,
@rules_foo//foo/runfiles
में जाएं.
* किसी बाहरी टूल, जैसे कि IDE या भाषा की मदद से Basel के साथ इंटरैक्ट करते समय
सर्वर, से मैपिंग करने के लिए bazel mod dump_repo_mapping
कमांड का इस्तेमाल करें
डेटा स्टोर करने की जगहों के दिए गए सेट के कैननिकल नामों के लिए, साफ़ तौर पर दिए गए नाम.
मॉड्यूल एक्सटेंशन भी अतिरिक्त डेटा स्टोर कर सकते हैं के स्कोप में दिखता है.