𝗣𝗮𝗰𝗸𝗮𝗴𝗲.𝗷𝘀𝗼𝗻 বনাম 𝗚𝗼.𝗺𝗼𝗱: ভার্সন ফিল্ডটি কোথায় হারিয়ে গেল?
আপনি যদি JavaScript থেকে Go-তে চলে আসেন, তবে একটি বিষয় আপনাকে অবাক করবে।
একটি package.json ফাইলে, ভার্সনটি একদম উপরে থাকে। আপনি এটি পড়তে পারেন। আপনি একটি pull request-এ এটি পরিবর্তন করতে পারেন। আপনি এটি সার্চ করতে পারেন। এটি আপনার কোডের ভেতরে থাকা একটি বাস্তব তথ্য।
এখন একটি go.mod ফাইল খুলুন। সেখানে ভার্সনটি নেই।
এটি কোনো ভুল নয়। এটি একটি সিদ্ধান্ত।
Go আপনার নিজস্ব মডিউলের জন্য কোনো version field ব্যবহার করে না। পরিবর্তে, Go git tags ব্যবহার করে।
Go-তে একটি ভার্সন সেট করতে আপনাকে এটি করতে হবে:
- git tag v1.2.3
- git push origin v1.2.3
git tag হলো তথ্যের একমাত্র উৎস (single source of truth)। যখন কেউ go get চালায়, তখন Go সঠিক commit খুঁজে পেতে আপনার রিপোজিটরি ট্যাগগুলো দেখে।
এই ডিজাইনের একটি বড় শক্তি রয়েছে। একটি ভার্সন কখনোই ভুল কোডকে নির্দেশ করতে পারে না। npm-এ, প্রকাশিত কোড এবং ট্যাগ করা সোর্স আলাদা হয়ে যেতে পারে। কিন্তু Go-তে, তারা একই জিনিস কারণ ভার্সনটি একটি commit-এর দিকে নির্দেশকারী একটি পয়েন্টার।
তবে, এটি আপনার কাজের ধারা বা workflow কয়েকভাবে পরিবর্তন করে দেয়:
- ভার্সন খুঁজে পেতে একটি কমান্ডের প্রয়োজন হয়। একটি ফাইলের পরিবর্তে আপনাকে
git describe --tagsচালাতে হবে। - ভার্সন পরিবর্তন (version bumps) কোড রিভিউতে দেখা যায় না। একটি tag push কোনো কোড পরিবর্তন নয়, তাই এটি pull request-এ প্রদর্শিত হয় না।
- লোকাল বিল্ডে pseudo-versions ব্যবহার করা হয়। যতক্ষণ না আপনি একটি commit ট্যাগ করছেন, ততক্ষণ আপনি v1.2.3-এর মতো একটি পরিষ্কার ভার্সনের পরিবর্তে নম্বর এবং হ্যাশ-এর একটি দীর্ঘ স্ট্রিং দেখতে পাবেন।
- মেজর ভার্সনগুলো আপনার import path পরিবর্তন করে দেয়। npm-এ, আপনি ভার্সন নম্বর পরিবর্তন করেন কিন্তু প্যাকেজের নাম একই থাকে। Go-তে, v2 এবং তার উপরের ভার্সনগুলোর জন্য /v2-এর মতো পাথ পরিবর্তন প্রয়োজন হয়। এটি একটি প্রোগ্রামকে কোনো সংঘর্ষ (clash) ছাড়াই একই লাইব্রেরির v1 এবং v2 একসাথে ব্যবহার করার সুযোগ দেয়।
অন্যান্য বেশিরভাগ ইকোসিস্টেম ভার্সন একটি ফাইলের মধ্যে রাখে:
- Node: package.json
- Rust: Cargo.toml
- Python: pyproject.toml
- Java: pom.xml
- .NET: .csproj
Go আলাদা। এটি শুধুমাত্র git tags-এর ওপর নির্ভর করে।
আপনি যদি চান আপনার Go binary একটি পরিষ্কার ভার্সন দেখাক, তবে আপনি build process চলাকালীন ldflags ব্যবহার করে এটি ইনজেক্ট করতে পারেন। অনেক ডেভেলপার tag এবং release প্রক্রিয়াটি স্বয়ংক্রিয় করতে goreleaser-এর মতো টুল ব্যবহার করেন।
এই দুটি মডেল ভিন্ন ভিন্ন অগ্রাধিকার (priorities) প্রকাশ করে:
- ফাইল-ভিত্তিক ভার্সনগুলো পড়া এবং রিভিউ করা সহজ। ঝুঁকি হলো, ফাইলটি আসল কোড থেকে আলাদা হয়ে যেতে পারে।
- ট্যাগ-ভিত্তিক ভার্সন জাল করা অসম্ভব। তবে অসুবিধা হলো, এগুলো দেখা এবং পরিচালনা করা কিছুটা কঠিন।
ম্যানিফেস্ট যেন সবসময় কোডের সাথে সামঞ্জস্যপূর্ণ থাকে, তা নিশ্চিত করতে Go ট্যাগ মডেলটি বেছে নিয়েছে।
যারা Go কোড শিপ করেন: আপনার দৈনন্দিন কাজে tag-only মডেলটি কেমন মনে হয়? আপনি কি এটি পরিবর্তন করতে চাইবেন?
উৎস: https://dev.to/dalirnet/packagejson-vs-gomod-where-did-the-version-field-go-3301