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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

उदाहरण

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

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

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