philiprehberger-semver
SemVer 2.0.0 parsing, comparison, range matching, and bump operations
Requirements
- Ruby >= 3.1
Installation
Add to your Gemfile:
gem "philiprehberger-semver"
Or install directly:
gem install philiprehberger-semver
Usage
require "philiprehberger/semver"
# Parse a version string
version = Philiprehberger::Semver.parse('1.2.3-beta.1+build.123')
version.major # => 1
version.minor # => 2
version.patch # => 3
version.pre_release # => 'beta.1'
version. # => 'build.123'
version.to_s # => '1.2.3-beta.1+build.123'
Comparison
Versions implement Comparable, so all standard Ruby comparison operators work. Pre-release versions sort lower than their release counterpart, and pre-release identifiers are compared per SemVer 2.0.0 precedence rules.
Philiprehberger::Semver.parse('2.0.0') > Philiprehberger::Semver.parse('1.9.9') # => true
Philiprehberger::Semver.parse('1.0.0-alpha') < Philiprehberger::Semver.parse('1.0.0') # => true
Philiprehberger::Semver.parse('1.0.0-alpha') < Philiprehberger::Semver.parse('1.0.0-beta') # => true
Philiprehberger::Semver.parse('1.0.0-alpha.1') < Philiprehberger::Semver.parse('1.0.0-alpha.2') # => true
Sorting
Pass an array of version strings and get back a sorted array in ascending order.
Philiprehberger::Semver.sort(['2.0.0', '1.0.0', '1.1.0'])
# => ['1.0.0', '1.1.0', '2.0.0']
Philiprehberger::Semver.sort(['1.0.0', '1.0.0-alpha', '1.0.0-beta'])
# => ['1.0.0-alpha', '1.0.0-beta', '1.0.0']
Bumping
bump returns a new immutable Version with the specified level incremented. Minor and patch are reset to zero when a higher level is bumped.
version = Philiprehberger::Semver.parse('1.2.3')
version.bump(:major).to_s # => '2.0.0'
version.bump(:minor).to_s # => '1.3.0'
version.bump(:patch).to_s # => '1.2.4'
Iterating pre-release identifiers
next_pre_release returns a new immutable Version with its pre-release identifier iterated. A stable version is promoted to a pre-release using the given label: (default 'alpha'). A version that already has a pre-release has its trailing numeric token incremented; if the last token is not numeric, .1 is appended. The label: keyword is ignored when the version is already a pre-release. build_metadata is preserved.
Philiprehberger::Semver.parse('1.2.3').next_pre_release.to_s # => '1.2.3-alpha.1'
Philiprehberger::Semver.parse('1.2.3').next_pre_release(label: 'beta').to_s # => '1.2.3-beta.1'
Philiprehberger::Semver.parse('1.0.0-alpha.1').next_pre_release.to_s # => '1.0.0-alpha.2'
Philiprehberger::Semver.parse('1.0.0-rc.4').next_pre_release.to_s # => '1.0.0-rc.5'
Philiprehberger::Semver.parse('1.0.0-rc').next_pre_release.to_s # => '1.0.0-rc.1'
Philiprehberger::Semver.parse('1.0.0-alpha.beta').next_pre_release.to_s # => '1.0.0-alpha.beta.1'
Version Predicates
require "philiprehberger/semver"
version = Philiprehberger::Semver.parse("1.0.0-alpha")
version.pre_release? # => true
version.stable? # => false
stable = Philiprehberger::Semver.parse("2.1.0")
stable.stable? # => true
stable.to_a # => [2, 1, 0]
Range Matching
Check whether a version satisfies one or more comma-separated constraints. Supports standard comparison operators, pessimistic (~>), and caret (^) constraints.
Philiprehberger::Semver.satisfies?('1.5.0', '>= 1.0.0, < 2.0.0') # => true
Philiprehberger::Semver.satisfies?('1.5.0', '~> 1.4') # => true
Philiprehberger::Semver.satisfies?('1.9.0', '^ 1.0.0') # => true
Philiprehberger::Semver.satisfies?('2.0.0', '>= 1.0.0, < 2.0.0') # => false
API
Philiprehberger::Semver
| Method | Description |
|---|---|
.parse(string) |
Parse a SemVer string into a Version object |
.satisfies?(version_str, constraint) |
Check if a version satisfies a constraint string |
.sort(versions) |
Sort an array of version strings |
Philiprehberger::Semver::Version
| Method | Description |
|---|---|
#major |
Major version number |
#minor |
Minor version number |
#patch |
Patch version number |
#pre_release |
Pre-release identifier or nil |
#build_metadata |
Build metadata or nil |
#bump(level) |
Return a new Version bumped at :major, :minor, or :patch |
#next_pre_release(label:) |
Return a new Version with its pre-release iterated (promotes stable, or bumps trailing numeric token) |
#pre_release? |
true if the version has a pre-release segment |
#stable? |
true if major >= 1 and no pre-release |
#to_a |
Return [major, minor, patch] as an array |
#to_s |
Format as a SemVer string |
#<=> |
Compare two versions per SemVer 2.0.0 precedence rules |
Supported Constraint Operators
| Operator | Example | Description |
|---|---|---|
>= |
>= 1.0.0 |
Greater than or equal |
<= |
<= 2.0.0 |
Less than or equal |
> |
> 1.0.0 |
Greater than |
< |
< 2.0.0 |
Less than |
= |
= 1.0.0 |
Exact match |
~> |
~> 1.4 |
Pessimistic (same major, minor >= target) |
^ |
^ 1.0.0 |
Compatible (same major) |
Development
bundle install
bundle exec rspec
bundle exec rubocop
Support
If you find this project useful: