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

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

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

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

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

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

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

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

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

लागू करने का फ़ंक्शन कब चलाया जाता है?

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

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

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

लागू करने वाले फ़ंक्शन को रीस्टार्ट करना

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

डेटा स्टोर की बाहरी फ़ाइलों को फिर से फ़ेच करने के लिए

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

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

उदाहरण

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

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

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