Bazel लॉकफ़ाइल

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

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

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

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

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

लॉकफ़ाइल का इस्तेमाल

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

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

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

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

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

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

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

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

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

  1. मॉड्यूल रिज़ॉल्यूशन के इनपुट, जैसे कि moduleFileHash, flags, और localOverrideHashes के साथ-साथ, रिज़ॉल्यूशन का आउटपुट भी moduleDepGraph होता है.
  2. हर मॉड्यूल एक्सटेंशन के लिए, लॉकफ़ाइल में ऐसे इनपुट शामिल होते हैं जो इस पर असर डालते हैं. इन्हें 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": {
      "general": {
        "transitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      }
    },
    "//:extension.bzl%lockfile_ext2": {
      "os:macos": {
        "transitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      },
      "os:linux": {
        "transitiveDigest": "eWDzxG/aLsyY3Ubrto....+Jp4maQvEPxn0pLK=",
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      }
    }
  }
}

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

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

झंडे

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

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

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

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

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

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

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

अगर कोई एक्सटेंशन ऑपरेटिंग सिस्टम या आर्किटेक्चर प्रकार से अलग है, तो इस सेक्शन में सिर्फ़ एक "सामान्य" एंट्री होती है. नहीं तो, कई एंट्री शामिल की जाती हैं, जिनके नाम ओएस, आर्किटेक्चर या दोनों के नाम पर रखे जाते हैं. हर एंट्री को उन खास चीज़ों पर एक्सटेंशन के आकलन से जुड़े नतीजों के तौर पर शामिल किया जाता है.

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

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

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

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

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

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

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

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

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