Update build.go, correct version detection

This commit is contained in:
Alexander Neumann 2018-01-12 22:06:42 +01:00
parent 5723636b35
commit 02f4f5dc66
1 changed files with 94 additions and 11 deletions

105
build.go
View File

@ -11,6 +11,7 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv"
"strings" "strings"
) )
@ -22,10 +23,11 @@ var (
) )
var config = struct { var config = struct {
Name string Name string
Namespace string Namespace string
Main string Main string
Tests []string Tests []string
MinVersion GoVersion
}{ }{
Name: "restic", // name of the program executable and directory Name: "restic", // name of the program executable and directory
Namespace: "github.com/restic/restic", // subdir of GOPATH, e.g. "github.com/foo/bar" Namespace: "github.com/restic/restic", // subdir of GOPATH, e.g. "github.com/foo/bar"
@ -33,6 +35,7 @@ var config = struct {
Tests: []string{ // tests to run Tests: []string{ // tests to run
"github.com/restic/restic/internal/...", "github.com/restic/restic/internal/...",
"github.com/restic/restic/cmd/..."}, "github.com/restic/restic/cmd/..."},
MinVersion: GoVersion{Major: 1, Minor: 8, Patch: 0}, // minimum Go version supported
} }
// specialDir returns true if the file begins with a special character ('.' or '_'). // specialDir returns true if the file begins with a special character ('.' or '_').
@ -137,7 +140,6 @@ func copyFile(dst, src string) error {
if err != nil { if err != nil {
return err return err
} }
defer fsrc.Close()
if err = os.MkdirAll(filepath.Dir(dst), 0755); err != nil { if err = os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
fmt.Printf("MkdirAll(%v)\n", filepath.Dir(dst)) fmt.Printf("MkdirAll(%v)\n", filepath.Dir(dst))
@ -148,17 +150,28 @@ func copyFile(dst, src string) error {
if err != nil { if err != nil {
return err return err
} }
defer fdst.Close()
_, err = io.Copy(fdst, fsrc) if _, err = io.Copy(fdst, fsrc); err != nil {
return err
}
if err == nil {
err = fsrc.Close()
}
if err == nil {
err = fdst.Close()
}
if err == nil { if err == nil {
err = os.Chmod(dst, fi.Mode()) err = os.Chmod(dst, fi.Mode())
} }
if err == nil { if err == nil {
err = os.Chtimes(dst, fi.ModTime(), fi.ModTime()) err = os.Chtimes(dst, fi.ModTime(), fi.ModTime())
} }
return err return nil
} }
// die prints the message with fmt.Fprintf() to stderr and exits with an error // die prints the message with fmt.Fprintf() to stderr and exits with an error
@ -300,10 +313,80 @@ func (cs Constants) LDFlags() string {
return strings.Join(l, " ") return strings.Join(l, " ")
} }
// GoVersion is the version of Go used to compile the project.
type GoVersion struct {
Major int
Minor int
Patch int
}
// ParseGoVersion parses the Go version s. If s cannot be parsed, the returned GoVersion is null.
func ParseGoVersion(s string) (v GoVersion) {
if !strings.HasPrefix(s, "go") {
return
}
s = s[2:]
data := strings.Split(s, ".")
if len(data) != 3 {
return
}
major, err := strconv.Atoi(data[0])
if err != nil {
return
}
minor, err := strconv.Atoi(data[1])
if err != nil {
return
}
patch, err := strconv.Atoi(data[2])
if err != nil {
return
}
v = GoVersion{
Major: major,
Minor: minor,
Patch: patch,
}
return
}
// AtLeast returns true if v is at least as new as other. If v is empty, true is returned.
func (v GoVersion) AtLeast(other GoVersion) bool {
var empty GoVersion
// the empty version satisfies all versions
if v == empty {
return true
}
if v.Major < other.Major {
return false
}
if v.Minor < other.Minor {
return false
}
if v.Patch < other.Patch {
return false
}
return true
}
func (v GoVersion) String() string {
return fmt.Sprintf("Go %d.%d.%d", v.Major, v.Minor, v.Patch)
}
func main() { func main() {
ver := runtime.Version() ver := ParseGoVersion(runtime.Version())
if strings.HasPrefix(ver, "go1") && ver < "go1.8" { if !ver.AtLeast(config.MinVersion) {
fmt.Fprintf(os.Stderr, "Go version %s detected, restic requires at least Go 1.8\n", ver) fmt.Fprintf(os.Stderr, "%s detected, this program requires at least %s\n", ver, config.MinVersion)
os.Exit(1) os.Exit(1)
} }