শব্দার্থিক সংস্করণ 2.0.0

সারসংক্ষেপ

যদি কোনো সফটওয়্যারের সংস্করণ MAJOR.MINOR.PATCH (ক.খ.গ) বিন্যাসে থাকে, তাহলে সংস্করণ/ভার্সন নম্বর বৃদ্ধি করার বিধিমালা হলো:

  1. বড় (MAJOR) সংখ্যা (ক) বৃদ্ধি পাবে যখন নতুন পরিবর্তনগুলো পুরোনো কোড বা সিস্টেমের সাথে কাজ করবে না, অর্থাৎ কোড বা API-তে আনা নতুন পরিবর্তন পূর্ববর্তী সংস্করণের সাথে অসামঞ্জস্যপূর্ণ (incompatible API changes)।
  2. ছোট (MINOR) সংখ্যা (খ) বৃদ্ধি পাবে যখন নতুন যোগ করা ফাংশনালিটি বা সংযুক্ত কোড পূর্ববর্তী কোড বা সিস্টেমের সাথে সামঞ্জস্যপূর্ণ থাকবে (backward compatible)।
  3. তালি/প্যাচ (PATCH) সংখ্যা (গ) বৃদ্ধি পাবে যখন আপনি কেবল ত্রুটি সংশোধন (bug fix) বা ছোটখাটো পরিমার্জন করবেন, অর্থাৎ পরিবর্তনগুলো পূর্ববর্তী সংস্করণের সাথে পুরোপুরি সামঞ্জস্যপূর্ণ থাকবে।

এছাড়াও প্রাক-প্রকাশ (pre-release) এবং বিল্ড মেটাডেটা (build metadata) যুক্ত করার জন্য MAJOR.MINOR.PATCH বিন্যাসের সাথে সংযোজন হিসেবে অতিরিক্ত লেবেল ব্যবহার করা যায়।

ভূমিকা

সফটওয়্যার ব্যবস্থাপনার জগতে “ডিপেন্ডেন্সি হেল” (dependency hell) নামক এক ভীতিজনক অবস্থা বিদ্যমান; এটি এমন পরিস্থিতি যখন কোন সফটওয়্যার/প্যাকেজ অন্যদের কোড বা প্যাকেজের উপর অত্যধিক নির্ভরশীল হয়ে যায়। আপনার সিস্টেম যত বড় হয় এবং আপনি যত বেশি প্যাকেজ আপনার সফটওয়্যারে যোগ (integrate) করেন, তত বেশি সম্ভাবনা থাকে যে একদিন আপনি নিজেকে এই হতাশার গর্তে খুঁজে পাবেন।

যেসব সিস্টেমে অনেক নির্ভরশীলতা (dependency) থাকে, সেগুলোর নতুন প্যাকেজ সংস্করণ প্রকাশ করা দ্রুতই এক দুঃস্বপ্ন হয়ে উঠতে পারে। যদি ডিপেনডেন্সির স্পেসিফিকেশন খুবই কঠোর হয়, তাহলে আপনি “ভার্সন লক”-এ আটকে যেতে পারেন (অর্থাৎ প্রতিটি নির্ভরশীল প্যাকেজের নতুন সংস্করণ প্রকাশ না করে কেবল নিজের প্যাকেজ আপগ্রেড করার অক্ষমতা বা করতে না পারা)। আর যদি স্পেসিফিকেশন খুব শিথিল হয় বা অল্প নিয়ম দিয়ে নির্ধারিত হয়, তবে আপনি অনিবার্যভাবে “ভার্সন প্রমিস্কুইটি” (version promiscuity) দ্বারা আক্রান্ত হবেন (অর্থাৎ ভবিষ্যতের অনেক ভার্সনের সাথে সামঞ্জস্যতা ধরে নেওয়া, যা বাস্তবসম্মত নয়)। ডিপেন্ডেন্সি হেল হলো সেই অবস্থা যখন ভার্সন লক এবং/অথবা ভার্সন প্রমিস্কুইটি আপনার প্রজেক্টকে সহজে এবং নিরাপদে এগিয়ে নিয়ে যেতে বাধা দেয়।

এই সমস্যার সমাধান হিসেবে আমরা প্রস্তাব দিচ্ছি এক সেট সহজ নিয়ম এবং শর্তসমূহের, যা নির্দেশ করে যে কীভাবে সংস্করণ নম্বরগুলো (version numbers) নির্ধারণ ও বৃদ্ধি করা উচিত। এই নিয়মগুলো মূলত পূর্বে প্রচলিত অনুশীলনের ওপর ভিত্তি করে তৈরি, যা আবদ্ধ-উৎস (closed-source) এবং উন্মুক্ত-উৎস (open-source) উভয় ধরণের সফটওয়্যারের ক্ষেত্রে ব্যাপকভাবে ব্যবহৃত হয়; তবে এগুলো শুধুমাত্র ইতোপূর্বে বিদ্যমান অনুশীলনের মধ্যেই সীমাবদ্ধ নয়। এই সিস্টেম কাজ করার জন্য, প্রথমে আপনাকে একটি পাবলিক এপিআই (public API) তৈরি করতে হবে। এটি হতে পারে ডকুমেন্টেশন আকারে অথবা কোডের মাধ্যমে বাস্তবায়িত। যাই হোক না কেন, এই API-টি স্পষ্ট এবং সুনির্দিষ্ট হওয়া গুরুত্বপূর্ণ। একবার আপনি যখন আপনার পাবলিক এপিআই সঙ্গায়িত করে নিবেন, এরপর থেকে তাতে কোনো নতুন পরিবর্তন আনলে, তা সংস্করণ নম্বর (version number) নির্দিষ্ট ভাবে বৃদ্ধি করার মাধ্যমে নতুন সংস্করণ রূপে প্রকাশ করবেন।

ধরুন, সংস্করণ নম্বরের বিন্যাস এরকম -> “ক.খ.গ” (Major.Minor.Patch), তাহলেঃ কোড বা API-কে উল্লেখযোগ্যভাবে প্রভাবিত করে না এমন ত্রুটি সংশোধন (bug fix) বা ছোটখাটো পরিবর্তনের ক্ষেত্রে “গ” (Patch) সংখ্যা বৃদ্ধি পাবে। উদাহরণঃ 1.4.2 => 1.4.3। কোড বা API-তে এমন সংযোজন/পরিবর্তন করা হয়েছে যা পূর্ববর্তী কোড বা সিস্টেমের সাথে সামঞ্জস্যপূর্ণ (backward compatible), সেক্ষেত্রে “খ” (Minor) সংখ্যা বৃদ্ধি পাবে। উদাহরণঃ 1.4.3 => 1.5.0। কোড বা API-তে এমন পরিবর্তন করা হয়েছে যা পূর্ববর্তী কোড বা সিস্টেমের সাথে অসামঞ্জস্যপূর্ণ (backward incompatible API changes), সেক্ষেত্রে “ক” (Major) সংখ্যা বৃদ্ধি পাবে। উদাহরণঃ 1.5.0 => 2.0.0।

আমরা এই প্রক্রিয়াকে “শব্দার্থিক সংস্করণ (Semantic Versioning)” বলি। এই নিয়ম অনুযায়ী, সংস্করণ নম্বরগুলো (version numbers) এবং সেগুলোর পরিবর্তনের পদ্ধতি সামগ্রিকভাবে কোডে কী পরিবর্তন হয়েছে এবং এক সংস্করণ থেকে অন্য সংস্করণে কী পরিবর্তন এসেছে তা স্পষ্টভাবে প্রকাশ করে।

শব্দার্থিক সংস্করণ স্পেসিফিকেশন বা সবিস্তার বিবরণী (SemVer)

শব্দার্থিক সংস্করণের সবিস্তার বিবরণী (Semantic Versioning Specification)-কে সংক্ষেপে সেমভার (SemVer) বলা হয়ে থাকে।

এই নথিতে “অবশ্যই” (MUST), “কখনো না/অবশ্যই নয়” (MUST NOT), “প্রয়োজনীয়” (REQUIRED), “উচিত” (SHALL), “উচিত নয়” (SHALL NOT), “করা উচিত” (SHOULD), “করা উচিত নয়” (SHOULD NOT), “প্রস্তাবিত” (RECOMMENDED), “পারে” (MAY), এবং “ঐচ্ছিক” (OPTIONAL) শব্দগুলি RFC 2119-এ বর্ণিতভাবে ব্যাখ্যা করতে হবে।

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

  2. একটি স্বাভাবিক সংস্করণ সংখ্যা অবশ্যই (MUST) “ক.খ.গ” আকারে বা বিন্যাসে হবে, যেখানে ‘ক’, ‘খ’, ‘গ’ সবই অঋণাত্মক পূর্ণসংখ্যা (non-negative integers), এবং এর শুরু শূন্য দিয়ে কখনো হবে না (MUST NOT)। ‘ক’ হলো বড় (MAJOR) সংস্করণ, ‘খ’ হলো ছোট (MINOR) সংস্করণ এবং ‘গ’ হলো তালি/প্যাচ (PATCH) সংস্করণ নম্বর। প্রতিটি অংশকে অবশ্যই (MUST) সংখ্যাগতভাবে বৃদ্ধি করতে হবে। উদাহরণস্বরূপ -
    ভুল: 01.10.5 / 1.05.3 / 2.1.007, সঠিক: 0.5.1 / 1.5.3 / 2.1.7, পরিবর্তন: 1.9.0 => 1.10.0 => 1.11.0 => 1.11.1

  3. একবার সংস্করণকৃত প্যাকেজ প্রকাশ করা হলে, সেই সংস্করণের বিষয়বস্তু আর কখনো পরিবর্তন করা যাবে না (MUST NOT)। যেকোনো পরিবর্তন অবশ্যই (MUST) একটি নতুন সংস্করণ হিসাবে প্রকাশ করতে হবে।

  4. বড় (MAJOR) সংস্করণ শূন্য (0.খ.গ) হল প্রাথমিক ডেভেলপমেন্টের জন্য। যেকোনো কিছু যেকোনো মুহূর্তে পরিবর্তন হতে পারে (MAY change)। এমন পাবলিক এপিআইকে স্থিতিশীল হিসেবে বিবেচনা করা উচিত নয় (SHOULD NOT be considered stable)।

  5. সংস্করণ 1.0.0 -এ মূলত পাবলিক API-কে প্রাথমিক ভাবে সংজ্ঞায়িত করে। এই রিলিজের পরে সংস্করণ নম্বর কীভাবে বৃদ্ধি পাবে, তা এই পাবলিক API এবং এটি কীভাবে পরিবর্তিত হচ্ছে তার উপর নির্ভর করে।

  6. কেবলমাত্র পূর্ববর্তী সংস্করণের সাথে সামঞ্জস্যপূর্ণ ত্রুটি সংশোধন (backward compatible bug fixes) করা হলে, তালি/প্যাচ (PATCH) সংস্করণ ‘গ’ (ক.খ.গ   ক>0) অবশ্যই (MUST) বৃদ্ধি করতে হবে। ত্রুটি সংশোধন হলো কোডের অভ্যন্তরীণ পরিবর্তন যা কোনো ভুল আচরণ ঠিক করে।
  7. যদি API-তে নতুন কোনো ফিচার যোগ করা হয় যা পূর্ববর্তী সংস্করণের সাথে সামঞ্জস্যপূর্ণ (backward compatible), তাহলে অবশ্যই (MUST) ছোট (MINOR) সংস্করণ সংখ্যা ‘গ’ (ক.খ.গ   ক>0) বৃদ্ধি করতে হবে। যদি পাবলিক API-এর কোন ফাংশনালিটি অপ্রচলিত/অননুমোদিত (deprecated) হিসাবে চিহ্নিত করা হয়, তবে ‘গ’ অবশ্যই (MUST) বৃদ্ধি করতে হবে। যদি সংরক্ষিত/অপ্রকাশ্য (private) কোডের মধ্যে উল্লেখযোগ্য নতুন ফাংশনালিটি বা উন্নতি আনা হয়, তবে ‘গ’ বৃদ্ধি পেতে পারে (MAY be incremented)। এই স্তরে প্যাচ/তালি পর্যায়ের পরিবর্তনগুলিও অন্তর্ভুক্ত থাকতে পারে (MAY include)। যখন ছোট (MINOR) সংস্করণ বৃদ্ধি করা হয়, তখন প্যাচ (PATCH) সংস্করণ ‘গ’ অবশ্যই (MUST) শূন্যতে (0) রিসেট করতে হবে।
  8. পাবলিক API-তে পূর্ববর্তী সংস্করণের সাথে অসামঞ্জস্যপূর্ণ কোনো পরিবর্তন আনা হলে বড় (MAJOR) সংস্করণ সংখ্যা ‘ক’ (ক.খ.গ   ক>0) অবশ্যই (MUST) বৃদ্ধি করতে হবে। এতে ছোট (MINOR) এবং প্যাচ (PATCH) পর্যায়ের পরিবর্তনও অন্তর্ভুক্ত থাকতে পারে (MAY also include)। যখন বড় সংস্করণ সংখ্যা ‘ক’ বৃদ্ধি করা হয়, তখন ছোট সংস্করণ সংখ্যা ‘খ’ এবং তালি/প্যাচ সংস্করণ সংখ্যা ‘গ’, উভয়কে অবশ্যই (MUST) শূন্যতে (0) রিসেট করতে নিতে হবে।
  9. একটি প্রাক-প্রকাশিত সংস্করণকে (pre-release version) সাধারণত PATCH সংস্করণ সংখ্যা (গ)-এর ঠিক পরে একটি হাইফেন এবং (.) দ্বারা পৃথককৃত শনাক্তকারীসমূহের (identifiers) একটি সিরিজ সংযুক্ত করে প্রকাশ করা যেতে পারে (MAY be denoted)। শনাক্তকারী (identifier) হিসেবে অবশ্যই (MUST) ASCII অক্ষর, সংখ্যা এবং হাইফেন [0-9A-Za-z-] ব্যবহার করতে হবে, এছাড়া আর কিছু ব্যবহার করা যাবে না। শনাক্তকারী (identifier) কখনোই ফাঁকা থাকতে পারবে না (MUST NOT)। যদি শনাক্তকারীটি সংখ্যাসূচক হয়, তাহলে সেটি কখনোই শূন্য (0) দিয়ে শুরু করা যাবে না (MUST NOT)। প্রাক-প্রকাশিত সংস্করণের প্রাধান্য (precedence) সংশ্লিষ্ট সাধারণ সংস্করণের তুলনায় সর্বদা কম হবে। এটি বোঝায় যে সংস্করণটি এখনও স্থিতিশীল নয় (unstable) এবং উপযুক্ততা যাচাইয়ের জন্য সংশ্লিষ্ট সাধারণ সংস্করণের নির্ধারিত শর্তাবলী এটি পূরণ নাও করতে পারে। উদাহরণ: 1.0.0-alpha 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92, 1.0.0-x-y-z.--.
  10. Patch বা Pre-release নম্বর-এর ঠিক পরে একটি যোগ চিহ্ন (+) এবং ডট (.) দ্বারা পৃথককৃত শনাক্তকারকের একটি সিরিজ যুক্ত করে বিল্ড মেটাডেটা (Build metadata) নির্দেশ করা যেতে পারে (MAY be denoted)। শনাক্তকারী (identifier) হিসেবে অবশ্যই (MUST) ASCII অক্ষর, সংখ্যা এবং হাইফেন [0-9A-Za-z-] ব্যবহার করতে হবে, এছাড়া আর কিছু ব্যবহার করা যাবে না। শনাক্তকারী কখনোই ফাঁকা থাকতে পারবে না (MUST NOT)। সংস্করণের অগ্রাধিকার নির্ধারণের সময় বিল্ড মেটাডেটাকে অবশ্যই (MUST) উপেক্ষা করতে হবে। সুতরাং, দুটি সংস্করণ যাদের কেবলমাত্র বিল্ড মেটাডেটা ভিন্ন, তাদের অগ্রাধিকার একই মূলত একই রকম হবে। উদাহরণ: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85, 1.0.0+21AF26D3----117B344092BD.

  11. প্রাধান্য/অগ্রাধিকার (Precedence) বলতে বোঝায় যে, ক্রমানুসারে সাজানোর সময় সংস্করণগুলোকে একে অপরের সাথে কীভাবে তুলনা করা হয়।

    1. অগ্রাধিকার গণনা করার সময় অবশ্যই (MUST) সংস্করণটিকে বড় (MAJOR), ছোট (MINOR), তালি/প্যাচ (PATCH) এবং প্রি-রিলিজ নম্বর/শনাক্তকারক অনুযায়ী ক্রমানুসারে আলাদা করে নিতে হবে (বিল্ড মেটাডেটাকে অগ্রাধিকারে গণনা করা হয় না)।

    2. শনাক্তকারীগুলোকে বাম থেকে ডানে প্রতিটির তুলনা করার সময় প্রথম পরিলক্ষীত পার্থক্য দ্বারা অগ্রাধিকার নির্ধারণ করা হয়: বড় (MAJOR), ছোট (MINOR), এবং প্যাচ (PATCH) সংস্করণগুলোকে সর্বদা সংখ্যাগতভাবে তুলনা করা হয়।

      উদাহরণ: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1.

    3. যখন বড় (MAJOR), ছোট (MINOR), এবং প্যাচ (PATCH) সমান হয়, তখন একটি প্রাক-প্রকাশিত (pre-release) সংস্করণের অগ্রাধিকার একটি সাধারণ সংস্করণের তুলনায় কম থাকে।

      উদাহরণ: 1.0.0-alpha < 1.0.0.

    4. একই বড় (MAJOR), ছোট (MINOR), এবং প্যাচ (PATCH) সংস্করণ-সহ, দুটি প্রি-রিলিজ সংস্করণের জন্য অগ্রাধিকার অবশ্যই (MUST) বাম থেকে ডানে প্রতিটি ডট দ্বারা পৃথক করা শনাক্তকারক তুলনা করে নির্ধারণ করতে হবে, যতক্ষণ না একটি পার্থক্য পাওয়া যায়। যেমন:

      1. শুধুমাত্র সংখ্যা নিয়ে গঠিত শনাক্তকারকগুলোকে সংখ্যাগতভাবে তুলনা করা হয়।

      2. অক্ষর বা হাইফেন সহ শনাক্তকারকগুলোকে ASCII সর্ট অর্ডারে আভিধানিকভাবে তুলনা করা হয়।

      3. সংখ্যাসূচক শনাক্তকারকগুলোর (numeric identifiers) অগ্রাধিকার সর্বদা অ-সংখ্যাসূচক শনাক্তকারকগুলির চেয়ে কম থাকে।

      4. যদি পূর্ববর্তী সমস্ত শনাক্তকারকগুলো সমান হয়, তবে প্রি-রিলিজ ক্ষেত্রের একটি বৃহত্তর সেটের অগ্রাধিকার, একটি ছোট সেটের তুলনায় বেশি।

      উদাহরণ: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.

সঠিক SemVer সংস্করণসমূহের জন্য ব্যাকাস-নাউর ফর্ম (Backus–Naur Form) ব্যাকরণ

<valid semver> ::= <version core>
                 | <version core> "-" <pre-release>
                 | <version core> "+" <build>
                 | <version core> "-" <pre-release> "+" <build>

<version core> ::= <major> "." <minor> "." <patch>

<major> ::= <numeric identifier>

<minor> ::= <numeric identifier>

<patch> ::= <numeric identifier>

<pre-release> ::= <dot-separated pre-release identifiers>

<dot-separated pre-release identifiers> ::= <pre-release identifier>
                                          | <pre-release identifier> "." <dot-separated pre-release identifiers>

<build> ::= <dot-separated build identifiers>

<dot-separated build identifiers> ::= <build identifier>
                                    | <build identifier> "." <dot-separated build identifiers>

<pre-release identifier> ::= <alphanumeric identifier>
                           | <numeric identifier>

<build identifier> ::= <alphanumeric identifier>
                     | <digits>

<alphanumeric identifier> ::= <non-digit>
                            | <non-digit> <identifier characters>
                            | <identifier characters> <non-digit>
                            | <identifier characters> <non-digit> <identifier characters>

<numeric identifier> ::= "0"
                       | <positive digit>
                       | <positive digit> <digits>

<identifier characters> ::= <identifier character>
                          | <identifier character> <identifier characters>

<identifier character> ::= <digit>
                         | <non-digit>

<non-digit> ::= <letter>
              | "-"

<digits> ::= <digit>
           | <digit> <digits>

<digit> ::= "0"
          | <positive digit>

<positive digit> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

<letter> ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J"
           | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T"
           | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | "b" | "c" | "d"
           | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n"
           | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x"
           | "y" | "z"

কেন শব্দার্থিক সংস্করণ (Semantic Versioning) ব্যবহার করবেন?

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

একটি সহজ উদাহরণ পরিষ্কার করবে যে কীভাবে শব্দার্থিক সংস্করণ (Semantic Versioning) নির্ভরতা সংক্রান্ত জটিলতা (dependency hell) কে অতীতের একটি বিষয় করে তুলতে পারেঃ
“Firetruck” নামক একটি লাইব্রেরির কথা বিবেচনা করুন, এটি “Ladder” নামক একটি শব্দার্থিক সংস্করণযুক্ত প্যাকেজের উপর নির্ভর করে। যখন Firetruck তৈরি করা হয়, তখন Ladder এর সংস্করণ “3.1.0” ছিল। যেহেতু Firetruck এমন কিছু ফাংশনালিটি ব্যবহার করছে যা “3.1.0” সংস্করণে অন্তর্ভুক্ত আছে, তাই আপনি নিরাপদে Ladder এর উপর নির্ভরতা (dependency) হিসেবে উল্লেখ করতে পারবেন এর সংস্করণ “3.1.0”-এর সমান বা বড়, কিন্তু সংস্করণ “4.0.0”-এর থেকে কম (≥ 3.1.0 এবং < 4.0.0)। এখন যখন Ladder-এর “3.1.1” এবং “3.2.0” সংস্করণ আসবে, তখন আপনি সেগুলো আপনার প্যাকেজ ম্যানেজমেন্ট সিস্টেমে ব্যবহার করতে পারবেন, এবং নিশ্চিত থাকতে পারবেন যে এগুলো বিদ্যমান নির্ভরশীল সফটওয়্যার (Firetruck)-এর সাথে সামঞ্জস্যপূর্ণ থাকবে।

একজন দায়িত্বশীল ডেভেলপার হিসেবে, আপনি অবশ্যই নিশ্চিত হতে চাইবেন যে কোনো প্যাকেজের আপগ্রেড প্রত্যাশা মতো কাজ করছে। বাস্তব জগৎ অগোছালো; এ ব্যাপারে আমাদের কিছুই করার নেই, কেবল সতর্ক থাকা ছাড়া। আপনি যা করতে পারেন তা হলো শব্দার্থিক সংস্করণ (Semantic Versioning) ব্যবহার করে একটি সুসঙ্গত পদ্ধতি অবলম্বন করা। এটি আপনাকে নির্ভরশীল প্রতিটি প্যাকেজের সংস্করণ আলাদা করে পরিবর্তন না করেও আপনার প্রজেক্টের নতুন প্যাকেজ প্রকাশ ও আপগ্রেড করার সুযোগ দেবে; এতে সময় বাঁচবে এবং ঝামেলা কমবে।

যদি এগুলো আপনার কাছে আকর্ষণীয় বা যৌক্তিক শোনায়, তাহলে শব্দার্থিক সংস্করণ (Semantic Versioning) ব্যবহার শুরু করার জন্য আপনাকে যা করতে হবে তা হলো, আপনি যে এটি ব্যবহার করছেন তা ঘোষণা করা এবং তারপর উল্লেখিত নিয়মগুলি অনুসরণ করা। পরিশেষে আদর্শ কমিউনিটি গঠনে, আপনার README ফাইল থেকে এই ওয়েবসাইটের লিঙ্ক দিতে পারেন, যাতে অন্যরাও এই নিয়মগুলো জানতে পারে এবং উপকৃত হতে পারে।

প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী (FAQ)

প্রাথমিক ডেভেলপমেন্ট পর্যায় “0.খ.গ”-তে, ধারাবাহিক সংশোধনী (revisions) নিয়ে আমার কীভাবে কাজ করা উচিত?

(How should I deal with revisions in the 0.y.z initial development phase?)

সবচেয়ে সহজ উপায় হলো আপনার প্রাথমিক ডেভেলপমেন্ট রিলিজ শুরু করা “0.1.0” থেকে এবং তারপর প্রতিটি পরবর্তী রিলিজে ছোট (MINOR) সংস্করণ (খ) বাড়ানো।

আমি কীভাবে বুঝব যে সংস্করণ “1.0.0” প্রকাশ করার সময় হয়েছে?

(How do I know when to release 1.0.0?)

এই পদ্ধতি কি ত্বরান্বিত ডেভেলপমেন্ট এবং দ্রুত পুনরাবৃত্তিকে নিরুৎসাহিত করে না?

(Doesn’t this discourage rapid development and fast iteration?)

বড় (MAJOR) সংস্করণ শূন্য (0.খ.গ) মূলত দ্রুত ডেভেলপমেন্টের জন্যেই থাকে। যদি এমন হয় যে আপনি প্রতিদিনই API পরিবর্তন করছেন, তাহলে হয় আপনার এখনো “0.খ.গ” পর্যায়ে থাকা উচিত অথবা পরবর্তী বড় সংস্করণ নিয়ে আলাদা একটি ডেভেলপমেন্ট শাখায়/ব্রাঞ্চে কাজ করা উচিত।

যদি পাবলিক API-তে পূর্ববর্তী সংস্করণের সাথে অসামঞ্জস্যপূর্ণ (backward incompatible) অতি ছোট কোনো পরিবর্তনের জন্যেও বড় (MAJOR) সংস্করণ সংখ্যা (ক) বাড়াতে হয়, তাহলে কি আমি খুব দ্রুতই “42.0.0”-এ পৌঁছে যাব না?

(If even the tiniest backward incompatible changes to the public API require a major version bump, won’t I end up at version 42.0.0 very rapidly?)

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

পুরো পাবলিক এপিআই নথিভুক্ত করা সত্যিই অতিরিক্ত পরিশ্রমসাধ্য কাজ!

(Documenting the entire public API is too much work!)

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

আমি যদি ভুলবশত পূর্ববর্তী সংস্করণের সাথে অসামঞ্জস্যপূর্ণ (backward incompatible) পরিবর্তনকে একটি ছোট সংস্করণ (MINOR version) হিসেবে প্রকাশ করে ফেলি, তবে আমার কী করা উচিত?

(What do I do if I accidentally release a backward incompatible change as a minor version?)

পূর্ববর্তী সংস্করণের সাথে অসামঞ্জস্যপূর্ণ পরিবর্তনকে বড় (MAJOR) সংস্করণ হিসবে প্রকাশ করতে হয়। তাই যখনই বুঝতে পারবেন যে আপনি শব্দার্থিক সংস্করণ (Semantic Versioning)-এর বিধি লঙ্ঘন করেছেন, তখনই সমস্যাটি সমাধান করুন এবং নতুন আরেকটি ছোট সংস্করণ (MINOR version) প্রকাশ করুন যা সমস্যাটি সংশোধন করে এবং পূর্ববর্তী সংস্করণের সাথে সামঞ্জস্যতা পুনরুদ্ধার করে (restores backward compatibility)। এমন পরিস্থিতিতেও, ইতিমধ্যে প্রকাশিত সংস্করণের কোডে কোন পরিবর্তন গ্রহণযোগ্য নয়। প্রযোজ্য ক্ষেত্রে, ত্রুটিযুক্ত সংস্করণটি নথিভুক্ত/ডকুমেন্ট করুন এবং আপনার সফটওয়্যার ব্যবহারকারীদের উক্ত সংস্করণটির সমস্যা সম্পর্কে অবহিত করুন যাতে তারা সচেতন থাকতে পারেন।

যদি আমি আমার নিজের ডিপেনডেন্সি আপডেট করি কিন্তু পাবলিক API পরিবর্তন না করি, তবে কী হবে?

(What should I do if I update my own dependencies without changing the public API?)

যেহেতু এটি পাবলিক এপিআইকে প্রভাবিত করে না, তাই এটিকে সামঞ্জস্যপূর্ণ (compatible) হিসাবে বিবেচনা করা হবে। যে সফটওয়্যার/সমূহ আপনার প্যাকেজের মতো একই ডিপেন্ডেন্সিগুলোর উপর স্পষ্টভাবে নির্ভর করে, তাদের নিজস্ব নির্ভরশীলতার সবিস্তার বিবরণী (dependency specifications) থাকা উচিত এবং সেক্ষেত্রে লেখক যেকোনো দ্বন্দ্ব সহজেই শনাক্ত করে নিবেন। কোনো পরিবর্তন প্যাচ (PATCH) নাকি ছোট (MINOR) পর্যায়ের পরিবর্তন হিসেবে গণ্য হবে তা নির্ভর করে দুটি বিষয়ের উপর। প্রথমত, ডিপেন্ডেন্সি আপডেটটি কি শুধুমাত্র কোনো ত্রুটি (bug) সংশোধনের জন্য করা হয়েছে, নাকি দ্বিতীয়ত এর মাধ্যমে নতুন ফাংশনালিটি যুক্ত হয়েছে। সাধারণত দ্বিতীয় ক্ষেত্রে নতুন কোড যুক্ত হয়, ফলে এটি স্পষ্টভাবে একটি ছোট (MINOR) পর্যায়ের পরিবর্তন হবে, অর্থাৎ সংস্করণের ‘খ’ (ক.খ.গ) অংশটি বৃদ্ধি পাবে।

আমি যদি ভুলবশত পাবলিক API-কে এমনভাবে পরিবর্তন করি যা সংস্করণ নম্বর পরিবর্তন বিধির সাথে সঙ্গতিপূর্ণ নয় (যেমন, প্যাচ রিলিজে ভুলবশত একটি বড় পরিবর্তন যুক্ত হয়ে গেছে), তবে কী করব?

(What if I inadvertently alter the public API in a way that is not compliant with the version number change (i.e. the code incorrectly introduces a major breaking change in a patch release)?)

আপনার সর্বোচ্চ বিচারবুদ্ধির প্রয়োগ করুন। যদি আপনার এপিআই ব্যবহারকারীর সংখ্যা অনেক বেশি হয় এবং তাদেরকে এই পরিবর্তন গুরুতরভাবে প্রভাবিত করে, তাহলে বড় সংস্করণ (MAJOR version) প্রকাশ করাই উত্তম হতে পারে, যদিও সংশোধনটি কেবল একটি প্যাচ (PATCH) হিসেবেই গণ্য হতে পারতো। মনে রাখবেন, শব্দার্থিক সংস্করণ (Semantic Versioning) হলো সংস্করণ নম্বরের পরিবর্তনের মাধ্যমে অর্থ বা বার্তা প্রকাশ করার একটি পদ্ধতি। যদি এই পরিবর্তনগুলি আপনার ব্যবহারকারীর জন্য গুরুত্বপূর্ণ হয়, তাহলে তাদের অবহিত করার জন্য যথাযথ সংস্করণ নম্বর ব্যবহার করুন।

আমি কীভাবে কোন ফাংশনালিটিকে অগ্রাহ্য/অননুমোদিত (deprecate) করবো?

(How should I handle deprecating functionality?)

বিদ্যমান ফাংশনালিটিকে ডিপ্রিকেট করা সফটওয়্যার ডেভেলপমেন্টের স্বাভাবিক একটি অংশ এবং নতুন ধারায় অগ্রগতির জন্য প্রায়ই প্রয়োজন হয়। যখন আপনি আপনার পাবলিক API-এর কোনো অংশ ডিপ্রিকেট/অননুমোদিত করবেন, তখন আপনার দুটি কাজ করা উচিতঃ (১) আপনার নথিপত্র/ডকুমেন্টেশন আপডেট করতে হবে যাতে ব্যবহারকারীরা পরিবর্তন সম্পর্কে জানতে পারেন, (২) ডিপ্রিকেটেড/অননুমোদিত হওয়া অংশ যুক্ত করে একটি নতুন ছোট (MINOR) সংস্করণ প্রকাশ করবেন। কোনো নতুন প্রকাশিত একটি বড় সংস্করণ (MAJOR version) থেকে ডিপ্রিকেটেড ফাংশনালিটি সম্পূর্ণরূপে সরিয়ে ফেলার আগে, ডিপ্রিকেট হওয়া অংশ সহ কমপক্ষে একটি ছোট (MINOR) সংস্করণ প্রকাশ করা উচিত, যাতে ব্যবহারকারীরা নতুন API-তে সহজে রূপান্তরিত হতে পারেন।

SemVer সংস্করণের স্ট্রিং-এ, দৈর্ঘ্যের কোনো সীমা আছে কি?

(Does SemVer have a size limit on the version string?)

না, তবে যৌক্তিক বিচার-বিবেচনা প্রয়োগ করুন। উদাহরণস্বরূপ, ২৫৫ অক্ষরের একটি সংস্করণ স্ট্রিং সম্ভবত অযথা দীর্ঘ হয়ে যাবে। এছাড়াও, কিছু সিস্টেম এক্ষেত্রে তাদের নিজস্ব সীমা আরোপ করতে পারে।

“v1.2.3” কি একটি শব্দার্থিক সংস্করণ (Semantic Version)?

(Is “v1.2.3” a semantic version?)

না, “v1.2.3” সরাসরি একটি শব্দার্থিক সংস্করণ নয়। তবে, কোনো শব্দার্থিক সংস্করণের আগে “v” উপসর্গ যোগ করে (ইংরেজিতে) এটিকে সংস্করণ সংখ্যা হিসেবে নির্দেশ করা একটি সাধারণ পদ্ধতি। “version” শব্দকে সংক্ষেপে “v” হিসেবে ব্যবহার করা সংস্করণ নিয়ন্ত্রণ (version control)-এ প্রায়ই দেখা যায়। উদাহরণস্বরূপ: git tag v1.2.3 -m "Release version 1.2.3", এখানে “v1.2.3” একটি ট্যাগের নাম, আর প্রকৃত শব্দার্থিক সংস্করণ হলো “1.2.3”।

SemVer স্ট্রিং যাচাই করার জন্য কি কোনো প্রস্তাবিত/প্রকাশিত রেগুলার এক্সপ্রেশন (RegEx) আছে কি?

(Is there a suggested regular expression (RegEx) to check a SemVer string?)

হ্যাঁ, দুইটি আছে। একটিতে নামযুক্ত গ্রুপ (named groups) রয়েছে সেসব সিস্টেমের জন্য যেগুলো তা সমর্থন করে (যেমন ― PCRE [Perl Compatible Regular Expressions, i.e. Perl, PHP and R], Python and Go)

দেখুন: https://regex101.com/r/Ly7O1x/3/

^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$

আরেকটিতে সংখ্যাযুক্ত ক্যাপচার গ্রুপ (numbered capture groups) রয়েছে (যেমন cg1 = major, cg2 = minor, cg3 = patch, cg4 = prerelease এবং cg5 = buildmetadata) যা ECMA Script (জাভাস্ক্রিপ্ট), PCRE, Python এবং Go-এর সাথে সামঞ্জস্যপূর্ণ।

দেখুন: https://regex101.com/r/vkijKf/1/

^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$

SemVer সম্পর্কে

শব্দার্থিক সংস্করণ (Semantic Versioning) স্পেসিফিকেশনটি রচনা করেছেন টম প্রেস্টন-ওয়ার্নার, যিনি গ্রেভাটার (Gravatar)-এর আবিষ্কারক এবং গিটহাবের (GitHub) সহ-প্রতিষ্ঠাতা। এর বাংলা অনুবাদ করেছেন ফরহাদ খান

এই স্পেসিফিকেশনটি নিয়ে আপনার কোনো মতামত বা প্রতিক্রিয়া থাকলে, অনুগ্রহ করে গিটহাবে একটি ইস্যু তৈরি করে জানান

লাইসেন্স

Creative Commons ― CC BY 3.0