एक्सटर्नल डिपेंडेंसी के बारे में खास जानकारी

समस्या की शिकायत करें सोर्स देखें ठीक

Baज़ल, आपके बिल्ड में इस्तेमाल की जाने वाली बाहरी डिपेंडेंसी और सोर्स फ़ाइलों (टेक्स्ट और बाइनरी, दोनों) के साथ काम करता है. ये आपके फ़ाइल फ़ोल्डर की नहीं हैं. उदाहरण के लिए, वे GitHub रेपो, Maven आर्टफ़ैक्ट या आपके मौजूदा फ़ाइल फ़ोल्डर के बाहर आपकी लोकल मशीन पर डायरेक्ट्री में होस्ट किए गए रूलसेट हो सकते हैं.

Bazz 6.0 के साथ, बाहरी डिपेंडेंसी को मैनेज करने के दो तरीके हैं: पारंपरिक, डेटा स्टोर करने की जगह पर फ़ोकस करने वाला WORKSPACE सिस्टम, और नया मॉड्यूल पर फ़ोकस करने वाला MODULE.bazel सिस्टम (कोडनेम Bzlmod, और इसे फ़्लैग --enable_bzlmod के साथ चालू किया गया है). ये दोनों सिस्टम एक साथ इस्तेमाल किए जा सकते हैं, लेकिन Bzlmod ने WORKSPACE सिस्टम की जगह ले रहा है, आने वाले समय में Baze माइग्रेशन की रिलीज़ के बारे में{/10 माइग्रेशन गाइड देखें{/1.

यह दस्तावेज़, Basel में एक्सटर्नल डिपेंडेंसी मैनेजमेंट से जुड़े सिद्धांतों के बारे में बताता है. इससे पहले, दोनों सिस्टम के बारे में ज़्यादा जानकारी हासिल की जा सकती है.

कॉन्सेप्ट

रिपॉज़िटरी

एक डायरेक्ट्री ट्री, जिसके रूट में बाउंड्री मार्कर फ़ाइल होती है. इसमें ऐसी सोर्स फ़ाइलें होती हैं जिन्हें बेज़ल बिल्ड में इस्तेमाल किया जा सकता है. आम तौर पर, इसे छोटा करके सिर्फ़ रेपो कर दिया जाता है.

रेपो बाउंड्री मार्कर फ़ाइल, MODULE.bazel हो सकती है. इससे पता चलता है कि यह रेपो, बज़ल मॉड्यूल को दिखाता है, REPO.bazel (नीचे देखें) या लेगसी कॉन्टेक्स्ट में WORKSPACE या WORKSPACE.bazel हो सकता है. कोई भी रेपो बाउंड्री मार्कर फ़ाइल, रेपो की सीमा दिखाती है. ऐसी कई फ़ाइलें, किसी डायरेक्ट्री में एक साथ मौजूद हो सकती हैं.

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

वह रिपॉज़िटरी जिसमें मौजूदा Basel कमांड चलाया जा रहा है.

डेटा स्टोर करने की मुख्य जगह के रूट को फ़ाइल फ़ोल्डर रूट भी कहा जाता है.

Workspace

सभी Bagel कमांड से शेयर किया जाने वाला एनवायरमेंट, एक ही डेटा स्टोर करने की जगह में चलता है. इसमें, मुख्य डेटा स्टोर करने की जगह के साथ-साथ, तय किए गए सभी बाहरी डेटा को स्टोर करने की जगह भी शामिल है.

ध्यान दें कि ऐतिहासिक तौर पर, "डेटा स्टोर करने की जगह" और "वर्कस्पेस" के सिद्धांतों का एक साथ इस्तेमाल किया जाता रहा है. अक्सर "वर्कस्पेस" शब्द का इस्तेमाल, मुख्य डेटा स्टोर करने की जगह के बारे में बताने के लिए किया जाता है. कभी-कभी इसका इस्तेमाल "डेटा स्टोर करने की जगह" के समानार्थी के तौर पर भी किया जाता है.

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

वह कैननिकल नाम जिससे रिपॉज़िटरी (डेटा स्टोर करने की जगह) दी जाती है. वर्कस्पेस में, हर रिपॉज़िटरी का एक कैननिकल नाम होता है. रेपो में मौजूद टारगेट, जिसका कैननिकल नाम canonical_name है, उसे @@canonical_name//package:target लेबल (डबल @ ध्यान दें) से समझा जा सकता है.

डेटा स्टोर करने की मुख्य जगह में, कैननिकल नाम के तौर पर हमेशा खाली स्ट्रिंग होती है.

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

वह नाम जहां रिपॉज़िटरी का पता लगाया जा सकता है. हालांकि, इसका इस्तेमाल किसी अन्य डेटा स्टोर करने के लिए किया जाता है. इसे रेपो के "निकनेम" के तौर पर माना जा सकता है: कैननिकल नाम वाले रेपो alice के लिए, रिपो का नाम mike हो सकता है. हालांकि, रेपो के लिए इसका नाम mickey हो सकता हैbob.michael इस मामले में, michael में मौजूद टारगेट को @mike//package:target लेबल, alice (ध्यान दें कि एक @) के हिसाब से बता सकता है.

इसके उलट, इसे डेटा स्टोर करने की जगह की मैपिंग के तौर पर समझा जा सकता है: हर रेपो में, "apparent repo name" से लेकर "कैननिकल रेपो नेम" तक की मैपिंग होती है.

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

रिपॉज़िटरी की परिभाषाओं के लिए स्कीमा, जो बेज़ल को डेटा स्टोर करने की जगह बनाने का तरीका बताता है. उदाहरण के लिए, यह "किसी खास यूआरएल से ज़िप संग्रह डाउनलोड करें और उसे एक्सट्रैक्ट करें" या "कोई खास Maven आर्टफ़ैक्ट फ़ेच करके, उसे java_import टारगेट के तौर पर उपलब्ध कराएं" या बस "किसी लोकल डायरेक्ट्री को सिमलिंक करें" हो सकता है. हर रेपो को तय किया जाता है. इसके लिए, सही संख्या में आर्ग्युमेंट के साथ रेपो नियम का इस्तेमाल किया जाता है.

डेटा स्टोर करने के लिए बनाए गए अपने नियम लिखने के तरीके के बारे में ज़्यादा जानने के लिए, डेटा स्टोर करने की जगह के नियम देखें.

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

डेटा स्टोर करने की जगह फ़ेच करना

लोकल डिस्क से जुड़े रेपो के नियम को चलाकर, उस पर मौजूद रेपो को उपलब्ध कराने की कार्रवाई. Workspace में तय किए गए रिपो, फ़ेच किए जाने से पहले लोकल डिस्क पर उपलब्ध नहीं होते.

आम तौर पर, बेज़ल रेपो को सिर्फ़ तब फ़ेच करता है, जब उसे रेपो की ज़रूरत होती है और रेपो को पहले से फ़ेच नहीं किया गया हो. अगर रेपो को पहले ही फ़ेच कर लिया गया है, तो बेज़ल उसे फिर से फ़ेच करता है, लेकिन इसकी परिभाषा बदलने पर ही ऐसा होता है.

किसी भी बिल्ड को पूरा करने के लिए, रिपॉज़िटरी, टारगेट या सभी ज़रूरी डेटा स्टोर करने की जगहों के लिए प्री-फ़ेच शुरू करने के लिए fetch कमांड का इस्तेमाल किया जा सकता है. इस सुविधा की मदद से, --nofetch विकल्प का इस्तेमाल करके ऑफ़लाइन बिल्ड चालू किए जा सकते हैं.

--fetch विकल्प का इस्तेमाल, नेटवर्क ऐक्सेस को मैनेज करने के लिए किया जाता है. इसकी डिफ़ॉल्ट वैल्यू 'सही' होती है. हालांकि, अगर 'गलत' (--nofetch) पर सेट किया जाता है, तो निर्देश, डिपेंडेंसी के कैश मेमोरी में सेव किए गए किसी भी वर्शन का इस्तेमाल करेगा. अगर कोई वर्शन मौजूद नहीं है, तो निर्देश काम नहीं करेगा.

फ़ेच करने की प्रोसेस को कंट्रोल करने के बारे में ज़्यादा जानकारी के लिए, फ़ेच के विकल्प देखें.

डायरेक्ट्री का लेआउट

डेटा फ़ेच करने के बाद, रेपो को उसके कैननिकल नाम के तहत, आउटपुट बेस की सबडायरेक्ट्री external में देखा जा सकता है.

कैननिकल नाम canonical_name के साथ, रेपो का कॉन्टेंट देखने के लिए यह निर्देश दिया जा सकता है:

ls $(bazel info output_base)/external/ canonical_name 

REPO.baकोई फ़ाइल

REPO.bazel फ़ाइल का इस्तेमाल, डायरेक्ट्री ट्री की सबसे ऊपरी सीमा को मार्क करने के लिए किया जाता है. यह सीमा, रेपो बनाती है. इसमें रेपो बाउंड्री फ़ाइल के तौर पर इस्तेमाल करने के लिए कुछ भी शामिल करने की ज़रूरत नहीं है. हालांकि, इसका इस्तेमाल रेपो के अंदर सभी बिल्ड टारगेट के लिए कुछ सामान्य एट्रिब्यूट की जानकारी देने के लिए भी किया जा सकता है.

REPO.bazel फ़ाइल का सिंटैक्स BUILD फ़ाइलों जैसा होता है. हालांकि, इसमें कोई भी load स्टेटमेंट काम नहीं करता और सिर्फ़ एक फ़ंक्शन, repo() उपलब्ध है. repo() वही आर्ग्युमेंट इस्तेमाल करता है जो BUILD फ़ाइलों में package() फ़ंक्शन में होता है. package(), पैकेज के अंदर सभी बिल्ड टारगेट के लिए सामान्य एट्रिब्यूट के बारे में बताता है. repo(), रेपो के अंदर मौजूद सभी बिल्ड टारगेट के लिए ऐसा ही करता है.

उदाहरण के लिए, नीचे दी गई REPO.bazel फ़ाइल का इस्तेमाल करके, अपने रेपो में मौजूद सभी टारगेट के लिए एक जैसा लाइसेंस तय किया जा सकता है:

repo(
    default_package_metadata = ["//:my_license"],
)

Bzlmod की मदद से बाहरी डिपेंडेंसी मैनेज करें

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

Basel मॉड्यूल एक Basel प्रोजेक्ट है, जिसके कई वर्शन हो सकते हैं. इनमें से हर वर्शन, उस मॉड्यूल के बारे में मेटाडेटा पब्लिश करता है जिस पर वह निर्भर करता है. मॉड्यूल के रेपो रूट में, WORKSPACE फ़ाइल के बगल में एक 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")

मॉड्यूल में सिर्फ़ अपनी डायरेक्ट डिपेंडेंसी शामिल होनी चाहिए, जो Bzlmod फ़ॉर्मैट में Baजेल रजिस्ट्री में ढूंढता है — डिफ़ॉल्ट रूप से, Bazu Central Registry. रजिस्ट्री, डिपेंडेंसी की MODULE.bazel फ़ाइलें उपलब्ध कराती है. इससे, बेज़ल, वर्शन रिज़ॉल्यूशन लागू करने से पहले, सभी ट्रांज़िटिव डिपेंडेंसी ग्राफ़ खोज पाते हैं.

वर्शन रिज़ॉल्यूशन के बाद, हर मॉड्यूल के लिए एक वर्शन चुना जाता है. इसके बाद, बैज़ल रजिस्ट्री से हर मॉड्यूल के लिए रेपो तय करने का तरीका जानने के लिए दोबारा अनुरोध करता है. ज़्यादातर मामलों में, http_archive का इस्तेमाल करके ऐसा किया जाता है.

मॉड्यूल से, अपनी ज़रूरत के मुताबिक टैग नाम के अलग-अलग हिस्सों को भी तय किया जा सकता है. इन टैग का इस्तेमाल, मॉड्यूल रिज़ॉल्यूशन के बाद मॉड्यूल एक्सटेंशन की मदद से किया जाता है, ताकि अतिरिक्त डेटा स्टोर करने की जानकारी दी जा सके. इन एक्सटेंशन में रेपो नियमों जैसी क्षमताएं होती हैं, जिनकी मदद से ये I/O फ़ाइल करने और नेटवर्क अनुरोध भेजने जैसी कार्रवाइयां कर सकते हैं. दूसरी बातों के साथ-साथ, वे Basel को दूसरे पैकेज मैनेजमेंट सिस्टम के साथ इंटरैक्ट करने की सुविधा भी देते हैं. साथ ही, वे Basel मॉड्यूल से बनाए गए डिपेंडेंसी ग्राफ़ के हिसाब से भी इंटरैक्ट करते हैं.

WORKSPACE की मदद से डेटा स्टोर करने की जगह तय करें

अब तक, WORKSPACE (या WORKSPACE.bazel) फ़ाइल में डेटा स्टोर करने की जगहों की जानकारी देकर, एक्सटर्नल डिपेंडेंसी मैनेज की जा सकती हैं. इस फ़ाइल का सिंटैक्स BUILD फ़ाइलों जैसा ही है. इसमें बिल्ड रूल के बजाय रेपो के नियम लागू होते हैं.

WORKSPACE फ़ाइल में http_archive रेपो नियम का इस्तेमाल करने के लिए, नीचे दिया गया स्निपेट एक उदाहरण है:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "foo",
    urls = ["https://example.com/foo.zip"],
    sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)

स्निपेट, ऐसे रेपो के बारे में बताता है जिसका कैननिकल नाम foo है. WORKSPACE सिस्टम में, डिफ़ॉल्ट रूप से रेपो का कैननिकल नाम ही अन्य सभी रेपो के लिए भी साफ़ तौर पर लिखा होता है.

WORKSPACE फ़ाइलों में मौजूद फ़ंक्शन की पूरी सूची देखें.

WORKSPACE सिस्टम की कमियां

WORKSPACE सिस्टम के लॉन्च होने के बाद से, अब तक लोगों ने कई समस्याओं के बारे में बताया है. जैसे:

  • Basel किसी भी डिपेंडेंसी की WORKSPACE फ़ाइलों का आकलन नहीं करता है. इसलिए, डायरेक्ट डिपेंडेंसी के साथ-साथ सभी ट्रांज़िशन डिपेंडेंसी को मुख्य रेपो की WORKSPACE फ़ाइल में तय किया जाना चाहिए.
  • इस पर काम करने के लिए, प्रोजेक्ट ने "deps.bzl" पैटर्न अपनाया है. इसमें वे एक मैक्रो तय करते हैं जो बदले में कई रिपो को तय करता है. साथ ही, उपयोगकर्ताओं को अपनी WORKSPACE फ़ाइलों में इस मैक्रो को कॉल करने के लिए कहते हैं.
    • इसमें अपनी समस्याएं हैं: मैक्रो load अन्य .bzl फ़ाइलें नहीं कर सकते, इसलिए इन प्रोजेक्ट को इस "डेप्स" मैक्रो में अपनी ट्रांज़िटिव डिपेंडेंसी तय करनी होगी या उपयोगकर्ता को एक से ज़्यादा लेयर वाले "deps" मैक्रो को कॉल करके इस समस्या को हल करना होगा.
    • Baज़र, WORKSPACE फ़ाइल का क्रम से आकलन करता है. इसके अलावा, डिपेंडेंसी के बारे में http_archive का इस्तेमाल करके यूआरएल के साथ बताया जाता है. इसमें वर्शन की जानकारी नहीं होती. इसका मतलब है कि डायमंड डिपेंडेंसी के मामले में, वर्शन रिज़ॉल्यूशन करने का कोई भरोसेमंद तरीका नहीं है. A B और C पर निर्भर करता है. B और C, दोनों D के अलग-अलग वर्शन पर निर्भर करते हैं.

Workspace की कमियों की वजह से, आने वाले समय में Basel की रिलीज़ के लिए, Bzlmod लेगसी Workspace सिस्टम की जगह ले रहा है. कृपया Bzlmod पर माइग्रेट करने का तरीका जानने के लिए, Bzlmod माइग्रेशन गाइड पढ़ें.