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

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 रिपॉज़िटरी को किसी ऐसी लोकल डायरेक्ट्री से बदलना जहां बदलाव आसानी से किए जा सकें.
  • वेंडरिंग. अगर आप ऐसे माहौल में हैं जहां नेटवर्क कॉल नहीं किए जा सकते, तो नेटवर्क पर आधारित रिपॉज़िटरी के नियमों को बदलकर, स्थानीय डायरेक्ट्री की ओर पॉइंट करें.
में local_path_override डायरेक्टिव की तरह काम करता है.

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

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

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

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

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

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

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

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

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