A Semantic Versioning 2.0.0 compliant parser and utility library written in Go.
The semver
library offers a comprehensive and efficient solution for working with Semantic Versioning 2.0.0. Key features include:
-
Zero Dependencies
- Lightweight implementation with no external dependencies beyond the standard library.
-
Full Compliance
- Parses and validates semantic versions according to the Semantic Versioning 2.0.0 specification.
-
Version Parsing and Validation
- Parses semantic version strings into structured
Version
objects. - Automatically validates version strings for correctness, including:
- Major, minor, and patch components.
- Pre-release identifiers (e.g.,
alpha
,beta
,rc.1
). - Build metadata (e.g.,
build.123
). - Enforces no leading zeroes in numeric components.
- Parses semantic version strings into structured
-
Customizable
- Define your own parser.
- Strict mode for enforcing strict version format rules.
-
Version Comparison
- Supports comparison of versions using Semantic Versioning rules:
Compare
: Returns -1, 0, or 1 for less than, equal to, or greater than comparisons.- Convenient helper methods:
LessThan
,LessThanOrEqual
,GreaterThan
,GreaterThanOrEqual
,Equal
.
- Correctly handles precedence rules for pre-release versions and build metadata.
- Supports comparison of versions using Semantic Versioning rules:
-
Version Ranges
- Flexible range functionality for evaluating version constraints:
- Define complex version ranges using a familiar syntax (e.g.,
">=1.0.0 <2.0.0"
). - Determine whether a version satisfies a given range.
- Combine multiple ranges for advanced constraints (e.g.,
">=1.2.3 || <1.0.0-alpha"
).
- Define complex version ranges using a familiar syntax (e.g.,
- Useful for dependency management, release gating, and compatibility checks.
- Flexible range functionality for evaluating version constraints:
-
JSON Support
- Seamlessly marshal and unmarshal
Version
objects to and from JSON. - Works with
encoding/json
for easy integration with APIs and configuration files.
- Seamlessly marshal and unmarshal
-
Database Support
- Compatible with
database/sql
:- Implements
driver.Valuer
to storeVersion
in databases. - Implements
sql.Scanner
to retrieveVersion
from databases.
- Implements
- Compatible with
-
Encoding and Decoding
- Implements standard Go interfaces:
encoding.TextMarshaler
andencoding.TextUnmarshaler
for text encoding.encoding.BinaryMarshaler
andencoding.BinaryUnmarshaler
for binary encoding.
- Implements standard Go interfaces:
-
Performance Optimizations
- Efficient parsing and comparison with minimal memory allocations.
- Designed for high performance with concurrent workloads.
-
Well-Tested
- Comprehensive test coverage, including:
- Functional tests for all features.
- Benchmarks to validate performance optimizations.
- Detailed tests for range evaluation, parsing, and edge cases.
- Comprehensive test coverage, including:
To install the package, run the following command:
go get -u github.com/sixafter/semver
To use the package in your Go project, import it as follows:
import "github.com/sixafter/semver"
Here are some common use cases for the semver
library:
Parse a version string into a Version
object and validate its correctness:
package main
import (
"fmt"
"log"
"github.com/sixafter/semver"
)
func main() {
v, err := semver.Parse("1.2.3-alpha.1+build.123")
if err != nil {
log.Fatalf("Error parsing version: %v", err)
}
fmt.Println(v) // Output: 1.2.3-alpha.1+build.123
}
Compare two versions to determine their order:
package main
import (
"fmt"
"github.com/sixafter/semver"
)
func main() {
v1, _ := semver.Parse("1.2.3")
v2, _ := semver.Parse("2.0.0")
fmt.Println(v1.LessThan(v2)) // Output: true
fmt.Println(v2.GreaterThan(v1)) // Output: true
}
Evaluate whether a version satisfies a given range:
package main
import (
"fmt"
"github.com/sixafter/semver"
)
func main() {
r, _ := semver.ParseRange(">=1.0.0 <2.0.0")
v, _ := semver.Parse("1.5.0")
fmt.Println(r.Contains(v)) // Output: true
}
Serialize and deserialize versions using JSON:
package main
import (
"encoding/json"
"fmt"
"github.com/sixafter/semver"
)
func main() {
v := semver.MustParse("1.2.3-alpha.1+build.123")
data, _ := json.Marshal(v)
fmt.Println(string(data)) // Output: "1.2.3-alpha.1+build.123"
var v2 semver.Version
_ = json.Unmarshal(data, &v2)
fmt.Println(v2) // Output: 1.2.3-alpha.1+build.123
}
make bench
Sample output might look like this:
Expand to see results
go test -bench=. -benchmem -memprofile=mem.out -cpuprofile=cpu.out
goos: darwin
goarch: arm64
pkg: github.com/sixafter/semver
cpu: Apple M2 Ultra
BenchmarkParseVersionSerial-24 9170428 123.1 ns/op 128 B/op 2 allocs/op
BenchmarkParseVersionConcurrent-24 17886765 68.35 ns/op 128 B/op 2 allocs/op
BenchmarkParseVersionAllocations-24 7576131 157.2 ns/op 144 B/op 4 allocs/op
PASS
ok github.com/sixafter/semver 4.109s
ns/op
: Nanoseconds per operation. Lower values indicate faster performance.B/op
: Bytes allocated per operation. Lower values indicate more memory-efficient code.allocs/op
: Number of memory allocations per operation. Fewer allocations generally lead to better performance.
Contributions are welcome. See CONTRIBUTING
This project is licensed under the Apache 2.0 License. See LICENSE file.