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