github.com/criteo/command-launcher@v0.0.0-20230407142452-fb616f546e98/internal/remote/version.go (about)

     1  package remote
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strconv"
     7  )
     8  
     9  // defaultVersion presents a version in format:
    10  // Major.Minor.Patch-Tag
    11  type defaultVersion struct {
    12  	Major int
    13  	Minor int
    14  	Patch int
    15  	Tag   string
    16  }
    17  
    18  type defaultVersionList []defaultVersion
    19  
    20  func toInt(str string) int {
    21  	val, err := strconv.Atoi(str)
    22  	if err != nil {
    23  		return 0
    24  	}
    25  
    26  	return val
    27  }
    28  
    29  func ParseVersion(versionAsString string, version *defaultVersion) error {
    30  	t := regexp.MustCompile(`([0-9]+)\.?([0-9]+)?\.?([0-9]+)?([-_]{1}([a-zA-Z0-9]+))?`)
    31  	if t.MatchString(versionAsString) {
    32  		fields := t.FindStringSubmatch(versionAsString)
    33  		*version = defaultVersion{
    34  			Major: toInt(fields[1]),
    35  			Minor: toInt(fields[2]),
    36  			Patch: toInt(fields[3]),
    37  			Tag:   fields[5],
    38  		}
    39  		return nil
    40  	}
    41  
    42  	return fmt.Errorf("version does not match with pattern (major.minor.path-tag)")
    43  }
    44  
    45  func (version defaultVersion) String() string {
    46  	if version.Tag != "" {
    47  		return fmt.Sprintf("%d.%d.%d-%s", version.Major, version.Minor, version.Patch, version.Tag)
    48  	}
    49  
    50  	return fmt.Sprintf("%d.%d.%d", version.Major, version.Minor, version.Patch)
    51  }
    52  
    53  func Less(l defaultVersion, r defaultVersion) bool {
    54  	lseg := [3]int{l.Major, l.Minor, l.Patch}
    55  	rseg := [3]int{r.Major, r.Minor, r.Patch}
    56  	for i := 0; i < 3; i++ {
    57  		if lseg[i] != rseg[i] {
    58  			return lseg[i] < rseg[i]
    59  		}
    60  	}
    61  
    62  	// If segments are equal, then compare the prerelease info
    63  	return l.Tag < r.Tag
    64  }
    65  
    66  func IsVersionSmaller(v1 string, v2 string) bool {
    67  	var l defaultVersion
    68  	var r defaultVersion
    69  
    70  	err := ParseVersion(v1, &l)
    71  	if err != nil { // wrong format version is considered smaller
    72  		return true
    73  	}
    74  	err = ParseVersion(v2, &r)
    75  	if err != nil { // wrong fromat version is considered smaller
    76  		return false
    77  	}
    78  
    79  	return Less(l, r)
    80  }
    81  
    82  func (lst defaultVersionList) Len() int {
    83  	return len(lst)
    84  }
    85  
    86  func (lst defaultVersionList) Less(i, j int) bool {
    87  	return Less(lst[i], lst[j])
    88  }
    89  
    90  func (lst defaultVersionList) Swap(i, j int) {
    91  	lst[i], lst[j] = lst[j], lst[i]
    92  }