Bazel में लॉकफ़ाइल की सुविधा की मदद से, किसी प्रोजेक्ट के लिए ज़रूरी सॉफ़्टवेयर लाइब्रेरी या पैकेज के खास वर्शन या डिपेंडेंसी रिकॉर्ड की जा सकती हैं. यह कुकी, मॉड्यूल रिज़ॉल्यूशन और एक्सटेंशन के आकलन के नतीजे को सेव करके ऐसा करती है. लॉकफ़ाइल, दोबारा बनाए जा सकने वाले बिल्ड को बढ़ावा देती है. इससे डेवलपमेंट एनवायरमेंट में एक जैसा माहौल बना रहता है. इसके अलावा, यह बिल्ड की परफ़ॉर्मेंस को बेहतर बनाता है. ऐसा इसलिए, क्योंकि जब प्रोजेक्ट की डिपेंडेंसी में कोई बदलाव नहीं होता है, तो Bazel को रिज़ॉल्यूशन प्रोसेस को स्किप करने की अनुमति मिलती है. इसके अलावा, लॉकफ़ाइल की मदद से, बाहरी लाइब्रेरी में अचानक होने वाले अपडेट या बड़े बदलावों को रोका जा सकता है. इससे, गड़बड़ियां होने का खतरा कम हो जाता है.
Lockfile Generation
लॉकफ़ाइल, वर्कस्पेस रूट में MODULE.bazel.lock नाम से जनरेट होती है. इसे बिल्ड प्रोसेस के दौरान बनाया या अपडेट किया जाता है. खास तौर पर, मॉड्यूल रिज़ॉल्यूशन और एक्सटेंशन के आकलन के बाद. लॉकफ़ाइल, प्रोजेक्ट की मौजूदा स्थिति को कैप्चर करती है. इसमें MODULE फ़ाइल, फ़्लैग, ओवरराइड, और काम की अन्य जानकारी शामिल होती है. अहम बात यह है कि इसमें सिर्फ़ वे डिपेंडेंसी शामिल होती हैं जो बिल्ड के मौजूदा इनवोकेशन में शामिल हैं.
जब प्रोजेक्ट में ऐसे बदलाव होते हैं जिनसे उसकी डिपेंडेंसी पर असर पड़ता है, तो लॉकफ़ाइल अपने-आप अपडेट हो जाती है. इससे नई स्थिति दिखती है. इससे यह पक्का होता है कि लॉकफ़ाइल, मौजूदा बिल्ड के लिए ज़रूरी डिपेंडेंसी के खास सेट पर फ़ोकस करती है. साथ ही, प्रोजेक्ट की हल की गई डिपेंडेंसी के बारे में सटीक जानकारी देती है.
लॉकफ़ाइल का इस्तेमाल
लॉकफ़ाइल को फ़्लैग --lockfile_mode से कंट्रोल किया जा सकता है. इससे, प्रोजेक्ट की स्थिति लॉकफ़ाइल से अलग होने पर Bazel के व्यवहार को पसंद के मुताबिक बनाया जा सकता है. ये मोड उपलब्ध हैं:
update(डिफ़ॉल्ट): अगर प्रोजेक्ट की स्थिति, लॉकफ़ाइल से मेल खाती है, तो लॉकफ़ाइल से तुरंत रिज़ॉल्यूशन का नतीजा मिलता है. ऐसा न होने पर, रिज़ॉल्यूशन लागू किया जाता है और लॉकफ़ाइल को अपडेट किया जाता है, ताकि मौजूदा स्थिति दिख सके.error: अगर प्रोजेक्ट की स्थिति, लॉकफ़ाइल से मेल खाती है, तो लॉकफ़ाइल से रिज़ॉल्यूशन का नतीजा मिलता है. ऐसा न होने पर, Bazel एक गड़बड़ी का मैसेज दिखाता है. इससे पता चलता है कि प्रोजेक्ट और लॉकफ़ाइल में अंतर है. यह मोड खास तौर पर तब मददगार होता है, जब आपको यह पक्का करना हो कि आपके प्रोजेक्ट की डिपेंडेंसी में कोई बदलाव न हो. साथ ही, किसी भी तरह के अंतर को गड़बड़ी के तौर पर माना जाए.off: लॉकफ़ाइल की जांच नहीं की गई है.
लॉकफ़ाइल के फ़ायदे
लॉकफ़ाइल के कई फ़ायदे हैं और इसे अलग-अलग तरीकों से इस्तेमाल किया जा सकता है:
फिर से बनाए जा सकने वाले बिल्ड. सॉफ़्टवेयर लाइब्रेरी के खास वर्शन या डिपेंडेंसी कैप्चर करके, लॉकफ़ाइल यह पक्का करती है कि अलग-अलग एनवायरमेंट और समय के साथ बिल्ड को फिर से बनाया जा सके. डेवलपर अपने प्रोजेक्ट बनाते समय, लगातार और अनुमान के मुताबिक नतीजे पा सकते हैं.
बेहतर रिज़ॉल्यूशन स्किप करना. लॉकफ़ाइल की मदद से, Bazel को रिज़ॉल्यूशन प्रोसेस को स्किप करने की सुविधा मिलती है. ऐसा तब होता है, जब पिछले बिल्ड के बाद से प्रोजेक्ट की डिपेंडेंसी में कोई बदलाव न हुआ हो. इससे, बिल्ड की प्रोसेस ज़्यादा तेज़ी से पूरी होती है. खास तौर पर, उन स्थितियों में जहां रिज़ॉल्यूशन में ज़्यादा समय लग सकता है.
स्थिरता और जोखिम कम करना. लॉकफ़ाइल, बाहरी लाइब्रेरी में अचानक होने वाले अपडेट या बड़े बदलावों को रोककर, स्थिरता बनाए रखने में मदद करती है. डिपेंडेंसी को किसी खास वर्शन पर लॉक करने से, ऐसे अपडेट की वजह से गड़बड़ियां होने का खतरा कम हो जाता है जो काम नहीं करते या जिनकी जांच नहीं की गई है.
लॉकफ़ाइल का कॉन्टेंट
लॉकफ़ाइल में, यह तय करने के लिए ज़रूरी जानकारी होती है कि प्रोजेक्ट की स्थिति में बदलाव हुआ है या नहीं. इसमें प्रोजेक्ट को मौजूदा स्थिति में बनाने का नतीजा भी शामिल होता है. लॉकफ़ाइल में दो मुख्य हिस्से होते हैं:
- मॉड्यूल रिज़ॉल्यूशन के इनपुट, जैसे कि
moduleFileHash,flags, औरlocalOverrideHashes. साथ ही, रिज़ॉल्यूशन का आउटपुट, जो किmoduleDepGraphहै. - हर मॉड्यूल एक्सटेंशन के लिए, लॉकफ़ाइल में ऐसे इनपुट शामिल होते हैं जो इसे प्रभावित करते हैं. इन्हें
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 मैप से हटा दिया जाता है.
इस मैप में मौजूद हर एंट्री, इस्तेमाल किए गए एक्सटेंशन से मेल खाती है. इसकी पहचान, इसमें मौजूद फ़ाइल और नाम से की जाती है. हर एंट्री की वैल्यू में, उस एक्सटेंशन से जुड़ी काम की जानकारी होती है:
transitiveDigestएक्सटेंशन को लागू करने और इसकी ट्रांज़िटिव .bzl फ़ाइलों का डाइजेस्ट है.generatedRepoSpecs, मौजूदा इनपुट के साथ उस एक्सटेंशन को चलाने का नतीजा है.
एक्सटेंशन के नतीजों पर असर डालने वाली एक और वजह, उनका इस्तेमाल है. हालांकि, इनका इस्तेमाल लॉकफ़ाइल में सेव नहीं किया जाता. फिर भी, एक्सटेंशन की मौजूदा स्थिति की तुलना लॉकफ़ाइल में मौजूद स्थिति से करते समय, इनके इस्तेमाल को ध्यान में रखा जाता है.
सबसे सही तरीके
लॉकफ़ाइल की सुविधा का ज़्यादा से ज़्यादा फ़ायदा पाने के लिए, इन सबसे सही तरीकों को अपनाएं:
प्रोजेक्ट की डिपेंडेंसी या कॉन्फ़िगरेशन में हुए बदलावों को दिखाने के लिए, लॉकफ़ाइल को समय-समय पर अपडेट करें. इससे यह पक्का होता है कि बाद के बिल्ड, डिपेंडेंसी के सबसे अप-टू-डेट और सटीक सेट पर आधारित हों.
साथ मिलकर काम करने के लिए, वर्शन कंट्रोल में लॉकफ़ाइल शामिल करें. इससे यह पक्का किया जा सकेगा कि टीम के सभी सदस्यों के पास एक ही लॉकफ़ाइल का ऐक्सेस हो. इससे पूरे प्रोजेक्ट में डेवलपमेंट एनवायरमेंट एक जैसा रहेगा.
इन सबसे सही तरीकों को अपनाकर, Bazel में लॉकफ़ाइल सुविधा का बेहतर तरीके से इस्तेमाल किया जा सकता है. इससे सॉफ़्टवेयर डेवलपमेंट के वर्कफ़्लो को ज़्यादा असरदार, भरोसेमंद, और सहयोगी बनाया जा सकता है.