https://github.com/andrew/vers

A Ruby gem for parsing, comparing and sorting versions according to the VERS spec.

https://github.com/andrew/vers

Science Score: 26.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (11.5%) to scientific vocabulary

Keywords

package-url purl ruby ruby-gem semantic-versioning version version-range
Last synced: 5 months ago · JSON representation

Repository

A Ruby gem for parsing, comparing and sorting versions according to the VERS spec.

Basic Info
Statistics
  • Stars: 5
  • Watchers: 1
  • Forks: 0
  • Open Issues: 0
  • Releases: 0
Topics
package-url purl ruby ruby-gem semantic-versioning version version-range
Created 7 months ago · Last pushed 6 months ago
Metadata Files
Readme Changelog Contributing Code of conduct Security

README.md

Vers - Version Range Parser for Ruby

A Ruby library for parsing, comparing and sorting versions according to the VERS specification.

This gem provides tools for working with version ranges across different package managers, using a mathematical interval model internally and supporting the vers specification from the Package URL (PURL) project.

Ruby Gem Version License: MIT

Available on RubyGems | API Documentation | GitHub Repository

Features

  • Universal version range parsing with support for 6 package ecosystems (npm, gem, pypi, maven, debian, rpm)
  • Mathematical interval model for precise set operations (union, intersection, complement)
  • VERS specification compliance with full support for the Package URL version range specification
  • Native syntax support - parse native package manager syntax (^1.2.3, ~>1.0, >=1.0,<2.0, [1.0,2.0))
  • Bidirectional conversion between native syntax and universal vers URI format
  • Semantic versioning features - version increment, constraint checking, prerelease handling
  • Comprehensive error handling with detailed parsing exceptions
  • 100% test coverage with 113 tests and 366 assertions

Installation

Add this line to your application's Gemfile:

ruby gem 'vers'

And then execute:

bash bundle install

Or install it yourself as:

bash gem install vers

Quick Start

```ruby require 'vers'

Parse a vers URI

range = Vers.parse("vers:npm/>=1.2.3|<2.0.0") range.contains?("1.5.0") # => true range.contains?("2.1.0") # => false

Parse native package manager syntax

npmrange = Vers.parsenative("^1.2.3", "npm") gemrange = Vers.parsenative("~> 1.0", "gem")

Check version containment

Vers.satisfies?("1.5.0", ">=1.0.0,<2.0.0") # => true

Compare versions

Vers.compare("1.2.3", "1.2.4") # => -1

Version operations

version = Vers::Version.new("1.2.3") version.increment_major # => # version.satisfies?("~> 1.2") # => true ```

Supported Package Managers

  • npm (Node.js): Caret ranges (^1.2.3), tilde ranges (~1.2.3), hyphen ranges (1.2.3 - 2.3.4), OR logic (||), wildcards (1.x, *)
  • RubyGems (Ruby): Pessimistic operator (~> 1.2), standard operators (>=, <=, etc.), comma-separated constraints
  • PyPI (Python): Comma-separated constraints (>=1.0,<2.0), exclusions (!=1.5.0), compatible release (~=1.4.2)
  • Maven (Java): Bracket notation ([1.0,2.0], (1.0,2.0)), union ranges, open ranges
  • NuGet (.NET): Bracket notation ([1.0,2.0], (1.0,2.0)), mixed brackets, open ranges
  • Packagist (PHP Composer): Caret ranges (^1.2.3), tilde ranges (~1.2), stability flags (@dev, @alpha)
  • Debian (apt): Standard comparison operators (>=1.0.0, <<2.0.0)
  • RPM (yum/dnf): Standard comparison operators (>=1.0.0, <=2.0.0)

Many other package managers are also supported using standard comparison operators (>=, <=, <, >, =, !=), including Cargo (Rust), Go modules, and more.

Mathematical Model

Internally, all version ranges are represented as mathematical intervals, similar to those used in mathematics:

  • [1.0.0, 2.0.0) represents versions from 1.0.0 (inclusive) to 2.0.0 (exclusive)
  • (1.0.0, 2.0.0] represents versions from 1.0.0 (exclusive) to 2.0.0 (inclusive)

This allows for precise set operations like union, intersection, and complement, regardless of the original package manager syntax.

Usage Examples

Basic Version Range Parsing

```ruby require 'vers'

Parse vers URI format

range = Vers.parse("vers:npm/>=1.2.3|<2.0.0") puts range.contains?("1.5.0") # => true puts range.contains?("2.1.0") # => false

Parse native package manager syntax

npmrange = Vers.parsenative("^1.2.3", "npm") gemrange = Vers.parsenative("~> 1.0", "gem") pypirange = Vers.parsenative(">=1.0,<2.0", "pypi") mavenrange = Vers.parsenative("[1.0,2.0)", "maven") ```

Creating Version Ranges

```ruby

Create exact version range

exact = Vers.exact("1.2.3") puts exact.contains?("1.2.3") # => true puts exact.contains?("1.2.4") # => false

Create comparison ranges

greater = Vers.greaterthan("1.0.0", inclusive: true) less = Vers.lessthan("2.0.0", inclusive: false)

Create unbounded and empty ranges

allversions = Vers.unbounded noversions = Vers.empty ```

Converting Between Formats

```ruby

Parse native syntax and convert to vers URI

npmrange = Vers.parsenative("^1.2.3", "npm") versstring = Vers.toversstring(npmrange, "npm") puts vers_string # => "vers:npm/>=1.2.3|<2.0.0"

Parse vers URI and use in your application

range = Vers.parse("vers:gem/~>1.0") puts range.contains?("1.5.0") # => true ```

Set Operations on Version Ranges

```ruby range1 = Vers.parse("vers:npm/>=1.0.0|<2.0.0") range2 = Vers.parse("vers:npm/>=1.5.0|<3.0.0")

Union: versions in either range

union = range1.union(range2) puts union.contains?("0.9.0") # => false puts union.contains?("1.2.0") # => true puts union.contains?("2.5.0") # => true

Intersection: versions in both ranges

intersection = range1.intersect(range2) puts intersection.contains?("1.2.0") # => false puts intersection.contains?("1.7.0") # => true puts intersection.contains?("2.5.0") # => false

Complement: versions NOT in range

complement = range1.complement puts complement.contains?("0.5.0") # => true puts complement.contains?("1.5.0") # => false

Exclusions: remove specific versions

excluded = range1.exclude("1.5.0") puts excluded.contains?("1.4.0") # => true puts excluded.contains?("1.5.0") # => false puts excluded.contains?("1.6.0") # => true ```

Version Comparison and Manipulation

```ruby version = Vers::Version.new("1.2.3-alpha.1+build.123")

Access version components

puts version.major # => 1 puts version.minor # => 2 puts version.patch # => 3 puts version.prerelease # => "alpha.1" puts version.build # => "build.123"

Compare versions

puts Vers.compare("1.2.3", "1.2.4") # => -1 puts Vers.compare("2.0.0", "1.9.9") # => 1 puts Vers.compare("1.0.0", "1.0.0") # => 0

Increment versions (returns new Version objects)

puts version.incrementmajor # => # puts version.incrementminor # => #
puts version.increment_patch # => #

Version properties

puts version.stable? # => false (has prerelease) puts version.prerelease? # => true puts version.to_h # => {major: 1, minor: 2, patch: 3, ...} ```

Constraint Checking

```ruby version = Vers::Version.new("1.2.5")

Pessimistic constraint checking (Ruby-style)

puts version.satisfies?("~> 1.2") # => true (>= 1.2.0, < 1.3.0) puts version.satisfies?("~> 1.2.3") # => true (>= 1.2.3, < 1.3.0) puts version.satisfies?("~> 1.3") # => false

General satisfaction checking

puts Vers.satisfies?("1.5.0", "vers:npm/>=1.0.0|<2.0.0") # => true puts Vers.satisfies?("1.5.0", "^1.2.3", "npm") # => true ```

Specification Compliance

This gem implements the PURL Version Range Specification, providing a universal way to express version ranges across different software packaging ecosystems.

Learn more about the motivation and design behind VERS in the presentation from Open Source Summit NA 2025 (slides PDF) by Eve Martin-Jones and Elitsa Bankova. The following table from their talk shows how different package managers express the same version constraints:

| Operator | NPM | Cargo | Carthage | RubyGems | PyPI | Maven | NuGet | |----------|-----|-------|----------|----------|------|-------|--------| | behavior with no op | 1.0.0 | ^1.0.0⁴ | illegal | 1.0.0 | illegal | ⁵ | >=1.0 | | *= ==** | =1.0 | = | == | = | == | [1.0]⁵ | [1.0]⁸ | | > | > | > | | > | > | (1.0,) | (1.0,) | | >= | >= | >= | >= | >= | >= | 1.0⁵ | 1.0⁷ᵇᵃ | | < | < | < | | < | < | (,1.0) | (,1.0) | | <= | <= | <= | | <= | <= | (,1.0] | (,1.0] | | != | | | | != | != | | | | ^ | ^ | ^² | | | | | | | ~ | ~, ~>¹ | ~ | | | ~= | | | | ~> | ¹ | | ~> | ~> | | | | | wildcards | * x X | * x X | | | * | * | | | OR | || | | | | | , | | | AND | space | , | | ,³ | , | | | | RANGE | - | | | | | [,],(,)⁶ | [,],(,) |

This complexity across ecosystems is exactly why VERS provides a universal format that works consistently across all package managers.

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/andrew/vers. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.

Related Projects

  • purl - Ruby implementation of Package URL (PURL)
  • semantic_range - Semantic version parsing (JavaScript style)
  • univers - Python implementation of version ranges
  • versatile - Java implementation of version ranges

License

The gem is available as open source under the terms of the MIT License.

Code of Conduct

Everyone interacting in the Vers project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

Owner

  • Name: Andrew Nesbitt
  • Login: andrew
  • Kind: user
  • Location: Bristol, UK
  • Company: @ecosyste-ms and @octobox

Working on mapping the world of open source software @ecosyste-ms and empowering developers with @octobox

GitHub Events

Total
  • Watch event: 2
  • Push event: 3
  • Create event: 5
Last Year
  • Watch event: 2
  • Push event: 3
  • Create event: 5

Committers

Last synced: 6 months ago

All Time
  • Total Commits: 8
  • Total Committers: 1
  • Avg Commits per committer: 8.0
  • Development Distribution Score (DDS): 0.0
Past Year
  • Commits: 8
  • Committers: 1
  • Avg Commits per committer: 8.0
  • Development Distribution Score (DDS): 0.0
Top Committers
Name Email Commits
Andrew Nesbitt a****z@g****m 8

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 0
  • Total pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Total issue authors: 0
  • Total pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 0
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 0
  • Pull request authors: 0
  • Average comments per issue: 0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
Pull Request Authors
Top Labels
Issue Labels
Pull Request Labels

Packages

  • Total packages: 1
  • Total downloads:
    • rubygems 493 total
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 3
  • Total maintainers: 1
rubygems.org: vers

Vers provides tools for working with version ranges across different package managers, using a mathematical interval model internally and supporting the vers specification from the Package URL (PURL) project.

  • Versions: 3
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 493 Total
Rankings
Dependent packages count: 14.3%
Dependent repos count: 43.9%
Average: 50.3%
Downloads: 92.8%
Maintainers (1)
Last synced: 6 months ago

Dependencies

.github/workflows/main.yml actions
  • actions/checkout v4 composite
  • ruby/setup-ruby v1 composite
Gemfile rubygems
  • irb >= 0
  • minitest ~> 5.16
  • rake ~> 13.0
Gemfile.lock rubygems
  • bundler 2.7.1
  • date 3.4.1
  • erb 5.0.2
  • io-console 0.8.1
  • irb 1.15.2
  • minitest 5.25.5
  • pp 0.6.2
  • prettyprint 0.2.0
  • psych 5.2.6
  • rake 13.3.0
  • rdoc 6.14.2
  • reline 0.6.2
  • stringio 3.1.7
  • vers 1.0.1
vers.gemspec rubygems