Skip to content

Latest commit

 

History

70 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vers

A Go implementation of the VERS specification for version range parsing and comparison across package ecosystems.

Installation

go get github.com/git-pkgs/vers

Usage

Parse VERS URIs

The VERS URI format provides a universal way to express version ranges:

package main

import (
    "fmt"
    "github.com/git-pkgs/vers"
)

func main() {
    // Parse a VERS URI
    r, _ := vers.Parse("vers:npm/>=1.0.0|<2.0.0")

    fmt.Println(r.Contains("1.5.0"))  // true
    fmt.Println(r.Contains("2.0.0"))  // false
    fmt.Println(r.Contains("0.9.0"))  // false
}

Parse Native Package Manager Syntax

Each package ecosystem has its own version constraint syntax. This library parses them all:

// npm: caret, tilde, x-ranges, hyphen ranges
r, _ := vers.ParseNative("^1.2.3", "npm")
r, _ = vers.ParseNative("~1.2.3", "npm")
r, _ = vers.ParseNative("1.0.0 - 2.0.0", "npm")
r, _ = vers.ParseNative(">=1.0.0 <2.0.0", "npm")

// Composer: caret, tilde, wildcard, hyphen, AND and OR ranges
r, _ = vers.ParseNative("^1.2.3", "composer")
r, _ = vers.ParseNative("~1.2", "composer")
r, _ = vers.ParseNative(">=1.0 <1.1 || >=1.2", "composer")

// Ruby gems: pessimistic operator
r, _ = vers.ParseNative("~> 1.2", "gem")
r, _ = vers.ParseNative(">= 1.0, < 2.0", "gem")

// Python: compatible release, exclusions
r, _ = vers.ParseNative("~=1.4.2", "pypi")
r, _ = vers.ParseNative(">=1.0.0,<2.0.0,!=1.5.0", "pypi")
r, _ = vers.ParseNative("==2.32.4", "pypi")

// Pub: caret and traditional intersection syntax
r, _ = vers.ParseNative("^1.2.3", "pub")
r, _ = vers.ParseNative(">=1.2.3 <2.0.0", "pub")

// Maven/NuGet: bracket notation
r, _ = vers.ParseNative("[1.0,2.0)", "maven")
r, _ = vers.ParseNative("[1.0,)", "maven")

// Cargo: same syntax as npm
r, _ = vers.ParseNative("^1.2.3", "cargo")

// Go: comma-separated constraints
r, _ = vers.ParseNative(">=1.0.0,<2.0.0", "go")

// Debian: >> and << operators
r, _ = vers.ParseNative(">> 1.0", "deb")

// RPM
r, _ = vers.ParseNative(">= 1.0", "rpm")

// Conan, OpenSSL, and Nginx
r, _ = vers.ParseNative("^1.2", "conan")
r, _ = vers.ParseNative("1.1.1w, 3.0.0", "openssl")
r, _ = vers.ParseNative("0.8.40+", "nginx")

Check Version Satisfaction

// Using VERS URI (empty scheme)
ok, _ := vers.Satisfies("1.5.0", "vers:npm/>=1.0.0|<2.0.0", "")
fmt.Println(ok)  // true

// Using native syntax
ok, _ = vers.Satisfies("1.5.0", "^1.0.0", "npm")
fmt.Println(ok)  // true

Compare Versions

vers.Compare("1.2.3", "1.2.4")  // -1 (a < b)
vers.Compare("2.0.0", "1.9.9")  // 1  (a > b)
vers.Compare("1.0.0", "1.0.0")  // 0  (equal)

// Prerelease versions sort before stable
vers.Compare("1.0.0", "1.0.0-alpha")  // 1 (stable > prerelease)

// Use ecosystem-specific ordering where versions are not SemVer
vers.CompareWithScheme("1.0~rc1", "1.0", "deb")  // -1
vers.CompareWithScheme("1.0.beta1", "1.0", "gem") // -1

Version Validation and Normalization

vers.Valid("1.2.3")        // true
vers.Valid("invalid")      // false

v, _ := vers.Normalize("1")      // "1.0.0"
v, _ = vers.Normalize("1.2")     // "1.2.0"
v, _ = vers.Normalize("1.2.3")   // "1.2.3"

vers.ValidWithScheme("1:2.3.4-1", "deb") // true
v, _ = vers.NormalizeWithScheme("01!02.0RC1", "pypi") // "1!2.0rc1"

Find a Baseline Version and Repository Tags

MinimumVersion returns an inclusive lower bound only when that exact version is part of the range. TagCandidates trims surrounding whitespace, preserves the remaining spelling, adds its scheme-normalized form, and tries the common optional v prefix.

r, _ := vers.ParseNative("^1.2", "npm")
baseline, ok := r.MinimumVersion() // "1.2", true
tags, _ := vers.TagCandidates(baseline, "npm")
// 1.2, v1.2, 1.2.0, v1.2.0

Create Ranges Programmatically

// Exact version
r := vers.Exact("1.2.3")

// Greater/less than
r = vers.GreaterThan("1.0.0", true)   // >=1.0.0
r = vers.GreaterThan("1.0.0", false)  // >1.0.0
r = vers.LessThan("2.0.0", false)     // <2.0.0

// Unbounded (matches all)
r = vers.Unbounded()

// Combine ranges
r1, _ := vers.ParseNative(">=1.0.0", "npm")
r2, _ := vers.ParseNative("<2.0.0", "npm")
intersection := r1.Intersect(r2)  // >=1.0.0 AND <2.0.0
union := r1.Union(r2)             // >=1.0.0 OR <2.0.0

// Add exclusions
r = r.Exclude("1.5.0")

Detect Exact Ranges

r, _ := vers.ParseNative("==2.32.4", "pypi")
version, exact := r.ExactVersion() // "2.32.4", true

r, _ = vers.ParseNative("^2.32.4", "npm")
_, exact = r.ExactVersion() // false

Convert Back to VERS URI

r, _ := vers.ParseNative("^1.2.3", "npm")
uri := vers.ToVersString(r, "npm")
// vers:npm/>=1.2.3|<2.0.0

// Unbounded range
r = vers.Unbounded()
uri = vers.ToVersString(r, "npm")
// vers:npm/*

Supported Ecosystems

Ecosystem Scheme Example Syntax
npm npm ^1.2.3, ~1.2.3, >=1.0.0 <2.0.0, 1.x, 1.0.0 - 2.0.0
Composer composer ^1.2.3, ~1.2, 1.2.*, >=1.0 <2.0, `
RubyGems gem, rubygems ~> 1.2, >= 1.0, < 2.0
PyPI pypi ~=1.4.2, >=1.0.0,<2.0.0, !=1.5.0
Pub pub ^1.2.3, >=1.2.3 <2.0.0, any
Maven maven [1.0,2.0), (1.0,2.0], [1.0,), [1.0]
NuGet nuget Same as Maven
Cargo cargo Same as npm
Go go, golang >=1.0.0,<2.0.0
Hex hex, elixir ~> 1.2, >= 1.0 and < 2.0
Debian deb, debian >> 1.0, << 2.0, >= 1.0
RPM rpm >= 1.0, <= 2.0
Conan conan ^1.2, ~1.2, >1 <2, `
OpenSSL openssl 1.1.1w, 1.1.1w, 3.0.0
Nginx nginx 0.8.40+, 0.7.52-0.8.39

Version comparison additionally supports semver, apk/alpine, alpm, gentoo, intdot, lexicographic, and datetime.

Development

Run Tests

go test ./...

Run Tests with Verbose Output

go test -v ./...

Run Specific Tests

go test -v -run TestParseNpmRange

Check Test Coverage

go test -cover ./...

Generate Coverage Report

go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

Run Benchmarks

go test -bench=. -benchmem

Run specific benchmarks:

go test -bench=BenchmarkContains -benchmem

License

MIT

About

A Go library for parsing, comparing and sorting version ranges according to the VERS spec.

Resources

Code of conduct

Contributing

Security policy

Stars

5 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages