semver

package module
v0.0.0-...-69d9307 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2024 License: Apache-2.0 Imports: 5 Imported by: 3

README

semver

The semver package implements parsing, ordering, and matching of versions, as defined by Semantic Versioning 2.0.0, with support for extensions and quirks implemented by a number of package management systems, including Go and npm.

For a detailed description of what is supported, see version.go.

Example usage

Determining which of two versions is greater:

v1, err := semver.NPM.Parse("1.2.3")
v2, err := semver.NPM.Parse("2.3.4")
if v1.Compare(v2) < 0 { ... }

Determining whether a version satisfies a constraint:

v, err := semver.NPM.Parse("1.2.3")
c, err := semver.NPM.ParseConstraint("^1.0.0")
if c.MatchVersion(v) { ... }

Documentation

Overview

Package semver handles versions as defined by semver.org Version 2.0.0 as well as constraints applied to them.

By default the package is permissive, honoring practice rather than the standard, since no packaging systems implement the standard strictly. The System type controls which packaging system's rules apply.

A semantic version string is a sequence of dot-separated components, usually numbers that specify a version, possibly followed by alphanumeric tags. The specification is at https://semver.org, but this practice is variant. For instance, RubyGems does not follow it exactly in that a pre-release tag can be introduced with a period rather than a hyphen. More generally, semver.org requires three version numbers (major, minor, patch) but in practice some are often missing and sometimes, especially with RubyGems, there may be more than three.

The default syntax is parsed as follows. Variations are discussed below.

No spaces may appear in a version string, and version strings are entirely printable ASCII from the set:

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.+-

- There must be one, two or three dot-separated components.
  If there are fewer than three, the missing ones are taken to be 0.
- Those components must be unsigned decimal integers.
- Following those may appear zero, one or two types of alphanumeric
  suffixes. If present (either may be absent) they are, in this order:
	- A hyphen followed by a dot-punctuated pre-release tag. For RubyGems,
	  we also allow this to be introduced by a period instead of a hyphen.
	- A plus sign followed by a dot-punctuated build tag.
  There may be multiple tags of each type, but only in this order.

Except for elements of the build tag, numbers may not begin with a zero (except of course for literal value 0).

Comparisons between versions match the semver.org specification:

  • Corresponding version components in order are compared. Numerical values are compared numerically, non-numeric ones lexically.
  • Any pre-release tagged version compares earlier than an equivalent non-pre-release.
  • Build tags are ignored in comparison.

Variants:

NPM
	A version string may begin with one or more 'v' characters.
Go
	A version string must begin with one 'v' character.
RubyGems
	There may be more than 3 numbers.
	A prerelease tag may be separated by a period rather than a
	than a hyphen. Such a prerelease tag must not be numeric.

The constraint grammar is derived from documentation, examples, and examination of public usage. (There is no standard uniform constraint algebra; Semver only specifies versions.) Again, we first describe the default grammar (that of DefaultSystem) and then list variants.

The grammar is written assuming VERSION and WILDCARD as terminals, with syntax defined above except that WILDCARD requires at least one of major, minor, or patch numbers to be a single wildcard character from the set

*xX

although PyPI accepts only * as a wildcard character. Items within a constraint can be separated by spaces. The character set is that of versions with the addition of

*^~><=

The default constraint grammar is listed here. Comments identify which non-default system supports each binary operator.

constraint = orList

orList = andList
	| orList '||' andList // NPM only.

andList = value
	| andList value
	| andList ',' value // Cargo only, but see below re: RubyGems

value = VERSION
	| span
	| unop VERSION
	| WILDCARD

unop = '='
	| '==' // PyPI only; other systems use '='.
	| '>'
	| '>='
	| '<'
	| '<='
	| '^'
	| '~'
	| '~>'

span = VERSION ' ' '-' ' ' VERSION // NPM only.

A span must be the only item in an andList. That is, a span may not be "anded", only "ored".

Operators supported:

NPM
	= > >= < <= ^ ~ ~>
Cargo
	= > >= < <= ^ ~
	A missing (empty) operator defaults to ^.
Go
	None.
Python
	== > >= < <= ~= ~=
	In Python, ~= is the same as RubyGems ~>.
RubyGems
	= != > >= < <= ~>

Other variants:

Go
	The constraint grammar is just a version, which then represents
	a constraint as follows:
		v.1.2.3 means >=1.2.3 and <2.0.0.
RubyGems
	Officially RubyGems does not support comma, but the web site and
	its API print lists of constraints separated by commas, so we
	accept them here.
Maven
	TODO: The implementation supports Maven version 2 only.
	Maven uses a grammar with open and closed ranges and
	comma-separated or-ed together range lists:
		[2.0,2.1),[3.0.0,3.4.0]
	means (2.0 <= v && v < 2.1) || (3.0.0 <= v && v <= 3.4.0).
	Versions can be omitted, so (,2.0) means v <= 2.0 and
	(,) means everything. Version syntax is standard, without
	wildcards.
NuGet
	NuGet uses a set grammar with the same syntax as Maven.
	Version syntax permits * as a wildcard.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Constraint

type Constraint struct {
	// contains filtered or unexported fields
}

Constraint holds a parsed constraint specification.

func (*Constraint) HasPrerelease

func (c *Constraint) HasPrerelease() bool

HasPrerelease reports whether the constraint contains a prerelease tag.

func (*Constraint) IsSimple

func (c *Constraint) IsSimple() bool

IsSimple reports whether the constraint is formed by a simple version or, for those systems that support it, an equality operator and a simple version. A simple constraint can still match multiple versions, depending on the System. For Maven, a simple constraint is a "soft" constraint; for Cargo, a simple version is equivalent to the version preceded by the caret operator, and so on. Present mostly to assist in understanding version resolution in Maven.

func (*Constraint) Match

func (c *Constraint) Match(version string) bool

Match reports whether the version represented by the argument string satisfies the constraint. It returns false if the argument is invalid or a wildcard.

A user's version U = x.y.z matches a simple constraint version V (a.b.c), possibly with an operator, by applying these rules given the operator:

""  (nothing) U == V (using the rules of version.Compare)
=   U == V
	This operator is spelled == in PyPI.
>=  U >= V
<   U < V
<=  U <= V
^   (major range operator) U >= a.b.c AND U < (a+1).0.0.
	• Cargo behaves differently when given exactly two zeros:
		- ^0.0  means >=0.0.0 AND < 0.1.0
	Otherwise it is the same as the others.
~   (minor range operator)
	• If a.b.c are present, x == a AND y == b AND c >= z
	• If only a.b are present, x == a AND y == b
	• If only a is present, x == a
~>  (pessimistic operator, a.k.a. compatible with and other fanciful names)
	This operator is spelled ~= in PyPI. In NPM, this token is supported
	but is just a variant spelling of ~.
	• If a.b.c are present, x == a AND y == b AND c >= z
	• If only a.b are present, x == a AND y >= b
	• If only a is present, x == a

For expressions involving lists separated by commas (",") ors ("||"), or spaces (" "), the precedence order is in that order in increasing precedence: Comma binds loosest, then ||, then spaces. Commas and spaces represent "AND" (conjunction); ors represent "OR" (disjunction). See the package comment for information about which packaging systems support which operators.

Maven represents constraints as unions of ranges, not using the syntax described above. For Maven, therefore, Match reports whether the version is in any of the ranges.

func (*Constraint) MatchVersion

func (c *Constraint) MatchVersion(v *Version) bool

MatchVersion is like Match but it takes a *Version.

func (*Constraint) MatchVersionPrerelease

func (c *Constraint) MatchVersionPrerelease(v *Version) bool

MatchVersionPrerelease is like Match but if v contains prereleases, they are ignored for the purpose of matching (assuming the constraint does not have them), and thus v matches if just the numbers match. It is used when matching vulnerabilities, not during constraint satisfaction for builds.

func (*Constraint) Set

func (c *Constraint) Set() Set

Set returns the set representation of the constraint.

func (*Constraint) String

func (c *Constraint) String() string

String returns the string used to create the Constraint, trimmed of leading and trailing space.

type Diff

type Diff int

Diff characterizes the most significant manner in which two versions differ: by major number, by minor number, and so on.

const (
	Same           Diff = iota // No difference.
	DiffOther                  // Unqualifiable difference.
	DiffMajor                  // Difference in Major number.
	DiffMinor                  // Difference in Minor number.
	DiffPatch                  // Difference in Patch number.
	DiffPrerelease             // Difference in prerelease information.
	DiffBuild                  // Difference in build tag.
)

Possible differences between versions, from most to least significant.

func (Diff) String

func (i Diff) String() string

type Set

type Set struct {
	// contains filtered or unexported fields
}

A Set represents a complete constraint specification as a slice of spans defining ranges of valid concrete versions that would satisfy the constraint. The slice is stored in increasing span.min order. A Set is created by parsing a valid constraint specification.

func (Set) Empty

func (s Set) Empty() bool

Empty reports whether the set is empty, that is, can match no versions.

func (*Set) Intersect

func (s *Set) Intersect(t Set) error

Intersect replaces the receiver with the set intersection of the receiver and the argument.

func (Set) Match

func (s Set) Match(version string) (bool, error)

Match reports whether the version defined by the argument string is contained in the set.

func (Set) MatchVersion

func (s Set) MatchVersion(v *Version) bool

MatchVersion reports whether the version is contained in the set.

func (Set) String

func (s Set) String() string

String returns a textual representation of the Set acceptable by ParseSetConstraint.

func (*Set) Union

func (s *Set) Union(t Set) error

Union replaces the receiver with the set union of the receiver and the argument.

type System

type System byte

System identifies a packaging system: RubyGems, NPM, etc. The "DefaultSystem" value represents a fictional but accommodating semantic versioning standard that permits most common operations and syntaxes. For more precise adherence to the rules of a known packaging system such as RubyGems, use the corresponding System value.

const (
	DefaultSystem System = iota // Unknown or default.
	Cargo
	Go
	Maven
	NPM
	NuGet
	PyPI
	RubyGems
	Composer
)

Supported systems.

func (System) Compare

func (sys System) Compare(str1, str2 string) int

Compare compares the two strings, considering them as versions in the (single) packaging system. It returns -1 if str1 represents an earlier version, +1 a later version, and 0 if they are equal. If versions match numerically, tags are compared lexicographically. Comparison of otherwise valid versions from different Systems returns the comparison of the System values in unspecified but stable order. A nil version compares below a non-nil version. Pre-release versions compare earlier than otherwise equal non-prerelease versions. Invalid version strings compare earlier than valid ones. Build metadata is ignored. Comparison ordering is defined by semver.org Version 2.0.0.

func (System) Difference

func (sys System) Difference(a, b string) (int, Diff, error)

Difference parses a and b and, if there is no error, returns the result of a.Difference(b).

func (System) MinVersion

func (sys System) MinVersion(v *Version) *Version

MinVersion returns a new Version for that system that precedes all other versions in comparison order.

func (System) Parse

func (sys System) Parse(str string) (*Version, error)

Parse returns the result of parsing the version string in the packaging system. The syntax is System-dependent and is defined in the package comment.

func (System) ParseConstraint

func (sys System) ParseConstraint(str string) (retC *Constraint, retErr error)

ParseConstraint returns the result of parsing the constraint string in the packaging system. The syntax is System-dependent and is defined in the package comment.

func (System) ParseSetConstraint

func (sys System) ParseSetConstraint(str string) (*Constraint, error)

ParseSetConstraint returns the result of parsing the set representated by str in the packaging system. The syntax is system-independent. Trimmed of leading and trailing spaces, the syntax is a list of comma-separated spans inside a braces:

{span,span,...}

There are no extraneous spaces. The string "{}" is the empty set and matches nothing. Spans are formatted according to their rank:

An empty span: <empty>
A single version: 1.2.3-alpha
A span between two versions: [1.2.3:2.3.4]

In the last case, a bracket will be ( or ) if the span is open on the corresponding side. On the right-hand side of a span, a number (major, minor, patch) may be replaced with ∞ to represent a value greater than all numeric values.

func (System) String

func (i System) String() string

type Version

type Version struct {
	// contains filtered or unexported fields
}

Version represents a specific semantic version, or possibly a wildcard pattern.

func (*Version) Canon

func (v *Version) Canon(showBuild bool) string

Canon returns a canonicalized string representation of the version. The showBuild argument specifies whether to include the build metadata.

func (*Version) Compare

func (v *Version) Compare(o *Version) int

Compare compares two versions. See the Compare func for the semantics.

func (*Version) Difference

func (v *Version) Difference(u *Version) (int, Diff)

Difference reports the level of the most significant difference between u and v. The return values are the result of v.Compare(u) and the type of difference. For example, the difference between 1.2.3 and 1.3.4 is MinorDiff. If the difference is not well characterized by the definition of Semver 2.0, Difference returns OtherDiff. Note that since build tags are ignored by Compare, Difference can return (0, BuildDiff).

func (*Version) Epoch

func (v *Version) Epoch() (int, bool)

Epoch extracts the epoch from the parsed semantic version. If the version did not specify an epoch, or the system doesn't support it, 0 and false are returned.

func (*Version) IsBuild

func (v *Version) IsBuild() bool

IsBuild reports whether the Version contains a build suffix.

func (*Version) IsPrerelease

func (v *Version) IsPrerelease() bool

IsPrerelease reports whether the Version contains a pre-release suffix. TODO: Does this need to be system-independent?

func (*Version) IsWildcard

func (v *Version) IsWildcard() bool

IsWildcard reports whether the Version contains wildcards. A nil Version is not a wildcard.

func (*Version) Major

func (v *Version) Major() (int64, bool)

Major extracts the major from the parsed semantic version. If the version did not specify a major version 0 and false are returned.

func (*Version) Prerelease

func (v *Version) Prerelease() string

Prerelease returns the prelease tags, if any, including the leading hyphen. TODO: What should Maven return here?

func (*Version) String

func (v *Version) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL