आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम

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

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

आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम में, सिस्टम के तय किए गए कुछ टास्क होते हैं जिन्हें इंजीनियर सीमित तौर पर कॉन्फ़िगर कर सकते हैं. इंजीनियर अब भी सिस्टम को क्या बनाना चाहते हैं, लेकिन बिल्ड सिस्टम तय करता है कि इसे कैसे बनाना है. टास्क पर आधारित बिल्ड सिस्टम की तरह ही, Basel जैसे आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम में भी बिल्ड फ़ाइलें होंगी. हालांकि, इन बिल्ड फ़ाइलों का कॉन्टेंट काफ़ी अलग होगा. बेज़ल में बिल्ड फ़ाइल, ट्यूरिंग-कंपलीट स्क्रिप्टिंग भाषा में ज़रूरी निर्देशों का हिस्सा होती है, जिसमें आउटपुट तैयार करने के तरीके के बारे में बताया जाता है. बिल्डफ़ाइल, डिक्लेरेटिव मैनिफ़ेस्ट होती है. इसमें, तैयार करने के लिए आर्टफ़ैक्ट का सेट, उनकी डिपेंडेंसी, और उन विकल्पों के सीमित सेट की जानकारी होती है जो उन्हें बनाने के तरीके पर असर डालते हैं. जब इंजीनियर bazel को कमांड लाइन पर चलाते हैं, तो वे बनाने के लिए टारगेट का एक सेट (नया) तय करते हैं. इसके बाद, कंपाइलेशन चरणों (कैसे) को कॉन्फ़िगर करने, चलाने, और शेड्यूल करने के लिए बैज की ज़िम्मेदारी होती है. बिल्ड सिस्टम के पास अब यह कंट्रोल करने का पूरा कंट्रोल है कि कौनसे टूल कब चलाएं. इससे इस बात की मज़बूत गारंटी मिलती है कि यह सटीक होने के साथ-साथ, बेहतर तरीके से काम करने में भी मदद कर सकता है.

फ़ंक्शनल नज़रिया

आर्टफ़ैक्ट-आधारित बिल्ड सिस्टम और फ़ंक्शनल प्रोग्रामिंग के बीच तुलना करना आसान है. ट्रेडिशनल इंपेरेटिव प्रोग्रामिंग लैंग्वेज (जैसे, Java, C, और Python) एक के बाद एक लागू किए जाने वाले स्टेटमेंट की सूचियां तय करती है. उसी तरह, टास्क पर आधारित बिल्ड सिस्टम की मदद से प्रोग्रामर, लागू करने के लिए कई चरण तय कर सकते हैं. इसके अलावा, फ़ंक्शनल प्रोग्रामिंग लैंग्वेज (जैसे कि हास्केल और एमएल) को गणित के समीकरणों की तरह बनाया जाता है. फ़ंक्शनल भाषाओं में प्रोग्रामर, कंप्यूटेशन के बारे में बताता है. हालांकि, यह इस बात की जानकारी देता है कि कंपाइलर में यह कंप्यूटेशन कब और कैसे किया जाएगा.

यह आर्टफ़ैक्ट वाले बिल्ड सिस्टम में मेनिफ़ेस्ट के बारे में बताने और सिस्टम को बिल्ड को एक्ज़ीक्यूट करने का तरीका बताने पर फ़ोकस करता है. फ़ंक्शनल प्रोग्रामिंग का इस्तेमाल करके, कई समस्याओं को आसानी से नहीं समझा जा सकता. हालांकि, जिन समस्याओं को इससे बहुत ज़्यादा फ़ायदा मिलता है वे हैं: भाषा के हिसाब से, अक्सर ऐसे प्रोग्राम को छोटे-छोटे हिस्सों में बांटा जा सकता है और उनके सही होने की मज़बूत गारंटी दी जा सकती है. फ़ंक्शनल प्रोग्रामिंग का इस्तेमाल करके, आसानी से वे समस्याएं आती हैं जिनमें कई नियमों या फ़ंक्शन का इस्तेमाल करके, डेटा के एक हिस्से को दूसरे में बदलना होता है. बिल्ड सिस्टम ठीक वैसा ही है, जैसा कि पूरा सिस्टम एक गणितीय फ़ंक्शन है जो सोर्स फ़ाइलों (और कंपाइलर जैसे टूल) को इनपुट के तौर पर लेता है और आउटपुट के तौर पर बाइनरी बनाता है. इसलिए, इसमें हैरानी की कोई बात नहीं है कि यह फ़ंक्शन, फ़ंक्शनल प्रोग्रामिंग के सिद्धांतों के हिसाब से एक बिल्ड सिस्टम बनाने में कामयाब होता है.

आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम को समझना

Google का बिल्ड सिस्टम, Blaze पहला आर्टफ़ैक्ट-आधारित बिल्ड सिस्टम था. Baze, Baze का ओपन सोर्स वर्शन है.

बेज़ल में एक बिल्डफ़ाइल (इसे आम तौर पर BUILD कहा जाता है) कैसी दिखती है:

java_binary(
    name = "MyBinary",
    srcs = ["MyBinary.java"],
    deps = [
        ":mylib",
    ],
)
java_library(
    name = "mylib",
    srcs = ["MyLibrary.java", "MyHelper.java"],
    visibility = ["//java/com/example/myproduct:__subpackages__"],
    deps = [
        "//java/com/example/common",
        "//java/com/example/myproduct/otherlib",
    ],
)

Baze में, BUILD फ़ाइलें टारगेट तय करती हैं—यहां दो तरह के टारगेट java_binary और java_library हैं. हर टारगेट एक आर्टफ़ैक्ट से जुड़ा होता है, जिसे सिस्टम बनाया जा सकता है: बाइनरी टारगेट, ऐसे बाइनरी बनाते हैं जिन्हें सीधे तौर पर लागू किया जा सकता है. वहीं, लाइब्रेरी टारगेट ऐसी लाइब्रेरी तैयार करते हैं जिनका इस्तेमाल बाइनरी या अन्य लाइब्रेरी में किया जा सकता है. हर टारगेट में:

  • name: कमांड लाइन और दूसरे टारगेट में टारगेट का रेफ़रंस कैसे दिया जाता है
  • srcs: टारगेट के लिए आर्टफ़ैक्ट बनाने के लिए, इकट्ठा की जाने वाली सोर्स फ़ाइलें
  • deps: अन्य ऐसे टारगेट जिन्हें इस टारगेट से पहले बनाया जाना चाहिए और जिन्हें इससे लिंक किया जाना चाहिए

डिपेंडेंसी या तो एक ही पैकेज में हो सकती हैं (जैसे कि MyBinary की :mylib पर निर्भरता) या उसी सोर्स हैरारकी में मौजूद किसी दूसरे पैकेज (जैसे कि //java/com/example/common पर mylib की डिपेंडेंसी).

टास्क पर आधारित बिल्ड सिस्टम की तरह ही, बेज़ल के कमांड-लाइन टूल का इस्तेमाल करके बिल्ड किया जा सकता है. MyBinary टारगेट बनाने के लिए, आप bazel build :MyBinary चलाएं. किसी क्लीन रिपॉज़िटरी में पहली बार यह निर्देश डालने के बाद, Baze:

  1. आर्टफ़ैक्ट में डिपेंडेंसी का ग्राफ़ बनाने के लिए, यह फ़ाइल फ़ोल्डर की हर BUILD फ़ाइल को पार्स करता है.
  2. यह MyBinary की ट्रांज़िटिव डिपेंडेंसी का पता लगाने के लिए ग्राफ़ का इस्तेमाल करता है. इसका मतलब है कि यह हर वह टारगेट है जिस पर MyBinary निर्भर करता है और वे हर टारगेट पर बार-बार निर्भर करते हैं.
  3. इनमें से हर डिपेंडेंसी को क्रम में बनाता है. Baज़ल, हर ऐसा टारगेट बनाकर शुरुआत करता है जिस पर कोई और डिपेंडेंसी नहीं है. साथ ही, यह ट्रैक करता है कि हर टारगेट के लिए अब भी कौनसी डिपेंडेंसी बनाने की ज़रूरत है. जैसे ही टारगेट की सभी डिपेंडेंसी बन जाती हैं, बेज़ल उस टारगेट को बनाना शुरू कर देता है. यह प्रोसेस तब तक जारी रहती है, जब तक MyBinary की सभी ट्रांज़िटिव डिपेंडेंसी नहीं बन जाती.
  4. यह MyBinary को एक्ज़ीक्यूट करने लायक फ़ाइनल बाइनरी बनाने के लिए बनाता है, जो तीसरे चरण में बनाई गई सभी डिपेंडेंसी से लिंक होती है.

बुनियादी तौर पर, ऐसा नहीं लग सकता कि यहां जो हो रहा है उससे बहुत अलग है. असल में, आखिरी नतीजा एक ही बाइनरी होता है. इसे बनाने की प्रक्रिया में, कई चरणों का विश्लेषण करके, उनमें डिपेंडेंसी का पता लगाना और फिर उन चरणों को क्रम से चलाना शामिल होता है. हालांकि, कुछ बड़े अंतर भी हैं. पहला चरण 3 में आता है: क्योंकि बेज़ल जानते हैं कि हर टारगेट सिर्फ़ एक Java लाइब्रेरी बनाती है, इसलिए यह जानता है कि इसे आर्बिट्रेरी उपयोगकर्ता-तय स्क्रिप्ट के बजाय Java कंपाइलर चलाना होगा, ताकि उसे पता चल जाए कि इन चरणों को साथ-साथ चलाना सुरक्षित है. इससे मल्टीकोर मशीन पर एक-एक करके टारगेट करने वालों की तुलना में परफ़ॉर्मेंस में बहुत ज़्यादा सुधार हो सकता है. यह सिर्फ़ इसलिए मुमकिन है, क्योंकि आर्टफ़ैक्ट पर आधारित अप्रोच, बिल्ड सिस्टम को उसकी परफ़ॉर्मेंस की रणनीति की ज़िम्मेदारी दे देती है, ताकि वह समानता की गारंटी दे सके.

हालांकि, इससे होने वाले फ़ायदों को समानता के साथ-साथ और भी ज़्यादा फ़ायदा मिल सकता है. अगली बार यह तरीका हमें तब साफ़ तौर पर दिखता है, जब डेवलपर दूसरी बार bazel build :MyBinary टाइप करता है और कोई बदलाव नहीं करता है: गेम एक सेकंड से भी कम समय में ऐप्लिकेशन से बाहर निकल जाता है और यह मैसेज भेजता है कि टारगेट अप-टू-डेट है. ऐसा, फ़ंक्शनल प्रोग्रामिंग मॉडल की वजह से हो सकता है, जिसके बारे में हमने पहले बात की थी. Ba वहीं, इस बात को अच्छी तरह जानता है कि किसी भी टारगेट के लिए सिर्फ़ Java कंपाइलर चलाया जा सकता है. साथ ही, उसे पता है कि Java कंपाइलर का आउटपुट सिर्फ़ उसके इनपुट पर निर्भर करता है. जब तक इनपुट में बदलाव नहीं होता, तब तक आउटपुट का फिर से इस्तेमाल किया जा सकता है. यह विश्लेषण हर लेवल पर काम करता है. अगर MyBinary.java में बदलाव किया जाता है, तो Baज़ल, MyBinary को फिर से बनाना चाहता है, लेकिन mylib का फिर से इस्तेमाल करता है. अगर //java/com/example/common के लिए सोर्स फ़ाइल बदल जाती है, तो Baze उस लाइब्रेरी, mylib, और MyBinary को फिर से बनाना जानता है, लेकिन //java/com/example/myproduct/otherlib का दोबारा इस्तेमाल करता है. Basel को हर कदम पर चलाए जाने वाले टूल के गुणों के बारे में पता है, इसलिए वह हर बार आर्टफ़ैक्ट के कम से कम सेट को ही फिर से बना सकता है. साथ ही, यह इस बात की गारंटी देता है कि वह पुराने सामान नहीं बनाएगा.

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

बेज़ेल की अन्य शानदार ट्रिक

आर्टफ़ैक्ट पर आधारित बिल्ड सिस्टम, समानता और फिर से इस्तेमाल करने की समस्याओं को बुनियादी तौर पर हल करते हैं. ये समस्याएं, टास्क पर आधारित बिल्ड सिस्टम में मौजूद हैं. हालांकि, ऐसी कुछ समस्याएं अब भी थीं जिन पर हम ध्यान नहीं दे पाए. बेज़ल के पास इन सभी चीज़ों को हल करने का चतुराई है और आगे बढ़ने से पहले हमें इन पर चर्चा करनी चाहिए.

डिपेंडेंसी के तौर पर टूल

हमने पहले एक समस्या का सामना किया. यह समस्या हमारी मशीन पर इंस्टॉल किए गए टूल पर निर्भर करती थी. टूल के अलग-अलग वर्शन या जगहों की वजह से, अलग-अलग सिस्टम पर बिल्ड बनाना मुश्किल हो सकता है. यह समस्या तब और भी मुश्किल हो जाती है जब आपका प्रोजेक्ट उन भाषाओं का इस्तेमाल करता है जिनमें अलग-अलग टूल की ज़रूरत होती है कि उन्हें किस प्लैटफ़ॉर्म पर बनाया जा रहा है या किस प्लैटफ़ॉर्म के लिए कंपाइल किया जा रहा है (जैसे कि Windows बनाम Linux). उनमें से हर प्लैटफ़ॉर्म पर वही काम करने के लिए अलग-अलग टूल की ज़रूरत पड़ती है.

Basel ने हर टारगेट के लिए टूल को डिपेंडेंसी के तौर पर इस्तेमाल करके, इस समस्या के पहले हिस्से को हल किया. फ़ाइल फ़ोल्डर का हर java_library, Java कंपाइलर पर निर्भर करता है, जो जाने-माने कंपाइलर को डिफ़ॉल्ट रूप से सेट करता है. जब भी Baज़ल, java_library बनाता है, तब यह जांच करके यह पक्का करता है कि बताया गया कंपाइलर किसी जानी-पहचानी जगह पर उपलब्ध है या नहीं. किसी अन्य डिपेंडेंसी की तरह ही, अगर Java कंपाइलर बदलता है, तो उस पर निर्भर हर आर्टफ़ैक्ट को फिर से बनाया जाता है.

Basel ने बिल्ड कॉन्फ़िगरेशन सेट करके, समस्या के दूसरे हिस्से, यानी प्लैटफ़ॉर्म की इंडिपेंडेंस से जुड़ी समस्या को हल किया. सीधे तौर पर टूल के हिसाब से टारगेट के बजाय, वे कॉन्फ़िगरेशन के टाइप पर निर्भर होते हैं:

  • होस्ट कॉन्फ़िगरेशन: बिल्ड के दौरान काम करने वाले टूल बनाना
  • टारगेट कॉन्फ़िगरेशन: उस बाइनरी को बनाना जिसका आपने असल में अनुरोध किया था

बिल्ड सिस्टम को बढ़ाना

बेज़ल कई लोकप्रिय प्रोग्रामिंग भाषाओं के लिए टारगेट उपलब्ध है, लेकिन इंजीनियर हमेशा कुछ और करना चाहेंगे. टास्क-आधारित सिस्टम का एक फ़ायदा यह है कि वे किसी भी तरह की बिल्ड प्रोसेस को सपोर्ट कर सकते हैं. बेहतर यही होगा कि इसे आर्टफ़ैक्ट-आधारित बिल्ड सिस्टम में न दें. अच्छी बात यह है कि Basel का इस्तेमाल करने वाले टारगेट टाइप को, कस्टम नियम जोड़कर बढ़ाया जा सकता है.

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

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

एनवायरमेंट को आइसोलेट करना

कार्रवाइयों से ऐसा लगता है कि उनमें भी वही समस्याएं हो सकती हैं जो अन्य सिस्टम के टास्क में हों. क्या अब भी ऐसी कार्रवाइयां लिखने में मदद नहीं मिलती जो एक ही फ़ाइल पर लिखें और एक-दूसरे में टकराव पैदा करें? दरअसल, बेज़ल इन समस्याओं को सैंडबॉक्सिंग का इस्तेमाल करके नामुमकिन बना देता है. काम करने वाले सिस्टम पर, हर कार्रवाई को फ़ाइल सिस्टम सैंडबॉक्स के ज़रिए अलग-अलग कार्रवाई से अलग किया जाता है. हर कार्रवाई में फ़ाइल सिस्टम का सिर्फ़ एक सीमित व्यू हो सकता है. इसमें वे इनपुट शामिल होते हैं जिनके बारे में उसने एलान किया है और जिनसे वह आउटपुट जनरेट करता है. इसे Linux पर LXC जैसे सिस्टम से लागू किया जाता है. यह Docker के पीछे काम करने वाली टेक्नोलॉजी है. इसका मतलब यह है कि कार्रवाइयों का एक-दूसरे के साथ विरोधाभास होना नामुमकिन है, क्योंकि वे ऐसी फ़ाइलें पढ़ नहीं सकते जिनके बारे में वे एलान नहीं करते हैं. साथ ही, जिन फ़ाइलों को उन्होंने लिखा है, लेकिन उनका एलान नहीं किया है उन्हें कार्रवाई के पूरा होने पर निकाल दिया जाएगा. बेज़ल, नेटवर्क के ज़रिए बातचीत करने से जुड़ी कार्रवाइयों को रोकने के लिए, सैंडबॉक्स का भी इस्तेमाल करते हैं.

बाहरी डिपेंडेंसी को डिटरमिनिस्टिक बनाना

अब भी एक समस्या बाकी है: बिल्ड सिस्टम को अक्सर बाहरी सोर्स से डिपेंडेंसी (चाहे टूल या लाइब्रेरी) डाउनलोड करनी पड़े, न कि उन्हें सीधे बनाना. इसे उदाहरण में, @com_google_common_guava_guava//jar डिपेंडेंसी के ज़रिए देखा जा सकता है, जो Maven से JAR फ़ाइल डाउनलोड करता है.

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

बुनियादी समस्या यह है कि हम चाहते हैं कि बिल्ड सिस्टम इन फ़ाइलों को जाने डिपेंडेंसी अपडेट करने का फ़ैसला सोच-समझकर लेना चाहिए. हालांकि, इस विकल्प को एक बार खुद मैनेज करने वाले इंजीनियर या सिस्टम की ओर से अपने-आप मैनेज करने के बजाय, एक ही जगह पर चुनना चाहिए. ऐसा इसलिए है, क्योंकि “Live at Head” मॉडल के साथ भी हम चाहते हैं कि बिल्ड डिटरमिनिस्टिक हो. इसका मतलब है कि अगर आपने पिछले हफ़्ते किए गए लेन-देन को चेक किया है, तो आपको अपनी डिपेंडेंसी वैसी ही दिखेंगी जैसी वे आज हैं, जैसी नहीं हैं.

Babel और कुछ अन्य बिल्ड सिस्टम इस समस्या को हल करते हैं. इसके लिए, Workspace के उपयोगकर्ताओं को एक ऐसी मेनिफ़ेस्ट फ़ाइल की ज़रूरत होती है जिसमें, उनके संगठन से बाहर होने वाली हर डिपेंडेंसी के लिए क्रिप्टोग्राफ़िक हैश की सूची मौजूद हो. हैश, सोर्स कंट्रोल में पूरी फ़ाइल की जांच किए बिना फ़ाइल को खास तरीके से दिखाने का एक छोटा तरीका है. जब भी किसी फ़ाइल फ़ोल्डर से नई बाहरी डिपेंडेंसी का रेफ़रंस दिया जाता है, तो उस डिपेंडेंसी के हैश को मेनिफ़ेस्ट में मैन्युअल तरीके से या अपने-आप जोड़ दिया जाता है. जब Basel कोई बिल्ड चलाता है, तब वह अपनी कैश मेमोरी में सेव की गई डिपेंडेंसी के असल हैश को मेनिफ़ेस्ट में तय किए गए हैश के साथ जांचता है. साथ ही, अगर हैश अलग हो, तो फ़ाइल को फिर से डाउनलोड करता है.

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

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