npm, Cargo, Composer మరియు pip అన్నీ ఒకే semver shorthand ను వేర్వేరుగా విశ్లేషిస్తాయి, మరియు నేను పరీక్షించిన పదమూడు range expressions లలో కేవలం రెండు మాత్రమే ఈ నాలుగింటిలోనూ ఒకేలా పనిచేస్తాయి.
నేను ప్రతి మేనేజర్ కోసం విడివిడి parsers రాసి, వాటి అధికారిక స్పెసిఫికేషన్లను అనుసరించాను, ఆపై ప్రతి range ను పందొమ్మిది వెర్షన్ నంబర్ల మ్యాట్రిక్స్తో పరీక్షించాను. ఆ 13 × 19 గ్రిడ్ (247 సెల్స్) ఒక విభిన్నమైన చిత్రాన్ని చూపించింది: కేవలం 17 సెల్స్ మాత్రమే ప్రతి టూల్ నుండి ఒకే విధమైన “yes” లేదా “no” సమాధానాన్ని ఇచ్చాయి, మరియు ఆ 17 లలో ఎక్కువ భాగం ఏకగ్రీవంగా తిరస్కరించబడ్డాయి. క్లుప్తంగా చెప్పాలంటే, ఈ టూల్స్ “yes” కంటే “no” విషయంలోనే ఎక్కువగా ఏకీభవిస్తాయి.
టూల్స్ ఎందుకు భిన్నంగా ఉంటాయి
ఈ నాలుగు మేనేజర్లు Semantic Versioning ను అనుసరిస్తామని చెబుతాయి, అయినప్పటికీ ప్రతి ఒక్కటి దాని స్వంత shorthand నియమాలను జోడిస్తుంది.
- Caret (^) మరియు dot-x – npm caret ను సపోర్ట్ చేస్తుంది; pip caret మరియు dot-x రెండింటినీ విస్మరిస్తుంది. దీని వల్ల మాత్రమే npm మరియు pip మధ్య 49-cell విభేదం ఏర్పడుతుంది.
- Bare versions – Cargo ఒక సాధారణ
1.2.3ను caret range గా పరిగణిస్తుంది, అంటే “1.x తో అనుకూలమైనది” అని అర్థం. npm మరియు Composer అదే స్ట్రింగ్ను ఖచ్చితమైన మ్యాచ్ (exact match) గా చదువుతాయి, అంటే1.2.3ను మాత్రమే అంగీకరిస్తాయి. - Tilde (~) – Cargo యొక్క tilde minor వెర్షన్ను నిర్ణయిస్తుంది (
~1.2అనేది1.2.*కి సరిపోతుంది కానీ1.3.0కి కాదు). Composer యొక్క tilde *major* వెర్షన్ను నిర్ణయిస్తుంది (~1.2అనేది1.*` కి సరిపోతుంది). minor component మారే ఏ వెర్షన్ పైనైనా ఈ రెండు విశ్లేషణలు భిన్నంగా ఉంటాయి.
Pre-release హ్యాండ్లింగ్ మరొక ఆశ్చర్యకరమైన విషయాన్ని తెలియజేస్తుంది. ^1.2.3 వంటి range లో 2.0.0-rc.1 చేర్చబడదు, దాని సంఖ్యా భాగం (numeric part) ఎగువ పరిమితి (upper bound) కంటే తక్కువగా ఉన్నప్పటికీ. నియమం ఏమిటంటే: range లో స్పష్టంగా pre-release identifier పేర్కొనబడనంత వరకు, pre-releases ని మినహాయించబడతాయి.
టూల్స్ మధ్య సురక్షితమైన ఏకైక సింటాక్స్
స్పష్టమైన inequality ranges—ఉదాహరణకు >=1.2.0 <2.0.0—npm, Cargo, Composer మరియు pip లలో ఒకే విధంగా పనిచేస్తాయని ఈ ప్రయోగం చూపుతోంది. ప్రతి మేనేజర్ ఈ రెండు సరిహద్దులను (boundaries) ఎటువంటి దాగి ఉన్న caret లేదా tilde semantics లేకుండా, ప్రత్యక్ష సంఖ్యా పరిమితులుగా (literal numeric limits) పరిగణిస్తుంది.
మీరు “కనీసం 1.2 ఉన్న ఏదైనా 1.x వెర్షన్” అని చెప్పాలనుకుంటే, దానిని పూర్తిగా రాయండి. దీనివల్ల కొన్ని అదనపు అక్షరాలు ఖర్చవుతాయి; కానీ కోడ్ ఎక్కడ నడిచినా ఫలితం ఊహించిన విధంగా ఉండేలా ఇది హామీ ఇస్తుంది.
shorthand ఎప్పుడు ఉపయోగకరంగా ఉంటుంది
సింగిల్-లాంగ్వేజ్ ప్రాజెక్టుల కోసం shorthand ఆకర్షణీయంగానే ఉంటుంది. కేవలం npm ఎకోసిస్టమ్ లో మాత్రమే అయితే, ^1.2.3 అనేది “భవిష్యత్తులో వచ్చే minor మరియు patch releases తో అనుకూలమైనది” అని క్లుప్తంగా తెలియజేస్తుంది. మీరు ఉపయోగించే టూల్ మారదని మీకు తెలిసినప్పుడు, Cargo యొక్క caret లేదా Composer యొక్క tilde కూడా ఇదే విధంగా పనిచేస్తాయి. అయితే, ఒకే manifest ను వేర్వేరు భాషల మధ్య తిరిగి ఉపయోగించినప్పుడు, లేదా ఒక CI job బహుళ ఎకోసిస్టమ్స్ నుండి dependencies ను పొందేటప్పుడు ప్రమాదం పొంచి ఉంటుంది.
ముగింపు
క్రాస్-లాంగ్వేజ్ అనుకూలత (compatibility) కోసం semver shorthand పై ఆధారపడటం ఒక జూదం వంటిది. వెర్షన్ కన్స్ట్రైంట్ (version constraint) అనేది అన్ని చోట్లా ఒకే అర్థాన్ని ఇస్తుందని హామీ ఇవ్వడానికి ఉన్న ఏకైక నమ్మదగిన మార్గం ఏమిటంటే, స్పష్టమైన inequalities రాయడం. మీకు సంక్షిప్తత (brevity) కావాలనుకున్నప్పుడు, ఒకే ఎకోసిస్టమ్ లో ఉండండి; మీకు స్థిరత్వం (consistency) కావాలనుకున్నప్పుడు, స్పష్టత కోసం shorthand ను వదిలేయండి.
