Package.json विरुद्ध Go.mod: व्हर्जन फील्ड कुठे गेले?
जर तुम्ही JavaScript कडून Go कडे गेलात, तर एक गोष्ट तुम्हाला आश्चर्यचकित करेल.
package.json फाईलमध्ये, व्हर्जन अगदी वरच्या बाजूला असते. तुम्ही ते वाचू शकता. तुम्ही pull request मध्ये ते बदलू शकता. तुम्ही ते शोधू शकता. हे तुमच्या कोडमध्येच असलेले एक वास्तव आहे.
आता go.mod फाईल उघडा. तिथे व्हर्जन नसते.
ही चूक नाही. हा एक निर्णय आहे.
Go तुमच्या स्वतःच्या मॉड्यूलसाठी व्हर्जन फील्ड वापरत नाही. त्याऐवजी, Go git tags वापरते.
Go मध्ये व्हर्जन सेट करण्यासाठी, तुम्हाला हे करावे लागते:
git tag v1.2.3git push origin v1.2.3
git tag हाच 'single source of truth' आहे. जेव्हा कोणी go get चालवते, तेव्हा Go योग्य commit शोधण्यासाठी तुमच्या रिपॉझिटरी टॅग्सकडे पाहते.
या डिझाइनची एक मोठी ताकद आहे. व्हर्जन कधीही चुकीच्या कोडकडे निर्देश करू शकत नाही. npm मध्ये, पब्लिश केलेला कोड आणि टॅग केलेला सोर्स एकमेकांपासून वेगळे होऊ शकतात. Go मध्ये, ते दोन्ही एकच असतात कारण व्हर्जन हे एका commit कडे निर्देश करणारे पॉइंटर असते.
तथापि, यामुळे तुमचा वर्कफ्लो (workflow) अनेक प्रकारे बदलतो:
- व्हर्जन शोधण्यासाठी कमांडची आवश्यकता असते. फाईल पाहण्याऐवजी तुम्हाला
git describe --tagsचालवावे लागते. - व्हर्जन अपडेट्स (version bumps) कोड रिव्ह्यूमध्ये दिसत नाहीत. टॅग पुश करणे हा कोड बदल नसतो, त्यामुळे तो pull request मध्ये दिसत नाही.
- लोकल बिल्ड्समध्ये
pseudo-versionsवापरले जातात. जोपर्यंत तुम्ही commit ला टॅग करत नाही, तोपर्यंत तुम्हालाv1.2.3सारख्या स्वच्छ व्हर्जनऐवजी नंबर आणि hashes ची एक लांब स्ट्रिंग दिसते. - मेजर व्हर्जनमुळे तुमचा import path बदलतो. npm मध्ये, तुम्ही व्हर्जन नंबर बदलता पण पॅकेजचे नाव तेच ठेवता. Go मध्ये,
v2आणि त्यावरील व्हर्जनसाठी/v2सारखा पाथ बदलणे आवश्यक असते. यामुळे एखादा प्रोग्राम कोणत्याही संघर्षाशिवाय (clashes) एकाच लायब्ररीचेv1आणिv2एकाच वेळी वापरू शकतो.
इतर बहुतेक इकोसिस्टम्स व्हर्जन फाईलमध्ये ठेवतात:
- Node:
package.json - Rust:
Cargo.toml - Python:
pyproject.toml - Java:
pom.xml - .NET:
.csproj
Go वेगळे आहे. ते फक्त git tags वर अवलंबून आहे.
जर तुम्हाला तुमच्या Go binary मध्ये स्वच्छ व्हर्जन दाखवायचे असेल, तर तुम्ही ldflags वापरून बिल्ड प्रक्रियेदरम्यान ते इंजेक्ट करू शकता. अनेक डेव्हलपर्स टॅग आणि रिलीज प्रक्रिया ऑटोमेट करण्यासाठी goreleaser सारखी टूल्स देखील वापरतात.
हे दोन मॉडेल्स वेगवेगळ्या प्राधान्यक्रमांचे प्रतिनिधित्व करतात:
- फाईल-आधारित व्हर्जन वाचायला आणि रिव्ह्यू करायला सोपे असतात. धोका असा आहे की फाईल प्रत्यक्ष कोडपासून वेगळी होऊ शकते.
- टॅग-आधारित व्हर्जन बनावट करणे अशक्य आहे. तोटा असा आहे की ते पाहणे आणि व्यवस्थापित करणे कठीण असते.
मॅनिफेस्ट (manifest) नेहमी कोडशी जुळेल याची खात्री करण्यासाठी Go ने टॅग मॉडेल निवडले आहे.
जे लोक Go कोड शिप करतात त्यांच्यासाठी: तुमच्या दैनंदिन कामात 'tag-only model' तुम्हाला कसा वाटतो? तुम्ही त्यात काही बदल कराल का?
स्रोत: https://dev.to/dalirnet/packagejson-vs-gomod-where-did-the-version-field-go-3301