वेंडर मोड एक ऐसी सुविधा है जिसकी मदद से, बाहरी डिपेंडेंसी की लोकल कॉपी बनाई जा सकती है. यह सुविधा, ऑफ़लाइन बिल्ड के लिए या बाहरी डिपेंडेंसी के सोर्स को कंट्रोल करने के लिए काम की है.
वेंडर मोड चालू करना
--vendor_dir फ़्लैग तय करके, वेंडर मोड चालू किया जा सकता है.
उदाहरण के लिए, इसे अपनी .bazelrc फ़ाइल में जोड़कर:
# Enable vendor mode with vendor directory under <workspace>/vendor_src
common --vendor_dir=vendor_src
वेंडर डायरेक्ट्री, आपके वर्कस्पेस रूट का कोई रिलेटिव पाथ या कोई ऐब्सलूट पाथ हो सकती है.
किसी खास बाहरी डेटाबेस को वेंडर करना
यह तय करने के लिए कि किस डेटाबेस को वेंडर करना है, vendor फ़्लैग के साथ --repo कमांड का इस्तेमाल किया जा सकता है. यह कैननिकल डेटाबेस
का नाम और दिखने वाले डेटाबेस
का नाम, दोनों स्वीकार करता है.
उदाहरण के लिए, इसे चलाने पर:
bazel vendor --vendor_dir=vendor_src --repo=@rules_cc
या
bazel vendor --vendor_dir=vendor_src --repo=@@rules_cc+
दोनों ही, rules_cc को
<workspace root>/vendor_src/rules_cc+ के तहत वेंडर करेंगे.
दिए गए टारगेट के लिए, बाहरी डिपेंडेंसी वेंडर करना
दिए गए टारगेट पैटर्न बनाने के लिए ज़रूरी सभी बाहरी डिपेंडेंसी को वेंडर करने के लिए,
आप bazel vendor <target patterns> चला सकते हैं.
उदाहरण के लिए
bazel vendor --vendor_dir=vendor_src //src/main:hello-world //src/test/...
मौजूदा कॉन्फ़िगरेशन के साथ, //src/main:hello-world टारगेट और //src/test/... के तहत सभी टारगेट बनाने के लिए ज़रूरी सभी डेटाबेस वेंडर किए जाएंगे.
बैकग्राउंड में, यह टारगेट पैटर्न का विश्लेषण करने के लिए, bazel build --nobuild कमांड चलाता है. इसलिए, इस कमांड पर बिल्ड फ़्लैग लागू किए जा सकते हैं और इससे नतीजे पर असर पड़ सकता है.
टारगेट को ऑफ़लाइन बनाना
बाहरी डिपेंडेंसी वेंडर करने के बाद, टारगेट को ऑफ़लाइन बनाया जा सकता है. इसके लिए
bazel build --vendor_dir=vendor_src //src/main:hello-world //src/test/...
बिल्ड, नेटवर्क ऐक्सेस और डेटाबेस कैश के बिना, साफ़-सुथरे बिल्ड एनवायरमेंट में काम करना चाहिए.
इसलिए, आपको वेंडर किए गए सोर्स को चेक इन करना चाहिए और दूसरे डिवाइस पर, ऑफ़लाइन तरीके से एक ही टारगेट बनाने चाहिए.
सभी बाहरी डिपेंडेंसी वेंडर करना
अपने ट्रांज़िटिव बाहरी डिपेंडेंसी ग्राफ़ में सभी डेटाबेस वेंडर करने के लिए, यह कमांड चलाएं:
bazel vendor --vendor_dir=vendor_src
ध्यान दें कि सभी डिपेंडेंसी वेंडर करने के कुछ नुकसान हैं:
- ट्रांज़िटिव तरीके से जोड़े गए डेटाबेस सहित सभी डेटाबेस फ़ेच करने में ज़्यादा समय लग सकता है.
- वेंडर डायरेक्ट्री का साइज़ बहुत बड़ा हो सकता है.
- अगर कुछ डेटाबेस, मौजूदा प्लैटफ़ॉर्म या एनवायरमेंट के साथ काम नहीं करते हैं, तो उन्हें फ़ेच नहीं किया जा सकता.
इसलिए, पहले कुछ खास टारगेट के लिए वेंडर करने पर विचार करें.
Bazel के सब-कमांड के लिए टूल वेंडर करना
Bazel के कुछ सब-कमांड (जैसे, bazel mod tidy) में, टूल की ऐसी डिपेंडेंसी होती हैं जिन्हें उपयोगकर्ता के बिल्ड टारगेट से ऐक्सेस नहीं किया जा सकता. इसलिए, इन्हें bazel vendor //... में शामिल नहीं किया जाता. उन टूल को भी वेंडर करने के लिए, अपने वेंडर इनवोकेशन में @bazel_tools//tools:tools_for_bazel_subcommands फ़ाइल ग्रुप जोड़ें:
bazel vendor //... @bazel_tools//tools:tools_for_bazel_subcommands
अगर आपको bazel mod tidy जैसे कमांड, ऑफ़लाइन या हर्मेटिक एनवायरमेंट में चलाने हैं, तो यह ज़रूरी है. उदाहरण के लिए, --vendor_dir और --nofetch के साथ.
VENDOR.bazel की मदद से, वेंडर मोड कॉन्फ़िगर करना
वेंडर डायरेक्ट्री में मौजूद VENDOR.bazel फ़ाइल की मदद से, यह कंट्रोल किया जा सकता है कि दिए गए डेटाबेस को कैसे हैंडल किया जाए.
दो डायरेक्टिव उपलब्ध हैं. दोनों में, कैननिकल डेटाबेस के नामों की सूची को आर्ग्युमेंट के तौर पर स्वीकार किया जाता है:
ignore(): किसी डेटाबेस को वेंडर मोड से पूरी तरह से अनदेखा करने के लिए.pin(): किसी डेटाबेस को उसके मौजूदा वेंडर किए गए सोर्स पर पिन करने के लिए. ऐसा माना जाता है कि इस डेटाबेस के लिए--override_repositoryफ़्लैग मौजूद है. जब तक वेंडर कमांड चलाया जाता है, तब तक Bazel इस डेटाबेस के वेंडर किए गए सोर्स को अपडेट नहीं करेगा. हालांकि, ऐसा तब तक होगा, जब तक इसे अनपिन नहीं किया जाता. उपयोगकर्ता, इस डेटाबेस के वेंडर किए गए सोर्स में मैन्युअल तरीके से बदलाव कर सकता है और उसे बनाए रख सकता है.
उदाहरण के लिए
ignore("@@rules_cc+")
pin("@@bazel_skylib+")
इस कॉन्फ़िगरेशन के साथ
- दोनों डेटाबेस को, इसके बाद के वेंडर कमांड से बाहर रखा जाएगा.
bazel_skylibडेटाबेस को, वेंडर डायरेक्ट्री में मौजूद सोर्स पर ओवरराइड किया जाएगा.- उपयोगकर्ता,
bazel_skylibके वेंडर किए गए सोर्स में सुरक्षित तरीके से बदलाव कर सकता है. bazel_skylibको फिर से वेंडर करने के लिए, उपयोगकर्ता को पहले पिन स्टेटमेंट बंद करना होगा.
यह समझना कि वेंडर मोड कैसे काम करता है
Bazel, किसी प्रोजेक्ट की बाहरी डिपेंडेंसी को $(bazel info
output_base)/external में फ़ेच करता है. बाहरी डिपेंडेंसी वेंडर करने का मतलब है कि काम की फ़ाइलों और डायरेक्ट्री को, दी गई वेंडर डायरेक्ट्री में ले जाना और बाद के बिल्ड के लिए, वेंडर किए गए सोर्स का इस्तेमाल करना.
वेंडर किए जा रहे कॉन्टेंट में ये शामिल हैं:
- डेटाबेस डायरेक्ट्री
- डेटाबेस मार्कर फ़ाइल
बिल्ड के दौरान, अगर वेंडर की गई मार्कर फ़ाइल अप-टू-डेट है या डेटाबेस को VENDOR.bazel फ़ाइल में पिन किया गया है, तो Bazel, डेटाबेस के नियम को असल में चलाने के बजाय, वेंडर किए गए सोर्स का इस्तेमाल करता है. इसके लिए, वह $(bazel info output_base)/external में उसका सिमलिंक बनाता है. इसके अलावा, एक चेतावनी दिखती है और Bazel, डेटाबेस का नया वर्शन फ़ेच करने की कोशिश करता है.
रजिस्ट्री फ़ाइलें वेंडर करना
Bazel को बाहरी डिपेंडेंसी फ़ेच करने के लिए, Bazel मॉड्यूल रिज़ॉल्यूशन करना होता है. इसके लिए, इंटरनेट के ज़रिए रजिस्ट्री फ़ाइलों को ऐक्सेस करना पड़ सकता है. ऑफ़लाइन बिल्ड करने के लिए, Bazel नेटवर्क से फ़ेच की गई सभी रजिस्ट्री फ़ाइलों को <vendor_dir>/_registries डायरेक्ट्री में वेंडर करता है.
सिमलिंक वेंडर करना
बाहरी डेटाबेस में, अन्य फ़ाइलों या डायरेक्ट्री की ओर ले जाने वाले सिमलिंक हो सकते हैं. यह पक्का करने के लिए कि सिमलिंक सही तरीके से काम करें, Bazel, वेंडर किए गए सोर्स में सिमलिंक को फिर से लिखने के लिए, यह तरीका अपनाता है:
- एक सिमलिंक
<vendor_dir>/bazel-externalबनाएं, जो$(bazel info output_base)/externalकी ओर ले जाता है. यह हर Bazel कमांड से अपने-आप रीफ़्रेश हो जाता है. - वेंडर किए गए सोर्स के लिए, उन सभी सिमलिंक को फिर से लिखें जो असल में a
$(bazel info output_base)/externalमें मौजूद किसी पाथ की ओर ले जाते हैं. इसके लिए,<vendor_dir>/bazel-externalमें कोई रिलेटिव पाथ इस्तेमाल करें.
उदाहरण के लिए, अगर ओरिजनल सिमलिंक यह है
<vendor_dir>/repo_foo+/link => $(bazel info output_base)/external/repo_bar+/file
तो इसे इस तरह से फिर से लिखा जाएगा
<vendor_dir>/repo_foo+/link => ../../bazel-external/repo_bar+/file
कहां
<vendor_dir>/bazel-external => $(bazel info output_base)/external # This might be new if output base is changed
चूंकि <vendor_dir>/bazel-external को Bazel अपने-आप जनरेट करता है, इसलिए इसे .gitignore या इसके बराबर की किसी फ़ाइल में जोड़ने का सुझाव दिया जाता है, ताकि इसे चेक इन न किया जा सके.
इस रणनीति के तहत, वेंडर किए गए सोर्स में मौजूद सिमलिंक सही तरीके से काम करने चाहिए. भले ही, वेंडर किए गए सोर्स को किसी दूसरी जगह पर ले जाया गया हो या bazel आउटपुट बेस बदल गया हो.