Skip to content

Instantly share code, notes, and snippets.

@FichteFoll
Last active December 18, 2016 15:28
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FichteFoll/a93e064468a6d9b14ea2 to your computer and use it in GitHub Desktop.
Save FichteFoll/a93e064468a6d9b14ea2 to your computer and use it in GitHub Desktop.
semantic version selectors for https://github.com/mojombo/semver/issues/205

Semantic Version Selectors

A semantic version selector (short: semsel) is a string that can match only onto specific semantic versions (semver). A semsel mainly consists of one or multiple comperators combined with inner logical ANDs and outer ORs.

A complete example could look like this:

>0.0.1-b.1337 <=0.0.2- || 0.0.3 +debug* || ~1.0 || 2.0.x +with* || 2.1.0- - 2.1.1- !2.1.1-b.9 || [3.1,3.3)

Logical operators

Multiple and chunks can be combined to or chunks using || (spaces are required) and match if any of the and chunks split by these satisfy.

Multiple comparators can be combined to and chunks by joining them with spaces and every comparator must match to make a version satisfy an and chunk.

Comparators

Comperators generally consist of an operator (no operator is an operator too) and a version specifier.

By default, metadata is ignored and pre-releases are never matched.

  • 1.0.0 matches the version 1.0.0, e.g. 1.0.0+windows.x68
  • !1.0.0 matches any version that is not 1.0.0
  • <1.0.0, >1.0.0, <=1.0.0, >=1.0.0, match versions greater, lower than or optionally equal 1.0.0

Advanced Comparators

Wildcard comparators (~, *, x or just leaving out a part of the version) are valid as well and usually result in an implicit and chunk of two normal comperators.

  • *, x match any version (and are equivalent to >=0.0.0)
  • 1 , 1.x, 1.* are equivalent to >=1.0.0 <2.0.0
  • 1.0, 1.0.x, 1.0.* are equivalent to >=1.0.0 <1.1.0
  • ~1.1.2 is equivalent to >=1.1.2 <1.2.0
  • ~1.1 is equivalent to >=1.1.0 <2.0.0
  • ~1 is equivalent to >=1.0.0
  • 1.0.0 - 1.0.3 is equivalent to >=1.0.0 <=1.0.3
  • 1.* - 2.2 is equivalent to >=1.0.0 <2.3.0

The "set notation" is based on mathematical sets and can be open or closed on either side respectively. Parts of the version may be omitted and an empty border denotes an open end.

  • [1.0.0,1.0.3] is equivalent to >=1.0.0 <=1.0.3
  • [1.0,1.0.3) is equivalent to >=1.0.0 <1.0.3
  • [1,) is equivalent to >=1.0.0
  • (,2) is equivalent to <2.0.0
  • (,) is equivalent to *

Matching metadata

The following comparators are specifically targetted at matching metadata and will not match versions with unsatisfying metadata or none at all. Pre-release versions are treated equally and should be filtered by other comparators in the same and chunk if necessary.

  • +any matches any version with +any as metadata
  • +windows* performs a wildcard match onto metadata with * being of arbitrary length and matching dots, e.g. 1.0.1+windows.x68
  • !+windows* matches all versions the wildcard match doesn't (including releases without metadata)
  • +/regex/ performs a regular expression match onto metadata

Matching pre-release versions

Any normal version specifier appended by a plain - hyphen makes it match pre-release versions as well. The following rules apply:

  • 1.0.0- matches 1.0.0 and any of its pre-releases, e.g. 1.0.0-rc.1+22
  • !1.0.0- matches everything that 1.0.0- doesn't
  • <=1.0.0- matches the version 1.0.0, all its pre-releases and every (pre-release) version before that, e.g. 1.0.0-rc.1
  • <1.0.0- matches all (pre-release) versions lower than 1.0.0 but no (pre-release) version of 1.0.0 itself (equivalent to <=1.0.0- !1.0.0-)
  • >=1.0.0- and >1.0.0- are analog

For advanced comperators the following rules apply:

  • *-, x- match any pre-release or normal version (>=0.0.0-)
  • 1- ... are equivalent to >=1.0.0- <1.1.0- (others are analog)
  • ~1.1 is equivalent to >=1.1.0- <2.0.0- (others are analog)
  • 1.0.0- - 1.0.0-beta.2 matches all pre-releases of 1.0.0 before and including 1.0.0-beta.2 (but excluding 1.0.0-beta.2.1).
  • 1.0.0- - 1.0.0 is illegal; only ranges with pre-release specifiers for both or no edges are allowed (including the generic hyphen)
  • 1- - 2.2- is equivalent to >=1.0.0- <2.3.0-
  • [1.0,1.0.3)- is equivalent to >=1.0.0- <1.0.3-
  • [1.0-,1.0.0-beta.2) is equivalent to >=1.0.0- <1.0.0-beta.2
  • [1.0-,1.0.0-beta.2)-, [1.0-,1.0.1)- are illegal; you may only append a hyphen to either the whole set or both border versions

To be specified

  1. Should >=1.0.0- match pre-releases of 1.0.0?
  • Are open end sets with angular brackets legal (e.g. [1,])?
  • Do we need advanced operations with parenthesis?
@0xallie
Copy link

0xallie commented Jul 3, 2014

  • 1.0.0- matches 1.0.0 and any of its pre-releases, e.g. 1.0.0-rc.1+22
  • <=1.0.0- matches the version 1.0.0 and all pre-release and build variants, e.g. 1.0.0-rc.1+22

What?

@FichteFoll
Copy link
Author

@nyuszika7h, apparently, I don't receive notifications for comments on my gists ... seems I need to send a friendly mail to support regarding that.

Anyway, I just revised that section.

Edit: Apparently, you can't even mention users in gist comments. Duh.

@haacked
Copy link

haacked commented Jul 9, 2014

My vote would be to adopt an existing standard unless there's good reason not to. http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html

@FichteFoll
Copy link
Author

Note: I plan to abandon the concept of abusing build metadata for "channels", which should instead be handled by the corresponding packet handler/update manager and using prefixes.

No idea when I will actually get to reiterate on the doc though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment