gitee.com/gricks/utils@v1.0.8/version.go (about)

     1  package utils
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"sort"
     7  	"strconv"
     8  )
     9  
    10  var (
    11  	// https://semver.org
    12  	semverRegexp = regexp.MustCompile(`^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`)
    13  )
    14  
    15  type Version struct {
    16  	build      string
    17  	prerelease string
    18  	segments   []int64
    19  	original   string
    20  }
    21  
    22  func NewVersion(v string) (*Version, error) {
    23  	matches := semverRegexp.FindStringSubmatch(v)
    24  	if matches == nil {
    25  		return nil, fmt.Errorf("invalid version: `%s`", v)
    26  	}
    27  
    28  	ver := &Version{}
    29  	for i := 1; i <= 3; i++ {
    30  		val, err := strconv.ParseInt(matches[i], 10, 64)
    31  		if err != nil {
    32  			return nil, fmt.Errorf("invalid version: `%s`, parse failed: `%v`", v, err)
    33  		}
    34  		ver.segments = append(ver.segments, val)
    35  	}
    36  
    37  	ver.prerelease = matches[4]
    38  	ver.build = matches[5]
    39  	ver.original = v
    40  
    41  	return ver, nil
    42  }
    43  
    44  func (v *Version) Compare(o *Version) int {
    45  	for i := 0; i < 3; i++ {
    46  		if v.segments[i] > o.segments[i] {
    47  			return 1
    48  		} else if v.segments[i] < o.segments[i] {
    49  			return -1
    50  		}
    51  	}
    52  	return 0
    53  }
    54  
    55  func (v *Version) Build() string      { return v.build }
    56  func (v *Version) PreRelease() string { return v.prerelease }
    57  func (v *Version) Original() string   { return v.original }
    58  func (v *Version) String() string     { return v.original }
    59  
    60  // Sort
    61  
    62  type Versions []*Version
    63  
    64  func (v Versions) Len() int           { return len(v) }
    65  func (v Versions) Less(i, j int) bool { return v[i].Compare(v[j]) < 0 }
    66  func (v Versions) Swap(i, j int)      { v[i], v[j] = v[j], v[i] }
    67  func (v Versions) Sort()              { sort.Sort(v) }