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

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

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

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

.bzl फ़ाइल में, डेटा स्टोर करने का नया नियम बनाने और उसे ग्लोबल वैरिएबल में सेव करने के लिए, repository_rule फ़ंक्शन का इस्तेमाल करें.

कस्टम रिपॉज़िटरी के नियम का इस्तेमाल, नेटिव रिपॉज़िटरी के नियम की तरह ही किया जा सकता है. इसमें एक ज़रूरी name एट्रिब्यूट है और इसकी बिल्ड फ़ाइलों में मौजूद हर टारगेट को @<name>//package:target कहा जा सकता है, जहां <name>, name एट्रिब्यूट की वैल्यू है.

नियम तब लोड होता है, जब इसे साफ़ तौर पर बनाया जाता है या यह बिल्ड पर निर्भरता पर निर्भर होता है. इस मामले में, Basel अपने implementation फ़ंक्शन को एक्ज़ीक्यूट करेगा. इस फ़ंक्शन में, रिपॉज़िटरी (डेटा स्टोर करने की जगह), उसका कॉन्टेंट, और BUILD फ़ाइलें बनाने का तरीका बताया गया है.

विशेषताएं

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

local_repository = 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 (बिल्ड नियमों की तरह) और repo_mapping हैं. डेटा स्टोर करने की जगह के नियम के नाम को repository_ctx.name से ऐक्सेस किया जा सकता है. repo_mapping का मतलब, नेटिव रिपॉज़िटरी के नियमों local_repository और new_local_repository के मतलब जैसा ही है.

अगर किसी एट्रिब्यूट का नाम _ से शुरू होता है, तो वह निजी होता है और उपयोगकर्ता उसे सेट नहीं कर सकते.

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

डेटा स्टोर करने के हर नियम के लिए, implementation फ़ंक्शन ज़रूरी होता है. इसमें नियम का असल लॉजिक होता है और इसे लोडिंग फ़ेज़ में सख्ती से लागू किया जाता है.

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

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

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

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

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

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

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

  • WORKSPACE फ़ाइल में, डेटा स्टोर करने की जगह के एलान के लिए पास किए गए पैरामीटर.
  • Starlark कोड, जिसमें रिपॉज़िटरी को लागू करने की जानकारी होती है.
  • किसी भी एनवायरमेंट वैरिएबल की वैल्यू, repository_rule के environ एट्रिब्यूट के साथ तय की जाती है. इन एनवायरमेंट वैरिएबल की वैल्यू को कमांड लाइन पर, --action_env फ़्लैग के साथ हार्ड-वायर किया जा सकता है. हालांकि, यह फ़्लैग बिल्ड के हर ऐक्शन को अमान्य कर देगा.
  • read(), execute() और repository_ctx के मिलते-जुलते तरीकों को पास की गई किसी भी फ़ाइल का कॉन्टेंट, जिसे लेबल से बताया जाता है (उदाहरण के लिए, //mypkg:label.txt, लेकिन mypkg/label.txt नहीं)
  • bazel sync शुरू होने पर.

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

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

    ऐसे मामलों में, डेटा स्टोर करने की गैर-स्थानीय जगहों को फिर से नहीं लाया जाता. ऐसा इसलिए है, क्योंकि इन रिपॉज़िटरी को नेटवर्क से कनेक्ट करने या अन्य तरीकों से इस्तेमाल करने पर ज़्यादा खर्च आता है.

लागू करने की सुविधा को रीस्टार्ट करना

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

बाहरी रिपॉज़िटरी को फिर से फ़ेच करने के लिए मजबूर करना

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

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

उदाहरण

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

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

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