Hi, I’m @Luo Zhu

This article was first published on luo Zhu’s official website

This article synchronizes in the public account “luo Zhu early teahouse”, reprint please contact the author.

Creation is not easy, form a habit, quality three even!

The Semver package provides the ability to use semantic versions in the Go language. Specifically, it provides the following functions:

  • Parsing semantic versions
  • Sort semantic versions
  • Check that the semantic version conforms to a set of constraints
  • (Optional) UsevThe prefix

If you’re looking for a command-line tool for version comparisons, use VERT.

Parsing semantic versions

There are two functions that parse the semantic version. StrictNewVersion only resolves versions that are valid in version 2 of the semantic specification. The NewVersion function attempts to cast a version to a semantic version and parse it. For example, if there is a leading V or all three parts of the version listed (e.g. V1.2) an attempt will be made to cast it to a valid semantic version (e.g. 1.2.0). In both cases, a Version object is returned that can be sorted, compared, and used in constraints.

When parsing the version, if you encounter problems parsing the version, the wrong version is returned. For example,

v, err := semver.NewVersion("1.2.3 - beta. 1 + build345")
Copy the code

Version objects have methods to get the version part, compare it to other versions, convert the version back to a string and get the original string. It is useful to get the raw string if you cast the semantic version into a valid form.

Sort semantic versions

You can sort a set of versions using the sort package in the standard library. For example,

raw := []string{"1.2.3"."1.0"."1.3"."2"."0.4.2",}
vs := make([]*semver.Version, len(raw))
for i, r := range raw {
    v, err := semver.NewVersion(r)
    iferr ! =nil {
        t.Errorf("Error parsing version: %s", err)
    }

    vs[i] = v
}

sort.Sort(semver.Collection(vs))
Copy the code

Checking version Constraints

There are two ways to compare versions. One comparison method uses Version instances, and the other uses Constraints. There are some important differences to note between these two methods of comparison.

  1. When you Compare two versions using functions such as Compare, LessThan, it follows the specification and always includes the pre-release version in the comparison. It will be in semver.org/#spec-item-… Valid answers are provided in the specification comparison section
  2. When constraint checking is used for checking or validation, it follows a different set of rules that are common to tools such as NPM/JS and Rust/Cargo. This includes treating pre-releases as invalid if they are not included in the scope. If you want to include pre-releases, a simple solution is to include ‘-0’ in your scope.
  3. A constraint scope can have some complex rules, including~^The abbreviations. For more details on these, see the options below.

There is a difference between the two methods or check versions because the comparison method on Version follows the specification while the comparison scope is not part of the specification. Different software packages and tools determine the scope rules themselves. This leads to differences. For example, NPM/JS and Cargo/Rust follow similar patterns, while PHP ^ has a different pattern. The comparison functionality in this package follows NPM/JS and Cargo/Rust because applications that use this package follow similar patterns on their versions.

Versioning against version limits is one of the most powerful parts of a package.

c, err := semver.NewConstraint("> = 1.2.3")
iferr ! =nil {
    // Handle constraints that are not resolvable.
}

v, err := semver.NewVersion("1.3")
iferr ! =nil {
    // Handle the case where the version cannot be resolved
}
// Check if the version conforms to the constraint, the variable will be 'true'
a := c.Check(v)
Copy the code

Basic comparison

There are two elements to comparison. First, a comparison string is a list of AND comparisons separated by Spaces or commas. Then they use | | space. (OR) comparison. > = 1.2, for example, < 3.0.0 | | > = holdings is looking for a greater than or equal to 1.2 and less than 3.0.0 or greater than or equal to holdings of comparison.

The basic comparison is:

  • =: equal (aliased to no operator)
  • ! =: not equal
  • >: greater than
  • <: less than
  • > =: greater than or equal to
  • < =: Less than or equal to

Use pre-releases

For those unfamiliar with them, pre-releases are used for software releases that precede stable or generally available versions. Examples of pre-release versions include development, alpha, beta, and release candidates. The pre-release could be something like 1.2.3-beta.1, while the stable release could be 1.2.3. Pre-releases precede their associated releases in order of precedence. In this example, 1.2.3-beta.1 < 1.2.3.

According to the semantic versioning specification, a pre-release may not conform to the API with its release:

A pre-release version indicates that the version is unstable and may not meet the expected compatibility requirements expressed by its associated normal version.

Using SemVer comparisons without the constraints of a pre-released comparator skips the pre-released version. For example, > = 1.2.3 will skip pre-releases when viewing the list of releases, while > = 1.2.3-0 will judge and find pre-releases.

The reason 0 is included as the pre-release in the example comparison is that, according to the specification, the pre-release can only contain ASCII alphanumeric and hyphen characters (and. Delimiter). Sort again in ASCII sort order according to the specification. The lowest character is 0 in the ASCII sort order (see ASCII table)

It is important to understand the ASCII sort order because a-z comes before A-z. This means that > = 1.2.3-BETA will return 1.2.3-alpha. What you might expect from case sensitivity does not apply here. This is due to the ASCII sort order specified by the specification.

Hyphen range comparison

There are several ways to handle ranges, the first being the hyphen range. These look like:

  • 1.2 1.4.5> 1.2 < = = 1.4.5equivalent
  • 2.3.4-4.5 -> = 2.3.4 < = 4.5equivalent

Wildcard character in comparison

X, x, and * can be used as wildcards. This applies to all comparison operators. When used on the = operator, it falls back to the patch level comparison (see tilde below). For example,

  • X 1.2.> = 1.2.0, < 1.3.0equivalent
  • > = 1.2 x> = 1.2.0equivalent
  • <= 2.x< 3equivalent
  • *> = 0.0.0equivalent

Wave Range comparison (patch)

If a minor version is specified, the tilde (~) comparison operator applies to the patch level range, and if a minor version number is missing, the primary operator level changes. For example,

  • ~ 1.2.31.2.3 = >, < 1.3.0equivalent
  • ~ 1< 2 > = 1,equivalent
  • ~ 2.3= 2.3, p < 2.4 >equivalent
  • ~ 1.2 x> = 1.2.0, < 1.3.0equivalent
  • ~1.x< 2 > = 1,equivalent

Caret range comparison (main)

The caret (^) comparison operator is used to make major level changes after a stable (1.0.0) release. Prior to the 1.0.0 release, the minor version served as the API stability level. This is useful when comparing API versions because there are destructive updates to the API. For example,

  • ^ 1.2.31.2.3 = >, < 2.0.0equivalent
  • ^ 1.2 x> = 1.2.0, < 2.0.0
  • ^ 2.3< 3 > = 2.3equivalent
  • ^2.x> = 2.0.0, < 3equivalent
  • ^ 0.2.3> = 0.2.3 < 0.3.0equivalent
  • ^ 0.2> = 0.2.0 < 0.3.0equivalent
  • ^ 0.0.3> = 0.0.3 < 0.0.4equivalent
  • ^ 0.0> = 0.0.0 < 0.1.0 fromequivalent
  • ^ 0> = 0.0.0 < 1.0.0equivalent

validation

In addition to testing the version against the constraint, you can also validate the version against the constraint. When validation fails, an error message is returned containing the reason why the version does not conform to the constraint. For example,

c, err := semver.NewConstraint("< = 1.2.3, > = 1.4")
iferr ! =nil {
    // Handle constraints that are not resolvable.
}

v, err := semver.NewVersion("1.3")
iferr ! =nil {
    // Handle the case where the version cannot be resolved
}

// Validate versions against constraints.
a, msgs := c.Validate(v)
/ / a is false
for _, m := range msgs {
    fmt.Println(m)

    // Loop read error
    // "1.3 is greater than 1.2.3"
    // "1.3 is less than 1.4"
}
Copy the code