कस्टम क्रिया बनाने के लिए मैक्रो का उपयोग करना

अभी तक किसी भी व्यक्ति ने चेक इन नहीं किया है किसी समस्या की शिकायत करें सोर्स देखें रात · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

बेज़ेल के साथ रोज़मर्रा की बातचीत कुछ खास निर्देशों के ज़रिए होती है: build, test, और run. हालांकि, कभी-कभी ऐसा लग सकता है कि आपको इन चीज़ों की कमी महसूस हो सकती है: पैकेज को डेटा स्टोर करने की जगह में भेजना, असली उपयोगकर्ताओं के लिए दस्तावेज़ पब्लिश करना या Kubernetes के साथ कोई ऐप्लिकेशन डिप्लॉय करें. लेकिन Babel के पास publish या deploy निर्देश – ये कार्रवाइयां कहां की जा सकती हैं?

बेज़ल रन कमांड

बेज़ल का मतलब है कि हरमैटिसिटी, दोबारा बनने की क्षमता, और बढ़ोतरी पर ध्यान देने से build और test निर्देश, ऊपर दिए गए टास्क के लिए मददगार नहीं हैं. ये कार्रवाइयां सीमित नेटवर्क पहुंच के साथ, सैंडबॉक्स में चलाया जा सकता है, और इसके होने की गारंटी नहीं दी जाती हर bazel build के साथ फिर से चलाएं.

इसके बजाय, bazel run का इस्तेमाल करें: जो टास्क आपको चाहिए हैं उनके लिए वर्कहॉर्स खराब असर पड़ सकता है. Babel के उपयोगकर्ता उन नियमों के अभ्यस्त होते हैं, जो एक्ज़ीक्यूटेबल बनाते हैं, और नियम बनाने वाले लोग, पैटर्न के एक सामान्य सेट का पालन करके "कस्टम क्रिया" का इस्तेमाल करें.

जंगल में: नियम_k8s

उदाहरण के लिए, rules_k8s, के नियम बनाए. मान लें कि आपके पास यह टारगेट है:

# BUILD file in //application/k8s
k8s_object(
    name = "staging",
    kind = "deployment",
    cluster = "testing",
    template = "deployment.yaml",
)

k8s_object नियम बनाता है जब staging पर bazel build का इस्तेमाल किया जाता है, तो स्टैंडर्ड Kubernetes YAML फ़ाइल टारगेट. हालांकि, k8s_object दूसरे टारगेट भी बनाता है staging.apply और :staging.delete जैसे नाम वाला मैक्रो. ये बिल्ड स्क्रिप्ट वे कार्रवाइयां करती हैं और 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 टारगेट मुकाबलों में इस्तेमाल करें. प्रभावी रूप से, "verify" में चलाने के लिए वही टेस्ट स्क्रिप्ट लिखी जा सकती है या "स्वीकार करें" मोड चालू किया जा सकता है. यह उसी पैटर्न को अपनाता है आपने पहले ही सीख लिया है: यहां कोई नेटिव bazel test-accept कमांड नहीं है, लेकिन उसी तरह, असर डालने के लिए bazel run //etc/api:angular_devkit_core_api.accept.

यह पैटर्न काफ़ी असरदार हो सकता है. जब यह पैटर्न बहुत आम हो जाता है, तो उसे पहचानना सीखें.

अपने नियम खुद बनाना

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

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

_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"],
)

इस उदाहरण में, "दस्तावेज़" लक्ष्य बनाया जाता है, ठीक वैसे ही जैसे मैक्रो मानक, सिंगल बेज़ल नियम. नियम बनाए जाने पर, नियम कुछ कॉन्फ़िगरेशन जनरेट करता है और स्फ़िंक्स को चलाकर एक HTML साइट बनाती है, जो मैन्युअल निरीक्षण के लिए तैयार है. हालांकि, एक अतिरिक्त "docs.publish" लक्ष्य भी बनाया जाता है, जो पब्लिश करने में मदद मिलती है. मुख्य टारगेट के आउटपुट की जांच करने के बाद, आपको ये काम करने में मदद मिलेगी इसे लोगों के पढ़ने के लिए पब्लिश करने के लिए, bazel run :docs.publish का इस्तेमाल करें, जैसे एक काल्पनिक bazel 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 निर्देश.