diff --git a/.travis.yml b/.travis.yml index 21aa363ee..82bc079f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,22 +25,9 @@ install: - export PATH="$PATH:$GOBIN" - export GOPATH="$GOPATH:${TRAVIS_BUILD_DIR}/Godeps/_workspace" - go env - - go get github.com/mattn/goveralls - - go get github.com/mitchellh/gox - - go version | grep -q "go1\.3" && export GOX_ARCH="386 amd64" || true - - go version | grep -q "darwin" && export GOX_OS="darwin" || true - - uname -s | grep -qi darwin && brew install caskroom/cask/brew-cask || true - - uname -s | grep -qi darwin && brew cask install osxfuse || true - - uname -s | grep -vqi darwin && export RESTIC_TEST_FUSE="0" || true - - echo "cross-compile for \"$GOX_OS\" on \"$GOX_ARCH\"" - - gox -build-toolchain -os "$GOX_OS" -arch "$GOX_ARCH" script: - - gox -verbose -os "$GOX_OS" -arch "$GOX_ARCH" -tags "release" ./cmd/restic - - gox -verbose -os "$GOX_OS" -arch "$GOX_ARCH" -tags "debug" ./cmd/restic - - go run build.go - - go run run_tests.go all.cov - - GOARCH=386 RESTIC_TEST_INTEGRATION=0 go test ./... + - go run run_integration_tests.go + +after_success: - goveralls -coverprofile=all.cov -service=travis-ci -repotoken "$COVERALLS_TOKEN" || true - - gofmt -l *.go */*.go */*/*.go - - test -z "$(gofmt -l *.go */*.go */*/*.go)" diff --git a/run_integration_tests.go b/run_integration_tests.go new file mode 100644 index 000000000..ac8ac6442 --- /dev/null +++ b/run_integration_tests.go @@ -0,0 +1,163 @@ +// +build ignore + +package main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" +) + +type CIEnvironment interface { + Prepare() + RunTests() +} + +type TravisEnvironment struct { + goxArch []string + goxOS []string +} + +func (env *TravisEnvironment) Prepare() { + fmt.Printf("preparing environment for Travis CI\n") + + run("go", "get", "github.com/mattn/goveralls") + run("go", "get", "github.com/mitchellh/gox") + + if runtime.GOOS == "darwin" { + // install the libraries necessary for fuse + run("brew", "install", "caskroom/cask/brew-cask") + run("brewcask", "install", "osxfuse") + } + + // only test cross compilation on linux with Travis + if runtime.GOOS == "linux" { + env.goxArch = []string{"386", "amd64"} + if !strings.HasPrefix(runtime.Version(), "go1.3") { + env.goxArch = append(env.goxArch, "arm") + } + + env.goxOS = []string{"linux", "darwin", "freebsd", "openbsd", "windows"} + } + + fmt.Printf("gox: OS %v, ARCH %v\n", env.goxOS, env.goxArch) + run("gox", "-build-toolchain", + "-os", strings.Join(env.goxOS, " "), + "-arch", strings.Join(env.goxArch, " ")) +} + +func (env *TravisEnvironment) RunTests() { + // run fuse tests on darwin + if runtime.GOOS != "darwin" { + fmt.Printf("skip fuse integration tests on %v\n", runtime.GOOS) + os.Setenv("RESTIC_TEST_FUSE", "0") + } + + // compile for all target architectures with tags + for _, tags := range []string{"release", "debug"} { + run("gox", "-verbose", + "-os", strings.Join(env.goxOS, " "), + "-arch", strings.Join(env.goxArch, " "), + "-tags", tags, + "./cmd/restic") + } + + // run the build script + run("go", "run", "build.go") + + // gather coverage information + run("go", "run", "run_tests.go", "all.cov") + + runGofmt() +} + +// findGoFiles returns a list of go source code file names below dir. +func findGoFiles(dir string) (list []string, err error) { + err = filepath.Walk(dir, func(name string, fi os.FileInfo, err error) error { + if filepath.Base(name) == "Godeps" { + return filepath.SkipDir + } + + if filepath.Ext(name) == ".go" { + relpath, err := filepath.Rel(dir, name) + if err != nil { + return err + } + + list = append(list, relpath) + } + + return err + }) + + return list, err +} + +func runGofmt() { + dir, err := os.Getwd() + if err != nil { + fmt.Fprintf(os.Stderr, "Getwd(): %v\n", err) + os.Exit(5) + } + + files, err := findGoFiles(dir) + if err != nil { + fmt.Fprintf(os.Stderr, "error finding Go files: %v\n", err) + os.Exit(4) + } + + fmt.Printf("runGofmt() with %d files\n", len(files)) + args := append([]string{"-l"}, files...) + cmd := exec.Command("gofmt", args...) + cmd.Stderr = os.Stderr + + buf, err := cmd.Output() + if err != nil { + fmt.Fprintf(os.Stderr, "error running gofmt: %v", err) + fmt.Fprintf(os.Stderr, "output:\n%s\n", buf) + os.Exit(3) + } + + if len(buf) > 0 { + fmt.Fprintf(os.Stderr, "not formatted with `gofmt`:\n") + fmt.Fprintln(os.Stderr, string(buf)) + os.Exit(6) + } +} + +func run(command string, args ...string) { + fmt.Printf("run %v %v\n", command, strings.Join(args, " ")) + cmd := exec.Command(command, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + + if err != nil { + fmt.Fprintf(os.Stderr, "error running %v %v: %v", + command, strings.Join(args, " "), err) + os.Exit(3) + } +} + +func isTravis() bool { + return os.Getenv("TRAVIS_BUILD_DIR") != "" +} + +func main() { + var env CIEnvironment + + switch { + case isTravis(): + env = &TravisEnvironment{} + default: + fmt.Fprintln(os.Stderr, "unknown CI environment") + os.Exit(1) + } + + for _, f := range []func(){env.Prepare, env.RunTests} { + f() + } +}