Bazel के साथ रोज़ाना होने वाला इंटरैक्शन मुख्य रूप से कुछ निर्देशों के ज़रिए होता है:
build
, test
, और run
. हालांकि, कभी-कभी ये सीमित ही लग सकते हैं: हो सकता है कि आपको डेटा स्टोर करने की जगह में पैकेज भेजने, असली उपयोगकर्ताओं के लिए दस्तावेज़ पब्लिश करने या Cubernetes में ऐप्लिकेशन डिप्लॉय करने की इच्छा हो. हालांकि, Bazel के पास publish
या
deploy
निर्देश नहीं है – ये कार्रवाइयां कहां फ़िट हो सकती हैं?
bazel रन कमांड
बैजल का फ़ोकस, हर्मेटिसिटी, रीप्रॉड्यूसिबिलिटी, और इंंक्रीमेंटलिटी पर है. इसका मतलब है कि build
और test
निर्देश, ऊपर दिए गए टास्क के लिए काम के नहीं हैं. ये कार्रवाइयां सीमित नेटवर्क ऐक्सेस के साथ
सैंडबॉक्स में चल सकती हैं. साथ ही, हर bazel build
के साथ इनके
फिर से चलने की गारंटी नहीं है.
इसके बजाय, bazel run
पर भरोसा करें: यह वह टास्क है जिसका खराब असर आप चाहते हैं. Bazel के उपयोगकर्ता, एक्ज़ीक्यूटेबल बनाने के नियमों को समझते हैं.
नियम बनाने वाले लोग, पैटर्न के सामान्य सेट का पालन करके इसे
"कस्टम क्रिया" तक बढ़ा सकते हैं.
जंगल में: नियम_k8s
उदाहरण के लिए, rules_k8s
पर विचार करें,
जिसमें Bazel के लिए Cubernetes नियम हैं. मान लें कि आपके पास नीचे दिया गया टारगेट है:
# BUILD file in //application/k8s
k8s_object(
name = "staging",
kind = "deployment",
cluster = "testing",
template = "deployment.yaml",
)
अगर staging
टारगेट पर bazel build
का इस्तेमाल किया जाता है, तो k8s_object
नियम एक स्टैंडर्ड Cubernetes YAML फ़ाइल बनाता है. हालांकि, staging.apply
और :staging.delete
जैसे नामों के साथ k8s_object
मैक्रो भी अतिरिक्त टारगेट बनाते हैं. ये कार्रवाइयां करने के लिए स्क्रिप्ट बनाती हैं. bazel run
staging.apply
के साथ एक्ज़ीक्यूट करने पर, ये हमारे bazel k8s-apply
या bazel
k8s-delete
निर्देशों की तरह काम करती हैं.
एक और उदाहरण: ts_api_Guardian_test
इस पैटर्न को Angular प्रोजेक्ट में भी देखा जा सकता है. ts_api_guardian_test
मैक्रो
दो टारगेट बनाता है. पहला स्टैंडर्ड nodejs_test
टारगेट है, जो जनरेट किए गए कुछ आउटपुट की तुलना "गोल्डन" फ़ाइल (यानी कि वह फ़ाइल जिसमें अनुमानित आउटपुट वाली फ़ाइल है) से किया जाता है. इसे सामान्य bazel
test
के साथ बनाया और चलाया जा सकता है. angular-cli
में, bazel test //etc/api:angular_devkit_core_api
के साथ ऐसा ही एक टारगेट
चलाया जा सकता है.
समय के साथ, इस गोल्डन फ़ाइल को सही वजहों से अपडेट करने की ज़रूरत पड़ सकती है.
इसे मैन्युअल तौर पर अपडेट करना मुश्किल होता है और इसमें गड़बड़ी की संभावना होती है. इसलिए, यह मैक्रो भी एक nodejs_binary
टारगेट देता है, जो तुलना करने के बजाय गोल्डन फ़ाइल को अपडेट करता है. आम तौर पर, टेस्ट स्क्रिप्ट को शुरू करने के तरीके के आधार पर उसे "पुष्टि करें"
या "स्वीकार करें" मोड में चलाने के लिए लिखा जा सकता है. यह उसी पैटर्न के हिसाब से होगा जिसे
आप पहले ही सीख चुके हैं: कोई नेटिव bazel test-accept
कमांड नहीं है, लेकिन
bazel run //etc/api:angular_devkit_core_api.accept
की मदद से भी ऐसा ही किया जा सकता है.
यह पैटर्न काफ़ी दमदार हो सकता है और जब इस पैटर्न को पहचानना सीख लिया जाता है, तब यह काफ़ी सामान्य हो जाता है.
अपने हिसाब से नियम बनाना
मैक्रो इस पैटर्न के मुख्य बिंदु हैं. मैक्रो का इस्तेमाल नियमों की तरह किया जाता है, लेकिन वे कई टारगेट बना सकते हैं. आम तौर पर, वे बताए गए नाम के साथ एक टारगेट बनाते हैं जो प्राइमरी बिल्ड ऐक्शन करता है: यह एक सामान्य बाइनरी, Docker इमेज या सोर्स कोड का संग्रह बनाता है. इस पैटर्न में, मुख्य टारगेट के आउटपुट पर खराब असर डालने वाली स्क्रिप्ट बनाने के लिए अतिरिक्त टारगेट बनाए जाते हैं. जैसे, नतीजे में मिलने वाली बाइनरी को पब्लिश करना या अनुमानित टेस्ट आउटपुट को अपडेट करना.
इसे समझने के लिए, एक काल्पनिक नियम को रैप करें जो Sphinx के साथ, मैक्रो के साथ वेबसाइट जनरेट करता है. इससे एक और टारगेट बनाने के लिए, उपयोगकर्ता उसे तैयार होने पर पब्लिश कर सकता है. Sling की मदद से वेबसाइट जनरेट करने के लिए, यहां दिए गए मौजूदा नियम पर विचार करें:
_sphinx_site = rule(
implementation = _sphinx_impl,
attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
)
इसके बाद, नीचे दिए गए नियम जैसे नियम पर ध्यान दें, जो एक ऐसी स्क्रिप्ट बनाता है जिसे चलाने पर, जनरेट किए गए पेजों को पब्लिश किया जाता है:
_sphinx_publisher = rule(
implementation = _publish_impl,
attrs = {
"site": attr.label(),
"_publisher": attr.label(
default = "//internal/sphinx:publisher",
executable = True,
),
},
executable = True,
)
आखिर में, ऊपर दिए गए दोनों नियमों के लिए एक साथ टारगेट बनाने के लिए नीचे दिया गया मैक्रो तय करें:
def sphinx_site(name, srcs = [], **kwargs):
# This creates the primary target, producing the Sphinx-generated HTML.
_sphinx_site(name = name, srcs = srcs, **kwargs)
# This creates the secondary target, which produces a script for publishing
# the site generated above.
_sphinx_publisher(name = "%s.publish" % name, site = name, **kwargs)
BUILD
फ़ाइलों में, मैक्रो का इस्तेमाल इस तरह करें, जैसे कि वह सिर्फ़ मुख्य टारगेट बनाता हो:
sphinx_site(
name = "docs",
srcs = ["index.md", "providers.md"],
)
इस उदाहरण में, एक "docs" टारगेट बनाया गया है, ठीक उसी तरह जैसे कि मैक्रो एक मानक, सिंगल बैजल नियम था. बनाए जाने के बाद, नियम कुछ कॉन्फ़िगरेशन जनरेट करता है और
Sphinx को एक एचटीएमएल साइट बनाने के लिए चलाता है, जो मैन्युअल जांच के लिए तैयार है. हालांकि,
एक और "docs.publish" टारगेट भी बनाया जाता है, जो साइट को पब्लिश करने के लिए एक स्क्रिप्ट बनाता है. प्राइमरी टारगेट के आउटपुट की जांच करने के बाद, किसी काल्पनिक bazel publish
कमांड की तरह ही, bazel run :docs.publish
का इस्तेमाल करके इसे सार्वजनिक तौर पर पब्लिश किया जा सकता है.
यह साफ़ तौर पर नहीं बताया जा सकता कि _sphinx_publisher
नियम लागू होने पर क्या होगा. अक्सर, इस तरह की कार्रवाइयां लॉन्चर शेल स्क्रिप्ट लिखती हैं.
इस तरीके में आम तौर पर, एक बहुत ही आसान शेल स्क्रिप्ट लिखने के लिए
ctx.actions.expand_template
का इस्तेमाल करना शामिल है. इस मामले में, पब्लिशर बाइनरी को
प्राइमरी टारगेट के आउटपुट पाथ के साथ शुरू करें. इस तरह, पब्लिशर
लागू करने की प्रोसेस सामान्य बनी रह सकती है, _sphinx_site
नियम सिर्फ़ एचटीएमएल बना सकता है, और इस छोटी स्क्रिप्ट की मदद से
दोनों को एक साथ जोड़ा जा सकता है.
rules_k8s
में, .apply
वाकई यही काम करता है:
expand_template
, apply.sh.tpl
के आधार पर एक बहुत ही आसान बैश स्क्रिप्ट लिखता है, जो मुख्य टारगेट के आउटपुट के साथ kubectl
चलती है. इसके बाद,
इस स्क्रिप्ट को bazel run :staging.apply
का इस्तेमाल करके बनाया और चलाया जा सकता है. इससे k8s_object
टारगेट के लिए,
k8s-apply
निर्देश मिलता है.