FreeToGenerate.com

ليست علامتا ‎^‎ و‎~‎ في مواصفة SemVer. ابحث فيها عن «caret» أو «tilde» أو «range» فلن تجد شيئًا — تلك الصياغة من npm.

هذا يغيّر كيفية بناء المدى لا كيفية فحصه وحدها: فمدًى جزئيٌّ مثل ‎^1 يصير ‎>=1.0.0-0 بدل ‎>=1.0.0.

مرفوضٌ لأنه تمهيديٌّ لا غير

كلُّ الحدود متحقّقة. وإنما رُفض لأنّ الإصدار التمهيدي لا يدخل مدًى إلا إذا سمّى أحدُ المقارِنات الأكبرَ والأصغرَ والترقيعَ نفسَها — ولا يفعل ذلك أيٌّ منها هنا. وهذه هي القاعدة وراء سؤال «لماذا لا تطابق نسختي التجريبية».

>=1.2.3 <2.0.0-0

تُفكَّك المدياتُ إلى مقارِناتٍ بسيطةٍ قبل أيّ مقارنة. والحدودُ العليا تحمل ‎-0 كي لا يتسلّل إصدارٌ تمهيديٌّ من النسخة التالية.

  • >=1.2.3متحقّق
  • <2.0.0-0متحقّق

الإصدار مفصَّلًا

الأكبر
1
الأصغر
2
الترقيع
4
تمهيدي
beta.1

لا شيء من صياغة المديات هذه في مواصفة SemVer

يعرّف semver.org صيغةَ الإصدار وقواعدَ أيُّ إصدارٍ أحدث، ويقف عند ذلك: فكلماتُ «caret» و«tilde» و«range» لا ترد فيه. أما صياغةُ ‎^ و‎~ و‎|| ومدياتُ x فمن npm، وهي عرفٌ فوق المعيار لا جزءٌ منه.

متوفر أيضًا بلغات أخرى: English · Español · Português · Français

فاحص semver

أيحقّق إصدارٌ مدًى، وما المقارِنات التي يتفكّك إليها ذلك المدى فعلًا، وجوابٌ صريحٌ حين يُرفض إصدارٌ تمهيدي.

ما الإصدار الدلالي؟

الإصدارُ الدلالي عُرفٌ يقضي بأن يكون رقمُ الإصدار ثلاثةَ أرقامٍ لها معنى: الأكبر والأصغر والترقيع. يُرفع الترقيعُ لإصلاحٍ لا يغيّر شيئًا آخر، والأصغرُ لشيءٍ أُضيف على نحوٍ متوافق، والأكبرُ حين ينكسر الكودُ القائم. والشرطةُ تُدخل إصدارًا تمهيديًّا — ‎2.0.0-rc.1 — وعلامةُ الزائد تُدخل بياناتِ بناءٍ تُهمَل تمامًا عند المقارنة.

والمواصفةُ في semver.org تعرّف تلك الصيغة وتعرّف الأسبقية: أيُّ الإصدارين أحدث، ومن ذلك قاعدةُ أنّ الإصدار التمهيدي يقع دائمًا دون الإصدار الذي يسبقه. فـ‎1.0.0-alpha قبل ‎1.0.0 لا بعده.

أما ما لا تعرّفه المواصفة فهو المديات. ابحث في نصّها عن «caret» أو «tilde» أو «range» فلن تجدها. فصياغةُ ‎^ و‎~ و‎|| ومدياتُ x التي تمتلئ بها كلُّ ملفات المشاريع إنما جاءت من npm، وهذه الصفحة تفحص إصدارًا مقابلها — مع التصريح بأيّ النصفين المعيارُ وأيّهما عُرفٌ فوقه.

كيف تستعمله

  1. ضع إصدارًا في الصندوق الأول ومدًى في الثاني. ‏1.2.4 مقابل ‎^1.2.3، أو إصدارًا تمهيديًّا مثل ‎1.2.4-beta.1، أو مدًى معقّدًا مثل ‎>=1.2.0 <2.0.0 || ^3.
  2. اقرأ التفكيك لا الحكم وحده. كلُّ مدًى يصير مقارِناتٍ بسيطةً قبل أيّ مقارنة، ويُبيَّن لكلٍّ منها أتحقّقت أم لا. والجوابُ المفاجئ يصير بديهيًّا عادةً ما إن تُكتب الحدود.
  3. جرّب مربّع الإصدارات التمهيدية إن كانت نسخةٌ تجريبية تُرفض. يريك ما الذي يتغيّر — وهو يغيّر المدى نفسَه لا المقارنةَ وحدها.

العلامة ‎^‎ تعني ثلاثةَ أشياء مختلفة

توصَف ‎^‎ بأنها «متوافقٌ مع»، وهذا يفي بالغرض حتى تلاحظ أنها تتصرف تصرفًا مختلفًا بحسب أيُّ الأرقام الأولى صفر. فـ‎^1.2.3 يسمح بكلّ شيءٍ حتى ‎2.0.0 دون بلوغها. و‎^0.2.3 لا يسمح إلا بإصدارات الترقيع ويقف عند ‎0.3.0. أما ‎^0.0.3 فلا يسمح بشيءٍ البتة بعد ‎0.0.3 نفسِها.

وهذا متعمَّد: فقبل ‎1.0.0 يقضي العُرف بأنّ كلّ شيءٍ قد ينكسر، فتضيق ‎^‎ تعويضًا. والنتيجةُ ممّا لا يتوقعه أحد: فدون ‎1.0.0 يكون ‎^0.2.3 و‎~0.2.3 المدى نفسَه. فالتفريقُ الذي يعتمد عليه الجميع بين «اسمح بالتحديثات الصغرى» و«اسمح بتحديثات الترقيع» يزول ببساطة، إذ لا تحديثَ أصغرَ كانت ‎^‎ لتسمح به.

وتفصيلٌ آخر يظهر في التفكيك أعلاه: الحدودُ العليا تُكتب ‎<2.0.0-0 لا ‎<2.0.0. فبغير تلك ‎-0 في آخرها كان إصدارٌ تمهيديٌّ من الرقم الأكبر التالي — ‎2.0.0-rc.1 — سيقع دون ‎2.0.0 ويتسلّل من مدًى كان يُفترض أن يقف قبله.

لماذا لا تطابق نسختُك التجريبية

هذا هو السؤال الذي يسوق أكثر الناس إلى فاحص semver، والشرحُ المعتاد ليس دقيقًا تمامًا. فالإصدارُ التمهيدي يُستبعَد من المدى وإن جلس مطمئنًّا داخل الحدود: فـ‎1.2.4-beta.1 يحقّق ‎>=1.2.3 و‎<2.0.0-0 كليهما، ومع ذلك يرفضه ‎^1.2.3.

وكثيرًا ما تُصاغ القاعدة هكذا: «إلا أن يذكر المدى نفسُه إصدارًا تمهيديًّا»، وهذا أوسع من الحقيقة. فالمطلوب أن يحمل أحدُ مقارِنات المدى الأكبرَ والأصغرَ والترقيعَ نفسَها. ولذلك يظلّ ‎^1.2.3-alpha رافضًا ‎1.2.4-beta.1 — فذلك المدى يسمّي إصدارًا تمهيديًّا فعلًا، لكن على ‎1.2.3، والإصدارُ المفحوص ‎1.2.4. غيّر الإصدارَ إلى ‎1.2.3-beta.1 فيُقبل.

والعلّةُ وراء ذلك أنّ إصدارًا تمهيديًّا من ‎1.2.4 لم يَعِد بأن يتصرف تصرفَ ‎1.2.4، فقبولُ مدًى ينبغي ألّا يُدخلك في صمتٍ في كودٍ غير منشورٍ لإصداراتٍ لم تسمّها قطّ. وحين تريده حقًّا فمربّعُ الإصدارات التمهيدية هو المخرج — ويجدر أن تعرف أنه يغيّر كيفية بناء المدى لا كيفية مقارنته. فتحته يصير ‎^1 هو ‎>=1.0.0-0، بينما يبقى ‎^1.0.0 عند ‎>=1.0.0، لأنه لا يُخفَّض إلا حدٌّ مُلئ من إصدارٍ جزئي.

حدودٌ صريحة

هذه تفحص نصوصَ إصداراتٍ مقابل نصوص مديات ولا شيء سواها. فهي لا تعرف ما هو منشور، فلا تستطيع أن تخبرك أيَّ إصدارٍ سيثبّته مدًى اليوم، ولا أستكسر ترقيةٌ كودَك — فالإصدار الدلالي وعدٌ من الناشر لا ضمانٌ يتحقق منه أحد. فإصدارٌ أكبر لا يمسّ شيئًا ممّا تستعمله لا ضرر منه؛ وإصدارُ ترقيعٍ قد يكسرك رغم ذلك.

وقواعدُ المديات المنفَّذة هنا قواعدُ npm، وهي الأشيع بفارقٍ كبيرٍ لا الوحيدة. فأنظمةٌ أخرى تكتب أفكارًا مشابهة بصياغةٍ مغايرة، والمدى المنسوخ من أحدها إما يُرفض هنا وإما — وهو أسوأ — يعني شيئًا آخر. أما المديات ذاتُ الإضافات الخاصة بـnpm التي تخرج عن قواعد الإصدارات — مسارُ git أو مسارٌ محليٌّ مكان الإصدار — فليست مدياتٍ بهذا المعنى ولا تُعالَج.

ولأنّ تلك القواعد بلا مواصفة، فمعيارُ الصواب هنا موافقةُ التطبيق المرجعي لا مطابقةُ وثيقة. وقد فُحص المحرّك مقابله على 1680 زوجًا من إصدارٍ ومدًى دون خلافٍ واحد، وفُحص على حدة مقابل قواعد الأسبقية في المواصفة، وهي موجودةٌ فعلًا.

لماذا هو مجاني؟

لأن تشغيله لا يكلّف شيئًا. فالتحليلُ والمقارنة يجريان في متصفحك؛ ولا يُرفع إصدارٌ ولا مدًى ولا ملفُّ مشروع، ولا حسابَ في الأمر.

وقواعدُ الأسبقية من المواصفة، وقواعدُ المديات من التطبيق الذي يعرّفها عمليًّا، والاختباراتُ محفوظةٌ إلى جانب الشفرة.