𝗣𝗮𝗰𝗸𝗮𝗴𝗲.𝗷𝘀𝗼𝗻 𝗹𝗮𝘄𝗮𝗻 𝗚𝗼.𝗺𝗼𝗱: 𝗞𝗲𝗺𝗮𝗻𝗮 𝗙𝗶𝗲𝗹𝗱 𝗩𝗲𝗿𝘀𝗶𝗼𝗻 𝗣𝗲𝗿𝗴𝗶?
Jika Anda berpindah dari JavaScript ke Go, satu hal akan mengejutkan Anda.
Dalam file package.json, versinya ada tepat di bagian atas. Anda bisa membacanya. Anda bisa mengubahnya dalam sebuah pull request. Anda bisa mencarinya. Ini adalah sebuah fakta yang hidup di dalam kode Anda.
Sekarang buka file go.mod. Versinya tidak ada di sana.
Ini bukan sebuah kesalahan. Ini adalah sebuah pilihan.
Go tidak menggunakan field versi untuk modul Anda sendiri. Sebaliknya, Go menggunakan git tags.
Untuk menetapkan versi di Go, Anda melakukan ini:
git tag v1.2.3git push origin v1.2.3
Git tag adalah satu-satunya sumber kebenaran (single source of truth). Saat seseorang menjalankan go get, Go akan melihat tag repositori Anda untuk menemukan commit yang tepat.
Desain ini memiliki kekuatan utama. Sebuah versi tidak akan pernah merujuk ke kode yang salah. Di npm, kode yang dipublikasikan dan sumber yang diberi tag bisa menjadi tidak sinkron. Di Go, keduanya adalah hal yang sama karena versi adalah penunjuk (pointer) ke sebuah commit.
Namun, hal ini mengubah alur kerja Anda dalam beberapa cara:
- Menemukan versi Anda memerlukan sebuah perintah. Anda harus menjalankan
git describe --tagsalih-alih melihat sebuah file. - Peningkatan versi (version bumps) tidak muncul dalam peninjauan kode (code reviews). Push tag bukanlah perubahan kode, sehingga tidak muncul dalam pull request.
- Build lokal menggunakan pseudo-versions. Sampai Anda memberi tag pada sebuah commit, Anda akan melihat deretan angka dan hash yang panjang alih-alih versi yang bersih seperti v1.2.3.
- Versi mayor mengubah jalur impor (import path) Anda. Di npm, Anda mengubah nomor versi tetapi tetap mempertahankan nama paket. Di Go, v2 dan ke atas memerlukan perubahan jalur seperti
/v2. Hal ini memungkinkan sebuah program untuk menggunakan v1 dan v2 dari pustaka yang sama secara bersamaan tanpa konflik.
Sebagian besar ekosistem lainnya menyimpan versi di dalam sebuah file:
- Node:
package.json - Rust:
Cargo.toml - Python:
pyproject.toml - Java:
pom.xml - .NET:
.csproj
Go berbeda. Go hanya mengandalkan git tags.
Jika Anda ingin biner Go Anda menampilkan versi yang bersih, Anda dapat menyuntikkannya selama proses build menggunakan ldflags. Banyak pengembang juga menggunakan alat seperti goreleaser untuk mengotomatiskan proses tag dan rilis.
Kedua model tersebut mewakili prioritas yang berbeda:
- Versi berbasis file mudah dibaca dan ditinjau. Risikonya adalah file tersebut dapat menjadi tidak sinkron dengan kode yang sebenarnya.
- Versi berbasis tag mustahil untuk dipalsukan. Konsekuensinya adalah versi tersebut lebih sulit untuk dilihat dan dikelola.
Go memilih model tag untuk memastikan manifest selalu sesuai dengan kode.
Bagi Anda yang merilis kode Go: Bagaimana rasanya menggunakan model berbasis tag saja dalam pekerjaan sehari-hari Anda? Apakah Anda akan mengubahnya?
Sumber: https://dev.to/dalirnet/packagejson-vs-gomod-where-did-the-version-field-go-3301