इस पेज पर, डेटा स्टोर करने की जगह के नियम बनाने का तरीका बताया गया है. साथ ही, ज़्यादा जानकारी के लिए उदाहरण भी दिए गए हैं.
बाहरी डेटा स्टोर करने की जगह एक नियम है जिसका इस्तेमाल सिर्फ़ WORKSPACE
फ़ाइल में किया जा सकता है. साथ ही, यह Bazel के लोड होने के दौरान, नॉन-हर्मेटिक ऑपरेशन को चालू करता है. डेटा स्टोर करने की सुविधा का हर बाहरी नियम, अपनी BUILD
फ़ाइलों और आर्टफ़ैक्ट के साथ, अपना फ़ाइल फ़ोल्डर बनाता है. इनका इस्तेमाल तीसरे पक्ष की लाइब्रेरी (जैसे, Maven की पैकेज्ड लाइब्रेरी) पर निर्भर करने के लिए किया जा सकता है. हालांकि, इसका इस्तेमाल उस होस्ट Bazel के लिए खास तौर पर चल रही BUILD
फ़ाइलों को जनरेट करने के लिए भी किया जा सकता है, जिस पर यह चल रहा है.
डेटा स्टोर करने की जगह के नियम बनाना
किसी .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
दिखाता है, ताकि यह बताया जा सके कि तय किए गए पैरामीटर के आधार पर नियम को फिर से बनाया जा सकता है. इसके अलावा, उस नियम के लिए पैरामीटर के सेट के साथ एक डिक्शनरी भी दिखाता है, जो उस नियम को उसी रिपॉज़िटरी को जनरेट करने वाले रीजनेबल में बदल देगा. उदाहरण
के लिए, ऐसा नियम ट्रैक करने के लिए जो गिट रिपॉज़िटरी को ट्रैक करता है. इसका मतलब है कि मूल रूप से तय की गई किसी फ़्लोटिंग ब्रांच के बजाय, कोई खास कमिट आइडेंटिफ़ायर दिया जाएगा.
इनपुट पैरामीटर 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
फ़्लैग वाली कमांड लाइन पर हार्ड वायर की जा सकती हैं.read()
,execute()
, औरrepository_ctx
की इसी तरह के तरीकों को पास की गई किसी भी फ़ाइल का कॉन्टेंट, जिसे लेबल से बताया जाता है (उदाहरण के लिए,//mypkg:label.txt
नहीं, बल्किmypkg/label.txt
से)- जब
bazel sync
चलाया जाता है.
repository_rule
के दो पैरामीटर होते हैं, जो यह कंट्रोल करते हैं कि डेटा स्टोर करने की जगहों को कब फिर से फ़ेच किया जाएगा:
- अगर
configure
फ़्लैग सेट है, तो रिपॉज़िटरी कोbazel sync
पर फिर से सिर्फ़ तब फ़ेच किया जाता है, जब--configure
पैरामीटर को पास किया जाता है (अगर एट्रिब्यूट सेट नहीं है, तो इस निर्देश से फिर से फ़ेच नहीं होगा) अगर
local
फ़्लैग को सेट किया गया है, तो ऊपर दिए गए मामलों के अलावा, डेटा स्टोर करने की जगह को फिर से फ़ेच किया जाता है.ऐसा, Bazel सर्वर के रीस्टार्ट होने या डेटा स्टोर करने की जगह के बदलावों (जैसे,WORKSPACE
फ़ाइल या लोड होने वाली फ़ाइल) पर असर डालने वाली किसी फ़ाइल पर होता है. इससे कोई फ़र्क़ नहीं पड़ता कि इन बदलावों की वजह से, डेटा स्टोर करने की जगह की जानकारी या उसके कोड में बदलाव हुआ है या नहीं.ऐसे मामलों में, डेटा स्टोर करने की जगह को फिर से फ़ेच नहीं किया जाता. ऐसा इसलिए क्योंकि यह माना जाता है कि ये डेटा स्टोर करने की जगहें, नेटवर्क से बात करती हैं या ये महंगी होती हैं.
लागू करने वाले फ़ंक्शन को रीस्टार्ट करना
अगर रिपॉज़िटरी को फ़ेच किया जा रहा है, तो लागू करने वाले फ़ंक्शन को फिर से शुरू किया जा सकता है. ऐसा तब किया जा सकता है, जब अनुरोध करने वाली डिपेंडेंसी उपलब्ध नहीं होती है. ऐसी स्थिति में, लागू करने वाला फ़ंक्शन रुक जाएगा, डिपेंडेंसी खत्म हो जाएगी, और डिपेंडेंसी खत्म होने के बाद फ़ंक्शन फिर से चालू हो जाएगा. बेवजह रीस्टार्ट (जो महंगे होते हैं, क्योंकि नेटवर्क ऐक्सेस को दोहराया जा सकता है) से बचने के लिए, लेबल वाले आर्ग्युमेंट प्रीफ़ेच किए जाते हैं, बशर्ते सभी लेबल आर्ग्युमेंट को मौजूदा फ़ाइल में रिज़ॉल्व किया जा सकता हो. ध्यान दें कि सिर्फ़ फ़ंक्शन के चलने के दौरान बनाए गए स्ट्रिंग या लेबल के पाथ को हल करने के बाद भी रीस्टार्ट हो सकता है.
बाहरी डेटा स्टोर करने की जगहों को ज़बरदस्ती फिर से फ़ेच करना
कभी-कभी, कोई बाहरी रिपॉज़िटरी, अपनी परिभाषा या डिपेंडेंसी में बिना किसी बदलाव के पुराना हो सकता है. उदाहरण के लिए, रिपॉज़िटरी को फ़ेच करने वाले सोर्स, तीसरे पक्ष के रिपॉज़िटरी की किसी खास ब्रांच को फ़ॉलो कर सकते हैं. साथ ही, उस ब्रांच पर नई कमिट उपलब्ध होती हैं. ऐसे मामले में, bazel sync
पर कॉल करके, बैजल से बिना किसी शर्त के सभी बाहरी डेटा स्टोर करने की जगहों को फिर से फ़ेच करने के लिए कहा जा सकता है.
इसके अलावा, कुछ नियम लोकल मशीन की जांच करते हैं और लोकल मशीन
अपग्रेड होने पर पुराने हो सकते हैं. यहां, बैजल से उन बाहरी डेटा स्टोर करने की जगहों को फिर से फ़ेच करने के लिए कहा जा सकता है जहां repository_rule
परिभाषा में configure
एट्रिब्यूट सेट किया गया है. ऐसे में, bazel sync --configure
का इस्तेमाल करें.
उदाहरण
C++ अपने-आप कॉन्फ़िगर होने वाला टूलचेन: यह रिपॉज़िटरी नियम का इस्तेमाल करता है, ताकि Bazel के लिए अपने-आप C++ कॉन्फ़िगरेशन फ़ाइलें बनाई जा सकें. ऐसा स्थानीय C++ कंपाइलर, एनवायरमेंट, और C++ कंपाइलर के साथ काम करने वाले फ़्लैग की मदद से किया जाता है.
Go के डेटा स्टोर करने की जगहें Go के नियमों का इस्तेमाल करने के लिए ज़रूरी डिपेंडेंसी की सूची तय करने के लिए, कई
repository_rule
का इस्तेमाल करता है.rules_jvm_external डिफ़ॉल्ट रूप से,
@maven
नाम का एक बाहरी रिपॉज़िटरी बनाता है. यह ट्रांज़िटिव डिपेंडेंसी ट्री में हर Maven आर्टफ़ैक्ट के लिए बिल्ड टारगेट जनरेट करता है.