npm, Cargo, Composer dan pip semuanya mentafsir singkatan semver yang sama secara berbeza, dan hanya dua daripada tiga belas ungkapan julat yang saya uji berkelakuan serupa merentasi keempat-empatnya.
Saya menulis parser berasingan untuk setiap pengurus, mengikut spesifikasi rasmi mereka, dan kemudian menjalankan setiap julat terhadap matriks sembilan belas nombor versi. Grid 13 × 19 (247 sel) menunjukkan gambaran yang berpecah-belah: hanya 17 sel memberikan jawapan “ya” atau “tidak” yang sama daripada setiap alatan, dan kebanyakan daripada 17 sel tersebut adalah penolakan sebulat suara. Ringkasnya, alatan-alatan ini lebih kerap bersetuju pada “tidak” berbanding “ya”.
Mengapa alatan-alatan ini berbeza
Keempat-empat pengurus mendakwa mengikut Semantic Versioning, namun setiap satu menambah peraturan singkatan tersendiri.
- Caret (^) dan dot-x – npm menyokong caret; pip mengabaikan kedua-dua caret dan dot-x. Perkara itu sahaja mewujudkan percanggahan sebanyak 49 sel antara npm dan pip.
- Versi kosong (Bare versions) – Cargo menganggap
1.2.3biasa sebagai julat caret, yang bermaksud “serasi dengan 1.x”. npm dan Composer membaca rentetan yang sama sebagai padanan tepat, dan hanya menerima1.2.3. - Tilde (~) – Tilde Cargo menetapkan versi minor (
~1.2sepadan dengan1.2.*tetapi bukan1.3.0). Tilde Composer menetapkan versi major (~1.2sepadan dengan1.*). Kedua-dua tafsiran ini berbeza pada mana-mana versi yang mengubah komponen minor.
Pengendalian pra-rilis (pre-release) menambah satu lagi kejutan. Julat seperti ^1.2.3 tidak menyertakan 2.0.0-rc.1, walaupun bahagian numeriknya lebih rendah daripada had atas. Peraturannya: pra-rilis dikecualikan melainkan julat tersebut menyebut pengenal pasti pra-rilis secara eksplisit.
Satu-satunya sintaks rentas-alatan yang selamat
Eksperimen ini menunjukkan bahawa julat ketidaksamaan eksplisit—contohnya >=1.2.0 <2.0.0—berkelakuan dengan cara yang sama dalam npm, Cargo, Composer dan pip. Setiap pengurus menganggap dua sempadan tersebut sebagai had numerik literal, tanpa sebarang semantik caret atau tilde yang tersembunyi.
Jika anda perlu menyatakan “mana-mana versi 1.x yang sekurang-kurangnya 1.2”, tuliskan ia sepenuhnya. Ia memerlukan beberapa aksara tambahan; namun ia menjamin resolusi yang boleh diramal di mana-mana sahaja kod itu dijalankan.
Bila singkatan masih masuk akal
Singkatan tetap menarik untuk projek bahasa tunggal. Dalam ekosistem npm tulen, ^1.2.3 secara ringkas merangkumi “serasi dengan rilis minor dan patch masa hadapan”. Perkara yang sama berlaku untuk caret Cargo atau tilde Composer apabila anda tahu alatan pengguna tidak akan berubah. Bahaya muncul apabila manifes yang sama digunakan semula merentasi sempadan bahasa, atau apabila tugasan CI menarik dependensi daripada pelbagai ekosistem.
Kesimpulan
Bergantung pada singkatan semver untuk keserasian rentas bahasa adalah satu perjudian. Satu-satunya cara yang boleh dipercayai untuk menjamin bahawa kekangan versi membawa maksud yang sama di mana-mana sahaja adalah dengan menulis ketidaksamaan eksplisit. Apabila anda memerlukan ringkas, kekal dalam satu ekosistem; apabila anda memerlukan konsistensi, tukarkan singkatan dengan kejelasan.
