initial commit
[govpp.git] / vendor / github.com / onsi / gomega / gexec / build.go
1 package gexec
2
3 import (
4         "errors"
5         "fmt"
6         "io/ioutil"
7         "os"
8         "os/exec"
9         "path"
10         "path/filepath"
11         "runtime"
12         "sync"
13 )
14
15 var (
16         mu     sync.Mutex
17         tmpDir string
18 )
19
20 /*
21 Build uses go build to compile the package at packagePath.  The resulting binary is saved off in a temporary directory.
22 A path pointing to this binary is returned.
23
24 Build uses the $GOPATH set in your environment.  It passes the variadic args on to `go build`.
25 */
26 func Build(packagePath string, args ...string) (compiledPath string, err error) {
27         return doBuild(os.Getenv("GOPATH"), packagePath, nil, args...)
28 }
29
30 /*
31 BuildWithEnvironment is identical to Build but allows you to specify env vars to be set at build time.
32 */
33 func BuildWithEnvironment(packagePath string, env []string, args ...string) (compiledPath string, err error) {
34         return doBuild(os.Getenv("GOPATH"), packagePath, env, args...)
35 }
36
37 /*
38 BuildIn is identical to Build but allows you to specify a custom $GOPATH (the first argument).
39 */
40 func BuildIn(gopath string, packagePath string, args ...string) (compiledPath string, err error) {
41         return doBuild(gopath, packagePath, nil, args...)
42 }
43
44 func doBuild(gopath, packagePath string, env []string, args ...string) (compiledPath string, err error) {
45         tmpDir, err := temporaryDirectory()
46         if err != nil {
47                 return "", err
48         }
49
50         if len(gopath) == 0 {
51                 return "", errors.New("$GOPATH not provided when building " + packagePath)
52         }
53
54         executable := filepath.Join(tmpDir, path.Base(packagePath))
55         if runtime.GOOS == "windows" {
56                 executable = executable + ".exe"
57         }
58
59         cmdArgs := append([]string{"build"}, args...)
60         cmdArgs = append(cmdArgs, "-o", executable, packagePath)
61
62         build := exec.Command("go", cmdArgs...)
63         build.Env = append([]string{"GOPATH=" + gopath}, os.Environ()...)
64         build.Env = append(build.Env, env...)
65
66         output, err := build.CombinedOutput()
67         if err != nil {
68                 return "", fmt.Errorf("Failed to build %s:\n\nError:\n%s\n\nOutput:\n%s", packagePath, err, string(output))
69         }
70
71         return executable, nil
72 }
73
74 /*
75 You should call CleanupBuildArtifacts before your test ends to clean up any temporary artifacts generated by
76 gexec. In Ginkgo this is typically done in an AfterSuite callback.
77 */
78 func CleanupBuildArtifacts() {
79         mu.Lock()
80         defer mu.Unlock()
81         if tmpDir != "" {
82                 os.RemoveAll(tmpDir)
83                 tmpDir = ""
84         }
85 }
86
87 func temporaryDirectory() (string, error) {
88         var err error
89         mu.Lock()
90         defer mu.Unlock()
91         if tmpDir == "" {
92                 tmpDir, err = ioutil.TempDir("", "gexec_artifacts")
93                 if err != nil {
94                         return "", err
95                 }
96         }
97
98         return ioutil.TempDir(tmpDir, "g")
99 }