View Source Version (Elixir v1.10.2)
Functions for parsing and matching versions against requirements.
A version is a string in a specific format or a Version
generated after parsing via Version.parse/1.
Although Elixir projects are not required to follow SemVer, they must follow the format outlined on SemVer 2.0 schema.
Versions
In a nutshell, a version is represented by three numbers:
MAJOR.MINOR.PATCHPre-releases are supported by optionally appending a hyphen and a series of
period-separated identifiers immediately following the patch version.
Identifiers consist of only ASCII alphanumeric characters and hyphens ([0-9A-Za-z-]):
"1.0.0-alpha.3"Build information can be added by appending a plus sign and a series of
dot-separated identifiers immediately following the patch or pre-release version.
Identifiers consist of only ASCII alphanumeric characters and hyphens ([0-9A-Za-z-]):
"1.0.0-alpha.3+20130417140000.amd64"Struct
The version is represented by the Version struct and fields
are named according to SemVer 2.0: :major, :minor, :patch,
:pre, and :build.
Requirements
Requirements allow you to specify which versions of a given
dependency you are willing to work against. Requirements support the common
comparison operators such as >, >=, <, <=, ==, != that work as one would expect,
and additionally the special operator ~> described in detail further below.
# Only version 2.0.0
"== 2.0.0"
# Anything later than 2.0.0
"> 2.0.0"Requirements also support and and or for complex conditions:
# 2.0.0 and later until 2.1.0
">= 2.0.0 and < 2.1.0"Since the example above is such a common requirement, it can be expressed as:
"~> 2.0.0"~> will never include pre-release versions of its upper bound,
regardless of the usage of the :allow_pre option, or whether the operand
is a pre-release version. It can also be used to set an upper bound on only the major
version part. See the table below for ~> requirements and
their corresponding translations.
~> | Translation |
|---|---|
~> 2.0.0 | >= 2.0.0 and < 2.1.0 |
~> 2.1.2 | >= 2.1.2 and < 2.2.0 |
~> 2.1.3-dev | >= 2.1.3-dev and < 2.2.0 |
~> 2.0 | >= 2.0.0 and < 3.0.0 |
~> 2.1 | >= 2.1.0 and < 3.0.0 |
The requirement operand after the ~> is allowed to omit the patch version,
allowing us to express ~> 2.1 or ~> 2.1-dev, something that wouldn't be allowed
when using the common comparison operators.
When the :allow_pre option is set false in Version.match?/3, the requirement
will not match a pre-release version unless the operand is a pre-release version.
The default is to always allow pre-releases but note that in
Hex :allow_pre is set to false. See the table below for examples.
| Requirement | Version | :allow_pre | Matches |
|---|---|---|---|
~> 2.0 | 2.1.0 | true or false | true |
~> 2.0 | 3.0.0 | true or false | false |
~> 2.0.0 | 2.0.5 | true or false | true |
~> 2.0.0 | 2.1.0 | true or false | false |
~> 2.1.2 | 2.1.6-dev | true | true |
~> 2.1.2 | 2.1.6-dev | false | false |
~> 2.1-dev | 2.2.0-dev | true or false | true |
~> 2.1.2-dev | 2.1.6-dev | true or false | true |
>= 2.1.0 | 2.2.0-dev | true | true |
>= 2.1.0 | 2.2.0-dev | false | false |
>= 2.1.0-dev | 2.2.6-dev | true or false | true |
Link to this section Summary
Functions
Compares two versions.
Compiles a requirement to its internal representation with
:ets.match_spec_compile/1 for faster matching.
Checks if the given version matches the specification.
Parses a version string into a Version struct.
Parses a version string into a Version.
Parses a version requirement string into a Version.Requirement struct.
Parses a version requirement string into a Version.Requirement struct.
Link to this section Types
@type build() :: String.t() | nil
@type major() :: non_neg_integer()
@type minor() :: non_neg_integer()
@type patch() :: non_neg_integer()
@type pre() :: [String.t() | non_neg_integer()]
@type requirement() :: String.t() | Version.Requirement.t()
Link to this section Functions
Compares two versions.
Returns :gt if the first version is greater than the second one, and :lt
for vice versa. If the two versions are equal, :eq is returned.
Pre-releases are strictly less than their corresponding release versions.
Patch segments are compared lexicographically if they are alphanumeric, and numerically otherwise.
Build segments are ignored: if two versions differ only in their build segment they are considered to be equal.
Raises a Version.InvalidVersionError exception if any of the two given
versions are not parsable. If given an already parsed version this function
won't raise.
Examples
iex> Version.compare("2.0.1-alpha1", "2.0.0")
:gt
iex> Version.compare("1.0.0-beta", "1.0.0-rc1")
:lt
iex> Version.compare("1.0.0-10", "1.0.0-2")
:gt
iex> Version.compare("2.0.1+build0", "2.0.1")
:eq
iex> Version.compare("invalid", "2.0.1")
** (Version.InvalidVersionError) invalid version: "invalid" @spec compile_requirement(Version.Requirement.t()) :: Version.Requirement.t()
Compiles a requirement to its internal representation with
:ets.match_spec_compile/1 for faster matching.
The internal representation is opaque and cannot be converted to external term format and then back again without losing its properties (meaning it can not be sent to a process on another node and still remain a valid compiled match_spec, nor can it be stored on disk).
@spec match?(version(), requirement(), keyword()) :: boolean()
Checks if the given version matches the specification.
Returns true if version satisfies requirement, false otherwise.
Raises a Version.InvalidRequirementError exception if requirement is not
parsable, or a Version.InvalidVersionError exception if version is not parsable.
If given an already parsed version and requirement this function won't
raise.
Options
:allow_pre(boolean) - whenfalse, pre-release versions will not match unless the operand is a pre-release version. Defaults totrue. For examples, please refer to the table above under the "Requirements" section.
Examples
iex> Version.match?("2.0.0", "> 1.0.0")
true
iex> Version.match?("2.0.0", "== 1.0.0")
false
iex> Version.match?("2.1.6-dev", "~> 2.1.2")
true
iex> Version.match?("2.1.6-dev", "~> 2.1.2", allow_pre: false)
false
iex> Version.match?("foo", "== 1.0.0")
** (Version.InvalidVersionError) invalid version: "foo"
iex> Version.match?("2.0.0", "== == 1.0.0")
** (Version.InvalidRequirementError) invalid requirement: "== == 1.0.0" Parses a version string into a Version struct.
Examples
iex> {:ok, version} = Version.parse("2.0.1-alpha1")
iex> version
#Version<2.0.1-alpha1>
iex> Version.parse("2.0-alpha1")
:error Parses a version string into a Version.
If string is an invalid version, a Version.InvalidVersionError is raised.
Examples
iex> Version.parse!("2.0.1-alpha1")
#Version<2.0.1-alpha1>
iex> Version.parse!("2.0-alpha1")
** (Version.InvalidVersionError) invalid version: "2.0-alpha1" @spec parse_requirement(String.t()) :: {:ok, Version.Requirement.t()} | :error
Parses a version requirement string into a Version.Requirement struct.
Examples
iex> {:ok, requirement} = Version.parse_requirement("== 2.0.1")
iex> requirement
#Version.Requirement<== 2.0.1>
iex> Version.parse_requirement("== == 2.0.1")
:error @spec parse_requirement!(String.t()) :: Version.Requirement.t()
Parses a version requirement string into a Version.Requirement struct.
If string is an invalid requirement, a Version.InvalidRequirementError is raised.
Examples
iex> Version.parse_requirement!("== 2.0.1")
#Version.Requirement<== 2.0.1>
iex> Version.parse_requirement!("== == 2.0.1")
** (Version.InvalidRequirementError) invalid requirement: "== == 2.0.1"