Skip to content
Semantic version parsing and comparison for ruby
Ruby
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib
spec
.gitignore
.rspec
LICENSE
README.md
Rakefile
sem_version.gemspec

README.md

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
You can’t perform that action at this time.