SemVer Package
The semver
package provides a complete implementation of the Semantic Versioning 2.0.0 specification in Go. It offers tools for parsing, comparing, and manipulating version strings following the SemVer standard.
Features
- Full SemVer Support: Complete implementation of SemVer 2.0.0 specification
- Version Parsing: Parse version strings into structured objects
- Version Comparison: Compare versions to determine precedence
- Pre-release Support: Handle pre-release version suffixes (e.g., alpha, beta)
- Build Metadata: Support for build metadata
- Version Increment: Methods to increment major, minor, and patch versions
Core Components
Version
The central type in the package is the Version
struct, which represents a semantic version with all its components:
type Version struct {
// Major version component (incompatible API changes)
Major int
// Minor version component (backwards-compatible functionality)
Minor int
// Patch version component (backwards-compatible bug fixes)
Patch int
// Pre-release version information
PreRelease string
// Build metadata
Build string
}
Parser Functions
Parse(version string) (*Version, error)
: Parse a version string into a Version objectMustParse(version string) *Version
: Like Parse, but panics on error
Comparison Functions
Compare(v1, v2 *Version) int
: Compare two versions for precedenceLessThan(v1, v2 *Version) bool
: Check if v1 is less than v2Equal(v1, v2 *Version) bool
: Check if v1 is equal to v2
Usage Examples
Parsing a Version String
package main
import (
"fmt"
"oss.nandlabs.io/golly/semver"
)
func main() {
// Parse a basic version
version, err := semver.Parse("1.2.3")
if err != nil {
fmt.Printf("Error parsing version: %v\n", err)
return
}
// Access version components
fmt.Printf("Major: %d\n", version.CurrentMajor())
fmt.Printf("Minor: %d\n", version.CurrentMinor())
fmt.Printf("Patch: %d\n", version.CurrentPatch())
// Parse a version with pre-release and build metadata
complexVersion, err := semver.Parse("2.0.0-alpha.1+build.123")
if err != nil {
fmt.Printf("Error parsing complex version: %v\n", err)
return
}
fmt.Printf("Complex version: %s\n", complexVersion.String())
fmt.Printf("Pre-release: %s\n", complexVersion.CurrentPreRelease())
fmt.Printf("Build metadata: %s\n", complexVersion.CurrentBuild())
}
Comparing Versions
package main
import (
"fmt"
"oss.nandlabs.io/golly/semver"
)
func main() {
v1, _ := semver.Parse("1.2.3")
v2, _ := semver.Parse("1.3.0")
v3, _ := semver.Parse("1.2.3-alpha")
v4, _ := semver.Parse("1.2.3")
// Compare versions
fmt.Println("v1 < v2:", semver.LessThan(v1, v2)) // true
fmt.Println("v3 < v1:", semver.LessThan(v3, v1)) // true (pre-release is less than regular)
fmt.Println("v1 == v4:", semver.Equal(v1, v4)) // true
// Sort a slice of versions
versions := []*semver.Version{v3, v1, v2, v4}
semver.Sort(versions)
fmt.Println("Sorted versions:")
for _, v := range versions {
fmt.Println(v.String())
}
// Output:
// 1.2.3-alpha
// 1.2.3
// 1.2.3
// 1.3.0
}
Incrementing Versions
package main
import (
"fmt"
"oss.nandlabs.io/golly/semver"
)
func main() {
version, _ := semver.Parse("1.2.3")
// Increment major version (2.0.0)
majorVersion := version.IncrementMajor()
fmt.Printf("Incremented major: %s\n", majorVersion.String())
// Increment minor version (1.3.0)
minorVersion := version.IncrementMinor()
fmt.Printf("Incremented minor: %s\n", minorVersion.String())
// Increment patch version (1.2.4)
patchVersion := version.IncrementPatch()
fmt.Printf("Incremented patch: %s\n", patchVersion.String())
// Working with pre-release versions
preRelease, _ := semver.Parse("1.2.3-alpha.1")
nextPreRelease := preRelease.IncrementPreRelease()
fmt.Printf("Next pre-release: %s\n", nextPreRelease.String()) // 1.2.3-alpha.2
}
Version Validation
package main
import (
"fmt"
"oss.nandlabs.io/golly/semver"
)
func main() {
validVersions := []string{
"1.0.0",
"1.0.0-alpha",
"1.0.0-alpha.1",
"1.0.0-alpha.beta",
"1.0.0+build.1",
"1.0.0-alpha+build.1",
}
invalidVersions := []string{
"1",
"1.0",
"1.a.0",
"v1.0.0", // 'v' prefix is not allowed by the strict spec
"1.0.0.0",
}
fmt.Println("Valid versions:")
for _, v := range validVersions {
_, err := semver.Parse(v)
fmt.Printf("%s: %v\n", v, err == nil)
}
fmt.Println("Invalid versions:")
for _, v := range invalidVersions {
_, err := semver.Parse(v)
fmt.Printf("%s: %v (%v)\n", v, err == nil, err)
}
}
Installation
go get oss.nandlabs.io/golly/semver