| 
									
										
										
										
											2016-06-29 09:36:40 +02:00
										 |  |  | // +build ignore | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-08-21 18:31:09 +02:00
										 |  |  | 	"bufio" | 
					
						
							| 
									
										
										
										
											2015-12-20 18:09:35 +01:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2016-08-21 18:31:09 +02:00
										 |  |  | 	"errors" | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | 	"flag" | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2016-01-26 23:42:45 +01:00
										 |  |  | 	"io" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	"os" | 
					
						
							|  |  |  | 	"os/exec" | 
					
						
							|  |  |  | 	"path/filepath" | 
					
						
							|  |  |  | 	"runtime" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 18:31:09 +02:00
										 |  |  | // ForbiddenImports are the packages from the stdlib that should not be used in | 
					
						
							|  |  |  | // our code. | 
					
						
							|  |  |  | var ForbiddenImports = map[string]bool{ | 
					
						
							|  |  |  | 	"errors": true, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | var runCrossCompile = flag.Bool("cross-compile", true, "run cross compilation tests") | 
					
						
							| 
									
										
										
										
											2016-04-17 17:49:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | func init() { | 
					
						
							|  |  |  | 	flag.Parse() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 20:33:45 +02:00
										 |  |  | // CIEnvironment is implemented by environments where tests can be run. | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | type CIEnvironment interface { | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 	Prepare() error | 
					
						
							|  |  |  | 	RunTests() error | 
					
						
							|  |  |  | 	Teardown() error | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 20:33:45 +02:00
										 |  |  | // TravisEnvironment is the environment in which Travis tests run. | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | type TravisEnvironment struct { | 
					
						
							| 
									
										
										
										
											2016-05-08 23:25:30 +02:00
										 |  |  | 	goxOSArch []string | 
					
						
							| 
									
										
										
										
											2017-05-12 20:37:44 +02:00
										 |  |  | 	env       map[string]string | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | func (env *TravisEnvironment) getMinio() error { | 
					
						
							| 
									
										
										
										
											2017-05-12 20:37:44 +02:00
										 |  |  | 	tempfile, err := os.Create(filepath.Join(os.Getenv("GOPATH"), "bin", "minio")) | 
					
						
							| 
									
										
										
										
											2016-01-26 23:42:45 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("create tempfile for minio download failed: %v", err) | 
					
						
							| 
									
										
										
										
											2016-01-26 23:42:45 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 23:52:39 +01:00
										 |  |  | 	url := fmt.Sprintf("https://dl.minio.io/server/minio/release/%s-%s/minio", | 
					
						
							|  |  |  | 		runtime.GOOS, runtime.GOARCH) | 
					
						
							|  |  |  | 	msg("downloading %v\n", url) | 
					
						
							|  |  |  | 	res, err := http.Get(url) | 
					
						
							| 
									
										
										
										
											2016-01-26 23:42:45 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("error downloading minio server: %v", err) | 
					
						
							| 
									
										
										
										
											2016-01-26 23:42:45 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	_, err = io.Copy(tempfile, res.Body) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("error saving minio server to file: %v", err) | 
					
						
							| 
									
										
										
										
											2016-01-26 23:42:45 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = res.Body.Close() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("error closing HTTP download: %v", err) | 
					
						
							| 
									
										
										
										
											2016-01-26 23:42:45 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = tempfile.Close() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		msg("closing tempfile failed: %v\n", err) | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("error closing minio server file: %v", err) | 
					
						
							| 
									
										
										
										
											2016-01-26 23:42:45 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err = os.Chmod(tempfile.Name(), 0755) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 		return fmt.Errorf("chmod(minio-server) failed: %v", err) | 
					
						
							| 
									
										
										
										
											2016-01-26 23:42:45 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	msg("downloaded minio server to %v\n", tempfile.Name()) | 
					
						
							| 
									
										
										
										
											2017-03-16 21:57:32 +01:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 20:33:45 +02:00
										 |  |  | // Prepare installs dependencies and starts services in order to run the tests. | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | func (env *TravisEnvironment) Prepare() error { | 
					
						
							| 
									
										
										
										
											2016-04-17 17:49:36 +02:00
										 |  |  | 	env.env = make(map[string]string) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 20:29:06 +02:00
										 |  |  | 	msg("preparing environment for Travis CI\n") | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 15:53:59 +02:00
										 |  |  | 	pkgs := []string{ | 
					
						
							| 
									
										
										
										
											2016-04-17 18:39:19 +02:00
										 |  |  | 		"golang.org/x/tools/cmd/cover", | 
					
						
							|  |  |  | 		"github.com/pierrre/gotestcover", | 
					
						
							| 
									
										
										
										
											2017-04-27 15:53:59 +02:00
										 |  |  | 		"github.com/NebulousLabs/glyphcheck", | 
					
						
							| 
									
										
										
										
											2017-06-27 21:19:48 +02:00
										 |  |  | 		"github.com/restic/rest-server/cmd/rest-server", | 
					
						
							| 
									
										
										
										
											2017-04-27 15:53:59 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, pkg := range pkgs { | 
					
						
							| 
									
										
										
										
											2016-04-17 18:39:19 +02:00
										 |  |  | 		err := run("go", "get", pkg) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := env.getMinio(); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-15 11:06:50 +02:00
										 |  |  | 	if *runCrossCompile { | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | 		// only test cross compilation on linux with Travis | 
					
						
							| 
									
										
										
										
											2016-04-17 18:39:19 +02:00
										 |  |  | 		if err := run("go", "get", "github.com/mitchellh/gox"); err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | 		if runtime.GOOS == "linux" { | 
					
						
							| 
									
										
										
										
											2016-05-08 23:25:30 +02:00
										 |  |  | 			env.goxOSArch = []string{ | 
					
						
							|  |  |  | 				"linux/386", "linux/amd64", | 
					
						
							|  |  |  | 				"windows/386", "windows/amd64", | 
					
						
							|  |  |  | 				"darwin/386", "darwin/amd64", | 
					
						
							|  |  |  | 				"freebsd/386", "freebsd/amd64", | 
					
						
							| 
									
										
										
										
											2017-01-12 19:50:41 +01:00
										 |  |  | 				"openbsd/386", "openbsd/amd64", | 
					
						
							| 
									
										
										
										
											2017-04-15 11:06:50 +02:00
										 |  |  | 				"linux/arm", "freebsd/arm", | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2016-05-08 23:25:30 +02:00
										 |  |  | 			env.goxOSArch = []string{runtime.GOOS + "/" + runtime.GOARCH} | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-08 23:25:30 +02:00
										 |  |  | 		msg("gox: OS/ARCH %v\n", env.goxOSArch) | 
					
						
							| 
									
										
										
										
											2015-08-20 19:42:40 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 20:33:45 +02:00
										 |  |  | // Teardown stops backend services and cleans the environment again. | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | func (env *TravisEnvironment) Teardown() error { | 
					
						
							| 
									
										
										
										
											2016-04-17 17:49:36 +02:00
										 |  |  | 	msg("run travis teardown\n") | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2016-04-17 17:49:36 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 20:33:45 +02:00
										 |  |  | // RunTests starts the tests for Travis. | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | func (env *TravisEnvironment) RunTests() error { | 
					
						
							| 
									
										
										
										
											2016-09-15 21:25:59 +02:00
										 |  |  | 	// do not run fuse tests on darwin | 
					
						
							|  |  |  | 	if runtime.GOOS == "darwin" { | 
					
						
							| 
									
										
										
										
											2015-08-19 20:29:06 +02:00
										 |  |  | 		msg("skip fuse integration tests on %v\n", runtime.GOOS) | 
					
						
							| 
									
										
										
										
											2017-04-27 15:53:59 +02:00
										 |  |  | 		_ = os.Setenv("RESTIC_TEST_FUSE", "0") | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-21 22:02:50 +02:00
										 |  |  | 	env.env["GOPATH"] = os.Getenv("GOPATH") | 
					
						
							| 
									
										
										
										
											2016-02-14 17:39:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 20:41:04 +02:00
										 |  |  | 	// ensure that the following tests cannot be silently skipped on Travis | 
					
						
							|  |  |  | 	ensureTests := []string{ | 
					
						
							|  |  |  | 		"restic/backend/rest.TestBackendREST", | 
					
						
							|  |  |  | 		"restic/backend/sftp.TestBackendSFTP", | 
					
						
							|  |  |  | 		"restic/backend/s3.TestBackendMinio", | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-05-14 00:29:10 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// if the test s3 repository is available, make sure that the test is not skipped | 
					
						
							|  |  |  | 	if os.Getenv("RESTIC_TEST_S3_REPOSITORY") != "" { | 
					
						
							|  |  |  | 		ensureTests = append(ensureTests, "restic/backend/s3.TestBackendS3") | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		msg("S3 repository not available\n") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-01 10:13:03 +02:00
										 |  |  | 	// if the test swift service is available, make sure that the test is not skipped | 
					
						
							|  |  |  | 	if os.Getenv("RESTIC_TEST_SWIFT") != "" { | 
					
						
							|  |  |  | 		ensureTests = append(ensureTests, "restic/backend/swift.TestBackendSwift") | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		msg("Swift service not available\n") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-28 10:19:01 +02:00
										 |  |  | 	// if the test b2 repository is available, make sure that the test is not skipped | 
					
						
							|  |  |  | 	if os.Getenv("RESTIC_TEST_B2_REPOSITORY") != "" { | 
					
						
							|  |  |  | 		ensureTests = append(ensureTests, "restic/backend/b2.TestBackendB2") | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		msg("B2 repository not available\n") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-13 20:41:04 +02:00
										 |  |  | 	env.env["RESTIC_TEST_DISALLOW_SKIP"] = strings.Join(ensureTests, ",") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-15 11:06:50 +02:00
										 |  |  | 	if *runCrossCompile { | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | 		// compile for all target architectures with tags | 
					
						
							|  |  |  | 		for _, tags := range []string{"release", "debug"} { | 
					
						
							| 
									
										
										
										
											2016-08-21 14:21:19 +02:00
										 |  |  | 			err := runWithEnv(env.env, "gox", "-verbose", | 
					
						
							| 
									
										
										
										
											2016-05-08 23:25:30 +02:00
										 |  |  | 				"-osarch", strings.Join(env.goxOSArch, " "), | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | 				"-tags", tags, | 
					
						
							|  |  |  | 				"-output", "/tmp/{{.Dir}}_{{.OS}}_{{.Arch}}", | 
					
						
							| 
									
										
										
										
											2017-07-21 22:02:50 +02:00
										 |  |  | 				"./cmd/restic") | 
					
						
							| 
									
										
										
										
											2016-08-21 14:21:19 +02:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return err | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-01-17 18:33:03 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// run the build script | 
					
						
							| 
									
										
										
										
											2016-04-17 18:39:19 +02:00
										 |  |  | 	if err := run("go", "run", "build.go"); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-19 17:21:45 +01:00
										 |  |  | 	// run the tests and gather coverage information | 
					
						
							| 
									
										
										
										
											2017-07-21 22:02:50 +02:00
										 |  |  | 	err := runWithEnv(env.env, "gotestcover", "-coverprofile", "all.cov", "github.com/restic/restic/cmd/...", "github.com/restic/restic/internal/...") | 
					
						
							| 
									
										
										
										
											2016-04-17 18:39:19 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-19 17:21:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 18:31:09 +02:00
										 |  |  | 	if err = runGofmt(); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 15:53:59 +02:00
										 |  |  | 	if err = runGlyphcheck(); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 18:31:09 +02:00
										 |  |  | 	deps, err := findImports() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	foundForbiddenImports := false | 
					
						
							|  |  |  | 	for name, imports := range deps { | 
					
						
							|  |  |  | 		for _, pkg := range imports { | 
					
						
							|  |  |  | 			if _, ok := ForbiddenImports[pkg]; ok { | 
					
						
							|  |  |  | 				fmt.Fprintf(os.Stderr, "========== package %v imports forbidden package %v\n", name, pkg) | 
					
						
							|  |  |  | 				foundForbiddenImports = true | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if foundForbiddenImports { | 
					
						
							|  |  |  | 		return errors.New("CI: forbidden imports found") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 20:33:45 +02:00
										 |  |  | // AppveyorEnvironment is the environment on Windows. | 
					
						
							| 
									
										
										
										
											2015-08-19 20:45:54 +02:00
										 |  |  | type AppveyorEnvironment struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 20:33:45 +02:00
										 |  |  | // Prepare installs dependencies and starts services in order to run the tests. | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | func (env *AppveyorEnvironment) Prepare() error { | 
					
						
							| 
									
										
										
										
											2015-08-19 20:45:54 +02:00
										 |  |  | 	msg("preparing environment for Appveyor CI\n") | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-08-19 20:45:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 20:33:45 +02:00
										 |  |  | // RunTests start the tests. | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | func (env *AppveyorEnvironment) RunTests() error { | 
					
						
							| 
									
										
										
										
											2016-04-17 18:39:19 +02:00
										 |  |  | 	return run("go", "run", "build.go", "-v", "-T") | 
					
						
							| 
									
										
										
										
											2015-08-19 20:45:54 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 20:33:45 +02:00
										 |  |  | // Teardown is a noop. | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | func (env *AppveyorEnvironment) Teardown() error { | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-17 17:49:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | // 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 { | 
					
						
							| 
									
										
										
										
											2017-05-12 20:37:44 +02:00
										 |  |  | 		relpath, err := filepath.Rel(dir, name) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return err | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 20:37:44 +02:00
										 |  |  | 		if relpath == "vendor" || relpath == "pkg" { | 
					
						
							|  |  |  | 			return filepath.SkipDir | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-12 20:37:44 +02:00
										 |  |  | 		if filepath.Ext(relpath) == ".go" { | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 			list = append(list, relpath) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return list, err | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 20:29:06 +02:00
										 |  |  | func msg(format string, args ...interface{}) { | 
					
						
							|  |  |  | 	fmt.Printf("CI: "+format, args...) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-19 17:21:45 +01:00
										 |  |  | func updateEnv(env []string, override map[string]string) []string { | 
					
						
							|  |  |  | 	var newEnv []string | 
					
						
							|  |  |  | 	for _, s := range env { | 
					
						
							|  |  |  | 		d := strings.SplitN(s, "=", 2) | 
					
						
							|  |  |  | 		key := d[0] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if _, ok := override[key]; ok { | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newEnv = append(newEnv, s) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for k, v := range override { | 
					
						
							|  |  |  | 		newEnv = append(newEnv, k+"="+v) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return newEnv | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-21 18:31:09 +02:00
										 |  |  | func findImports() (map[string][]string, error) { | 
					
						
							|  |  |  | 	res := make(map[string][]string) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cwd, err := os.Getwd() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("Getwd() returned error: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gopath := cwd + ":" + filepath.Join(cwd, "vendor") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cmd := exec.Command("go", "list", "-f", `{{.ImportPath}} {{join .Imports " "}}`, "./src/...") | 
					
						
							|  |  |  | 	cmd.Env = updateEnv(os.Environ(), map[string]string{"GOPATH": gopath}) | 
					
						
							|  |  |  | 	cmd.Stderr = os.Stderr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	output, err := cmd.Output() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sc := bufio.NewScanner(bytes.NewReader(output)) | 
					
						
							|  |  |  | 	for sc.Scan() { | 
					
						
							|  |  |  | 		wordScanner := bufio.NewScanner(strings.NewReader(sc.Text())) | 
					
						
							|  |  |  | 		wordScanner.Split(bufio.ScanWords) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !wordScanner.Scan() { | 
					
						
							|  |  |  | 			return nil, fmt.Errorf("package name not found in line: %s", output) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		name := wordScanner.Text() | 
					
						
							|  |  |  | 		var deps []string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for wordScanner.Scan() { | 
					
						
							|  |  |  | 			deps = append(deps, wordScanner.Text()) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		res[name] = deps | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return res, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | func runGofmt() error { | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	dir, err := os.Getwd() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("Getwd(): %v", err) | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	files, err := findGoFiles(dir) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("error finding Go files: %v", err) | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 20:29:06 +02:00
										 |  |  | 	msg("runGofmt() with %d files\n", len(files)) | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	args := append([]string{"-l"}, files...) | 
					
						
							|  |  |  | 	cmd := exec.Command("gofmt", args...) | 
					
						
							|  |  |  | 	cmd.Stderr = os.Stderr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buf, err := cmd.Output() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("error running gofmt: %v\noutput: %s", err, buf) | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(buf) > 0 { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("not formatted with `gofmt`:\n%s", buf) | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 15:53:59 +02:00
										 |  |  | func runGlyphcheck() error { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:39 +02:00
										 |  |  | 	cmd := exec.Command("glyphcheck", "./cmd/...", "./internal/...") | 
					
						
							| 
									
										
										
										
											2017-04-27 15:53:59 +02:00
										 |  |  | 	cmd.Stderr = os.Stderr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buf, err := cmd.Output() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-07-23 15:51:44 +02:00
										 |  |  | 		return fmt.Errorf("error running glyphcheck: %v\noutput: %s", err, buf) | 
					
						
							| 
									
										
										
										
											2017-04-27 15:53:59 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-17 18:39:19 +02:00
										 |  |  | func run(command string, args ...string) error { | 
					
						
							| 
									
										
										
										
											2015-08-19 20:29:06 +02:00
										 |  |  | 	msg("run %v %v\n", command, strings.Join(args, " ")) | 
					
						
							| 
									
										
										
										
											2016-04-17 18:39:19 +02:00
										 |  |  | 	return runWithEnv(nil, command, args...) | 
					
						
							| 
									
										
										
										
											2015-12-19 17:21:45 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // runWithEnv calls a command with the current environment, except the entries | 
					
						
							|  |  |  | // of the env map are set additionally. | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | func runWithEnv(env map[string]string, command string, args ...string) error { | 
					
						
							| 
									
										
										
										
											2015-12-19 17:21:45 +01:00
										 |  |  | 	msg("runWithEnv %v %v\n", command, strings.Join(args, " ")) | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	cmd := exec.Command(command, args...) | 
					
						
							|  |  |  | 	cmd.Stdout = os.Stdout | 
					
						
							|  |  |  | 	cmd.Stderr = os.Stderr | 
					
						
							| 
									
										
										
										
											2015-12-19 17:21:45 +01:00
										 |  |  | 	if env != nil { | 
					
						
							|  |  |  | 		cmd.Env = updateEnv(os.Environ(), env) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	err := cmd.Run() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 		return fmt.Errorf("error running %v %v: %v", | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 			command, strings.Join(args, " "), err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func isTravis() bool { | 
					
						
							|  |  |  | 	return os.Getenv("TRAVIS_BUILD_DIR") != "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 20:45:54 +02:00
										 |  |  | func isAppveyor() bool { | 
					
						
							|  |  |  | 	return runtime.GOOS == "windows" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | func main() { | 
					
						
							|  |  |  | 	var env CIEnvironment | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch { | 
					
						
							|  |  |  | 	case isTravis(): | 
					
						
							|  |  |  | 		env = &TravisEnvironment{} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:45:54 +02:00
										 |  |  | 	case isAppveyor(): | 
					
						
							|  |  |  | 		env = &AppveyorEnvironment{} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	default: | 
					
						
							|  |  |  | 		fmt.Fprintln(os.Stderr, "unknown CI environment") | 
					
						
							|  |  |  | 		os.Exit(1) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-17 18:47:00 +02:00
										 |  |  | 	foundError := false | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 	for _, f := range []func() error{env.Prepare, env.RunTests, env.Teardown} { | 
					
						
							|  |  |  | 		err := f() | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-04-17 18:47:00 +02:00
										 |  |  | 			foundError = true | 
					
						
							| 
									
										
										
										
											2016-04-17 18:22:26 +02:00
										 |  |  | 			fmt.Fprintf(os.Stderr, "error: %v\n", err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-17 18:47:00 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if foundError { | 
					
						
							|  |  |  | 		os.Exit(1) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-08-19 20:12:41 +02:00
										 |  |  | } |