रिपॉज़िटरी के नियम

किसी समस्या की शिकायत करें सोर्स देखें Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

इस पेज में, डेटा स्टोर करने की जगह के नियमों को तय करने का तरीका बताया गया है. साथ ही, ज़्यादा जानकारी के लिए उदाहरण भी दिए गए हैं.

बाहरी रिपॉज़िटरी एक डायरेक्ट्री ट्री होती है. इसमें ऐसी सोर्स फ़ाइलें होती हैं जिनका इस्तेमाल Bazel बिल्ड में किया जा सकता है. यह रिपॉज़िटरी नियम को चलाकर, मांग पर जनरेट होती है. रिपॉज़िटरी को कई तरीकों से तय किया जा सकता है. हालांकि, आखिर में हर रिपॉज़िटरी को रिपॉज़िटरी नियम को लागू करके तय किया जाता है. ठीक उसी तरह जैसे बिल्ड टारगेट को बिल्ड नियमों को लागू करके तय किया जाता है. इनका इस्तेमाल तीसरे पक्ष की लाइब्रेरी (जैसे कि Maven के पैकेज की गई लाइब्रेरी) पर निर्भर करने के लिए किया जा सकता है. साथ ही, इनका इस्तेमाल होस्ट Basel के चल रहे होस्ट के लिए खास BUILD फ़ाइलों को जनरेट करने के लिए भी किया जा सकता है.

रिपॉज़िटरी के नियम की परिभाषा

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

किसी रिपॉज़िटरी के नियम की परिभाषा के दो मुख्य कॉम्पोनेंट हैं, एट्रिब्यूट स्कीमा और लागू करने का फ़ंक्शन. एट्रिब्यूट स्कीमा, रिपॉज़िटरी के नियम के लागू होने पर इस्तेमाल होने वाले एट्रिब्यूट के नाम और टाइप तय करता है. साथ ही, रिपॉज़िटरी को फ़ेच करने पर, लागू करने वाला फ़ंक्शन चलता है.

विशेषताएं

एट्रिब्यूट, ऐसे आर्ग्युमेंट होते हैं जिन्हें रेपो नियम को लागू करने के लिए भेजा जाता है. जब किसी repo नियम को repository_rule को कॉल करके तय किया जाता है, तो attrs आर्ग्युमेंट का इस्तेमाल करके, repo नियम से स्वीकार किए गए एट्रिब्यूट का स्कीमा तय किया जाता है. 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 का इस्तेमाल करके रिपॉज़िटरी नियम के लागू करने वाले फ़ंक्शन से पढ़ने पर, यह रिपॉज़िटरी का कैननिकल नाम दिखाता है.

लागू करने का फ़ंक्शन

हर repo नियम के लिए, 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, बदलावों का पता नहीं लगा सकता या इससे हर बिल्ड पर बहुत ज़्यादा ओवरहेड होगा. उदाहरण के लिए, नेटवर्क से फ़ेच की गई चीज़ें. इसलिए, सिर्फ़ इनमें से किसी एक चीज़ में बदलाव होने पर ही, रिपॉज़िटरी फिर से फ़ेच किए जाते हैं:

  • वे एट्रिब्यूट जिन्हें repo rule invocation में पास किया गया है.
  • Starlark कोड, जिसमें रिपॉज़िटरी के नियम को लागू करने की जानकारी होती है.
  • repository_ctx के getenv() तरीके में पास किए गए किसी भी एनवायरमेंट वैरिएबल की वैल्यू या repository_rule के environ एट्रिब्यूट के साथ बताई गई वैल्यू. इन एनवायरमेंट वैरिएबल की वैल्यू को कमांड लाइन पर, --repo_env फ़्लैग की मदद से हार्ड-वाइर्ड किया जा सकता है.
  • रिपॉज़िटरी नियम के लागू करने वाले फ़ंक्शन में, watch किए जा रहे किसी भी पाथ का अस्तित्व, कॉन्टेंट, और टाइप.
    • watch पैरामीटर वाले repository_ctx के कुछ दूसरे तरीकों, जैसे कि 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 को सिर्फ़ उन बाहरी रिपॉज़िटरी को फिर से फ़ेच करने के लिए कहा जा सकता है जिनमें repository_rule परिभाषा में configure एट्रिब्यूट सेट है. इसके लिए, bazel fetch --force --configure का इस्तेमाल करें.

उदाहरण

  • C++ के लिए अपने-आप कॉन्फ़िगर होने वाला टूलचैन: यह किसी रिपॉज़िटरी नियम का इस्तेमाल करके, Bazel के लिए C++ कॉन्फ़िगरेशन फ़ाइलें अपने-आप बनाता है. इसके लिए, यह लोकल C++ कंपाइलर, एनवायरमेंट, और उन फ़्लैग को खोजता है जिनका इस्तेमाल C++ कंपाइलर करता है.

  • Go रिपॉज़िटरी में, Go नियमों का इस्तेमाल करने के लिए ज़रूरी डिपेंडेंसी की सूची तय करने के लिए, कई repository_rule का इस्तेमाल किया जाता है.

  • rules_jvm_external, डिफ़ॉल्ट रूप से @maven नाम की एक बाहरी रिपॉज़िटरी बनाता है. यह रिपॉज़िटरी, ट्रांज़िटिव डिपेंडेंसी ट्री में मौजूद हर Maven आर्टफ़ैक्ट के लिए, बिल्ड टारगेट जनरेट करती है.