| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | // Description | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // This program aims to make building Go programs for end users easier by just | 
					
						
							|  |  |  | // calling it with `go run`, without having to setup a GOPATH. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2022-02-10 19:25:19 +01:00
										 |  |  | // This program needs Go >= 1.12. It'll use Go modules for compilation. It | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | // builds the package configured as Main in the Config struct. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 11:34:49 +01:00
										 |  |  | // BSD 2-Clause License | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Copyright (c) 2016-2018, Alexander Neumann <alexander@bumpern.de> | 
					
						
							|  |  |  | // All rights reserved. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | // This file has been derived from the repository at: | 
					
						
							| 
									
										
										
										
											2018-02-11 11:34:49 +01:00
										 |  |  | // https://github.com/fd0/build-go | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  | // modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // * Redistributions of source code must retain the above copyright notice, this | 
					
						
							|  |  |  | //   list of conditions and the following disclaimer. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // * Redistributions in binary form must reproduce the above copyright notice, | 
					
						
							|  |  |  | //   this list of conditions and the following disclaimer in the documentation | 
					
						
							|  |  |  | //   and/or other materials provided with the distribution. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
					
						
							|  |  |  | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
					
						
							|  |  |  | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | 
					
						
							|  |  |  | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
					
						
							|  |  |  | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
					
						
							|  |  |  | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
					
						
							|  |  |  | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
					
						
							|  |  |  | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
					
						
							|  |  |  | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-10 19:25:19 +01:00
										 |  |  | //go:build ignore_build_go | 
					
						
							| 
									
										
										
										
											2018-02-11 11:34:49 +01:00
										 |  |  | // +build ignore_build_go | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"io" | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"os/exec" | 
					
						
							|  |  |  | 	"path/filepath" | 
					
						
							|  |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 11:34:49 +01:00
										 |  |  | // config contains the configuration for the program to build. | 
					
						
							|  |  |  | var config = Config{ | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	Name:       "rest-server",                                   // name of the program executable and directory | 
					
						
							|  |  |  | 	Namespace:  "github.com/restic/rest-server",                 // subdir of GOPATH, e.g. "github.com/foo/bar" | 
					
						
							|  |  |  | 	Main:       "github.com/restic/rest-server/cmd/rest-server", // package name for the main package | 
					
						
							|  |  |  | 	Tests:      []string{"./..."},                               // tests to run | 
					
						
							| 
									
										
										
										
											2025-04-14 20:40:07 +02:00
										 |  |  | 	MinVersion: GoVersion{Major: 1, Minor: 23, Patch: 0},        // minimum Go version supported | 
					
						
							| 
									
										
										
										
											2018-02-11 11:34:49 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 11:34:49 +01:00
										 |  |  | // Config configures the build. | 
					
						
							|  |  |  | type Config struct { | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	Name             string | 
					
						
							|  |  |  | 	Namespace        string | 
					
						
							|  |  |  | 	Main             string | 
					
						
							|  |  |  | 	DefaultBuildTags []string | 
					
						
							|  |  |  | 	Tests            []string | 
					
						
							|  |  |  | 	MinVersion       GoVersion | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-11 11:34:49 +01:00
										 |  |  | var ( | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	verbose   bool | 
					
						
							|  |  |  | 	runTests  bool | 
					
						
							|  |  |  | 	enableCGO bool | 
					
						
							|  |  |  | 	enablePIE bool | 
					
						
							|  |  |  | 	goVersion = ParseGoVersion(runtime.Version()) | 
					
						
							| 
									
										
										
										
											2018-02-11 11:34:49 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | // die prints the message with fmt.Fprintf() to stderr and exits with an error | 
					
						
							|  |  |  | // code. | 
					
						
							|  |  |  | func die(message string, args ...interface{}) { | 
					
						
							|  |  |  | 	fmt.Fprintf(os.Stderr, message, args...) | 
					
						
							|  |  |  | 	os.Exit(1) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func showUsage(output io.Writer) { | 
					
						
							|  |  |  | 	fmt.Fprintf(output, "USAGE: go run build.go OPTIONS\n") | 
					
						
							|  |  |  | 	fmt.Fprintf(output, "\n") | 
					
						
							|  |  |  | 	fmt.Fprintf(output, "OPTIONS:\n") | 
					
						
							|  |  |  | 	fmt.Fprintf(output, "  -v     --verbose       output more messages\n") | 
					
						
							|  |  |  | 	fmt.Fprintf(output, "  -t     --tags          specify additional build tags\n") | 
					
						
							|  |  |  | 	fmt.Fprintf(output, "  -T     --test          run tests\n") | 
					
						
							| 
									
										
										
										
											2017-06-02 08:49:50 +02:00
										 |  |  | 	fmt.Fprintf(output, "  -o     --output        set output file name\n") | 
					
						
							| 
									
										
										
										
											2017-06-02 08:55:27 +02:00
										 |  |  | 	fmt.Fprintf(output, "         --enable-cgo    use CGO to link against libc\n") | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	fmt.Fprintf(output, "         --enable-pie    use PIE buildmode\n") | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	fmt.Fprintf(output, "         --goos value    set GOOS for cross-compilation\n") | 
					
						
							|  |  |  | 	fmt.Fprintf(output, "         --goarch value  set GOARCH for cross-compilation\n") | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	fmt.Fprintf(output, "         --goarm value   set GOARM for cross-compilation\n") | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func verbosePrintf(message string, args ...interface{}) { | 
					
						
							|  |  |  | 	if !verbose { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fmt.Printf("build: "+message, args...) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | // printEnv prints Go-relevant environment variables in a nice way using verbosePrintf. | 
					
						
							|  |  |  | func printEnv(env []string) { | 
					
						
							|  |  |  | 	verbosePrintf("environment (GO*):\n") | 
					
						
							|  |  |  | 	for _, v := range env { | 
					
						
							|  |  |  | 		// ignore environment variables which do not start with GO*. | 
					
						
							|  |  |  | 		if !strings.HasPrefix(v, "GO") { | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 		verbosePrintf("  %s\n", v) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // build runs "go build args..." with GOPATH set to gopath. | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | func build(cwd string, env map[string]string, args ...string) error { | 
					
						
							| 
									
										
										
										
											2022-02-10 19:25:19 +01:00
										 |  |  | 	// -trimpath removes all absolute paths from the binary. | 
					
						
							|  |  |  | 	a := []string{"build", "-trimpath"} | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if enablePIE { | 
					
						
							|  |  |  | 		a = append(a, "-buildmode=pie") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 08:56:08 +02:00
										 |  |  | 	a = append(a, args...) | 
					
						
							|  |  |  | 	cmd := exec.Command("go", a...) | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	cmd.Env = os.Environ() | 
					
						
							|  |  |  | 	for k, v := range env { | 
					
						
							|  |  |  | 		cmd.Env = append(cmd.Env, k+"="+v) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-02 08:55:27 +02:00
										 |  |  | 	if !enableCGO { | 
					
						
							|  |  |  | 		cmd.Env = append(cmd.Env, "CGO_ENABLED=0") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	printEnv(cmd.Env) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	cmd.Dir = cwd | 
					
						
							|  |  |  | 	cmd.Stdout = os.Stdout | 
					
						
							|  |  |  | 	cmd.Stderr = os.Stderr | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	verbosePrintf("chdir %q\n", cwd) | 
					
						
							|  |  |  | 	verbosePrintf("go %q\n", a) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return cmd.Run() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // test runs "go test args..." with GOPATH set to gopath. | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | func test(cwd string, env map[string]string, args ...string) error { | 
					
						
							|  |  |  | 	args = append([]string{"test", "-count", "1"}, args...) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	cmd := exec.Command("go", args...) | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	cmd.Env = os.Environ() | 
					
						
							|  |  |  | 	for k, v := range env { | 
					
						
							|  |  |  | 		cmd.Env = append(cmd.Env, k+"="+v) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !enableCGO { | 
					
						
							|  |  |  | 		cmd.Env = append(cmd.Env, "CGO_ENABLED=0") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	cmd.Dir = cwd | 
					
						
							|  |  |  | 	cmd.Stdout = os.Stdout | 
					
						
							|  |  |  | 	cmd.Stderr = os.Stderr | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	printEnv(cmd.Env) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	verbosePrintf("chdir %q\n", cwd) | 
					
						
							|  |  |  | 	verbosePrintf("go %q\n", args) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return cmd.Run() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | // getVersion returns the version string from the file VERSION in the current | 
					
						
							|  |  |  | // directory. | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | func getVersionFromFile() string { | 
					
						
							|  |  |  | 	buf, err := ioutil.ReadFile("VERSION") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		verbosePrintf("error reading file VERSION: %v\n", err) | 
					
						
							|  |  |  | 		return "" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return strings.TrimSpace(string(buf)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | // getVersion returns a version string which is a combination of the contents | 
					
						
							|  |  |  | // of the file VERSION in the current directory and the version from git (if | 
					
						
							|  |  |  | // available). | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | func getVersion() string { | 
					
						
							|  |  |  | 	versionFile := getVersionFromFile() | 
					
						
							|  |  |  | 	versionGit := getVersionFromGit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	verbosePrintf("version from file 'VERSION' is %q, version from git %q\n", | 
					
						
							|  |  |  | 		versionFile, versionGit) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch { | 
					
						
							|  |  |  | 	case versionFile == "": | 
					
						
							|  |  |  | 		return versionGit | 
					
						
							|  |  |  | 	case versionGit == "": | 
					
						
							|  |  |  | 		return versionFile | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return fmt.Sprintf("%s (%s)", versionFile, versionGit) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | // getVersionFromGit returns a version string that identifies the currently | 
					
						
							|  |  |  | // checked out git commit. | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | func getVersionFromGit() string { | 
					
						
							|  |  |  | 	cmd := exec.Command("git", "describe", | 
					
						
							|  |  |  | 		"--long", "--tags", "--dirty", "--always") | 
					
						
							|  |  |  | 	out, err := cmd.Output() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		verbosePrintf("git describe returned error: %v\n", err) | 
					
						
							|  |  |  | 		return "" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	version := strings.TrimSpace(string(out)) | 
					
						
							|  |  |  | 	verbosePrintf("git version is %s\n", version) | 
					
						
							|  |  |  | 	return version | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | // Constants represents a set of constants that are set in the final binary to | 
					
						
							|  |  |  | // the given value via compiler flags. | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | type Constants map[string]string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LDFlags returns the string that can be passed to go build's `-ldflags`. | 
					
						
							|  |  |  | func (cs Constants) LDFlags() string { | 
					
						
							|  |  |  | 	l := make([]string, 0, len(cs)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for k, v := range cs { | 
					
						
							|  |  |  | 		l = append(l, fmt.Sprintf(`-X "%s=%s"`, k, v)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return strings.Join(l, " ") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | // 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, ".") | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	if len(data) < 2 || len(data) > 3 { | 
					
						
							|  |  |  | 		// invalid version | 
					
						
							|  |  |  | 		return GoVersion{} | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	var err error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	v.Major, err = strconv.Atoi(data[0]) | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 		return GoVersion{} | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-02 09:26:02 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	// try to parse the minor version while removing an eventual suffix (like | 
					
						
							|  |  |  | 	// "rc2" or so) | 
					
						
							|  |  |  | 	for s := data[1]; s != ""; s = s[:len(s)-1] { | 
					
						
							|  |  |  | 		v.Minor, err = strconv.Atoi(s) | 
					
						
							|  |  |  | 		if err == nil { | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	if v.Minor == 0 { | 
					
						
							|  |  |  | 		// no minor version found | 
					
						
							|  |  |  | 		return GoVersion{} | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	if len(data) >= 3 { | 
					
						
							|  |  |  | 		v.Patch, err = strconv.Atoi(data[2]) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return GoVersion{} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 	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() { | 
					
						
							| 
									
										
										
										
											2022-02-10 19:25:19 +01:00
										 |  |  | 	if !goVersion.AtLeast(GoVersion{1, 12, 0}) { | 
					
						
							|  |  |  | 		die("Go version (%v) is too old, restic requires Go >= 1.12\n", goVersion) | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if !goVersion.AtLeast(config.MinVersion) { | 
					
						
							|  |  |  | 		fmt.Fprintf(os.Stderr, "%s detected, this program requires at least %s\n", goVersion, config.MinVersion) | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 		os.Exit(1) | 
					
						
							| 
									
										
										
										
											2017-06-02 08:52:04 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	buildTags := config.DefaultBuildTags | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	skipNext := false | 
					
						
							|  |  |  | 	params := os.Args[1:] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	env := map[string]string{ | 
					
						
							|  |  |  | 		"GO111MODULE": "on", // make sure we build in Module mode | 
					
						
							|  |  |  | 		"GOOS":        runtime.GOOS, | 
					
						
							|  |  |  | 		"GOARCH":      runtime.GOARCH, | 
					
						
							|  |  |  | 		"GOARM":       "", | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 08:49:50 +02:00
										 |  |  | 	var outputFilename string | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	for i, arg := range params { | 
					
						
							|  |  |  | 		if skipNext { | 
					
						
							|  |  |  | 			skipNext = false | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		switch arg { | 
					
						
							|  |  |  | 		case "-v", "--verbose": | 
					
						
							|  |  |  | 			verbose = true | 
					
						
							|  |  |  | 		case "-t", "-tags", "--tags": | 
					
						
							|  |  |  | 			if i+1 >= len(params) { | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 				die("-t given but no tag specified") | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			skipNext = true | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 			buildTags = append(buildTags, strings.Split(params[i+1], " ")...) | 
					
						
							| 
									
										
										
										
											2017-06-02 08:49:50 +02:00
										 |  |  | 		case "-o", "--output": | 
					
						
							|  |  |  | 			skipNext = true | 
					
						
							|  |  |  | 			outputFilename = params[i+1] | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 		case "-T", "--test": | 
					
						
							|  |  |  | 			runTests = true | 
					
						
							| 
									
										
										
										
											2017-06-02 08:55:27 +02:00
										 |  |  | 		case "--enable-cgo": | 
					
						
							|  |  |  | 			enableCGO = true | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 		case "--enable-pie": | 
					
						
							|  |  |  | 			enablePIE = true | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 		case "--goos": | 
					
						
							|  |  |  | 			skipNext = true | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 			env["GOOS"] = params[i+1] | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 		case "--goarch": | 
					
						
							|  |  |  | 			skipNext = true | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 			env["GOARCH"] = params[i+1] | 
					
						
							|  |  |  | 		case "--goarm": | 
					
						
							|  |  |  | 			skipNext = true | 
					
						
							|  |  |  | 			env["GOARM"] = params[i+1] | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 		case "-h": | 
					
						
							|  |  |  | 			showUsage(os.Stdout) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		default: | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 			fmt.Fprintf(os.Stderr, "Error: unknown option %q\n\n", arg) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 			showUsage(os.Stderr) | 
					
						
							|  |  |  | 			os.Exit(1) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	verbosePrintf("detected Go version %v\n", goVersion) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-10 19:25:19 +01:00
										 |  |  | 	preserveSymbols := false | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	for i := range buildTags { | 
					
						
							|  |  |  | 		buildTags[i] = strings.TrimSpace(buildTags[i]) | 
					
						
							| 
									
										
										
										
											2022-02-10 19:25:19 +01:00
										 |  |  | 		if buildTags[i] == "debug" || buildTags[i] == "profile" { | 
					
						
							|  |  |  | 			preserveSymbols = true | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	verbosePrintf("build tags: %s\n", buildTags) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	root, err := os.Getwd() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 		die("Getwd(): %v\n", err) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-02 08:49:50 +02:00
										 |  |  | 	if outputFilename == "" { | 
					
						
							|  |  |  | 		outputFilename = config.Name | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 		if env["GOOS"] == "windows" { | 
					
						
							| 
									
										
										
										
											2017-06-02 08:49:50 +02:00
										 |  |  | 			outputFilename += ".exe" | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 	output := outputFilename | 
					
						
							|  |  |  | 	if !filepath.IsAbs(output) { | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 		output = filepath.Join(root, output) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	version := getVersion() | 
					
						
							|  |  |  | 	constants := Constants{} | 
					
						
							|  |  |  | 	if version != "" { | 
					
						
							|  |  |  | 		constants["main.version"] = version | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-02-10 19:25:19 +01:00
										 |  |  | 	ldflags := constants.LDFlags() | 
					
						
							|  |  |  | 	if !preserveSymbols { | 
					
						
							|  |  |  | 		// Strip debug symbols. | 
					
						
							|  |  |  | 		ldflags = "-s -w " + ldflags | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	verbosePrintf("ldflags: %s\n", ldflags) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	var ( | 
					
						
							|  |  |  | 		buildArgs []string | 
					
						
							|  |  |  | 		testArgs  []string | 
					
						
							|  |  |  | 	) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mainPackage := config.Main | 
					
						
							|  |  |  | 	if strings.HasPrefix(mainPackage, config.Namespace) { | 
					
						
							|  |  |  | 		mainPackage = strings.Replace(mainPackage, config.Namespace, "./", 1) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buildTarget := filepath.FromSlash(mainPackage) | 
					
						
							|  |  |  | 	buildCWD, err := os.Getwd() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		die("unable to determine current working directory: %v\n", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buildArgs = append(buildArgs, | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 		"-tags", strings.Join(buildTags, " "), | 
					
						
							|  |  |  | 		"-ldflags", ldflags, | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 		"-o", output, buildTarget, | 
					
						
							|  |  |  | 	) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 	err = build(buildCWD, env, buildArgs...) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 		die("build failed: %v\n", err) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if runTests { | 
					
						
							|  |  |  | 		verbosePrintf("running tests\n") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-04 20:41:32 +02:00
										 |  |  | 		testArgs = append(testArgs, config.Tests...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		err = test(buildCWD, env, testArgs...) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2018-01-13 10:41:28 +01:00
										 |  |  | 			die("running tests failed: %v\n", err) | 
					
						
							| 
									
										
										
										
											2016-12-28 21:41:22 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |