From 440866d26c64f9fc2616fa87a532c57999939ebb Mon Sep 17 00:00:00 2001 From: Bala FA Date: Sat, 11 Feb 2017 14:57:27 +0530 Subject: [PATCH] Move go version check into main() (#3734) Previously the check was done in init(). This patch moves into main for unit testable friendly function. --- Makefile | 1 + cmd/globals.go | 5 ----- cmd/main.go | 6 ------ cmd/runtime-checks.go | 45 -------------------------------------- main.go | 38 +++++++++++++++++++++++++++++++- main_test.go | 50 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 88 insertions(+), 57 deletions(-) delete mode 100644 cmd/runtime-checks.go create mode 100644 main_test.go diff --git a/Makefile b/Makefile index 57bdf888e..f9eb341fa 100644 --- a/Makefile +++ b/Makefile @@ -107,6 +107,7 @@ spelling: test: build @echo "Running all minio testing:" + @go test $(GOFLAGS) . @go test $(GOFLAGS) github.com/minio/minio/cmd... @go test $(GOFLAGS) github.com/minio/minio/pkg... diff --git a/cmd/globals.go b/cmd/globals.go index f143d531c..56439f635 100644 --- a/cmd/globals.go +++ b/cmd/globals.go @@ -31,11 +31,6 @@ import ( "github.com/minio/minio/pkg/objcache" ) -// Global constants for Minio. -const ( - minGoVersion = ">= 1.7" // Minio requires at least Go v1.7 -) - // minio configuration related constants. const ( globalMinioConfigVersion = "13" diff --git a/cmd/main.go b/cmd/main.go index 5bfb8f77b..31d2d8047 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -65,12 +65,6 @@ VERSION: ` + Version + `{{ "\n"}}` -// init - check the environment before main starts -func init() { - // Check if minio was compiled using a supported version of Golang. - checkGoVersion() -} - func migrate() { // Migrate config file err := migrateConfig() diff --git a/cmd/runtime-checks.go b/cmd/runtime-checks.go deleted file mode 100644 index fc16e53e7..000000000 --- a/cmd/runtime-checks.go +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Minio Cloud Storage, (C) 2015, 2016 Minio, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package cmd - -import ( - "fmt" - "runtime" - - "github.com/hashicorp/go-version" - "github.com/minio/mc/pkg/console" -) - -// check if minimum Go version is met. -func checkGoVersion() { - // Current version. - curVersion, e := version.NewVersion(runtime.Version()[2:]) - if e != nil { - console.Fatalln("Unable to determine current go version.", e) - } - - // Prepare version constraint. - constraints, e := version.NewConstraint(minGoVersion) - if e != nil { - console.Fatalln("Unable to check go version.") - } - - // Check for minimum version. - if !constraints.Check(curVersion) { - console.Fatalln(fmt.Sprintf("Please recompile Minio with Golang version %s.", minGoVersion)) - } -} diff --git a/main.go b/main.go index 7c635a6b7..43d2a73ed 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,5 @@ /* - * Minio Cloud Storage, (C) 2016 Minio, Inc. + * Minio Cloud Storage, (C) 2016,2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,11 +23,47 @@ package main // import "github.com/minio/minio" import ( + "fmt" "os" + "runtime" + version "github.com/hashicorp/go-version" + "github.com/minio/mc/pkg/console" minio "github.com/minio/minio/cmd" ) +const ( + // Minio requires at least Go v1.7 + minGoVersion = "1.7" + goVersionConstraint = ">= " + minGoVersion +) + +// Check if this binary is compiled with at least minimum Go version. +func checkGoVersion(goVersionStr string) error { + constraint, err := version.NewConstraint(goVersionConstraint) + if err != nil { + return fmt.Errorf("'%s': %s", goVersionConstraint, err) + } + + goVersion, err := version.NewVersion(goVersionStr) + if err != nil { + return err + } + + if !constraint.Check(goVersion) { + return fmt.Errorf("Minio is not compiled by Go %s. Please recompile accordingly.", + goVersionConstraint) + } + + return nil +} + func main() { + // When `go get` is used minimum Go version check is not triggered but it would have compiled it successfully. + // However such binary will fail at runtime, hence we also check Go version at runtime. + if err := checkGoVersion(runtime.Version()[2:]); err != nil { + console.Fatalln("Go runtime version check failed.", err) + } + minio.Main(os.Args, os.Exit) } diff --git a/main_test.go b/main_test.go new file mode 100644 index 000000000..85b9b2e8e --- /dev/null +++ b/main_test.go @@ -0,0 +1,50 @@ +/* + * Minio Cloud Storage, (C) 2017 Minio, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "fmt" + "testing" +) + +func TestCheckGoVersion(t *testing.T) { + // Test success cases. + testCases := []struct { + version string + expectedErr error + }{ + {minGoVersion, nil}, + {minGoVersion + ".10", nil}, + {"1.6.8", fmt.Errorf("Minio is not compiled by Go >= 1.7. Please recompile accordingly.")}, + {"0.1", fmt.Errorf("Minio is not compiled by Go >= 1.7. Please recompile accordingly.")}, + {".1", fmt.Errorf("Malformed version: .1")}, + {"somejunk", fmt.Errorf("Malformed version: somejunk")}, + } + + for _, testCase := range testCases { + err := checkGoVersion(testCase.version) + if testCase.expectedErr == nil { + if err != nil { + t.Fatalf("expected: %v, got: %v", testCase.expectedErr, err) + } + } else if err == nil { + t.Fatalf("expected: %v, got: %v", testCase.expectedErr, err) + } else if testCase.expectedErr.Error() != err.Error() { + t.Fatalf("expected: %v, got: %v", testCase.expectedErr, err) + } + } +}