@@ -56,15 +56,19 @@ vulnerability databases like `VulnerableCode
5656To better understand the problem, here are some of the notations and conventions
5757in use:
5858
59- - Rubygems strongly suggest using semver but does not enforce it
59+ - ``semver `` https://semver.org/ is a popular specification to structure version
60+ strings, but does not provide a way to express version ranges.
61+
62+ - Rubygems strongly suggest using ``semver `` for version but does not enforce it.
63+ It use its own notation for version ranges.
6064 https://guides.rubygems.org/patterns/#semantic-versioning
6165
6266- node-semver ranges are used in npms https://github.com/npm/node-semver#ranges
63- with semantics specific to semver and node and npm.
67+ with their own range semantics that are specific to `` semver `` and npm.
6468
65- - Dart pub versioning scheme is similar to node-semver and the documentation at
66- https://dart.dev/tools/pub/versioning provides a comprehensive coverage of the
67- topic of versioning. But version resolution is using its own algorithm.
69+ - Dart pub versioning scheme is similar to `` node-semver `` and the documentation
70+ at https://dart.dev/tools/pub/versioning provides a comprehensive coverage of
71+ the topic of versioning. Version resolution is using its own algorithm.
6872
6973- Python uses its own version ranges notation https://www.python.org/dev/peps/pep-0440/
7074
@@ -74,21 +78,24 @@ in use:
7478- RPM distros use their own range notation
7579 https://rpm-software-management.github.io/rpm/manual/dependencies.html
7680
77- - Perl CPAN define its own version range notation similar to this specification:
81+ - Perl CPAN define its own version range notation similar to this specification
7882 https://metacpan.org/pod/CPAN::Meta: :Spec#Version-Ranges
7983
8084- Apache Maven and NuGet use math intervals notation
8185 https://en.wikipedia.org/wiki/Interval_(mathematics)
86+
8287 - Apache Maven http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html
8388 - NuGet https://docs.microsoft.com/en-us/nuget/concepts/package-versioning#version-ranges
8489
90+ - gradle uses Apache Maven notation with extensions
91+ https://docs.gradle.org/current/userguide/single_versions.html
92+
8593- Gentoo and Alpine Linux use comparison operators similar to this specification:
8694 - Gentoo https://wiki.gentoo.org/wiki/Version_specifier
8795 - Alpine linux https://gitlab.alpinelinux.org/alpine/apk-tools/-/blob/master/src/version.c
8896
89- - Arch Linux https://wiki.archlinux.org/title/PKGBUILD#Dependencies use a
90- simplified notation for its PKGBUILD depends array with comparison operators
91- similar to this specification.
97+ - Arch Linux https://wiki.archlinux.org/title/PKGBUILD#Dependencies use its
98+ own simplified notation for its PKGBUILD depends array.
9299
93100- Go modules https://golang.org/ref/mod#versions use semver versions with
94101 specific version resolution algorithms.
@@ -103,16 +110,16 @@ in use:
103110 a daily feed.
104111
105112Note that there is a closely related problem as the way two versions are compared
106- as equal, lesser or greater is often complex.
113+ as equal, lesser or greater is often complex:
107114
108- Each package ecosystem may have evolved its own peculiar version comparison
109- procedure.
115+ - Each package ecosystem may have evolved its own peculiar version comparison
116+ procedure.
110117
111- For instance, semver is a prominent specification in this domain but this is
112- just one of the many ways to structure a version string.
118+ - For instance, semver is a prominent specification in this domain but this is
119+ just one of the many ways to structure a version string.
113120
114- Debian, RPM, PyPI, Rubygems, and Composer have their own subtly different
115- approach on how to determine which version is greater or lesser.
121+ - Debian, RPM, PyPI, Rubygems, and Composer have their own subtly different
122+ approach on how to determine which version is greater or lesser.
116123
117124
118125Solution
@@ -121,11 +128,11 @@ Solution
121128A solution to the many version range syntaxes is to design a new notation to
122129unify them all with:
123130
124- - a mostly universal and minimalist notation to express the version range
125- notations from many different package types and ecosystems.
131+ - a mostly universal and minimalist, compact notation to express version ranges
132+ from many different package types and ecosystems.
126133
127134- the package type-specific definitions to normalize existing range expressions
128- to this common notation .
135+ to this common notation.
129136
130137- the designation of which algorithm or procedure to use when comparing two
131138 versions such that it is possible to resolve if a version is within or
@@ -145,9 +152,9 @@ URI-scheme with this syntax::
145152
146153For example to define a set of versions that contains either version ``1.2.3 ``,
147154or any versions greater than or equal to ``2.0.0 `` but less than ``5.0.0 `` using
148- the `semver ` versioning scheme, the version range specifier will be::
155+ the `` node- semver` ` versioning scheme, the version range specifier will be::
149156
150- vers:semver/1.2.3,>=2.0.0&<5.0.0
157+ vers:node- semver/1.2.3,>=2.0.0&<5.0.0
151158
152159Each ``<version-constraint> `` in the comma-separated list is either a simple
153160constraint such as::
@@ -173,7 +180,7 @@ for a future formal registration for this URI-scheme at the IANA registry.
173180``<versioning-scheme> ``
174181------------------------
175182
176- The ``<versioning-scheme> `` (such as ``semver ``,
183+ The ``<versioning-scheme> `` (such as ``node- semver ``,
177184``debian ``, etc.) determines:
178185
179186- the specific notation and conventions used for a version string encoded in
@@ -368,7 +375,7 @@ Notes and caveats
368375~~~~~~~~~~~~~~~~~~~
369376
370377- Comparing versions from two different versioning schemes is unspecified. Even
371- though there may be some similarities between the `semver ` version of an npm
378+ though there may be some similarities between the `` semver ` ` version of an npm
372379 and the `debian ` version of its Debian packaging, these similarities are
373380 specific to each versioning scheme. Tools may report an error in these
374381 cases.
@@ -394,12 +401,15 @@ scheme and package type.
394401 The version comparison routine of rmpvercmp is also used by archlinux Pacman.
395402
396403- ``rubygems ``: Rubygems https://guides.rubygems.org/patterns/#semantic-versioning
397- which is almost but not exactly semver.
404+ which is almost but not exactly `` node- semver`` .
398405
399- - ``semver ``: node-semver as used for npm https://github.com/npm/node-semver#ranges
400- It is also used by Rust: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
401- and several other package types. `composer ` may need its own scheme as this is
402- not strictly semver.
406+ - ``node-semver ``: node-semver is based on semver and is used for npm
407+ https://github.com/npm/node-semver#ranges
408+ A similar scheme is used by Rust https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
409+ and several other package types that use ``semver ``. But most of these related
410+ schemes are not strictly the same as what is implemented in ``node-semver ``.
411+ For instance PHP ``composer `` may need its own scheme as this is not strictly
412+ ``node-semver ``.
403413
404414- ``python ``: Python https://www.python.org/dev/peps/pep-0440/
405415
@@ -417,12 +427,13 @@ scheme and package type.
417427- ``gentoo ``: Gentoo https://wiki.gentoo.org/wiki/Version_specifier
418428
419429- ``alpine ``: Alpine linux https://gitlab.alpinelinux.org/alpine/apk-tools/-/blob/master/src/version.c
420- ( which might be using Gentoo conventions)
430+ which is using Gentoo-like conventions.
421431
422432- ``generic ``: a generic version comparison algorithm (which is TBD, likely a
423433 split on punctuation and dealing with digit vs. strings comparisons, like is
424434 done in libversion)
425435
436+ TODO: add Rust, composer and archlinux
426437
427438
428439Implementations
@@ -493,14 +504,16 @@ specified in ``vers`` and found in other notations.
493504Why not use node-semver ranges?
494505###############################
495506
496- https://github.com/npm/node-semver#ranges
507+ - https://github.com/npm/node-semver#ranges
497508
498- The node semver is very similar to this spec (this is also an OR of ANDs) but it
499- has a few practical issues:
509+ The node- semver spec is similar to this spec but is an AND of ORs with a few
510+ issues:
500511
501- - The space means "AND" and significant whitespace in a single string makes
502- normalization more complicated and may be a source of confusion or errors. The
503- explicit ampersand used as "AND" operator specified here improves clarity.
512+ - The space means "AND", therefore whitespaces are significant. Having
513+ significant whitespaces in string makes normalization more complicated and may
514+ be a source of confusion if you remove the spaces from the string. Using an
515+ ampersand as an "AND" operator in ``vers `` makes this explicit and avoids any
516+ ambiguity.
504517
505518- There is no negation "!=" operator meaning that some version constraints are
506519 difficult to express and require combining < and > comparators. For instance
@@ -510,14 +523,18 @@ has a few practical issues:
510523- The advanced range syntax has grown to be rather complex using hyphen, stars,
511524 carets and tilde constructs are all tied to the JavaScript and npm ways of
512525 handling versions in their specific ecosystem and furthermore are bound to the
513- semver semantics. These are not readily reusable elsewhere. And these multiple
514- comparators and modifiers make the grammar and parsing more complex.
526+ semver semantics and the npm implementation. These are not readily reusable
527+ elsewhere. And these multiple comparators and modifiers make the grammar and
528+ parsing more complex.
529+
530+ Notations that are directly derived from node-semver as used in Rust and PHP
531+ Composer have the same issues.
515532
516533
517534Why not use Python pep-0440 ranges?
518535#####################################
519536
520- https://www.python.org/dev/peps/pep-0440/#version-specifiers
537+ - https://www.python.org/dev/peps/pep-0440/#version-specifiers
521538
522539The Python pep-0440 "Version Identification and Dependency Specification"
523540provides a comprehensive specification for Python package versioning and a
@@ -542,7 +559,7 @@ only in the Python ecosystem.
542559Why not use Rubygems requirements notation?
543560##############################################################
544561
545- https://guides.rubygems.org/patterns/#declaring-dependencies
562+ - https://guides.rubygems.org/patterns/#declaring-dependencies
546563
547564The rubygems specification suggests but does not enforce using semver. It is
548565similar to this spec's operators with the addition of the "~>" aka. pessimistic
0 commit comments