बाहरी डिपेंडेंसी के बेहतर विषय

WORKSPACE में डिपेंडेंसी को शैडो करना

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

myproject/WORKSPACE

workspace(name = "myproject")

local_repository(
    name = "A",
    path = "../A",
)
local_repository(
    name = "B",
    path = "../B",
)

A/WORKSPACE

workspace(name = "A")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "testrunner",
    urls = ["https://github.com/testrunner/v1.zip"],
    sha256 = "...",
)

B/WORKSPACE

workspace(name = "B")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "testrunner",
    urls = ["https://github.com/testrunner/v2.zip"],
    sha256 = "..."
)

दोनों डिपेंडेंसी A और B, testrunner के अलग-अलग वर्शन पर निर्भर करती हैं. myproject में दोनों को शामिल करें. इसके लिए, myproject में उन्हें अलग-अलग नाम दें, ताकि कोई टकराव न हो:myproject/WORKSPACE

workspace(name = "myproject")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "testrunner-v1",
    urls = ["https://github.com/testrunner/v1.zip"],
    sha256 = "..."
)
http_archive(
    name = "testrunner-v2",
    urls = ["https://github.com/testrunner/v2.zip"],
    sha256 = "..."
)
local_repository(
    name = "A",
    path = "../A",
    repo_mapping = {"@testrunner" : "@testrunner-v1"}
)
local_repository(
    name = "B",
    path = "../B",
    repo_mapping = {"@testrunner" : "@testrunner-v2"}
)

इस तरीके का इस्तेमाल करके, डायमंड भी जोड़े जा सकते हैं. उदाहरण के लिए, अगर A और B की एक ही डिपेंडेंसी है, लेकिन उसे अलग-अलग नामों से कॉल किया जाता है, तो उन डिपेंडेंसी को myproject/WORKSPACE में शामिल करें.

कमांड लाइन से रिपॉज़िटरी को बदलना

कमांड लाइन से, डिक्लेयर की गई रिपॉज़िटरी को किसी लोकल रिपॉज़िटरी से बदलने के लिए, --override_repository फ़्लैग का इस्तेमाल करें. इस फ़्लैग का इस्तेमाल करने से, आपके सोर्स कोड में बदलाव किए बिना बाहरी रिपॉज़िटरी के कॉन्टेंट में बदलाव हो जाता है.

उदाहरण के लिए, @foo को स्थानीय डायरेक्ट्री /path/to/local/foo में बदलने के लिए, --override_repository=foo=/path/to/local/foo फ़्लैग पास करें.

इस्तेमाल के उदाहरणों में ये शामिल हैं:

  • समस्याओं को डीबग करना. उदाहरण के लिए, किसी http_archive रिपॉज़िटरी को किसी स्थानीय डायरेक्ट्री में बदलने के लिए, ताकि उसमें आसानी से बदलाव किए जा सकें.
  • वेंडरिंग. अगर आप ऐसे माहौल में हैं जहां नेटवर्क कॉल नहीं किए जा सकते, तो नेटवर्क पर आधारित रिपॉज़िटरी के नियमों को बदलकर, स्थानीय डायरेक्ट्री की ओर पॉइंट करें.

प्रॉक्सी का इस्तेमाल करना

Bazel, HTTPS_PROXY और HTTP_PROXY एनवायरमेंट वैरिएबल से प्रॉक्सी पते लेता है. इनका इस्तेमाल, HTTP और HTTPS फ़ाइलों को डाउनलोड करने के लिए करता है. हालांकि, ऐसा तब होता है, जब इन फ़ाइलों को डाउनलोड करने के लिए कहा गया हो.

IPv6 के साथ काम करने वाला वर्शन

सिर्फ़ IPv6 वाले कंप्यूटरों पर, Bazel बिना किसी बदलाव के डिपेंडेंसी डाउनलोड कर सकता है. हालांकि, ड्यूअल-स्टैक IPv4/IPv6 मशीनों पर Bazel, Java के जैसे ही नियमों का पालन करता है. अगर IPv4 चालू है, तो Bazel इसे प्राथमिकता देता है. कुछ मामलों में, जैसे कि जब IPv4 नेटवर्क बाहरी पतों को हल/पहुंच नहीं कर पाता है, तो इससे Network unreachable अपवाद हो सकते हैं और बिल्ड फ़ेल हो सकते हैं. ऐसे मामलों में, Bazel के डिफ़ॉल्ट व्यवहार को बदला जा सकता है. इसके लिए, java.net.preferIPv6Addresses=true system property का इस्तेमाल करके, IPv6 को प्राथमिकता दी जा सकती है. खास तौर पर, इस बारे में जानकारी मिलती है:

  • --host_jvm_args=-Djava.net.preferIPv6Addresses=true startup option का इस्तेमाल करें. उदाहरण के लिए, अपनी .bazelrc फ़ाइल में यह लाइन जोड़ें:

    startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true

  • जब आपको ऐसे Java बिल्ड टारगेट चलाने हों जिन्हें इंटरनेट से कनेक्ट करने की ज़रूरत होती है (जैसे, इंटिग्रेशन टेस्ट के लिए), तब --jvmopt=-Djava.net.preferIPv6Addresses=true टूल फ़्लैग का इस्तेमाल करें. उदाहरण के लिए, अपनी .bazelrc फ़ाइल में यह शामिल करें:

    build --jvmopt=-Djava.net.preferIPv6Addresses

  • अगर डिपेंडेंसी के वर्शन को हल करने के लिए rules_jvm_external का इस्तेमाल किया जा रहा है, तो COURSIER_OPTS एनवायरमेंट वैरिएबल में -Djava.net.preferIPv6Addresses=true भी जोड़ें, ताकि Coursier के लिए जेवीएम के विकल्प दिए जा सकें.

ऑफ़लाइन बिल्ड

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

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

Bazel खुद इस तकनीक का इस्तेमाल करके, distribution artifact से ऑफ़लाइन बूटस्ट्रैप करता है. यह ऐसा, सभी ज़रूरी बाहरी डिपेंडेंसी को इकट्ठा करके करता है. इसके बाद, इन्हें एक इंटरनल distdir_tar में रखा जाता है.

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