Module: Vers

Defined in:
lib/vers.rb,
lib/vers/parser.rb,
lib/vers/interval.rb,
lib/vers/constraint.rb,
lib/vers/version_range.rb

Overview

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

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.

Features

  • Parse version ranges from multiple package ecosystems (npm, gem, pypi, maven, etc.)

  • Convert between native version range syntax and universal vers URI format

  • Mathematical interval-based operations (union, intersection, complement)

  • Version comparison and containment checking

  • Extensible architecture for adding new package manager support

Quick Start

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
npm_range = Vers.parse_native("^1.2.3", "npm")
gem_range = Vers.parse_native("~> 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

Mathematical Model

Internally, all version ranges are represented as mathematical intervals, similar to those used in mathematics (e.g., [1.0.0, 2.0.0) represents versions from 1.0.0 inclusive to 2.0.0 exclusive).

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

Defined Under Namespace

Classes: Constraint, Error, Interval, Parser, VersionRange

Constant Summary collapse

@@parser =

Default parser instance for convenience methods

Parser.new

Class Method Summary collapse

Class Method Details

.compare(a, b) ⇒ Integer

Compares two version strings

Examples

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

Parameters:

  • a (String)

    First version string

  • b (String)

    Second version string

Returns:

  • (Integer)

    -1 if a < b, 0 if a == b, 1 if a > b



142
143
144
# File 'lib/vers.rb', line 142

def self.compare(a, b)
  Version.compare(a, b)
end

.emptyVersionRange

Creates an empty version range (matches no versions)

Returns:



212
213
214
# File 'lib/vers.rb', line 212

def self.empty
  VersionRange.empty
end

.exact(version) ⇒ VersionRange

Creates an exact version range

Parameters:

  • version (String)

    The exact version

Returns:

  • (VersionRange)

    A range containing only the specified version



172
173
174
# File 'lib/vers.rb', line 172

def self.exact(version)
  VersionRange.exact(version)
end

.greater_than(version, inclusive: false) ⇒ VersionRange

Creates a greater-than version range

Parameters:

  • version (String)

    The minimum version

  • inclusive (Boolean) (defaults to: false)

    Whether to include the minimum version

Returns:

  • (VersionRange)

    A range for versions greater than (or equal to) the specified version



183
184
185
# File 'lib/vers.rb', line 183

def self.greater_than(version, inclusive: false)
  VersionRange.greater_than(version, inclusive: inclusive)
end

.less_than(version, inclusive: false) ⇒ VersionRange

Creates a less-than version range

Parameters:

  • version (String)

    The maximum version

  • inclusive (Boolean) (defaults to: false)

    Whether to include the maximum version

Returns:

  • (VersionRange)

    A range for versions less than (or equal to) the specified version



194
195
196
# File 'lib/vers.rb', line 194

def self.less_than(version, inclusive: false)
  VersionRange.less_than(version, inclusive: inclusive)
end

.normalize(version_string) ⇒ String

Normalizes a version string to a consistent format

Parameters:

  • version_string (String)

    The version string to normalize

Returns:

  • (String)

    The normalized version string



152
153
154
# File 'lib/vers.rb', line 152

def self.normalize(version_string)
  Version.normalize(version_string)
end

.parse(vers_string) ⇒ VersionRange

Parses a vers URI string into a VersionRange

Examples

Vers.parse("vers:npm/>=1.2.3|<2.0.0")
Vers.parse("vers:gem/~>1.0")
Vers.parse("*")  # unbounded range

Parameters:

  • vers_string (String)

    The vers URI string (e.g., “vers:npm/>=1.2.3|<2.0.0”)

Returns:

Raises:

  • (ArgumentError)

    if the vers string is invalid



74
75
76
# File 'lib/vers.rb', line 74

def self.parse(vers_string)
  @@parser.parse(vers_string)
end

.parse_native(range_string, scheme) ⇒ VersionRange

Parses a native package manager version range into a VersionRange

Examples

Vers.parse_native("^1.2.3", "npm")      # npm caret range
Vers.parse_native("~> 1.0", "gem")      # gem pessimistic operator
Vers.parse_native(">=1.0,<2.0", "pypi") # python constraints

Parameters:

  • range_string (String)

    The native version range string

  • scheme (String)

    The package manager scheme (npm, gem, pypi, etc.)

Returns:



91
92
93
# File 'lib/vers.rb', line 91

def self.parse_native(range_string, scheme)
  @@parser.parse_native(range_string, scheme)
end

.satisfies?(version, constraint, scheme = nil) ⇒ Boolean

Checks if a version satisfies a version range constraint

Examples

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

Parameters:

  • version (String)

    The version to check

  • constraint (String)

    The version constraint (vers URI or native format)

  • scheme (String, nil) (defaults to: nil)

    The package manager scheme (if not using vers URI)

Returns:

  • (Boolean)

    true if the version satisfies the constraint



119
120
121
122
123
124
125
126
127
# File 'lib/vers.rb', line 119

def self.satisfies?(version, constraint, scheme = nil)
  range = if scheme
            parse_native(constraint, scheme)
          else
            parse(constraint)
          end
  
  range.contains?(version)
end

.to_vers_string(version_range, scheme) ⇒ String

Converts a VersionRange to a vers URI string

Parameters:

  • version_range (VersionRange)

    The version range to convert

  • scheme (String)

    The package manager scheme

Returns:

  • (String)

    The vers URI string



102
103
104
# File 'lib/vers.rb', line 102

def self.to_vers_string(version_range, scheme)
  @@parser.to_vers_string(version_range, scheme)
end

.unboundedVersionRange

Creates an unbounded version range (matches all versions)

Returns:



203
204
205
# File 'lib/vers.rb', line 203

def self.unbounded
  VersionRange.unbounded
end

.valid?(version_string) ⇒ Boolean

Checks if a version string is valid

Parameters:

  • version_string (String)

    The version string to validate

Returns:

  • (Boolean)

    true if the version is valid



162
163
164
# File 'lib/vers.rb', line 162

def self.valid?(version_string)
  Version.valid?(version_string)
end