github.com/balzaczyy/golucene@v0.0.0-20151210033525-d0be9ee89713/core/util/version.go (about)

     1  package util
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  )
     9  
    10  type Version [4]int
    11  
    12  var (
    13  	// Match settings and bugs in Lucene's 3.1 release.
    14  	VERSION_31 = Version([4]int{3, 1, 0, 0})
    15  	// Match settings and bugs in Lucene's 4.0 release.
    16  	VERSION_4_0 = Version([4]int{4, 0, 0, 0})
    17  	// Match settings and bugs in Lucene's 4.5 release.
    18  	VERSION_45 = Version([4]int{4, 5, 0, 0})
    19  	// Match settings and bugs in Lucene's 4.9 release.
    20  	// Use this to get the latest and greatest settings, bug fixes, etc,
    21  	// for Lucnee.
    22  	VERSION_49     = Version([4]int{4, 9, 0, 0})
    23  	VERSION_4_10   = Version([4]int{4, 10, 0, 0})
    24  	VERSION_4_10_1 = Version([4]int{4, 10, 1, 0})
    25  
    26  	VERSION_LATEST = VERSION_4_10_1
    27  )
    28  
    29  /*
    30  Parse a version number of the form major.minor.bugfix.prerlease
    31  
    32  Part .bugfix and part .prerelease are optional.
    33  Note that this is forwards compatible: the parsed version does not
    34  have to exist as a constant.
    35  */
    36  func ParseVersion(version string) (ver Version, err error) {
    37  	if version == "" {
    38  		return
    39  	}
    40  
    41  	parts := strings.SplitN(version, ".", 4)
    42  	if len(parts) < 2 || len(parts) > 4 {
    43  		err = errors.New(fmt.Sprintf(
    44  			"Version is not in form major.minor(.bugfix.prerelease) (got: %v)",
    45  			version))
    46  		return
    47  	}
    48  
    49  	var major, minor, bugfix, prerelease int
    50  	if major, err = parse(parts[0], version, "major"); err != nil {
    51  		return
    52  	}
    53  	if minor, err = parse(parts[1], version, "minor"); err != nil {
    54  		return
    55  	}
    56  
    57  	if len(parts) > 2 {
    58  		if bugfix, err = parse(parts[2], version, "bugfix"); err != nil {
    59  			return
    60  		}
    61  
    62  		if len(parts) > 3 {
    63  			if prerelease, err = parse(parts[3], version, "prerelease"); err != nil {
    64  				return
    65  			}
    66  			if prerelease == 0 {
    67  				err = errors.New(fmt.Sprintf(
    68  					"Invalid value %v for prerelease; should be 1 or 2 (got: %v)",
    69  					prerelease, version))
    70  				return
    71  			}
    72  		}
    73  	}
    74  
    75  	return newVersion(major, minor, bugfix, prerelease), nil
    76  }
    77  
    78  func parse(part, text, name string) (int, error) {
    79  	if n, err := strconv.ParseInt(part, 10, 64); err == nil {
    80  		return int(n), nil
    81  	}
    82  	return 0, errors.New(fmt.Sprintf(
    83  		"Failed to parse %v version from '%v' (got: %v)",
    84  		name, part, text))
    85  }
    86  
    87  func newVersion(major, minor, bugfix, prerelease int) Version {
    88  	ans := Version([4]int{major, minor, bugfix, prerelease})
    89  
    90  	// NOTE: do not enforce major version so we remain future proof,
    91  	// except to make sure it fits in the 8 bits we encode it into:
    92  	assert2(major >= 0 && major <= 255, "Illegal major version: %v", major)
    93  	assert2(minor >= 0 && minor <= 255, "Illegal minor version: %v", minor)
    94  	assert2(bugfix >= 0 && bugfix <= 255, "Illegal bugfix version: %v", bugfix)
    95  	assert2(prerelease >= 0 || prerelease <= 2, "Illegal prerelease version: %v", prerelease)
    96  	assert2(prerelease == 0 || minor == 0 && bugfix == 0,
    97  		"Prerelease version only supported with major release (got prerelease: %v, minor: %v, bugfix: %v)",
    98  		prerelease, minor, bugfix)
    99  
   100  	return ans
   101  }
   102  
   103  func encoded(v Version) int {
   104  	if len(v) < 4 {
   105  		return 0
   106  	}
   107  	return v[0]<<18 | v[1]<<10 | v[2]<<2 | v[3]
   108  }
   109  
   110  func (v Version) OnOrAfter(other Version) bool {
   111  	return encoded(v) >= encoded(other)
   112  }
   113  
   114  func (v Version) String() string {
   115  	if v[3] == 0 {
   116  		return fmt.Sprintf("%v.%v.%v", v[0], v[1], v[2])
   117  	}
   118  	return fmt.Sprintf("%v.%v.%v.%v", v[0], v[1], v[2], v[3])
   119  }
   120  
   121  func (v Version) Equals(other Version) bool {
   122  	return encoded(v) == encoded(other)
   123  }