𝗣𝗮𝗰𝗸𝗮𝗴𝗲.𝗷𝘀𝗼𝗻 बनाम 𝗚𝗼.𝗺𝗼𝗱: 𝗩𝗲𝗿𝘀𝗶𝗼𝗻 𝗙𝗶𝗲𝗹𝗱 कहाँ गया?
यदि आप JavaScript से Go पर जाते हैं, तो एक चीज़ आपको हैरान कर देगी।
package.json फ़ाइल में, version बिल्कुल ऊपर होता है। आप इसे पढ़ सकते हैं। आप इसे pull request में बदल सकते हैं। आप इसे खोज सकते हैं। यह एक ऐसा तथ्य है जो आपके कोड के भीतर रहता है।
अब एक go.mod फ़ाइल खोलें। वहाँ version नहीं है।
यह कोई गलती नहीं है। यह एक चुनाव है।
Go आपके अपने module के लिए version field का उपयोग नहीं करता है। इसके बजाय, Go git tags का उपयोग करता है।
Go में version सेट करने के लिए, आप यह करते हैं:
- git tag v1.2.3
- git push origin v1.2.3
git tag ही 'single source of truth' है। जब कोई go get चलाता है, तो Go सही commit खोजने के लिए आपके repository tags को देखता है।
इस डिज़ाइन की एक बड़ी ताकत है। version कभी भी गलत कोड की ओर इशारा नहीं कर सकता। npm में, published code और tagged source अलग-अलग हो सकते हैं। Go में, वे एक ही चीज़ हैं क्योंकि version एक commit का pointer है।
हालाँकि, यह आपके workflow को कई तरह से बदल देता है:
- अपना version खोजने के लिए एक command की आवश्यकता होती है। आपको फ़ाइल देखने के बजाय
git describe --tagsचलाना होगा। - Version bumps code reviews में दिखाई नहीं देते हैं। Tag push कोई code change नहीं है, इसलिए यह pull request में दिखाई नहीं देता है।
- Local builds pseudo-versions का उपयोग करते हैं। जब तक आप किसी commit को tag नहीं करते, आपको v1.2.3 जैसे साफ version के बजाय नंबरों और hashes की एक लंबी स्ट्रिंग दिखाई देती है।
- Major versions आपके import path को बदल देते हैं। npm में, आप version number बदलते हैं लेकिन package name वही रखते हैं। Go में, v2 और उससे ऊपर के लिए
/v2जैसा path change आवश्यक है। यह एक प्रोग्राम को बिना किसी टकराव (clash) के एक ही library के v1 और v2 का एक साथ उपयोग करने की अनुमति देता है।
अधिकांश अन्य ecosystems version को एक फ़ाइल में रखते हैं:
- Node: package.json
- Rust: Cargo.toml
- Python: pyproject.toml
- Java: pom.xml
- .NET: .csproj
Go अलग है। यह केवल git tags पर निर्भर करता है।
यदि आप चाहते हैं कि आपका Go binary एक साफ version दिखाए, तो आप build process के दौरान ldflags का उपयोग करके इसे inject कर सकते हैं। कई developers tag और release process को automate करने के लिए goreleaser जैसे tools का भी उपयोग करते हैं।
ये दोनों मॉडल अलग-अलग प्राथमिकताओं (priorities) को दर्शाते हैं:
- File-based versions को पढ़ना और review करना आसान है। जोखिम यह है कि फ़ाइल वास्तविक कोड से अलग हो सकती है।
- Tag-based versions को फर्जी बनाना असंभव है। इसकी कीमत यह है कि उन्हें देखना और manage करना कठिन होता है।
Go ने tag model को इसलिए चुना ताकि यह सुनिश्चित किया जा सके कि manifest हमेशा कोड से मेल खाए।
जो लोग Go कोड शिप करते हैं: आपके दैनिक कार्य में केवल टैग वाला मॉडल (tag-only model) कैसा महसूस होता है? क्या आप इसे बदलना चाहेंगे?
स्रोत: https://dev.to/dalirnet/packagejson-vs-gomod-where-did-the-version-field-go-3301