Skip to content

Commit

Permalink
improved Go version check
Browse files Browse the repository at this point in the history
Highlights:
 - Go version doesn't follow semver style from syntax perspective, so
 use semver pkg wasn't helpful
 - re-implemented go version check without using the semver pkg.
  • Loading branch information
droot committed Oct 15, 2018
1 parent a8871fd commit 80bf75f
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 24 deletions.
34 changes: 34 additions & 0 deletions cmd/go_version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package main

import "testing"

func TestCheckGoVersion(t *testing.T) {

tests := []struct {
ver string
isInvalid bool
}{
{"go1.8", true},
{"go1.9", true},
{"go1.10", false},
{"go1.10rc", false},
{"go1.10.1", false},
{"go1.11rc2", false},
}

for _, test := range tests {
err := checkGoVersion(test.ver)
if err != nil {
// go error, but the version isn't invalid
if !test.isInvalid {
t.Errorf("Go version check failed valid version '%s' with error '%s'", test.ver, err)
}
} else {
// got no error, but the version is invalid
if test.isInvalid {
t.Errorf("version '%s' is invalid, but got no error", test.ver)
}
}
}

}
78 changes: 54 additions & 24 deletions cmd/init_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"

"github.com/Masterminds/semver"
"github.com/spf13/cobra"
flag "github.com/spf13/pflag"

Expand Down Expand Up @@ -63,6 +64,8 @@ kubebuilder init --domain example.org --license apache2 --owner "The Kubernetes
},
}

initCmd.Flags().BoolVar(
&o.skipGoVersionCheck, "skip-go-version-check", false, "if specified, skip checking the Go version")
initCmd.Flags().BoolVar(
&o.dep, "dep", true, "if specified, determines whether dep will be used.")
o.depFlag = initCmd.Flag("dep")
Expand All @@ -77,17 +80,20 @@ kubebuilder init --domain example.org --license apache2 --owner "The Kubernetes
}

type projectOptions struct {
prj *project.Project
bp *project.Boilerplate
gopkg *project.GopkgToml
mgr *manager.Cmd
dkr *manager.Dockerfile
dep bool
depFlag *flag.Flag
prj *project.Project
bp *project.Boilerplate
gopkg *project.GopkgToml
mgr *manager.Cmd
dkr *manager.Dockerfile
dep bool
depFlag *flag.Flag
skipGoVersionCheck bool
}

func (o *projectOptions) runInit() {
checkGoVersion()
if !o.skipGoVersionCheck {
ensureGoVersionIsCompatible()
}

if !depExists() {
log.Fatalf("Dep is not installed. Follow steps at: https://golang.github.io/dep/docs/installation.html")
Expand Down Expand Up @@ -185,30 +191,54 @@ func boilerplateForFlags(f *flag.FlagSet) *project.Boilerplate {
f.StringVar(&b.Owner, "owner", "", "Owner to add to the copyright")
return b
}
func checkGoVersion() {

func ensureGoVersionIsCompatible() {
err := fetchAndCheckGoVersion()
if err != nil {
log.Fatalf("%s. You can skip this check using the --skip-go-version-check flag", err)
}
}

func fetchAndCheckGoVersion() error {
cmd := exec.Command("go", "version")
out, err := cmd.Output()
if err != nil {
log.Fatalf("Could not execute 'go version': %v", err)
return fmt.Errorf("Failed to retrieve 'go version': %v", string(out))
}

split := strings.Split(string(out), " ")
if len(split) < 3 {
log.Fatalf("Invalid go version: %q", string(out))
return fmt.Errorf("Found invalid Go version: %q", string(out))
}
goVersion := strings.TrimPrefix(split[2], "go")
if ver, err := semver.NewVersion(goVersion); err != nil {
if err != nil {
log.Fatalf("Invalid go version %q: %v", goVersion, err)
}
c, err := semver.NewConstraint(">= 1.10")
if err != nil {
log.Fatal("Invalid constraint: %v", err)
}
if !c.Check(ver) {
log.Fatalf("The go version is %v, must be 1.10+", goVersion)
}
goVer := split[2]
if err := checkGoVersion(goVer); err != nil {
return fmt.Errorf("Go version '%s' is incompatible because '%s'", goVer, err)
}
return nil
}

func checkGoVersion(verStr string) error {
goVerRegex := `^go?([0-9]+)\.([0-9]+)([\.0-9A-Za-z\-]+)?$`
m := regexp.MustCompile(goVerRegex).FindStringSubmatch(verStr)
if m == nil {
return fmt.Errorf("invalid version string")
}

major, err := strconv.ParseInt(m[1], 10, 64)
if err != nil {
return fmt.Errorf("error parsing major version '%s': %s", m[1], err)
}

minor, err := strconv.ParseInt(m[2], 10, 64)
if err != nil {
return fmt.Errorf("error parsing minor version '%s': %s", m[2], err)
}

if major < 1 || minor < 10 {
return fmt.Errorf("requires version >= 1.10")
}

return nil
}

func depExists() bool {
Expand Down

0 comments on commit 80bf75f

Please sign in to comment.