इस पेज पर, रिपॉज़िटरी के नियमों को तय करने का तरीका बताया गया है. साथ ही, ज़्यादा जानकारी के लिए उदाहरण भी दिए गए हैं.
कोई बाहरी रिपॉज़िटरी, डायरेक्ट्री ट्री होती है,
इसमें सोर्स फ़ाइलें होती हैं, जिनका इस्तेमाल Bazel बिल्ड में किया जा सकता है. इसे, इससे जुड़े रिपो नियम को चलाकर, मांग पर जनरेट किया जाता है. रिपो को कई तरीकों से तय किया जा सकता है. हालांकि, हर रिपो को रिपो नियम लागू करके तय किया जाता है. ठीक उसी तरह जैसे बिल्ड टारगेट को बिल्ड नियम लागू करके तय किया जाता है. इनका इस्तेमाल, तीसरे पक्ष की लाइब्रेरी (जैसे, Maven पैकेज वाली लाइब्रेरी) पर निर्भर रहने के लिए किया जा सकता है. साथ ही, इनका इस्तेमाल, उस होस्ट के लिए खास तौर पर BUILD फ़ाइलें जनरेट करने के लिए भी किया जा सकता है जिस पर Bazel चल रहा है.
रिपॉज़िटरी के नियम की परिभाषा
कोई नया रिपो नियम तय करने और उसे ग्लोबल वैरिएबल में सेव करने के लिए, .bzl फ़ाइल में
repository_rule फ़ंक्शन का इस्तेमाल करें. रिपो नियम तय करने के बाद, रिपो तय करने के लिए इसे किसी फ़ंक्शन के तौर पर लागू किया जा सकता है. आम तौर पर, यह कार्रवाई किसी मॉड्यूल एक्सटेंशन के लागू करने वाले फ़ंक्शन के अंदर से की जाती है.
रिपो नियम की परिभाषा के दो मुख्य कॉम्पोनेंट होते हैं: इसका एट्रिब्यूट स्कीमा और लागू करने वाला फ़ंक्शन. एट्रिब्यूट स्कीमा, रिपो नियम को लागू करने के लिए पास किए गए एट्रिब्यूट के नाम और टाइप तय करता है. वहीं, रिपो को फ़ेच करने की ज़रूरत पड़ने पर, लागू करने वाला फ़ंक्शन रन होता है.
एट्रिब्यूट
एट्रिब्यूट, रिपो नियम को लागू करने के लिए पास किए गए आर्ग्युमेंट होते हैं. किसी रिपो नियम के लिए स्वीकार किए जाने वाले एट्रिब्यूट का स्कीमा, repository_rule को कॉल करके रिपो नियम तय करते समय, attrs आर्ग्युमेंट का इस्तेमाल करके तय किया जाता है. url और sha256 एट्रिब्यूट को स्ट्रिंग के तौर पर तय करने का उदाहरण:
http_archive = repository_rule(
implementation=_impl,
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 एट्रिब्यूट पहले से तय होता है. यह एक स्ट्रिंग एट्रिब्यूट है, जो कुछ हद तक जादुई तरीके से काम करता है: जब इसे रिपो नियम को लागू करने के लिए इनपुट के तौर पर तय किया जाता है, तो यह रिपो का कोई नाम लेता है. हालांकि, repository_ctx.attr.name का इस्तेमाल करके, रिपो नियम के लागू करने वाले फ़ंक्शन से इसे पढ़ने पर, यह रिपो का कैननिकल नाम दिखाता है.
लागू करने वाला फ़ंक्शन
हर रिपो नियम के लिए, 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 कुछ चीज़ों में बदलाव का पता नहीं लगा सकता या हर बिल्ड पर बहुत ज़्यादा ओवरहेड हो सकता है. उदाहरण के लिए, नेटवर्क से फ़ेच की गई चीज़ें. इसलिए, रिपो को सिर्फ़ तब फिर से फ़ेच किया जाता है, जब इनमें से कोई एक चीज़ बदलती है:
- रिपो नियम को लागू करने के लिए पास किए गए एट्रिब्यूट.
- रिपो नियम को लागू करने वाले Starlark कोड.
repository_ctxके तरीके को पास किए गए किसी भी एनवायरमेंट वैरिएबल की वैल्यू याenvironएट्रिब्यूट के साथ तय की गई वैल्यूrepository_rule.getenv()कमांड लाइन पर--repo_envफ़्लैग के साथ, इन एनवायरमेंट वैरिएबल की वैल्यू को हार्ड-वायर किया जा सकता है.- रिपो नियम के लागू करने वाले फ़ंक्शन में
watched किए जा रहे किसी भी पाथ का मौजूद होना, कॉन्टेंट, और टाइप.repository_ctxके कुछ अन्य तरीके, जिनमेंwatchपैरामीटर होता है. जैसे,read(),execute(), औरextract()की वजह से भी पाथ को वॉच किया जा सकता है.- इसी तरह,
repository_ctx.watch_treeऔरpath.readdirकी वजह से भी पाथ को अन्य तरीकों से वॉच किया जा सकता है.
- जब
bazel fetch --forceलागू किया जाता है.
repository_rule के दो पैरामीटर होते हैं. इनसे यह कंट्रोल किया जाता है कि रिपॉज़िटरी को कब फिर से फ़ेच किया जाए:
- अगर
configureफ़्लैग सेट है, तोbazel fetch --force --configureपर रिपॉज़िटरी को फिर से फ़ेच किया जाता है.configureनहीं की गई रिपॉज़िटरी को फिर से फ़ेच नहीं किया जाता . - अगर
localफ़्लैग सेट है, तो ऊपर बताए गए मामलों के अलावा, Bazel सर्वर के रीस्टार्ट होने पर भी रिपो को फिर से फ़ेच किया जाता है.
बाहरी रिपो को फिर से फ़ेच करने के लिए मजबूर करना
कभी-कभी, किसी बाहरी रिपो की परिभाषा या डिपेंडेंसी में कोई बदलाव न होने पर भी, वह पुराना हो सकता है. उदाहरण के लिए, सोर्स फ़ेच करने वाला कोई रिपो, तीसरे पक्ष की रिपॉज़िटरी की किसी खास ब्रांच को फ़ॉलो कर सकता है. साथ ही, उस ब्रांच पर नए कमिट उपलब्ध हैं. इस मामले में, bazel fetch --force --all को कॉल करके, Bazel से सभी बाहरी रिपो को बिना किसी शर्त के फिर से फ़ेच करने के लिए कहा जा सकता है.
इसके अलावा, कुछ रिपो नियम, लोकल मशीन की जांच करते हैं. अगर लोकल मशीन को अपग्रेड किया गया है, तो वे पुराने हो सकते हैं. यहां Bazel से सिर्फ़ उन
बाहरी रिपो को फिर से फ़ेच करने के लिए कहा जा सकता है जिनकी repository_rule
की परिभाषा में configure एट्रिब्यूट सेट है. इसके लिए, bazel fetch --force
--configure का इस्तेमाल करें.
उदाहरण
C++ टूलचेन को अपने-आप कॉन्फ़िगर करना: यह Bazel के लिए C++ कॉन्फ़िगरेशन फ़ाइलें अपने-आप बनाने के लिए, रिपो नियम का इस्तेमाल करता है. इसके लिए, यह लोकल C++ कंपाइलर, एनवायरमेंट, और उन फ़्लैग को देखता है जिन्हें C++ कंपाइलर सपोर्ट करता है.
Go repositories Go के नियमों का इस्तेमाल करने के लिए ज़रूरी डिपेंडेंसी की सूची तय करने के लिए, कई
repository_ruleका इस्तेमाल करती हैं.rules_jvm_external डिफ़ॉल्ट रूप से
@mavenनाम की एक बाहरी रिपॉज़िटरी बनाता है. यह ट्रांज़िटिव डिपेंडेंसी ट्री में मौजूद हर Maven आर्टफ़ैक्ट के लिए, बिल्ड टारगेट जनरेट करता है.