इस पेज पर, डेटा स्टोर करने की जगह के लिए नियम बनाने का तरीका बताया गया है. साथ ही, ज़्यादा जानकारी के लिए उदाहरण भी दिए गए हैं.
बाहरी रिपॉज़िटरी एक ऐसा नियम है जिसका इस्तेमाल सिर्फ़ WORKSPACE
फ़ाइल में किया जा सकता है. साथ ही, यह Bazel के लोडिंग फ़ेज़ में नॉन-हर्मेटिक ऑपरेशन को चालू करता है. हर बाहरी रिपॉज़िटरी नियम, अपनी BUILD
फ़ाइलों और आर्टफ़ैक्ट के साथ अपना वर्कस्पेस बनाता है. इनका इस्तेमाल, तीसरे पक्ष की लाइब्रेरी (जैसे, मेवन पैकेज वाली लाइब्रेरी) पर निर्भर करने के लिए किया जा सकता है. साथ ही, इनका इस्तेमाल उस होस्ट के लिए खास BUILD
फ़ाइलें जनरेट करने के लिए भी किया जा सकता है जिस पर Bazel चल रहा है.
रिपॉज़िटरी का नियम बनाना
.bzl
फ़ाइल में, repository_rule फ़ंक्शन का इस्तेमाल करके, नया रिपॉज़िटरी नियम बनाएं और उसे ग्लोबल वैरिएबल में सेव करें.
कस्टम रिपॉज़िटरी नियम का इस्तेमाल, नेटिव रिपॉज़िटरी नियम की तरह ही किया जा सकता है. इसमें name
एट्रिब्यूट ज़रूरी है. साथ ही, इसकी बिल्ड फ़ाइलों में मौजूद हर टारगेट को @<name>//package:target
के तौर पर रेफ़र किया जा सकता है. यहां <name>
, name
एट्रिब्यूट की वैल्यू है.
नियम तब लोड होता है, जब उसे साफ़ तौर पर बनाया जाता है या वह बिल्ड की डिपेंडेंसी होता है. इस मामले में, Bazel अपना implementation
फ़ंक्शन लागू करेगा. इस फ़ंक्शन में, रिपॉज़िटरी, उसका कॉन्टेंट, और BUILD
फ़ाइलें बनाने का तरीका बताया गया है.
विशेषताएं
एट्रिब्यूट, नियम के आर्ग्युमेंट होते हैं. इन्हें attrs
नियम के आर्ग्युमेंट के तौर पर डिक्शनरी के तौर पर पास किया जाता है.
रिपॉज़िटरी का नियम तय करते समय, एट्रिब्यूट और उनके टाइप की सूची दी जाती है. url
और sha256
एट्रिब्यूट को स्ट्रिंग के तौर पर दिखाने का उदाहरण:
local_repository = repository_rule(
implementation=_impl,
local=True,
attrs={
"url": attr.string(mandatory=True)
"sha256": attr.string(mandatory=True)
}
)
लागू करने के फ़ंक्शन में किसी एट्रिब्यूट को ऐक्सेस करने के लिए, repository_ctx.attr.<attribute_name>
का इस्तेमाल करें:
def _impl(repository_ctx):
url = repository_ctx.attr.url
checksum = repository_ctx.attr.sha256
सभी repository_rule
में, बिल्ड नियमों की तरह ही एट्रिब्यूट अपने-आप तय होते हैं. दो इंप्लिसिट एट्रिब्यूट, name
(बिल्ड नियमों की तरह) और
repo_mapping
हैं. किसी रिपॉज़िटरी रूल का नाम, repository_ctx.name
की मदद से ऐक्सेस किया जा सकता है. repo_mapping
का मतलब, नेटिव रिपॉज़िटरी के नियमों local_repository
और new_local_repository
के मतलब जैसा ही है.
अगर किसी एट्रिब्यूट का नाम _
से शुरू होता है, तो वह निजी होता है और उपयोगकर्ता उसे सेट नहीं कर सकते.
लागू करने का फ़ंक्शन
हर रिपॉज़िटरी नियम के लिए, implementation
फ़ंक्शन की ज़रूरत होती है. इसमें नियम का असल लॉजिक होता है और इसे लोडिंग फ़ेज़ में सख्ती से लागू किया जाता है.
फ़ंक्शन में सिर्फ़ एक इनपुट पैरामीटर, repository_ctx
है. यह फ़ंक्शन, दिए गए पैरामीटर के हिसाब से, नियम को फिर से लागू किया जा सकता है या नहीं, यह बताने के लिए None
दिखाता है. इसके अलावा, यह उस नियम के लिए पैरामीटर के सेट के साथ एक डायक्शन दिखाता है, जो उस नियम को फिर से लागू किया जा सकने वाला नियम बना देगा और उसी रिपॉज़िटरी को जनरेट करेगा. उदाहरण के लिए, किसी git रिपॉज़िटरी को ट्रैक करने वाले नियम के लिए, इसका मतलब है कि मूल रूप से तय की गई फ़्लोटिंग शाखा के बजाय, किसी खास कमिट आइडेंटिफ़ायर को दिखाना.
इनपुट पैरामीटर repository_ctx
का इस्तेमाल, एट्रिब्यूट की वैल्यू और ऐसे फ़ंक्शन को ऐक्सेस करने के लिए किया जा सकता है जो पूरी तरह से सुरक्षित नहीं होते. जैसे, कोई बाइनरी ढूंढना, बाइनरी को चलाना, रिपॉज़िटरी में कोई फ़ाइल बनाना या इंटरनेट से कोई फ़ाइल डाउनलोड करना. ज़्यादा जानकारी के लिए, लाइब्रेरी देखें. उदाहरण:
def _impl(repository_ctx):
repository_ctx.symlink(repository_ctx.attr.path, "")
local_repository = repository_rule(
implementation=_impl,
...)
लागू करने वाला फ़ंक्शन कब लागू होता है?
किसी रिपॉज़िटरी का लागू करने वाला फ़ंक्शन तब लागू होता है, जब Bazel को उस रिपॉज़िटरी से किसी टारगेट की ज़रूरत होती है. उदाहरण के लिए, जब कोई दूसरा टारगेट (किसी दूसरी रिपॉज़िटरी में) उस पर निर्भर होता है या कमांड लाइन में उसका ज़िक्र किया जाता है. इसके बाद, लागू करने वाले फ़ंक्शन को फ़ाइल सिस्टम में रिपॉज़िटरी बनानी होगी. इसे रिपॉज़िटरी को "फ़ेच करना" कहा जाता है.
सामान्य टारगेट के उलट, जब कोई ऐसा बदलाव होता है जिससे रिपॉज़िटरी अलग हो जाती है, तो ज़रूरी नहीं है कि रिपॉज़िटरी को फिर से फ़ेच किया जाए. ऐसा इसलिए है, क्योंकि कुछ चीज़ों में Bazel, बदलावों का पता नहीं लगा सकता या हर बिल्ड पर बहुत ज़्यादा ओवरहेड होगा. उदाहरण के लिए, नेटवर्क से फ़ेच की गई चीज़ें. इसलिए, रिपॉज़िटरी सिर्फ़ तब फिर से फ़ेच की जाती हैं, जब इनमें से कोई एक चीज़ बदलती है:
WORKSPACE
फ़ाइल में, डेटा स्टोर करने की जगह के एलान के लिए पास किए गए पैरामीटर.- Starlark कोड, जिसमें रिपॉज़िटरी को लागू करने की जानकारी होती है.
repository_ctx
केgetenv()
तरीके में पास किए गए किसी भी एनवायरमेंट वैरिएबल की वैल्यू याrepository_rule
केenviron
एट्रिब्यूट के साथ बताई गई वैल्यू. इन एनवायरमेंट वैरिएबल की वैल्यू को कमांड लाइन पर,--repo_env
फ़्लैग की मदद से हार्ड-वाइर्ड किया जा सकता है.repository_ctx
केread()
,execute()
, और मिलते-जुलते तरीकों में पास की गई किसी भी फ़ाइल का कॉन्टेंट, जिसे लेबल से रेफ़र किया जाता है (उदाहरण के लिए,//mypkg:label.txt
, लेकिनmypkg/label.txt
नहीं)- जब
bazel sync
को लागू किया जाता है.
repository_rule
के दो पैरामीटर हैं, जिनसे यह कंट्रोल होता है कि रिपॉज़िटरी को फिर से कब फ़ेच किया जाए:
- अगर
configure
फ़्लैग सेट है, तोbazel sync
पर सिर्फ़ तब रिपॉज़िटरी को फिर से फ़ेच किया जाता है, जब उसमें--configure
पैरामीटर पास किया जाता है. अगर एट्रिब्यूट सेट नहीं है, तो इस कमांड से फिर से फ़ेच नहीं किया जाएगा अगर
local
फ़्लैग सेट है, तो ऊपर बताए गए मामलों के अलावा, Bazel सर्वर के फिर से शुरू होने पर या किसी ऐसी फ़ाइल में बदलाव होने पर भी, रिपॉज़िटरी को फिर से फ़ेच किया जाता है जिससे रिपॉज़िटरी के एलान पर असर पड़ता है.उदाहरण के लिए,WORKSPACE
फ़ाइल या वह फ़ाइल जिसे लोड किया जाता है. भले ही, इन बदलावों की वजह से रिपॉज़िटरी के एलान या उसके कोड में बदलाव हुआ हो या नहीं.इन मामलों में, नॉन-लोकल रिपॉज़िटरी को फिर से फ़ेच नहीं किया जाता. ऐसा इसलिए है, क्योंकि इन रिपॉज़िटरी को नेटवर्क से कनेक्ट करने या अन्य तरीकों से इस्तेमाल करने पर ज़्यादा खर्च आता है.
लागू करने की सुविधा को फिर से शुरू करना
अगर किसी डिपेंडेंसी का अनुरोध किया जाता है और वह मौजूद नहीं है, तो रिपॉज़िटरी को फ़ेच करते समय, लागू करने वाले फ़ंक्शन को फिर से शुरू किया जा सकता है. ऐसे में, लागू करने वाले फ़ंक्शन का इस्तेमाल बंद हो जाएगा. साथ ही, फ़ंक्शन को फिर से लागू करने के लिए, डिपेंडेंसी को ठीक किया जाएगा. ज़रूरत से ज़्यादा रीस्टार्ट (जो कि महंगे होते हैं, क्योंकि नेटवर्क ऐक्सेस को दोबारा करना पड़ सकता है) से बचने के लिए, लेबल के आर्ग्युमेंट पहले से फ़ेच किए जाते हैं. हालांकि, ऐसा तब ही किया जाता है, जब सभी लेबल के आर्ग्युमेंट को किसी मौजूदा फ़ाइल में हल किया जा सकता हो. ध्यान दें कि सिर्फ़ फ़ंक्शन के लागू होने के दौरान बनाई गई स्ट्रिंग या लेबल से पाथ को हल करने पर भी, रीस्टार्ट हो सकता है.
बाहरी रिपॉज़िटरी को फिर से फ़ेच करने के लिए मजबूर करना
कभी-कभी, किसी बाहरी रिपॉज़िटरी की परिभाषा या डिपेंडेंसी में कोई बदलाव किए बिना भी वह पुरानी हो सकती है. उदाहरण के लिए, सोर्स फ़ेच करने वाली कोई रिपॉज़िटरी, तीसरे पक्ष की किसी रिपॉज़िटरी की किसी खास शाखा का पालन कर सकती है और उस शाखा पर नए कमिट उपलब्ध होते हैं. इस मामले में, bazel sync
को कॉल करके, bazel से सभी बाहरी रिपॉज़िटरी को बिना किसी शर्त के फिर से फ़ेच करने के लिए कहा जा सकता है.
इसके अलावा, कुछ नियम स्थानीय मशीन की जांच करते हैं. अगर स्थानीय मशीन को अपग्रेड किया जाता है, तो हो सकता है कि ये नियम पुराने हो जाएं. यहां bazel को सिर्फ़ उन बाहरी रिपॉज़िटरी को फिर से फ़ेच करने के लिए कहा जा सकता है जिनमें repository_rule
परिभाषा में configure
एट्रिब्यूट सेट है. इसके लिए, bazel sync --configure
का इस्तेमाल करें.
उदाहरण
C++ के लिए अपने-आप कॉन्फ़िगर होने वाला टूलचैन: यह एक रिपॉज़िटरी नियम का इस्तेमाल करके, Bazel के लिए C++ कॉन्फ़िगरेशन फ़ाइलों को अपने-आप बनाता है. इसके लिए, यह लोकल C++ कंपाइलर, एनवायरमेंट, और उन फ़्लैग को खोजता है जिनका इस्तेमाल C++ कंपाइलर करता है.
Go रिपॉज़िटरी, Go के नियमों का इस्तेमाल करने के लिए ज़रूरी डिपेंडेंसी की सूची तय करने के लिए, कई
repository_rule
का इस्तेमाल करता है.rules_jvm_external, डिफ़ॉल्ट रूप से
@maven
नाम की एक बाहरी रिपॉज़िटरी बनाता है. यह ट्रांज़िटिव डिपेंडेंसी ट्री में मौजूद हर Maven आर्टफ़ैक्ट के लिए, बिल्ड टारगेट जनरेट करता है.