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