কাস্টম ক্রিয়া তৈরি করতে ম্যাক্রো ব্যবহার করে

Bazel-এর সাথে প্রতিদিনের মিথস্ক্রিয়া প্রাথমিকভাবে কয়েকটি কমান্ডের মাধ্যমে ঘটে: build , test এবং run । মাঝে মাঝে, যদিও, এগুলি সীমিত বোধ করতে পারে: আপনি প্যাকেজগুলিকে একটি সংগ্রহস্থলে ঠেলে দিতে, শেষ-ব্যবহারকারীদের জন্য ডকুমেন্টেশন প্রকাশ করতে বা Kubernetes-এর সাথে একটি অ্যাপ্লিকেশন স্থাপন করতে চাইতে পারেন। কিন্তু Bazel এর কোনো publish বা deploy কমান্ড নেই - এই ক্রিয়াগুলি কোথায় ফিট করে?

বেজেল রান কমান্ড

হারমেটিসিটি, প্রজননযোগ্যতা এবং বর্ধনশীলতার উপর ব্যাজেলের ফোকাস মানে build এবং test কমান্ড উপরের কাজের জন্য সহায়ক নয়। এই ক্রিয়াগুলি সীমিত নেটওয়ার্ক অ্যাক্সেস সহ একটি স্যান্ডবক্সে চলতে পারে এবং প্রতিটি bazel build সাথে পুনরায় চালানোর নিশ্চয়তা নেই৷

পরিবর্তে, bazel run উপর নির্ভর করুন: আপনি পার্শ্বপ্রতিক্রিয়া করতে চান এমন কাজের জন্য ওয়ার্কহরস। ব্যাজেল ব্যবহারকারীরা এমন নিয়মে অভ্যস্ত যেগুলি এক্সিকিউটেবল তৈরি করে, এবং নিয়ম লেখকরা এটিকে "কাস্টম ক্রিয়া" পর্যন্ত প্রসারিত করতে একটি সাধারণ সেট অনুসরণ করতে পারেন।

বন্য মধ্যে: নিয়ম_k8s

উদাহরণ স্বরূপ, বাজেলের জন্য rules_k8s , Kubernetes নিয়মগুলি বিবেচনা করুন। ধরুন আপনার নিম্নলিখিত লক্ষ্য আছে:

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

যখন staging টার্গেটে bazel build k8s_object একটি আদর্শ Kubernetes YAML ফাইল তৈরি করে। যাইহোক, staging.apply এবং :staging.delete এর মতো নাম সহ k8s_object ম্যাক্রো দ্বারা অতিরিক্ত লক্ষ্যগুলিও তৈরি করা হয়। এই ক্রিয়াগুলি সম্পাদন করার জন্য এই স্ক্রিপ্টগুলি তৈরি করে এবং যখন bazel run staging.apply সাথে কার্যকর করা হয়, তখন এগুলি আমাদের নিজস্ব bazel k8s-apply বা bazel k8s-delete কমান্ডের মতো আচরণ করে।

আরেকটি উদাহরণ: ts_api_guardian_test

এই প্যাটার্নটি কৌণিক প্রকল্পেও দেখা যায়। 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 দিয়ে অর্জন করা যেতে পারে।

এই প্যাটার্নটি বেশ শক্তিশালী হতে পারে, এবং আপনি এটি চিনতে শিখলে এটি বেশ সাধারণ হতে পারে।

আপনার নিজস্ব নিয়ম মানিয়ে

ম্যাক্রো এই প্যাটার্নের হৃদয়। ম্যাক্রোগুলি নিয়মের মতো ব্যবহার করা হয়, তবে তারা বেশ কয়েকটি লক্ষ্য তৈরি করতে পারে। সাধারণত, তারা নির্দিষ্ট নামের সাথে একটি লক্ষ্য তৈরি করবে যা প্রাথমিক বিল্ড অ্যাকশনটি সম্পাদন করে: সম্ভবত এটি একটি সাধারণ বাইনারি, একটি ডকার ইমেজ বা উত্স কোডের একটি সংরক্ষণাগার তৈরি করে। এই প্যাটার্নে, প্রাথমিক টার্গেটের আউটপুটের উপর ভিত্তি করে পার্শ্ব প্রতিক্রিয়া সম্পাদনকারী স্ক্রিপ্ট তৈরি করার জন্য অতিরিক্ত লক্ষ্য তৈরি করা হয়, যেমন ফলাফল বাইনারি প্রকাশ করা বা প্রত্যাশিত পরীক্ষার আউটপুট আপডেট করা।

এটি ব্যাখ্যা করার জন্য, একটি কাল্পনিক নিয়ম মোড়ানো যা একটি অতিরিক্ত লক্ষ্য তৈরি করতে একটি ম্যাক্রো সহ স্ফিনক্সের সাথে একটি ওয়েবসাইট তৈরি করে যা ব্যবহারকারী প্রস্তুত হলে এটি প্রকাশ করতে দেয়৷ স্ফিংসের সাথে একটি ওয়েবসাইট তৈরি করার জন্য নিম্নলিখিত বিদ্যমান নিয়মগুলি বিবেচনা করুন:

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

এই উদাহরণে, একটি "ডক্স" টার্গেট তৈরি করা হয়েছে, ঠিক যেমন ম্যাক্রো একটি স্ট্যান্ডার্ড, একক Bazel নিয়ম। নির্মিত হলে, নিয়মটি কিছু কনফিগারেশন তৈরি করে এবং একটি HTML সাইট তৈরি করতে স্ফিঙ্কস চালায়, ম্যানুয়াল পরিদর্শনের জন্য প্রস্তুত। যাইহোক, একটি অতিরিক্ত "docs.publish" লক্ষ্যও তৈরি করা হয়েছে, যা সাইট প্রকাশের জন্য একটি স্ক্রিপ্ট তৈরি করে৷ একবার আপনি প্রাথমিক টার্গেটের আউটপুট পরীক্ষা করে নিলে, আপনি একটি কাল্পনিক bazel publish কমান্ডের মতো এটিকে সর্বজনীন ব্যবহারের জন্য প্রকাশ করতে bazel run :docs.publish ব্যবহার করতে পারেন।

_sphinx_publisher নিয়মের বাস্তবায়ন কেমন হতে পারে তা অবিলম্বে স্পষ্ট নয়। প্রায়শই, এই ধরনের কর্ম একটি লঞ্চার শেল স্ক্রিপ্ট লিখতে. এই পদ্ধতিতে সাধারণত একটি খুব সাধারণ শেল স্ক্রিপ্ট লেখার জন্য ctx.actions.expand_template ব্যবহার করা হয়, এই ক্ষেত্রে প্রকাশক বাইনারিকে প্রাথমিক টার্গেটের আউটপুটে যাওয়ার পথ দিয়ে আমন্ত্রণ জানানো হয়। এইভাবে, প্রকাশক বাস্তবায়ন জেনেরিক থাকতে পারে, _sphinx_site নিয়মটি কেবল HTML তৈরি করতে পারে, এবং এই ছোট স্ক্রিপ্টটি দুটিকে একত্রিত করার জন্য প্রয়োজনীয়।

rules_k8s এ, এটি আসলে .apply করে: expand_template একটি খুব সাধারণ ব্যাশ স্ক্রিপ্ট লিখে, যা apply.sh.tpl এর উপর ভিত্তি করে, যা প্রাথমিক লক্ষ্যের আউটপুট দিয়ে kubectl চালায়। এই স্ক্রিপ্টটি তখন bazel run :staging.apply দিয়ে তৈরি এবং চালানো যেতে পারে, কার্যকরভাবে k8s_object লক্ষ্যগুলির জন্য k8s k8s-apply কমান্ড প্রদান করে।