Bazel लॉकफ़ाइल

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

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

लॉकफ़ाइल जनरेशन

Lockfile को फ़ाइल फ़ोल्डर के रूट में, MODULE.bazel.lock नाम से जनरेट किया जाता है. इसे बिल्ड प्रोसेस के दौरान बनाया या अपडेट किया जाता है. खास तौर पर, मॉड्यूल रिज़ॉल्यूशन और एक्सटेंशन की जांच के बाद. लॉकफ़ाइल, प्रोजेक्ट की मौजूदा स्थिति कैप्चर करती है. इसमें MODULE फ़ाइल, फ़्लैग, ओवरराइड, और अन्य ज़रूरी जानकारी शामिल होती है. अहम बात यह है कि इसमें सिर्फ़ वे डिपेंडेंसी शामिल होती हैं जो बिल्ड के मौजूदा इनवॉइस में शामिल होती हैं.

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

Lockfile का इस्तेमाल

प्रोजेक्ट की स्थिति और उसकी लॉकफ़ाइल में अंतर होने पर, लॉकफ़ाइल को फ़्लैग --lockfile_mode की मदद से कंट्रोल किया जा सकता है. इनमें ये मोड उपलब्ध हैं:

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

लॉक फ़ाइल के फ़ायदे

लॉकफ़ाइल के कई फ़ायदे हैं और इसे अलग-अलग तरीकों से इस्तेमाल किया जा सकता है:

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

  • समस्या को बेहतर तरीके से स्किप करना. अगर पिछले बिल्ड के बाद से प्रोजेक्ट डिपेंडेंसी में कोई बदलाव नहीं किया गया है, तो lockfile की मदद से बेज़ल, रिज़ॉल्यूशन की प्रोसेस को स्किप कर सकते हैं. इससे बिल्ड की क्षमता में काफ़ी सुधार होता है, खास तौर पर ऐसी स्थितियों में, जिनके समाधान में समय लगता है.

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

लॉकफ़ाइल कॉन्टेंट

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

  1. मॉड्यूल रिज़ॉल्यूशन के इनपुट, जैसे कि moduleFileHash, flags, और localOverrideHashes. साथ ही, रिज़ॉल्यूशन का आउटपुट, जो कि moduleDepGraph है.
  2. हर मॉड्यूल एक्सटेंशन के लिए, lockfile में ऐसे इनपुट शामिल होते हैं जो उस पर असर डालते हैं. इन्हें transitiveDigest में दिखाया जाता है. साथ ही, उस एक्सटेंशन को चलाने का आउटपुट, जिसे generatedRepoSpecs कहा जाता है

यहां एक उदाहरण दिया गया है, जिसमें लॉकफ़ाइल के स्ट्रक्चर के साथ-साथ हर सेक्शन की पूरी जानकारी दी गई है:

{
  "lockFileVersion": 1,
  "moduleFileHash": "b0f47b98a67ee15f9.......8dff8721c66b721e370",
  "flags": {
    "cmdRegistries": [
      "https://bcr.bazel.build/"
    ],
    "cmdModuleOverrides": {},
    "allowedYankedVersions": [],
    "envVarAllowedYankedVersions": "",
    "ignoreDevDependency": false,
    "directDependenciesMode": "WARNING",
    "compatibilityMode": "ERROR"
  },
  "localOverrideHashes": {
    "bazel_tools": "b5ae1fa37632140aff8.......15c6fe84a1231d6af9"
  },
  "moduleDepGraph": {
    "<root>": {
      "name": "",
      "version": "",
      "executionPlatformsToRegister": [],
      "toolchainsToRegister": [],
      "extensionUsages": [
        {
          "extensionBzlFile": "extension.bzl",
          "extensionName": "lockfile_ext"
        }
      ],
      ...
    }
  },
  "moduleExtensions": {
    "//:extension.bzl%lockfile_ext": {
      "transitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
      "generatedRepoSpecs": {
        "hello": {
          "bzlFile": "@@//:extension.bzl",
          ...
        }
      }
    }
  }
}

मॉड्यूल फ़ाइल हैश

moduleFileHash, MODULE.bazel फ़ाइल के कॉन्टेंट का हैश दिखाता है. अगर इस फ़ाइल में कोई बदलाव होता है, तो हैश वैल्यू अलग-अलग होती है.

झंडे

Flags ऑब्जेक्ट में वे सभी फ़्लैग सेव किए जाते हैं जो रिज़ॉल्यूशन के नतीजे पर असर डाल सकते हैं.

लोकल ओवरराइड हैश

अगर रूट मॉड्यूल में local_path_overrides शामिल है, तो यह सेक्शन MODULE.bazel फ़ाइल के हैश को लोकल रिपॉज़िटरी में सेव करता है. इससे इस डिपेंडेंसी में बदलावों को ट्रैक किया जा सकता है.

मॉड्यूल डिपेंडेंसी ग्राफ़

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

मॉड्यूल एक्सटेंशन

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

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

  1. transitiveDigest, एक्सटेंशन लागू करने का डाइजेस्ट और इसकी ट्रांज़िव .bzl फ़ाइलें.
  2. generatedRepoSpecs, उस एक्सटेंशन को मौजूदा इनपुट के साथ चलाने का नतीजा है.

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

सबसे सही तरीके

लॉकफ़ाइल की सुविधा का ज़्यादा से ज़्यादा फ़ायदा पाने के लिए, ये सबसे सही तरीके अपनाएं:

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

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

इन सबसे सही तरीकों को अपनाकर, Basel में lockfile की सुविधा का असरदार तरीके से इस्तेमाल किया जा सकता है. इससे, ज़्यादा कुशल, भरोसेमंद, और सहयोगी सॉफ़्टवेयर डेवलपमेंट वर्कफ़्लो मिलता है.