আর্টিফ্যাক্ট-ভিত্তিক বিল্ড সিস্টেম

এই পৃষ্ঠাটি আর্টিফ্যাক্ট-ভিত্তিক বিল্ড সিস্টেম এবং তাদের সৃষ্টির পিছনের দর্শন কভার করে। Bazel একটি আর্টিফ্যাক্ট-ভিত্তিক বিল্ড সিস্টেম। যদিও টাস্ক-ভিত্তিক বিল্ড সিস্টেমগুলি বিল্ড স্ক্রিপ্টগুলির উপরে একটি ভাল পদক্ষেপ, তারা পৃথক ইঞ্জিনিয়ারদের তাদের নিজস্ব কাজগুলি সংজ্ঞায়িত করতে দিয়ে খুব বেশি শক্তি দেয়।

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

একটি কার্যকরী দৃষ্টিকোণ

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

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

আর্টিফ্যাক্ট-ভিত্তিক বিল্ড সিস্টেম বোঝা

গুগলের বিল্ড সিস্টেম, ব্লেজ ছিল প্রথম আর্টিফ্যাক্ট-ভিত্তিক বিল্ড সিস্টেম। Bazel হল ব্লেজের ওপেন-সোর্স সংস্করণ।

এখানে একটি বিল্ডফাইল (সাধারণত BUILD নামে) ব্যাজেলে দেখতে কেমন লাগে:

java_binary(
    name = "MyBinary",
    srcs = ["MyBinary.java"],
    deps = [
        ":mylib",
    ],
)
java_library(
    name = "mylib",
    srcs = ["MyLibrary.java", "MyHelper.java"],
    visibility = ["//java/com/example/myproduct:__subpackages__"],
    deps = [
        "//java/com/example/common",
        "//java/com/example/myproduct/otherlib",
    ],
)

Bazel-এ, BUILD ফাইলগুলি লক্ষ্যগুলিকে সংজ্ঞায়িত করে—এখানে দুটি ধরনের লক্ষ্য হল java_binary এবং java_library । প্রতিটি লক্ষ্য একটি আর্টিফ্যাক্টের সাথে মিলে যায় যা সিস্টেম দ্বারা তৈরি করা যেতে পারে: বাইনারি লক্ষ্যগুলি বাইনারি তৈরি করে যা সরাসরি চালানো যেতে পারে এবং লাইব্রেরি লক্ষ্যগুলি লাইব্রেরি তৈরি করে যা বাইনারি বা অন্যান্য লাইব্রেরি দ্বারা ব্যবহার করা যেতে পারে। প্রতিটি লক্ষ্য আছে:

  • name : কিভাবে লক্ষ্যটি কমান্ড লাইনে এবং অন্যান্য লক্ষ্য দ্বারা উল্লেখ করা হয়
  • srcs : লক্ষ্যের জন্য আর্টিফ্যাক্ট তৈরি করতে কম্পাইল করা উৎস ফাইল
  • deps : অন্যান্য লক্ষ্যগুলি যা এই লক্ষ্যের আগে তৈরি করা উচিত এবং এটির সাথে সংযুক্ত করা উচিত

নির্ভরতা হয় একই প্যাকেজের মধ্যে হতে পারে (যেমন :mylib এর উপর MyBinary এর নির্ভরতা) অথবা একই উৎস শ্রেণিবিন্যাসের (যেমন mylib এর উপর নির্ভরতা //java/com/example/common ) একটি ভিন্ন প্যাকেজে থাকতে পারে।

টাস্ক-ভিত্তিক বিল্ড সিস্টেমের মতো, আপনি Bazel-এর কমান্ড-লাইন টুল ব্যবহার করে বিল্ডগুলি সম্পাদন করেন। MyBinary টার্গেট তৈরি করতে, আপনি bazel build :MyBinary । একটি পরিষ্কার সংগ্রহস্থলে প্রথমবার সেই কমান্ডটি প্রবেশ করার পরে, Bazel:

  1. শিল্পকর্মের মধ্যে নির্ভরতার একটি গ্রাফ তৈরি করতে কর্মক্ষেত্রে প্রতিটি BUILD ফাইল পার্স করে।
  2. MyBinary এর ট্রানজিটিভ নির্ভরতা নির্ধারণ করতে গ্রাফ ব্যবহার করে; অর্থাৎ, প্রতিটি লক্ষ্য যার উপর MyBinary নির্ভর করে এবং প্রতিটি লক্ষ্য যার উপর সেই লক্ষ্যগুলি নির্ভর করে, পুনরাবৃত্তিমূলকভাবে।
  3. ক্রমানুসারে সেই প্রতিটি নির্ভরতা তৈরি করে। Bazel প্রতিটি টার্গেট তৈরি করে শুরু করে যার অন্য কোন নির্ভরতা নেই এবং প্রতিটি টার্গেটের জন্য কোন নির্ভরতা এখনও তৈরি করা দরকার তা ট্র্যাক রাখে। যত তাড়াতাড়ি একটি লক্ষ্যের সমস্ত নির্ভরতা তৈরি হয়, Bazel সেই লক্ষ্য তৈরি করা শুরু করে। এই প্রক্রিয়া চলতে থাকে যতক্ষণ না MyBinary এর প্রতিটি ট্রানজিটিভ নির্ভরতা তৈরি করা হয়।
  4. একটি চূড়ান্ত এক্সিকিউটেবল বাইনারি তৈরি করতে MyBinary তৈরি করে যা ধাপ 3 এ নির্মিত সমস্ত নির্ভরতার সাথে লিঙ্ক করে।

মৌলিকভাবে, এটা মনে হতে পারে না যে এখানে যা ঘটছে তা একটি টাস্ক-ভিত্তিক বিল্ড সিস্টেম ব্যবহার করার সময় যা ঘটেছিল তার চেয়ে অনেক আলাদা। প্রকৃতপক্ষে, শেষ ফলাফলটি একই বাইনারি, এবং এটি তৈরির প্রক্রিয়াটি তাদের মধ্যে নির্ভরশীলতা খুঁজে বের করার জন্য একগুচ্ছ পদক্ষেপ বিশ্লেষণ করে এবং তারপরে সেই পদক্ষেপগুলিকে ক্রমানুসারে চালায়। কিন্তু সমালোচনামূলক পার্থক্য আছে. প্রথমটি ধাপ 3-এ প্রদর্শিত হয়: কারণ Bazel জানে যে প্রতিটি লক্ষ্য শুধুমাত্র একটি জাভা লাইব্রেরি তৈরি করে, এটি জানে যে এটি যা করতে হবে তা হল একটি নির্বিচারে ব্যবহারকারী-সংজ্ঞায়িত স্ক্রিপ্টের পরিবর্তে জাভা কম্পাইলার চালানো, তাই এটি জানে যে এটি চালানো নিরাপদ সমান্তরাল এই পদক্ষেপ. এটি একটি মাল্টিকোর মেশিনে একের পর এক লক্ষ্যমাত্রা নির্মাণের চেয়ে ব্যাপক কর্মক্ষমতা উন্নতির একটি আদেশ তৈরি করতে পারে এবং কেবলমাত্র সম্ভব কারণ আর্টিফ্যাক্ট-ভিত্তিক পদ্ধতিটি বিল্ড সিস্টেমকে তার নিজস্ব কার্যকরী কৌশলের দায়িত্বে ছেড়ে দেয় যাতে এটি আরও শক্তিশালী গ্যারান্টি তৈরি করতে পারে। সমান্তরালতা

যদিও সুবিধাগুলি সমান্তরালতার বাইরে প্রসারিত। এই পদ্ধতির পরবর্তী যে জিনিসটি আমাদের দেয় তা স্পষ্ট হয়ে ওঠে যখন ডেভেলপার টাইপ করে bazel build :MyBinary এক সেকেন্ডেরও কম সময়ের মধ্যে একটি বার্তা দিয়ে প্রস্থান করে যে টার্গেট আপ টু ডেট। এটি সম্ভব হয়েছে কার্যকরী প্রোগ্রামিং দৃষ্টান্তের কারণে যা আমরা আগে বলেছি—ব্যাজেল জানে যে প্রতিটি টার্গেট শুধুমাত্র একটি জাভা কম্পাইলার চালানোর ফলাফল, এবং এটি জানে যে জাভা কম্পাইলার থেকে আউটপুট শুধুমাত্র তার ইনপুটগুলির উপর নির্ভর করে, তাই যতক্ষণ না ইনপুট পরিবর্তিত হয়নি, আউটপুট পুনরায় ব্যবহার করা যেতে পারে। এবং এই বিশ্লেষণ প্রতিটি স্তরে কাজ করে; যদি MyBinary.java পরিবর্তন হয়, Bazel MyBinary mylib ব্যবহার করতে পারে। যদি //java/com/example/common এর জন্য একটি উৎস ফাইল পরিবর্তন হয়, Bazel সেই লাইব্রেরি, mylib , এবং MyBinary পুনঃনির্মাণ করতে জানে, কিন্তু //java/com/example/myproduct/otherlib পুনরায় ব্যবহার করুন। যেহেতু Bazel প্রতিটি ধাপে এটি চালানোর সরঞ্জামগুলির বৈশিষ্ট্যগুলি সম্পর্কে জানে, তাই এটি বাসি বিল্ড তৈরি করবে না এমন গ্যারান্টি দিয়ে প্রতিবার আর্টিফ্যাক্টের ন্যূনতম সেটটি পুনর্নির্মাণ করতে সক্ষম।

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

অন্যান্য নিফটি Bazel কৌশল

আর্টিফ্যাক্ট-ভিত্তিক বিল্ড সিস্টেমগুলি মৌলিকভাবে সমান্তরালতা এবং পুনঃব্যবহারের সাথে সমস্যাগুলি সমাধান করে যা টাস্ক-ভিত্তিক বিল্ড সিস্টেমের অন্তর্নিহিত। কিন্তু এখনও কিছু সমস্যা রয়েছে যা আগে এসেছিল যা আমরা সমাধান করিনি। Bazel এর প্রতিটি সমাধান করার চতুর উপায় আছে, এবং আমাদের এগিয়ে যাওয়ার আগে সেগুলি নিয়ে আলোচনা করা উচিত।

নির্ভরতা হিসাবে সরঞ্জাম

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

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

Bazel বিল্ড কনফিগারেশন সেট করে সমস্যার দ্বিতীয় অংশ, প্ল্যাটফর্মের স্বাধীনতা সমাধান করে। লক্ষ্যগুলি সরাসরি তাদের সরঞ্জামগুলির উপর নির্ভর করার পরিবর্তে, তারা কনফিগারেশনের প্রকারের উপর নির্ভর করে:

  • হোস্ট কনফিগারেশন : বিল্ডিং টুল যা বিল্ড করার সময় চলে
  • লক্ষ্য কনফিগারেশন : বাইনারি তৈরি করা যা আপনি শেষ পর্যন্ত অনুরোধ করেছেন

বিল্ড সিস্টেম প্রসারিত

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

Bazel-এ একটি নিয়ম সংজ্ঞায়িত করার জন্য, নিয়ম লেখক নিয়মের জন্য প্রয়োজনীয় ইনপুটগুলি ঘোষণা করেন ( BUILD ফাইলে পাস করা বৈশিষ্ট্যগুলির আকারে) এবং আউটপুটগুলির নির্দিষ্ট সেট যা নিয়ম তৈরি করে। লেখক সেই নিয়ম দ্বারা উত্পন্ন ক্রিয়াগুলিও সংজ্ঞায়িত করেছেন। প্রতিটি ক্রিয়া তার ইনপুট এবং আউটপুট ঘোষণা করে, একটি নির্দিষ্ট এক্সিকিউটেবল চালায় বা একটি ফাইলে একটি নির্দিষ্ট স্ট্রিং লেখে এবং এর ইনপুট এবং আউটপুটগুলির মাধ্যমে অন্যান্য ক্রিয়াগুলির সাথে সংযুক্ত হতে পারে। এর মানে হল যে অ্যাকশন হল বিল্ড সিস্টেমের সর্বনিম্ন-স্তরের সংমিশ্রণযোগ্য একক—একটি অ্যাকশন যা ইচ্ছা তাই করতে পারে যতক্ষণ না এটি শুধুমাত্র তার ঘোষিত ইনপুট এবং আউটপুট ব্যবহার করে, এবং Bazel সময়সূচী ক্রিয়াগুলির যত্ন নেয় এবং উপযুক্ত হিসাবে তাদের ফলাফল ক্যাশে করে।

সিস্টেমটি নির্বোধ নয় এই কারণে যে কোনও অ্যাকশন ডেভেলপারকে তাদের ক্রিয়াকলাপের অংশ হিসাবে একটি ননডিটারমিনিস্টিক প্রক্রিয়া চালু করার মতো কিছু করা থেকে থামানোর কোনও উপায় নেই। কিন্তু অনুশীলনে এটি প্রায়শই ঘটে না, এবং অপব্যবহারের সম্ভাবনাগুলিকে অ্যাকশন লেভেল পর্যন্ত ঠেলে দিলে ত্রুটির সুযোগ অনেক কমে যায়। অনেক সাধারণ ভাষা এবং সরঞ্জামগুলিকে সমর্থন করে এমন নিয়মগুলি অনলাইনে ব্যাপকভাবে উপলব্ধ, এবং বেশিরভাগ প্রকল্পের তাদের নিজস্ব নিয়মগুলি সংজ্ঞায়িত করার প্রয়োজন হবে না। এমনকি যারা করে তাদের জন্য, নিয়মের সংজ্ঞাগুলি শুধুমাত্র সংগ্রহস্থলের একটি কেন্দ্রীয় স্থানে সংজ্ঞায়িত করা প্রয়োজন, যার অর্থ বেশিরভাগ প্রকৌশলী তাদের বাস্তবায়ন সম্পর্কে চিন্তা না করেই সেই নিয়মগুলি ব্যবহার করতে সক্ষম হবেন।

পরিবেশ বিচ্ছিন্ন করা

অ্যাকশনগুলি মনে হয় যে তারা অন্যান্য সিস্টেমে কাজগুলির মতো একই সমস্যায় পড়তে পারে—এখনও কি এমন ক্রিয়াগুলি লেখা সম্ভব নয় যা উভয়ই একই ফাইলে লিখে এবং একে অপরের সাথে বিরোধপূর্ণ হয়? আসলে, বেজেল স্যান্ডবক্সিং ব্যবহার করে এই দ্বন্দ্বগুলিকে অসম্ভব করে তোলে। সমর্থিত সিস্টেমে, প্রতিটি ক্রিয়া একটি ফাইল সিস্টেম স্যান্ডবক্সের মাধ্যমে প্রতিটি অন্য ক্রিয়া থেকে আলাদা করা হয়। কার্যকরীভাবে, প্রতিটি ক্রিয়া ফাইল সিস্টেমের শুধুমাত্র একটি সীমাবদ্ধ দৃশ্য দেখতে পারে যা এটি ঘোষিত ইনপুট এবং এটি উত্পাদিত যেকোনো আউটপুট অন্তর্ভুক্ত করে। এটি লিনাক্সে LXC এর মতো সিস্টেম দ্বারা প্রয়োগ করা হয়, ডকারের পিছনে একই প্রযুক্তি। এর অর্থ হ'ল ক্রিয়াগুলির পক্ষে একে অপরের সাথে বিরোধ করা অসম্ভব কারণ তারা যে ফাইলগুলি ঘোষণা করে না তা পড়তে অক্ষম এবং তারা যে ফাইলগুলি লিখে কিন্তু ঘোষণা করে না তা ক্রিয়া শেষ হলে ফেলে দেওয়া হবে৷ ব্যাজেল নেটওয়ার্কের মাধ্যমে যোগাযোগ করা থেকে ক্রিয়াগুলি সীমাবদ্ধ করতে স্যান্ডবক্স ব্যবহার করে।

বাহ্যিক নির্ভরতাকে নির্ধারক করা

এখনও একটি সমস্যা বাকি রয়েছে: বিল্ড সিস্টেমগুলিকে প্রায়শই সরাসরি তৈরি করার পরিবর্তে বাহ্যিক উত্স থেকে নির্ভরতা (যে সরঞ্জাম বা লাইব্রেরি হোক না কেন) ডাউনলোড করতে হবে। এটি @com_google_common_guava_guava//jar নির্ভরতার মাধ্যমে উদাহরণে দেখা যেতে পারে, যা Maven থেকে একটি JAR ফাইল ডাউনলোড করে।

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

মৌলিক সমস্যা হল আমরা চাই যে বিল্ড সিস্টেম এই ফাইলগুলিকে সোর্স কন্ট্রোলে চেক না করেই সচেতন থাকুক। একটি নির্ভরতা আপডেট করা একটি সচেতন পছন্দ হওয়া উচিত, তবে সেই পছন্দটি পৃথক প্রকৌশলীদের দ্বারা বা সিস্টেম দ্বারা স্বয়ংক্রিয়ভাবে পরিচালিত না হয়ে একটি কেন্দ্রীয় স্থানে একবার করা উচিত। এর কারণ হল "লিভ অ্যাট হেড" মডেলের সাথেও, আমরা এখনও বিল্ডগুলিকে নির্ধারক হতে চাই, যা বোঝায় যে আপনি যদি গত সপ্তাহের একটি প্রতিশ্রুতি পরীক্ষা করে দেখেন, তাহলে আপনার নির্ভরতাগুলি এখন যেমন ছিল তার চেয়ে দেখতে হবে।

Bazel এবং অন্যান্য কিছু বিল্ড সিস্টেম একটি ওয়ার্কস্পেসওয়াইড ম্যানিফেস্ট ফাইলের প্রয়োজন যা ওয়ার্কস্পেসের প্রতিটি বাহ্যিক নির্ভরতার জন্য একটি ক্রিপ্টোগ্রাফিক হ্যাশ তালিকাভুক্ত করে এই সমস্যার সমাধান করে। হ্যাশ হল একটি সংক্ষিপ্ত উপায় যা উৎস নিয়ন্ত্রণে সম্পূর্ণ ফাইলটি পরীক্ষা না করেই ফাইলটিকে অনন্যভাবে উপস্থাপন করে। যখনই একটি ওয়ার্কস্পেস থেকে একটি নতুন বাহ্যিক নির্ভরতা উল্লেখ করা হয়, তখন সেই নির্ভরতার হ্যাশটি ম্যানিফেস্টে যোগ করা হয়, হয় ম্যানুয়ালি বা স্বয়ংক্রিয়ভাবে। যখন Bazel একটি বিল্ড চালায়, তখন এটি ম্যানিফেস্টে সংজ্ঞায়িত প্রত্যাশিত হ্যাশের বিপরীতে তার ক্যাশে নির্ভরতার প্রকৃত হ্যাশ পরীক্ষা করে এবং হ্যাশ ভিন্ন হলেই ফাইলটি পুনরায় ডাউনলোড করে।

যদি আমরা যে আর্টিফ্যাক্টটি ডাউনলোড করি তাতে ম্যানিফেস্টে ঘোষিত হ্যাশের চেয়ে আলাদা হ্যাশ থাকে, তবে ম্যানিফেস্টের হ্যাশ আপডেট না হওয়া পর্যন্ত বিল্ড ব্যর্থ হবে। এটি স্বয়ংক্রিয়ভাবে করা যেতে পারে, তবে বিল্ড নতুন নির্ভরতা গ্রহণ করার আগে সেই পরিবর্তনটি অনুমোদিত হতে হবে এবং উত্স নিয়ন্ত্রণে চেক করতে হবে। এর মানে হল যে কখন একটি নির্ভরতা আপডেট করা হয়েছিল তার একটি রেকর্ড সর্বদা থাকে এবং একটি বহিরাগত নির্ভরতা কর্মক্ষেত্রের উত্সে সংশ্লিষ্ট পরিবর্তন ছাড়া পরিবর্তন করতে পারে না। এর মানে হল যে, সোর্স কোডের একটি পুরানো সংস্করণ চেক করার সময়, বিল্ডটি সেই একই নির্ভরতা ব্যবহার করার গ্যারান্টি দেয় যা এটি সেই সংস্করণটি চেক ইন করার সময় ব্যবহার করেছিল (অথবা সেই নির্ভরতাগুলি আর না থাকলে এটি ব্যর্থ হবে উপলব্ধ)।

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