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

समस्या की शिकायत करें सोर्स देखें

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

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

डेटा स्टोर करने की जगह के नियम की परिभाषा

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

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

एट्रिब्यूट

एट्रिब्यूट, रेपो नियम को शुरू करने पर पास किए गए तर्क होते हैं. स्टोर करने के नियम के हिसाब से स्वीकार किए जाने वाले एट्रिब्यूट के स्कीमा को, attrs आर्ग्युमेंट का इस्तेमाल करके तय किया जाता है. ऐसा तब किया जाता है, जब रिपो नियम को repository_rule को कॉल करके तय किया जाता है. url और sha256 एट्रिब्यूट को स्ट्रिंग के तौर पर परिभाषित करने वाला उदाहरण:

http_archive = 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 होता है. यह ऐसा स्ट्रिंग एट्रिब्यूट है जो थोड़ा-बहुत जादुई तरीके से काम करता है: जब इसे रेपो नियम को शुरू करने के लिए इनपुट के तौर पर बताया जाता है, तो यह साफ़ तौर पर रेपो का नाम लेता है. हालांकि, 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 के getenv() तरीके से पास किया जाता है या repository_rule के environ एट्रिब्यूट की मदद से एलान किया जाता है. इन एनवायरमेंट वैरिएबल की वैल्यू, कमांड लाइन पर --repo_env फ़्लैग के साथ तार के साथ जोड़ी जा सकती हैं.
  • किसी फ़ाइल का कॉन्टेंट, जो read(), execute(), और repository_ctx से मिलते-जुलते तरीकों से पास किया जाता है. यह कॉन्टेंट, लेबल से जुड़ा होता है, जैसे कि //mypkg:label.txt, mypkg/label.txt से नहीं
  • जब bazel fetch --force चलाया जाता है.

repository_rule के दो पैरामीटर होते हैं, जो यह कंट्रोल करते हैं कि डेटा स्टोर करने की जगहों को कब फिर से फ़ेच किया जाएगा:

  • अगर configure फ़्लैग सेट है, तो रिपॉज़िटरी को bazel fetch पर फिर से फ़ेच किया जाता है. ऐसा तब ही होता है, जब --configure पैरामीटर को पास किया जाता है. अगर एट्रिब्यूट की वैल्यू सेट नहीं की गई है, तो इस निर्देश से डेटा फिर से फ़ेच नहीं होगा
  • अगर local फ़्लैग सेट किया गया है, तो ऊपर दिए गए मामलों के अलावा, Bzel सर्वर के रीस्टार्ट होने पर भी रेपो को फिर से फ़ेच किया जाता है.

लागू करने की प्रोसेस को फिर से शुरू किया जा रहा है

अगर कोई डिपेंडेंसी अनुरोध उपलब्ध नहीं है, तब रेपो फ़ेच होने के दौरान, लागू करने वाले फ़ंक्शन को फिर से शुरू किया जा सकता है. ऐसी स्थिति में, लागू करने का फ़ंक्शन बंद हो जाएगा, जो डिपेंडेंसी मौजूद नहीं थी वह ठीक हो जाएगी. साथ ही, डिपेंडेंसी के बंद होने के बाद फ़ंक्शन फिर से चालू हो जाएगा. ग़ैर-ज़रूरी रीस्टार्ट (जो महंगा होता है, क्योंकि नेटवर्क ऐक्सेस को दोहराना पड़ सकता है) से बचने के लिए, लेबल के तर्क प्रीफ़ेच किए जाते हैं, बशर्ते सभी लेबल तर्कों को किसी मौजूदा फ़ाइल से हल किया जा सकता हो. ध्यान दें कि सिर्फ़ फ़ंक्शन के चलने के दौरान बनाए गए स्ट्रिंग या किसी लेबल से पाथ हल करने पर भी रीस्टार्ट हो सकता है.

डेटा स्टोर से बाहर के डेटा को ज़बरदस्ती फिर से फ़ेच करना

कभी-कभी, बाहरी डेटा संग्रह की परिभाषा या डिपेंडेंसी में कोई बदलाव किए बिना, यह पुराना हो सकता है. उदाहरण के लिए, रेपो फ़ेच करने वाले सोर्स, तीसरे पक्ष के रिपॉज़िटरी की किसी खास ब्रांच को फ़ॉलो कर सकते हैं. साथ ही, उस ब्रांच पर नई शर्तें लागू होती हैं. इस मामले में, आप bazel fetch --force --all पर कॉल करके, bazel से सभी बाहरी रिपोज़ को बिना किसी शर्त के फिर से फ़ेच करने के लिए कह सकते हैं.

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

उदाहरण

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

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

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