github.com/getgauge/gauge@v1.6.9/version/version.go (about)

     1  /*----------------------------------------------------------------
     2   *  Copyright (c) ThoughtWorks, Inc.
     3   *  Licensed under the Apache License, Version 2.0
     4   *  See LICENSE in the project root for license information.
     5   *----------------------------------------------------------------*/
     6  
     7  package version
     8  
     9  import (
    10  	"fmt"
    11  	"sort"
    12  	"strconv"
    13  	"strings"
    14  )
    15  
    16  // CurrentGaugeVersion represents the current version of Gauge
    17  var CurrentGaugeVersion = &Version{1, 6, 9}
    18  
    19  // BuildMetadata represents build information of current release (e.g, nightly build information)
    20  var BuildMetadata = ""
    21  var CommitHash = ""
    22  
    23  type Version struct {
    24  	Major int
    25  	Minor int
    26  	Patch int
    27  }
    28  
    29  type VersionSupport struct {
    30  	Minimum string
    31  	Maximum string
    32  }
    33  
    34  func ParseVersion(versionText string) (*Version, error) {
    35  	splits := strings.Split(versionText, ".")
    36  	if len(splits) != 3 {
    37  		return nil, fmt.Errorf("incorrect version format. version should be in the form 1.5.7")
    38  	}
    39  	Major, err := strconv.Atoi(splits[0])
    40  	if err != nil {
    41  		return nil, VersionError("major", splits[0], err)
    42  	}
    43  	Minor, err := strconv.Atoi(splits[1])
    44  	if err != nil {
    45  		return nil, VersionError("minor", splits[1], err)
    46  	}
    47  	Patch, err := strconv.Atoi(splits[2])
    48  	if err != nil {
    49  		return nil, VersionError("patch", splits[2], err)
    50  	}
    51  
    52  	return &Version{Major, Minor, Patch}, nil
    53  }
    54  
    55  func VersionError(level, text string, err error) error {
    56  	return fmt.Errorf("error parsing %s version %s to integer. %s", level, text, err.Error())
    57  }
    58  
    59  func (Version *Version) IsBetween(lower, greater *Version) bool {
    60  	return Version.IsGreaterThanEqualTo(lower) && Version.IsLesserThanEqualTo(greater)
    61  }
    62  
    63  func (Version *Version) IsLesserThan(version1 *Version) bool {
    64  	return CompareVersions(Version, version1, LesserThanFunc)
    65  }
    66  
    67  func (Version *Version) IsGreaterThan(version1 *Version) bool {
    68  	return CompareVersions(Version, version1, GreaterThanFunc)
    69  }
    70  
    71  func (Version *Version) IsLesserThanEqualTo(version1 *Version) bool {
    72  	return Version.IsLesserThan(version1) || Version.IsEqualTo(version1)
    73  }
    74  
    75  func (Version *Version) IsGreaterThanEqualTo(version1 *Version) bool {
    76  	return Version.IsGreaterThan(version1) || Version.IsEqualTo(version1)
    77  }
    78  
    79  func (Version *Version) IsEqualTo(version1 *Version) bool {
    80  	return IsEqual(Version.Major, version1.Major) && IsEqual(Version.Minor, version1.Minor) && IsEqual(Version.Patch, version1.Patch)
    81  }
    82  
    83  func CompareVersions(first, second *Version, compareFunc func(int, int) bool) bool {
    84  	if compareFunc(first.Major, second.Major) {
    85  		return true
    86  	} else if IsEqual(first.Major, second.Major) {
    87  		if compareFunc(first.Minor, second.Minor) {
    88  			return true
    89  		} else if IsEqual(first.Minor, second.Minor) {
    90  			return compareFunc(first.Patch, second.Patch)
    91  		}
    92  	}
    93  	return false
    94  }
    95  
    96  func LesserThanFunc(first, second int) bool {
    97  	return first < second
    98  }
    99  
   100  func GreaterThanFunc(first, second int) bool {
   101  	return first > second
   102  }
   103  
   104  func IsEqual(first, second int) bool {
   105  	return first == second
   106  }
   107  
   108  func (Version *Version) String() string {
   109  	return fmt.Sprintf("%d.%d.%d", Version.Major, Version.Minor, Version.Patch)
   110  }
   111  
   112  // FullVersion returns the CurrentGaugeVersion including build metadata.
   113  func FullVersion() string {
   114  	var metadata string
   115  	if BuildMetadata != "" {
   116  		metadata = fmt.Sprintf(".%s", BuildMetadata)
   117  	}
   118  	return fmt.Sprintf("%s%s", CurrentGaugeVersion.String(), metadata)
   119  }
   120  
   121  type byDecreasingVersion []*Version
   122  
   123  func (a byDecreasingVersion) Len() int      { return len(a) }
   124  func (a byDecreasingVersion) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
   125  func (a byDecreasingVersion) Less(i, j int) bool {
   126  	return a[i].IsGreaterThan(a[j])
   127  }
   128  
   129  func GetLatestVersion(versions []*Version) *Version {
   130  	sort.Sort(byDecreasingVersion(versions))
   131  	return versions[0]
   132  }
   133  
   134  func CheckCompatibility(currentVersion *Version, versionSupport *VersionSupport) error {
   135  	minSupportVersion, err := ParseVersion(versionSupport.Minimum)
   136  	if err != nil {
   137  		return fmt.Errorf("invalid minimum support version %s. : %s. ", versionSupport.Minimum, err.Error())
   138  	}
   139  	if versionSupport.Maximum != "" {
   140  		maxSupportVersion, err := ParseVersion(versionSupport.Maximum)
   141  		if err != nil {
   142  			return fmt.Errorf("invalid maximum support version %s. : %s. ", versionSupport.Maximum, err.Error())
   143  		}
   144  		if currentVersion.IsBetween(minSupportVersion, maxSupportVersion) {
   145  			return nil
   146  		}
   147  		return fmt.Errorf("version %s is not between %s and %s", currentVersion, minSupportVersion, maxSupportVersion)
   148  	}
   149  
   150  	if minSupportVersion.IsLesserThanEqualTo(currentVersion) {
   151  		return nil
   152  	}
   153  	return fmt.Errorf("incompatible version. Minimum support version %s is higher than current version %s", minSupportVersion, currentVersion)
   154  }