Module: Vers

Defined in:
lib/vers.rb,
lib/vers/parser.rb,
lib/vers/scheme.rb,
lib/vers/version.rb,
lib/vers/interval.rb,
lib/vers/constraint.rb,
lib/vers/gem_version.rb,
lib/vers/pub_version.rb,
lib/vers/pypi_version.rb,
lib/vers/bazel_version.rb,
lib/vers/conan_version.rb,
lib/vers/maven_version.rb,
lib/vers/nuget_version.rb,
lib/vers/version_range.rb,
lib/vers/semver_version.rb,
lib/vers/special_version.rb,
lib/vers/composer_version.rb,
lib/vers/version_comparison.rb,
lib/vers/distribution_version.rb,
sig/vers.rbs

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", "pypi")  # => 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

Modules: ALPMVersion, APKVersion, BazelVersion, CargoVersion, ComposerVersion, ConanVersion, DatetimeVersion, DebianVersion, GemVersion, GentooVersion, GoVersion, IntDotVersion, LexicographicVersion, MavenVersion, NpmVersion, NuGetVersion, OpenSSLVersion, PubVersion, PyPIVersion, RPMVersion, Scheme, SemverVersion, VersionComparison Classes: Constraint, Error, Interval, Parser, Version, VersionRange

Constant Summary collapse

VERSION =

Returns:

  • (String)
"2.0.0"
@@parser =

Default parser instance for convenience methods

Parser.new

Class Method Summary collapse

Class Method Details

.clean(version_string, scheme = nil) ⇒ String?

Returns a normalized version, or nil when the version is invalid.

Parameters:

  • version_string (String)

    The version string to clean

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

    Package manager scheme or nil for generic cleaning

Returns:

  • (String, nil)

    The normalized version or nil



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

def self.clean(version_string, scheme = nil)
  Version.clean(version_string, scheme)
end

.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



147
148
149
# File 'lib/vers.rb', line 147

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

.compare_with_scheme(a, b, scheme) ⇒ Integer

Compares two version strings using scheme-specific rules

Parameters:

  • a (String)

    First version string

  • b (String)

    Second version string

  • scheme (String, nil)

    Package manager scheme or nil for generic comparison

Returns:

  • (Integer)

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



159
160
161
# File 'lib/vers.rb', line 159

def self.compare_with_scheme(a, b, scheme)
  Version.compare_with_scheme(a, b, scheme)
end

.emptyVersionRange

Creates an empty version range (matches no versions)

Returns:



262
263
264
# File 'lib/vers.rb', line 262

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



222
223
224
# File 'lib/vers.rb', line 222

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



233
234
235
# File 'lib/vers.rb', line 233

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



244
245
246
# File 'lib/vers.rb', line 244

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

.normalize(version_string, scheme = nil) ⇒ String

Normalizes a version string to a consistent format

Parameters:

  • version_string (String)

    The version string to normalize

Returns:

  • (String)

    The normalized version string



169
170
171
# File 'lib/vers.rb', line 169

def self.normalize(version_string, scheme = nil)
  Version.normalize(version_string, scheme)
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_native("~>1.0", "gem")
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



77
78
79
# File 'lib/vers.rb', line 77

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:



94
95
96
# File 'lib/vers.rb', line 94

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

.prerelease?(version_string, scheme = nil) ⇒ Boolean

Checks if a version is a prerelease using scheme-specific rules

Parameters:

  • version_string (String)

    The version string to classify

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

    Package manager scheme or nil for generic classification

Returns:

  • (Boolean)

    true if the version is a prerelease



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

def self.prerelease?(version_string, scheme = nil)
  Version.prerelease?(version_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



122
123
124
125
126
127
128
129
130
131
132
# File 'lib/vers.rb', line 122

def self.satisfies?(version, constraint, scheme = nil)
  sub_ranges = constraint.split('||').map(&:strip).reject(&:empty?)
  sub_ranges.any? do |sub_range|
    range = if scheme
              parse_native(sub_range, scheme)
            else
              parse(sub_range)
            end
    range&.contains?(version) || false
  end
end

.stable?(version_string, scheme = nil) ⇒ Boolean

Checks if a version is stable using scheme-specific rules

Parameters:

  • version_string (String)

    The version string to classify

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

    Package manager scheme or nil for generic classification

Returns:

  • (Boolean)

    true if the version is stable



191
192
193
# File 'lib/vers.rb', line 191

def self.stable?(version_string, scheme = nil)
  Version.stable?(version_string, scheme)
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



105
106
107
# File 'lib/vers.rb', line 105

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:



253
254
255
# File 'lib/vers.rb', line 253

def self.unbounded
  VersionRange.unbounded
end

.valid?(version_string, scheme = nil) ⇒ Boolean

Checks if a version string is valid

Parameters:

  • version_string (String)

    The version string to validate

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

    Package manager scheme or nil for generic validation

Returns:

  • (Boolean)

    true if the version is valid



180
181
182
# File 'lib/vers.rb', line 180

def self.valid?(version_string, scheme = nil)
  Version.valid?(version_string, scheme)
end