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

समस्या की शिकायत करें सोर्स देखें Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

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

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

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

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

विशेषताएं

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

इनपुट पैरामीटर repository_ctx का इस्तेमाल, एट्रिब्यूट की वैल्यू ऐक्सेस करने के लिए किया जा सकता है. साथ ही, इसका इस्तेमाल नॉन-हर्मेटिक फ़ंक्शन के लिए भी किया जा सकता है. जैसे, बाइनरी ढूंढना, बाइनरी को एक्ज़ीक्यूट करना, रिपॉज़िटरी में कोई फ़ाइल बनाना या इंटरनेट से कोई फ़ाइल डाउनलोड करना. ज़्यादा जानकारी के लिए, एपीआई से जुड़े दस्तावेज़ देखें. उदाहरण:

def _impl(repository_ctx):
  repository_ctx.symlink(repository_ctx.attr.path, "")

local_repository = repository_rule(
    implementation=_impl,
    ...)

लागू करने वाला फ़ंक्शन कब लागू होता है?

किसी रिपॉज़िटरी के नियम का लागू करने वाला फ़ंक्शन तब एक्ज़ीक्यूट होता है, जब Bazel को उस रिपॉज़िटरी से किसी टारगेट की ज़रूरत होती है. उदाहरण के लिए, जब किसी दूसरे रिपॉज़िटरी का कोई टारगेट उस पर निर्भर करता है या जब उसे कमांड लाइन पर मेंशन किया जाता है. इसके बाद, लागू करने वाले फ़ंक्शन से फ़ाइल सिस्टम में रेपो बनाने की उम्मीद की जाती है. इसे रेपो को "फ़ेच करना" कहा जाता है.

सामान्य टारगेट के उलट, जब कोई ऐसी चीज़ बदलती है जिसकी वजह से रेपो अलग हो जाती है, तो ज़रूरी नहीं कि रेपो को फिर से फ़ेच किया जाए. ऐसा इसलिए होता है, क्योंकि Bazel कुछ चीज़ों में बदलावों का पता नहीं लगा सकता या हर बिल्ड पर बहुत ज़्यादा ओवरहेड हो सकता है. उदाहरण के लिए, नेटवर्क से फ़ेच की गई चीज़ें. इसलिए, रिपॉज़िटरी को सिर्फ़ तब फिर से फ़ेच किया जाता है, जब इनमें से कोई एक बदलाव होता है:

  • रेपो के नियम को लागू करने के लिए पास किए गए एट्रिब्यूट.
  • Starlark कोड, जिसमें repo नियम को लागू करने की जानकारी शामिल होती है.
  • 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 से सभी बाहरी रेपो को बिना किसी शर्त के फिर से फ़ेच करने के लिए कहा जा सकता है.

इसके अलावा, कुछ रीपो नियम स्थानीय मशीन की जांच करते हैं. अगर स्थानीय मशीन को अपग्रेड किया गया है, तो ये नियम पुराने हो सकते हैं. यहां Bazel से सिर्फ़ उन बाहरी रिपॉज़िटरी को फिर से फ़ेच करने के लिए कहा जा सकता है जहां repository_rule डेफ़िनिशन में configure एट्रिब्यूट सेट है. इसके लिए, bazel fetch --force --configure का इस्तेमाल करें.

उदाहरण

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

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

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