SemVersion
SemVersion is a gem to help parse, validate, modify, and compare Semantic Versions.
Note that this version of the gem adheres to SemVer v2.0.0.
If you want v1.0.0 behaviour, use the semver-v1.0.0
branch.
Parsing
Parsing is easy:
v = SemVersion.new('1.2.3-pre.4+metadata.5')
v.major # => 1
v.minor # => 2
v.patch # => 3
v.pre # => 'pre.4'
v.prerelease # => 'pre.4'
v.metadata # => 'metadata.5'
v.to_s # => '1.2.3-pre.4+metadata.5'
You can pass any valid semantic version string, as specified by Semantic Versions. Invalid versions will raise an ArgumentError.
You can also create a new SemVersion from an array or a hash, and serialise back to arrays and hashes.
v1 = SemVersion.new([1, 2, 3, 'pre.4', 'metadata.5'])
v1.to_s # => '1.2.3-pre.4+metadata.5'
v1.to_a # => [1, 2, 3, 'pre.4', 'metadata.5']
v2 = SemVersion.new(1, 2, 3, nil, 'metadata.5')
v2.to_s # => '1.2.3+metadata.5'
v2.to_a # => [1, 2, 3, nil, 'metadata.5']
v3 = SemVersion.new(:major => 1, :minor => 2, :patch => 3, :pre => 'pre.4', :metadata => 'metadata.5')
v.to_s # => '1.2.3-pre.4+metadata.5'
v.to_h # => {:major => 1, :minor => 2, :patch => 3, :pre => 'pre.4', :metadata => 'metadata.5'}
v4 = SemVersion.new(:major => 1, :minor => 2, :patch => 3, :metadata => 'metadata.6')
v4.to_h # => {:major => 1, :minor => 2, :patch => 3, :metadata => 'metadata.6'}
You can also use SemVersion()
as an alias for SemVersion.new()
.
Validating
Validating is easier:
SemVersion.valid?('1.2.3') # => true
SemVersion.valid?('1.2') # => false
SemVersion.valid?('1.2.3-pre.1') # => true
SemVersion.valid?('1.2.3-pre.!') # => false
And so on...
Modifying
You can modify any part of a parsed version. Invalid new values will raise an ArgumentError
v = SemVersion.new('1.2.3')
v.major = 3
v.minor = 5
v.pre = 'pre.2'
v.metadata = 'metadata.x.7'
v.to_s # => '3.5.1-pre.2+metadata.x.7'
v.major = -1 # => ArgumentError
v.major = 'a' # => ArgumentError
v.pre = 'a.!' # => ArgumentError
v.pre = '.a' # => ArgumentError
Comparing
You can compare semantic versions using <
, >
, <=
, >=
, ==
, and <=>
SemVersion.new('1.2.3') < SemVersion.new('1.2.2') # => true
SemVersion.new('1.2.3-pre.1') <= SemVersion.new('1.2.3-pre') # => false
SemVersion.new('1.2.3+metadata.11') > SemVersion.new('1.2.3+metadata.2') # => false
Satisfying constraints
You can see whether a semantic version satisfies a particular constraint.
Constraints are in the form "<comparison> <version>"
, e.g. ">= 1.2.2", "= 1.3", or "~> 1.2".
When using the pessimistic operation, ~>
, versions may be specified in the form "x.y"
or "x.y.z"
(with "~> x.y"
meaning ">= x.y.0" && "< x+1.0.0"
, and "~> x.y.z"
meaning ">= x.y.z" && "< x.y+1.0"
).
When using the other operations, versions may be in the form "x"
, "x.y"
, or a full semantic version (including optional pre-release and metadata).
In the former two cases, the missing versions out of minor and patch will be filled in with 0's, and the pre-release and metadata ignored.
SemVersion.new('1.2.3').satisfies?('>= 1.2') # => true
SemVersion.new('1.2.3-pre.1').satisfies?('>= 1.2.3') # => false
SemVersion.new('0.1.0').satisfies?('> 0') # => true
SemVersion.new('2.3.0').satisfies?('~> 2.2') # => true
You can also see whether a given constraint is 'open' (allows a range of versions), or 'closed' (allows only one version).
For example:
SemVersion.open_constraint?('1.2.3') # => false
SemVersion.open_constraint?('= 1.2.3') # => false
SemVersion.open_constraint?('== 1.2.3') # => false
SemVersion.open_constraint?('<= 1.2.3') # => true
SemVersion.open_constraint?('~> 1.2.3') # => true
It's also possible to split a constraint into its comparison and version. If the comparison is not given, or is '==', it is normalised to '='.
SemVersion.split_constraint('1.2.3') # => ['=', '1.2.3']
SemVersion.split_constraint('= 1.2.3') # => ['=', '1.2.3']
SemVersion.split_constraint('== 1.2.3') # => ['=', '1.2.3']
SemVersion.split_constraint('> 1.2.3') # => ['>', '1.2.3']
Core Extensions
You can also load a set of core extensions using an optional require.
require 'sem_version'
require 'sem_version/core_ext'
"1.2.3+pre.4-metadata.5".to_version