डिपेंडेंसी मैनेजमेंट

किसी समस्या की शिकायत करें सोर्स देखें रात · 7.4 को अपनाएं. 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

मॉड्यूल और डिपेंडेंसी से जुड़ी समस्याओं को हल करना

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

ज़्यादा जानकारी वाले मॉड्यूल और 1:1:1 नियम का इस्तेमाल करना

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

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

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

छोटे बिल्ड टारगेट के फ़ायदे, बड़े पैमाने पर दिखने लगते हैं. ऐसा इसलिए होता है, क्योंकि इससे डिस्ट्रिब्यूट किए गए बिल्ड तेज़ी से बनते हैं और टारगेट को फिर से बनाने की ज़रूरत कम पड़ती है. जब जांच के नतीजे और भी बेहतर हो जाते हैं, तो ज़्यादा सटीक टारगेट का मतलब है कि बिल्ड सिस्टम परीक्षणों का केवल एक सीमित सबसेट चलाना, जो किसी बदलें. Google, छोटे टारगेट का इस्तेमाल करने के सिस्टम के फ़ायदों में विश्वास करता है. इसलिए, हमने BUILD फ़ाइलों को अपने-आप मैनेज करने के लिए टूल बनाने में निवेश किया है, ताकि डेवलपर पर बोझ न पड़े. इससे, इस समस्या को कम करने में मदद मिली है.

buildifier और buildozer जैसे कुछ टूल इसके साथ उपलब्ध हैं बेज़ल इन द buildtools डायरेक्ट्री.

मॉड्यूल दिखने की संभावना कम करना

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

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

डिपेंडेंसी मैनेज करना

मॉड्यूल ऐसा होना चाहिए कि वे एक-दूसरे को रेफ़र कर सकें. कोडबेस को छोटे-छोटे मॉड्यूल में बांटने का नुकसान यह है कि आपको उन मॉड्यूल के बीच डिपेंडेंसी मैनेज करनी पड़ती है. हालांकि, टूल की मदद से इसे ऑटोमेट किया जा सकता है. आम तौर पर, BUILD फ़ाइल में ज़्यादातर कॉन्टेंट, इन डिपेंडेंसी के बारे में जानकारी देने में खर्च होता है.

इंटरनल डिपेंडेंसी

किसी बड़े प्रोजेक्ट को छोटे-छोटे मॉड्यूल में बांटने पर, ज़्यादातर डिपेंडेंसी इंटरनल हो सकती हैं. इसका मतलब है कि वे उसी सोर्स रिपॉज़िटरी में तय किए गए और बनाए गए किसी दूसरे टारगेट पर होंगी. इंटरनल डिपेंडेंसी, बाहरी डिपेंडेंसी से इसमें अलग होती हैं: कि उन्हें पहले से बने आर्टफ़ैक्ट के तौर पर डाउनलोड करने के बजाय, सोर्स से बनाया गया हो बिल्ड रन करते समय. इसका मतलब यह भी है कि ऐसी किसी रणनीति के लिए “वर्शन” इंटरनल डिपेंडेंसी—टारगेट और उसकी सभी इंटरनल डिपेंडेंसी हमेशा डेटा स्टोर करने की जगह में उसी कमिट/रिविज़न के साथ बनाया जाता है. एक समस्या जो यह होनी चाहिए कि यह समझना ज़रूरी है कि आंतरिक डिपेंडेंसी का ध्यान रखते हुए कैसे काम किया जाए ट्रांज़िटिव डिपेंडेंसी (इमेज 1). मान लीजिए कि टारगेट A, टारगेट B पर निर्भर करता है. एक सामान्य लाइब्रेरी टारगेट C पर निर्भर होता है. क्या टारगेट A, टारगेट C में तय की गई क्लास का इस्तेमाल कर सकता है?

ट्रांज़िटिव डिपेंडेंसी

पहली इमेज. ट्रांज़िटिव डिपेंडेंसी

जहां तक बुनियादी टूल का सवाल है, इसमें कोई समस्या नहीं है; दोनों टारगेट A के बनने पर B और C को टारगेट A में जोड़ा जाएगा, इसलिए इनमें से कोई भी सिंबल C को A के तौर पर जाना जाता है. Bazel ने कई सालों तक इसकी अनुमति दी, लेकिन Google के बड़े होने के साथ ही, हमें समस्याएं दिखने लगीं. मान लें कि B को इस तरह रीफ़ैक्टर किया गया था कि अब उसे C पर निर्भर रहने की ज़रूरत नहीं है. अगर C पर B की डिपेंडेंसी हटा दी गई है, तो A और अन्य B पर निर्भरता के ज़रिए C का इस्तेमाल करने वाला टारगेट काम नहीं करेगा. असरदार तरीके से, टारगेट डिपेंडेंसी उसके सार्वजनिक अनुबंध का हिस्सा बन गई और उसे कभी भी बदल दिया गया है. इसका मतलब है कि समय के साथ डिपेंडेंसी इकट्ठा हो गईं और Google पर बिल्ड की प्रोसेस धीमी होने लगी.

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

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

बाहरी डिपेंडेंसी

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

अपने-आप बनाम मैन्युअल डिपेंडेंसी मैनेजमेंट

बिल्ड सिस्टम की मदद से, बाहरी डिपेंडेंसी के वर्शन मैनेज किए जा सकते हैं मैन्युअल तरीके से या अपने-आप. मैन्युअल तरीके से मैनेज किए जाने पर, बिल्डफ़ाइल में साफ़ तौर पर उस वर्शन की जानकारी होती है जिसे आर्टफ़ैक्ट रिपॉज़िटरी से डाउनलोड करना है. इसके लिए, अक्सर 1.1.4 जैसी सेमांटिक वर्शन स्ट्रिंग का इस्तेमाल किया जाता है. अपने-आप मैनेज होने पर, सोर्स फ़ाइल में इस्तेमाल किए जा सकने वाले वर्शन की सीमा तय की जाती है. साथ ही, बिल्ड सिस्टम हमेशा नया वर्शन डाउनलोड करता है. इसके लिए उदाहरण के लिए, Gradle, डिपेंडेंसी वर्शन को “1.+” के तौर पर इस्तेमाल करने की अनुमति देता है, ताकि यह तय किया जा सके कि कि किसी डिपेंडेंसी का कोई माइनर या पैच वर्शन तब तक स्वीकार किया जा सकता है, जब तक कि मेजर वर्शन 1 है.

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

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

एक वर्शन वाला नियम

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

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

ट्रांसिटिव बाहरी डिपेंडेंसी

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

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

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

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

बाहरी डिपेंडेंसी का इस्तेमाल करके, बिल्ड के नतीजों को कैश मेमोरी में सेव करना

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

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

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

बाहरी डिपेंडेंसी की सुरक्षा और विश्वसनीयता

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