func (v GoVersion) Compare(other GoVersion) int {
	if v.major > other.major {
		return 1
	}
	if v.major < other.major {
		return -1
	}
	if v.minor > other.minor {
		return 1
	}
	if v.minor < other.minor {
		return -1
	}
	if v.patch > other.patch {
		return 1
	}
	if v.patch < other.patch {
		return -1
	}
	if v.prerelease == other.prerelease {
		return 0
	}
	if v.prerelease == "" {
		return 1
	}
	if other.prerelease == "" {
		return -1
	}
	if v.prerelease > other.prerelease {
		return 1
	}
	return -1
}
Compare returns -1, 0, or 1 if v < other, v == other, or v > other, respectively.
package golang
import (
	"fmt"
	"os/exec"
	"regexp"
	"strconv"
	"strings"
)
const (
	goVerPattern = `^go(?P<major>[0-9]+)\.(?P<minor>[0-9]+)(?:\.(?P<patch>[0-9]+)|(?P<pre>(?:alpha|beta|rc)[0-9]+))?$`
)
var (
	goVerRegexp = regexp.MustCompile(goVerPattern)
)
type GoVersion struct {
	major, minor, patch int
	prerelease          string
}
func (v GoVersion) String() string {
	switch {
	case v.patch != 0:
		return fmt.Sprintf("go%d.%d.%d", v.major, v.minor, v.patch)
	case v.prerelease != "":
		return fmt.Sprintf("go%d.%d%s", v.major, v.minor, v.prerelease)
	}
	return fmt.Sprintf("go%d.%d", v.major, v.minor)
}
func MustParse(verStr string) (v GoVersion) {
	if err := v.parse(verStr); err != nil {
		panic(err)
	}
	return v
}
func (v *GoVersion) parse(verStr string) error {
	m := goVerRegexp.FindStringSubmatch(verStr)
	if m == nil {
		return fmt.Errorf("invalid version string")
	}
	var err error
	v.major, err = strconv.Atoi(m[1])
	if err != nil {
		return fmt.Errorf("error parsing major version '%s': %s", m[1], err)
	}
	v.minor, err = strconv.Atoi(m[2])
	if err != nil {
		return fmt.Errorf("error parsing minor version '%s': %s", m[2], err)
	}
	if m[3] != "" {
		v.patch, err = strconv.Atoi(m[3])
		if err != nil {
			return fmt.Errorf("error parsing patch version '%s': %s", m[2], err)
		}
	}
	v.prerelease = m[4]
	return nil
}