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