BazelCon 2022 16-17 নভেম্বর নিউ ইয়র্ক এবং অনলাইনে আসছে।
নিবন্ধন আজ!

Bzlmod দিয়ে বাহ্যিক নির্ভরতা পরিচালনা করুন

সেভ করা পৃষ্ঠা গুছিয়ে রাখতে 'সংগ্রহ' ব্যবহার করুন আপনার পছন্দ অনুযায়ী কন্টেন্ট সেভ করুন ও সঠিক বিভাগে রাখুন।

Bzlmod হল Bazel 5.0-এ প্রবর্তিত নতুন বাহ্যিক নির্ভরতা সিস্টেমের কোডনেম। এটি পুরানো সিস্টেমের বেশ কয়েকটি ব্যথার পয়েন্টগুলিকে মোকাবেলা করার জন্য চালু করা হয়েছিল যা সম্ভাব্যভাবে ক্রমবর্ধমানভাবে স্থির করা যায় না; আরও বিশদ বিবরণের জন্য মূল ডিজাইন ডকের সমস্যা বিবৃতি বিভাগটি দেখুন।

Bazel 5.0 এ, Bzlmod ডিফল্টরূপে চালু করা হয় না; নিম্নলিখিতগুলি কার্যকর করার জন্য পতাকা --experimental_enable_bzlmod নির্দিষ্ট করা প্রয়োজন৷ ফ্ল্যাগ নামটি নির্দেশ করে, এই বৈশিষ্ট্যটি বর্তমানে পরীক্ষামূলক ; বৈশিষ্ট্যটি আনুষ্ঠানিকভাবে চালু না হওয়া পর্যন্ত API এবং আচরণ পরিবর্তন হতে পারে।

আপনার প্রকল্প Bzlmod-এ স্থানান্তর করতে, Bzlmod মাইগ্রেশন গাইড অনুসরণ করুন। আপনি উদাহরণ সংগ্রহস্থলে উদাহরণ Bzlmod ব্যবহারগুলিও খুঁজে পেতে পারেন।

বেজেল মডিউল

পুরানো WORKSPACE -ভিত্তিক বাহ্যিক নির্ভরতা সিস্টেম রিপোজিটরি (বা repos ) এর চারপাশে কেন্দ্রীভূত, সংগ্রহস্থলের নিয়ম (বা রেপো নিয়ম ) এর মাধ্যমে তৈরি করা হয়েছে। যদিও নতুন সিস্টেমে রেপো এখনও একটি গুরুত্বপূর্ণ ধারণা, মডিউলগুলি নির্ভরতার মূল ইউনিট।

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

একটি মডিউল শুধুমাত্র WORKSPACE এ নির্দিষ্ট URL-এর পরিবর্তে name এবং version জোড়া ব্যবহার করে তার নির্ভরতা নির্দিষ্ট করে। নির্ভরতাগুলি তখন একটি Bazel রেজিস্ট্রিতে দেখা হয়; ডিফল্টরূপে, Bazel কেন্দ্রীয় রেজিস্ট্রি । আপনার কর্মক্ষেত্রে, প্রতিটি মডিউল তারপর একটি রেপোতে পরিণত হয়।

MODULE.bazel

প্রতিটি মডিউলের প্রতিটি সংস্করণে একটি MODULE.bazel ফাইল রয়েছে যা তার নির্ভরতা এবং অন্যান্য মেটাডেটা ঘোষণা করে। এখানে একটি মৌলিক উদাহরণ:

module(
    name = "my-module",
    version = "1.0",
)

bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")

MODULE.bazel ফাইলটি ওয়ার্কস্পেস ডিরেক্টরির রুটে অবস্থিত হওয়া উচিত ( WORKSPACE ফাইলের পাশে)। WORKSPACE ফাইলের বিপরীতে, আপনাকে আপনার ট্রানজিটিভ নির্ভরতা নির্দিষ্ট করতে হবে না; পরিবর্তে, আপনার শুধুমাত্র সরাসরি নির্ভরতা নির্দিষ্ট করা উচিত, এবং আপনার নির্ভরতার MODULE.bazel ফাইলগুলি স্বয়ংক্রিয়ভাবে ট্রানজিটিভ নির্ভরতা আবিষ্কার করতে প্রক্রিয়া করা হয়।

MODULE.bazel ফাইলটি BUILD ফাইলের অনুরূপ কারণ এটি কোনো ধরনের নিয়ন্ত্রণ প্রবাহ সমর্থন করে না; এটি অতিরিক্ত load বিবৃতি নিষিদ্ধ. নির্দেশাবলী MODULE.bazel ফাইল সমর্থন করে:

  • module , বর্তমান মডিউল সম্পর্কে মেটাডেটা নির্দিষ্ট করতে, এর নাম, সংস্করণ এবং আরও কিছু সহ;
  • bazel_dep , অন্যান্য Bazel মডিউলের উপর সরাসরি নির্ভরতা নির্দিষ্ট করতে;
  • ওভাররাইড, যা শুধুমাত্র রুট মডিউল দ্বারা ব্যবহার করা যেতে পারে (অর্থাৎ, নির্ভরতা হিসাবে ব্যবহৃত মডিউল দ্বারা নয়) একটি নির্দিষ্ট প্রত্যক্ষ বা ট্রানজিটিভ নির্ভরতার আচরণ কাস্টমাইজ করতে:
  • মডিউল এক্সটেনশন সম্পর্কিত নির্দেশাবলী:

সংস্করণ বিন্যাস

ব্যাজেলের একটি বৈচিত্র্যময় বাস্তুতন্ত্র রয়েছে এবং প্রকল্পগুলি বিভিন্ন সংস্করণের স্কিম ব্যবহার করে। এখন পর্যন্ত সবচেয়ে জনপ্রিয় হল SemVer , কিন্তু এছাড়াও বিভিন্ন স্কিম ব্যবহার করে বিশিষ্ট প্রকল্প রয়েছে যেমন Abseil , যার সংস্করণগুলি তারিখ-ভিত্তিক, উদাহরণস্বরূপ 20210324.2 )।

এই কারণে, Bzlmod SemVer স্পেকের আরও স্বাচ্ছন্দ্যপূর্ণ সংস্করণ গ্রহণ করে। পার্থক্য অন্তর্ভুক্ত:

  • SemVer নির্দেশ করে যে সংস্করণের "রিলিজ" অংশে অবশ্যই 3টি বিভাগ থাকতে হবে: MAJOR.MINOR.PATCH । Bazel-এ, এই প্রয়োজনীয়তা শিথিল করা হয়েছে যাতে যেকোনো সংখ্যক সেগমেন্ট অনুমোদিত হয়।
  • SemVer-এ, "রিলিজ" অংশের প্রতিটি সেগমেন্ট শুধুমাত্র সংখ্যা হতে হবে। Bazel-এ, অক্ষরগুলিকেও অনুমতি দেওয়ার জন্য এটি শিথিল করা হয়েছে, এবং তুলনামূলক শব্দার্থবিদ্যাগুলি "প্রি-রিলিজ" অংশে "আইডেন্টিফায়ার" এর সাথে মেলে।
  • উপরন্তু, প্রধান, ছোট এবং প্যাচ সংস্করণ বৃদ্ধির শব্দার্থবিদ্যা প্রয়োগ করা হয় না। (তবে, আমরা কীভাবে পিছনের সামঞ্জস্যকে বোঝাই তার বিস্তারিত জানার জন্য সামঞ্জস্যের স্তর দেখুন।)

যেকোনো বৈধ SemVer সংস্করণ একটি বৈধ Bazel মডিউল সংস্করণ। উপরন্তু, দুটি SemVer সংস্করণ a এবং b তুলনা a < b iff একই ধারণ করে যখন সেগুলিকে Bazel মডিউল সংস্করণের সাথে তুলনা করা হয়।

সংস্করণ রেজোলিউশন

ডায়মন্ড নির্ভরতা সমস্যাটি সংস্করণ নির্ভরতা ব্যবস্থাপনার ক্ষেত্রে একটি প্রধান বিষয়। ধরুন আপনার নিম্নলিখিত নির্ভরতা গ্রাফ আছে:

       A 1.0
      /     \
   B 1.0    C 1.1
     |        |
   D 1.0    D 1.1

D এর কোন সংস্করণ ব্যবহার করা উচিত? এই প্রশ্নের সমাধান করার জন্য, Bzlmod Go মডিউল সিস্টেমে প্রবর্তিত Minimal Version Selection (MVS) অ্যালগরিদম ব্যবহার করে। MVS অনুমান করে যে একটি মডিউলের সমস্ত নতুন সংস্করণ পিছনের দিকে সামঞ্জস্যপূর্ণ, এবং এইভাবে যে কোনও নির্ভরশীল দ্বারা নির্দিষ্ট করা সর্বোচ্চ সংস্করণটি বেছে নেয় (আমাদের উদাহরণে D 1.1)। এটিকে "ন্যূনতম" বলা হয় কারণ D 1.1 এখানে ন্যূনতম সংস্করণ যা আমাদের প্রয়োজনীয়তা পূরণ করতে পারে; এমনকি যদি D 1.2 বা নতুন থেকে থাকে, আমরা সেগুলি নির্বাচন করি না। এটির অতিরিক্ত সুবিধা রয়েছে যে সংস্করণ নির্বাচন উচ্চ-বিশ্বস্ততা এবং পুনরুত্পাদনযোগ্য

সংস্করণ রেজোলিউশন আপনার মেশিনে স্থানীয়ভাবে সঞ্চালিত হয়, রেজিস্ট্রি দ্বারা নয়।

সামঞ্জস্য স্তর

মনে রাখবেন যে পিছনের দিকে সামঞ্জস্যের বিষয়ে MVS-এর অনুমান সম্ভব কারণ এটি কেবল একটি মডিউলের পিছনের বেমানান সংস্করণগুলিকে একটি পৃথক মডিউল হিসাবে বিবেচনা করে। SemVer এর পরিপ্রেক্ষিতে, এর মানে হল A 1.x এবং A 2.x আলাদা মডিউল হিসাবে বিবেচিত হয় এবং সমাধানকৃত নির্ভরতা গ্রাফে সহাবস্থান করতে পারে। এটি, পরিবর্তে, এই সত্য দ্বারা সম্ভব হয়েছে যে প্রধান সংস্করণটি গো-তে প্যাকেজ পাথে এনকোড করা হয়েছে, তাই কোনও কম্পাইল-টাইম বা লিঙ্কিং-টাইম দ্বন্দ্ব নেই।

Bazel-এ, আমাদের কাছে এই ধরনের গ্যারান্টি নেই। সুতরাং পিছনের বেমানান সংস্করণগুলি সনাক্ত করার জন্য আমাদের "প্রধান সংস্করণ" নম্বরটি বোঝানোর একটি উপায় দরকার। এই সংখ্যাটিকে বলা হয় সামঞ্জস্য স্তর , এবং প্রতিটি মডিউল সংস্করণ দ্বারা তার module() নির্দেশে নির্দিষ্ট করা হয়। এই তথ্যটি হাতে রেখে, আমরা একটি ত্রুটি নিক্ষেপ করতে পারি যখন আমরা সনাক্ত করি যে একই মডিউলের বিভিন্ন সামঞ্জস্যপূর্ণ স্তরের সংস্করণগুলি সমাধান করা নির্ভরতা গ্রাফে বিদ্যমান।

সংগ্রহস্থলের নাম

বাজেলে, প্রতিটি বাহ্যিক নির্ভরতার একটি সংগ্রহস্থলের নাম রয়েছে। কখনও কখনও, একই নির্ভরতা বিভিন্ন রিপোজিটরি নামের মাধ্যমে ব্যবহার করা যেতে পারে (উদাহরণস্বরূপ, @io_bazel_skylib এবং @bazel_skylib মানে Bazel skylib ), অথবা একই সংগ্রহস্থলের নাম বিভিন্ন প্রকল্পে বিভিন্ন নির্ভরতার জন্য ব্যবহার করা যেতে পারে।

Bzlmod-এ, Bazel মডিউল এবং মডিউল এক্সটেনশন দ্বারা সংগ্রহস্থল তৈরি করা যেতে পারে। রিপোজিটরি নামের দ্বন্দ্ব সমাধানের জন্য, আমরা নতুন সিস্টেমে রিপোজিটরি ম্যাপিং মেকানিজমকে আলিঙ্গন করছি। এখানে দুটি গুরুত্বপূর্ণ ধারণা রয়েছে:

  • ক্যানোনিকাল রিপোজিটরি নাম : প্রতিটি সংগ্রহস্থলের জন্য বিশ্বব্যাপী অনন্য সংগ্রহস্থলের নাম। এটি সেই ডিরেক্টরির নাম হবে যেখানে রিপোজিটরি থাকে।
    এটি নিম্নরূপ তৈরি করা হয়েছে ( সতর্কতা : ক্যানোনিকাল নামের বিন্যাসটি এমন একটি API নয় যার উপর আপনার নির্ভর করা উচিত, এটি যে কোনো সময় পরিবর্তন হতে পারে):

    • Bazel মডিউল repos এর জন্য: module_name ~ version
      ( উদাহরণ . @bazel_skylib~1.0.3 )
    • মডিউল এক্সটেনশন রেপোর জন্য: module_name ~ version ~ extension_name ~ repo_name
      ( উদাহরণ@rules_cc~0.0.1~cc_configure~local_config_cc )
  • স্থানীয় সংগ্রহস্থলের নাম : একটি রেপোর মধ্যে BUILD এবং .bzl ফাইলগুলিতে ব্যবহৃত সংগ্রহস্থলের নাম। একই নির্ভরতার বিভিন্ন রেপোর জন্য বিভিন্ন স্থানীয় নাম থাকতে পারে।
    এটি নিম্নরূপ নির্ধারিত হয়:

    • Bazel মডিউল repos এর জন্য: ডিফল্টরূপে module_name , অথবা bazel_deprepo_name বৈশিষ্ট্য দ্বারা নির্দিষ্ট করা নাম।
    • মডিউল এক্সটেনশন রেপোর জন্য: ভান্ডার নাম use_repo মাধ্যমে চালু করা হয়েছে।

প্রতিটি সংগ্রহস্থলের সরাসরি নির্ভরতার একটি সংগ্রহস্থল ম্যাপিং অভিধান রয়েছে, যা স্থানীয় সংগ্রহস্থলের নাম থেকে ক্যানোনিকাল সংগ্রহস্থলের নাম পর্যন্ত একটি মানচিত্র। একটি লেবেল তৈরি করার সময় আমরা সংগ্রহস্থলের নাম সমাধান করতে সংগ্রহস্থল ম্যাপিং ব্যবহার করি। উল্লেখ্য যে, ক্যানোনিকাল রিপোজিটরি নামের কোনো বিরোধ নেই, এবং স্থানীয় সংগ্রহস্থলের নামের ব্যবহারগুলি MODULE.bazel ফাইল পার্স করে আবিষ্কৃত করা যেতে পারে, তাই দ্বন্দ্বগুলি সহজেই ধরা এবং অন্যান্য নির্ভরতাকে প্রভাবিত না করে সমাধান করা যেতে পারে।

কঠোর deps

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

রিপোজিটরি ম্যাপিংয়ের উপর ভিত্তি করে কঠোর ডিপ প্রয়োগ করা হয়। মূলত, প্রতিটি রেপোর জন্য সংগ্রহস্থল ম্যাপিং এর সমস্ত সরাসরি নির্ভরতা ধারণ করে, অন্য কোন সংগ্রহস্থল দৃশ্যমান নয়। প্রতিটি সংগ্রহস্থলের জন্য দৃশ্যমান নির্ভরতা নিম্নরূপ নির্ধারিত হয়:

  • একটি Bazel মডিউল রেপো bazel_dep এবং use_repo এর মাধ্যমে MODULE.bazel ফাইলে প্রবর্তিত সমস্ত রেপো দেখতে পারে।
  • একটি মডিউল এক্সটেনশন রেপো সেই মডিউলের সমস্ত দৃশ্যমান নির্ভরতা দেখতে পারে যা এক্সটেনশন প্রদান করে, এবং একই মডিউল এক্সটেনশন দ্বারা উত্পন্ন অন্যান্য সমস্ত রেপো।

রেজিস্ট্রি

Bzlmod Bazel রেজিস্ট্রি থেকে তাদের তথ্যের অনুরোধ করে নির্ভরতা আবিষ্কার করে। একটি Bazel রেজিস্ট্রি সহজভাবে Bazel মডিউলগুলির একটি ডাটাবেস। রেজিস্ট্রিগুলির একমাত্র সমর্থিত ফর্ম হল একটি সূচক রেজিস্ট্রি , যা একটি স্থানীয় ডিরেক্টরি বা একটি নির্দিষ্ট বিন্যাস অনুসরণ করে একটি স্ট্যাটিক HTTP সার্ভার। ভবিষ্যতে, আমরা একক-মডিউল রেজিস্ট্রিগুলির জন্য সমর্থন যোগ করার পরিকল্পনা করছি, যা কেবলমাত্র একটি প্রকল্পের উত্স এবং ইতিহাস ধারণকারী গিট রেপো।

সূচক রেজিস্ট্রি

একটি সূচক রেজিস্ট্রি হল একটি স্থানীয় ডিরেক্টরি বা একটি স্ট্যাটিক HTTP সার্ভার যাতে মডিউলগুলির একটি তালিকা, তাদের হোমপেজ, রক্ষণাবেক্ষণকারী, প্রতিটি সংস্করণের MODULE.bazel ফাইল এবং প্রতিটি সংস্করণের উত্স কীভাবে আনতে হয় সে সম্পর্কে তথ্য রয়েছে। উল্লেখযোগ্যভাবে, এটির উৎস সংরক্ষণাগারগুলিকে পরিবেশন করার প্রয়োজন নেই

একটি সূচক রেজিস্ট্রি অবশ্যই নীচের বিন্যাস অনুসরণ করবে:

  • /bazel_registry.json : রেজিস্ট্রির জন্য মেটাডেটা ধারণকারী একটি JSON ফাইল। বর্তমানে, এটিতে শুধুমাত্র একটি কী আছে, mirrors , উৎস সংরক্ষণাগারের জন্য ব্যবহার করার জন্য আয়নার তালিকা উল্লেখ করে।
  • /modules : এই রেজিস্ট্রির প্রতিটি মডিউলের জন্য একটি সাবডিরেক্টরি ধারণকারী একটি ডিরেক্টরি।
  • /modules/$MODULE : এই মডিউলের প্রতিটি সংস্করণের পাশাপাশি নিম্নলিখিত ফাইলের জন্য একটি সাবডিরেক্টরি ধারণকারী একটি ডিরেক্টরি:
    • metadata.json : একটি JSON ফাইল যেখানে মডিউল সম্পর্কে তথ্য রয়েছে, নিম্নলিখিত ক্ষেত্রগুলি সহ:
      • homepage : প্রকল্পের হোমপেজের URL।
      • maintainers : JSON অবজেক্টের একটি তালিকা, যার প্রতিটি রেজিস্ট্রিতে মডিউলের রক্ষণাবেক্ষণকারীর তথ্যের সাথে মিলে যায়। মনে রাখবেন যে এটি অগত্যা প্রকল্পের লেখকদের মতো নয়।
      • versions : এই মডিউলের সমস্ত সংস্করণের একটি তালিকা এই রেজিস্ট্রিতে পাওয়া যাবে।
      • yanked_versions : এই মডিউলের yanked সংস্করণের একটি তালিকা। এটি বর্তমানে একটি নো-অপ, কিন্তু ভবিষ্যতে, ইয়াঙ্ক করা সংস্করণগুলি এড়িয়ে যাবে বা একটি ত্রুটি দেখাবে৷
  • /modules/$MODULE/$VERSION : নিম্নলিখিত ফাইল ধারণকারী একটি ডিরেক্টরি:
    • MODULE.bazel : এই মডিউল সংস্করণের MODULE.bazel ফাইল।
    • source.json : নিম্নলিখিত ক্ষেত্র সহ এই মডিউল সংস্করণের উত্স কীভাবে আনতে হয় সে সম্পর্কে তথ্য ধারণকারী একটি JSON ফাইল:
      • url : উৎস সংরক্ষণাগারের URL।
      • integrity : আর্কাইভের সাবারসোর্স ইন্টিগ্রিটি চেকসাম।
      • strip_prefix : উৎস আর্কাইভ বের করার সময় স্ট্রীপ করার জন্য একটি ডিরেক্টরি উপসর্গ।
      • patches : স্ট্রিংগুলির একটি তালিকা, যার প্রত্যেকটি নিষ্কাশিত সংরক্ষণাগারে প্রয়োগ করার জন্য একটি প্যাচ ফাইলের নাম দেয়। প্যাচ ফাইলগুলি /modules/$MODULE/$VERSION/patches ডিরেক্টরির অধীনে অবস্থিত।
      • patch_strip : ইউনিক্স প্যাচের --strip আর্গুমেন্টের মতই।
    • patches/ : প্যাচ ফাইল ধারণকারী একটি ঐচ্ছিক ডিরেক্টরি।

Bazel কেন্দ্রীয় রেজিস্ট্রি

Bazel Central Registry (BCR) হল একটি সূচক রেজিস্ট্রি যা bcr.bazel.build এ অবস্থিত। এর বিষয়বস্তু GitHub repo bazelbuild/bazel-central-registry দ্বারা সমর্থিত।

BCR বাজেল সম্প্রদায় দ্বারা রক্ষণাবেক্ষণ করা হয়; অবদানকারীদের পুল অনুরোধ জমা স্বাগত জানাই. Bazel সেন্ট্রাল রেজিস্ট্রি নীতি এবং পদ্ধতি দেখুন।

একটি সাধারণ সূচক রেজিস্ট্রির বিন্যাস অনুসরণ করার পাশাপাশি, BCR-এর প্রতিটি মডিউল সংস্করণের জন্য একটি presubmit.yml ফাইল প্রয়োজন ( /modules/$MODULE/$VERSION/presubmit.yml )। এই ফাইলটি কয়েকটি প্রয়োজনীয় বিল্ড এবং টেস্ট লক্ষ্য নির্দিষ্ট করে যা এই মডিউল সংস্করণের বৈধতা পরীক্ষা করতে ব্যবহার করা যেতে পারে, এবং BCR-এর CI পাইপলাইনগুলি BCR-তে মডিউলগুলির মধ্যে আন্তঃকার্যযোগ্যতা নিশ্চিত করতে ব্যবহার করে।

রেজিস্ট্রি নির্বাচন করা হচ্ছে

পুনরাবৃত্তিযোগ্য Bazel পতাকা --registry থেকে মডিউল অনুরোধ করার জন্য রেজিস্ট্রিগুলির তালিকা নির্দিষ্ট করতে ব্যবহার করা যেতে পারে, যাতে আপনি তৃতীয়-পক্ষ বা অভ্যন্তরীণ রেজিস্ট্রি থেকে নির্ভরতা আনতে আপনার প্রকল্প সেট আপ করতে পারেন। পূর্ববর্তী রেজিস্ট্রি অগ্রাধিকার নিতে. সুবিধার জন্য, আপনি আপনার প্রকল্পের .bazelrc ফাইলে --registry পতাকার একটি তালিকা রাখতে পারেন।

মডিউল এক্সটেনশন

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

মডিউল এক্সটেনশনগুলি .bzl ফাইলগুলিতে সংজ্ঞায়িত করা হয়, ঠিক রেপো নিয়ম বা WORKSPACE ম্যাক্রোগুলির মতো৷ তারা সরাসরি আহ্বান করা হয় না; বরং, প্রতিটি মডিউল এক্সটেনশন পড়ার জন্য ট্যাগ নামক ডেটার টুকরো নির্দিষ্ট করতে পারে। তারপর, মডিউল সংস্করণ রেজোলিউশন সম্পন্ন হওয়ার পরে, মডিউল এক্সটেনশন চালানো হয়। প্রতিটি এক্সটেনশন একবার মডিউল রেজোলিউশনের পরে চালানো হয় (এখনও কোনও বিল্ড বাস্তবে হওয়ার আগে), এবং সম্পূর্ণ নির্ভরতা গ্রাফ জুড়ে এটির সাথে সম্পর্কিত সমস্ত ট্যাগ পড়তে পারে।

          [ A 1.1                ]
          [   * maven.dep(X 2.1) ]
          [   * maven.pom(...)   ]
              /              \
   bazel_dep /                \ bazel_dep
            /                  \
[ B 1.2                ]     [ C 1.0                ]
[   * maven.dep(X 1.2) ]     [   * maven.dep(X 2.1) ]
[   * maven.dep(Y 1.3) ]     [   * cargo.dep(P 1.1) ]
            \                  /
   bazel_dep \                / bazel_dep
              \              /
          [ D 1.4                ]
          [   * maven.dep(Z 1.4) ]
          [   * cargo.dep(Q 1.1) ]

উপরের নির্ভরতা গ্রাফের উদাহরণে, A 1.1 এবং B 1.2 ইত্যাদি হল Bazel মডিউল; আপনি প্রতিটিকে একটি MODULE.bazel ফাইল হিসাবে ভাবতে পারেন। প্রতিটি মডিউল মডিউল এক্সটেনশনের জন্য কিছু ট্যাগ নির্দিষ্ট করতে পারে; এখানে কিছু এক্সটেনশন "maven" এর জন্য নির্দিষ্ট করা হয়েছে, এবং কিছু "কার্গো" এর জন্য নির্দিষ্ট করা হয়েছে। যখন এই নির্ভরতা গ্রাফটি চূড়ান্ত করা হয় (উদাহরণস্বরূপ, সম্ভবত B 1.2 এর প্রকৃতপক্ষে D 1.3 তে একটি bazel_dep আছে কিন্তু C এর কারণে D 1.4 তে আপগ্রেড করা হয়েছে), "maven" এক্সটেনশন চালানো হয় এবং এটি সমস্ত maven.* ট্যাগ , কোন repos তৈরি করতে হবে তা সিদ্ধান্ত নিতে সেখানে তথ্য ব্যবহার করে। একইভাবে "কার্গো" এক্সটেনশনের জন্য।

এক্সটেনশন ব্যবহার

ব্যাজেল মডিউলে এক্সটেনশনগুলি হোস্ট করা হয়, তাই আপনার মডিউলে একটি এক্সটেনশন ব্যবহার করতে, আপনাকে প্রথমে সেই মডিউলে একটি bazel_dep যোগ করতে হবে এবং তারপর এটিকে সুযোগে আনতে use_extension বিল্ট-ইন ফাংশনটিতে কল করতে হবে। নিম্নলিখিত উদাহরণটি বিবেচনা করুন, rules_jvm_external মডিউলে সংজ্ঞায়িত একটি অনুমানমূলক "maven" এক্সটেনশন ব্যবহার করার জন্য একটি MODULE.bazel ফাইল থেকে একটি স্নিপেট:

bazel_dep(name = "rules_jvm_external", version = "1.0")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

এক্সটেনশনটিকে সুযোগে আনার পরে, আপনি ডট-সিনট্যাক্স ব্যবহার করে এটির জন্য ট্যাগগুলি নির্দিষ্ট করতে পারেন। মনে রাখবেন যে ট্যাগগুলিকে সংশ্লিষ্ট ট্যাগ ক্লাস দ্বারা সংজ্ঞায়িত স্কিমা অনুসরণ করতে হবে (নীচে এক্সটেনশন সংজ্ঞা দেখুন)। এখানে কিছু maven.dep এবং maven.pom ট্যাগ নির্দিষ্ট করার একটি উদাহরণ।

maven.dep(coord="org.junit:junit:3.0")
maven.dep(coord="com.google.guava:guava:1.2")
maven.pom(pom_xml="//:pom.xml")

যদি এক্সটেনশনটি রেপো তৈরি করে যা আপনি আপনার মডিউলে ব্যবহার করতে চান, সেগুলি ঘোষণা করতে use_repo নির্দেশিকা ব্যবহার করুন। এটি কঠোর ডিপস শর্তকে সন্তুষ্ট করতে এবং স্থানীয় রেপো নামের দ্বন্দ্ব এড়াতে।

use_repo(
    maven,
    "org_junit_junit",
    guava="com_google_guava_guava",
)

একটি এক্সটেনশন দ্বারা উত্পন্ন রেপোগুলি এর API এর অংশ, তাই আপনার নির্দিষ্ট করা ট্যাগগুলি থেকে, আপনার জানা উচিত যে "maven" এক্সটেনশনটি "org_junit_junit" নামে একটি রেপো তৈরি করতে চলেছে এবং একটি "com_google_guava_guava" নামে পরিচিত। use_repo দিয়ে, আপনি ঐচ্ছিকভাবে আপনার মডিউলের সুযোগে তাদের নাম পরিবর্তন করতে পারেন, যেমন এখানে "পেয়ারা"।

এক্সটেনশন সংজ্ঞা

মডিউল এক্সটেনশনগুলি module_extension ফাংশন ব্যবহার করে রেপো নিয়মের অনুরূপভাবে সংজ্ঞায়িত করা হয়। উভয় একটি বাস্তবায়ন ফাংশন আছে; কিন্তু রেপো নিয়মে অনেকগুলো অ্যাট্রিবিউট থাকার সময়, মডিউল এক্সটেনশনে অনেকগুলো tag_class es থাকে, যার প্রতিটিতে বেশ কিছু অ্যাট্রিবিউট থাকে। ট্যাগ ক্লাস এই এক্সটেনশন দ্বারা ব্যবহৃত ট্যাগের জন্য স্কিমা সংজ্ঞায়িত করে। উপরের অনুমানমূলক "মাভেন" এক্সটেনশনের আমাদের উদাহরণ অব্যাহত রাখা:

# @rules_jvm_external//:extensions.bzl
maven_dep = tag_class(attrs = {"coord": attr.string()})
maven_pom = tag_class(attrs = {"pom_xml": attr.label()})
maven = module_extension(
    implementation=_maven_impl,
    tag_classes={"dep": maven_dep, "pom": maven_pom},
)

এই ঘোষণাগুলি স্পষ্ট করে যে maven.dep এবং maven.pom ট্যাগগুলি নির্দিষ্ট করা যেতে পারে, উপরে সংজ্ঞায়িত অ্যাট্রিবিউট স্কিমা ব্যবহার করে।

ইমপ্লিমেন্টেশন ফাংশনটি module_ctx WORKSPACE পায়, যা নির্ভরতা গ্রাফ এবং সমস্ত প্রাসঙ্গিক ট্যাগগুলিতে অ্যাক্সেস দেয়। ইমপ্লিমেন্টেশন ফাংশনটি তখন রেপো তৈরি করতে রেপো নিয়মগুলিকে কল করা উচিত:

# @rules_jvm_external//:extensions.bzl
load("//:repo_rules.bzl", "maven_single_jar")
def _maven_impl(ctx):
  coords = []
  for mod in ctx.modules:
    coords += [dep.coord for dep in mod.tags.dep]
  output = ctx.execute(["coursier", "resolve", coords])  # hypothetical call
  repo_attrs = process_coursier(output)
  [maven_single_jar(**attrs) for attrs in repo_attrs]

উপরের উদাহরণে, আমরা নির্ভরতা গ্রাফের সমস্ত মডিউলের মধ্য দিয়ে যাই ( ctx.modules ), যার প্রতিটি একটি bazel_module অবজেক্ট যার tags ফিল্ডটি মডিউলের সমস্ত maven maven.* ট্যাগগুলিকে প্রকাশ করে। তারপরে আমরা মাভেনের সাথে যোগাযোগ করতে এবং রেজোলিউশন সম্পাদন করতে CLI ইউটিলিটি কুরসিয়ারকে আহ্বান করি। অবশেষে, আমরা অনুমানমূলক maven_single_jar রেপো নিয়ম ব্যবহার করে অনেকগুলি রেপো তৈরি করতে রেজোলিউশনের ফলাফল ব্যবহার করি।