podman

Форк
0
233 строки · 6.8 Кб
1
// untested sections: 5
2

3
package gexec
4

5
import (
6
	"errors"
7
	"fmt"
8
	"go/build"
9
	"os"
10
	"os/exec"
11
	"path"
12
	"path/filepath"
13
	"runtime"
14
	"strings"
15
	"sync"
16

17
	"github.com/onsi/gomega/internal/gutil"
18
)
19

20
var (
21
	mu     sync.Mutex
22
	tmpDir string
23
)
24

25
/*
26
Build uses go build to compile the package at packagePath.  The resulting binary is saved off in a temporary directory.
27
A path pointing to this binary is returned.
28

29
Build uses the $GOPATH set in your environment. If $GOPATH is not set and you are using Go 1.8+,
30
it will use the default GOPATH instead.  It passes the variadic args on to `go build`.
31
*/
32
func Build(packagePath string, args ...string) (compiledPath string, err error) {
33
	return doBuild(build.Default.GOPATH, packagePath, nil, args...)
34
}
35

36
/*
37
BuildWithEnvironment is identical to Build but allows you to specify env vars to be set at build time.
38
*/
39
func BuildWithEnvironment(packagePath string, env []string, args ...string) (compiledPath string, err error) {
40
	return doBuild(build.Default.GOPATH, packagePath, env, args...)
41
}
42

43
/*
44
BuildIn is identical to Build but allows you to specify a custom $GOPATH (the first argument).
45
*/
46
func BuildIn(gopath string, packagePath string, args ...string) (compiledPath string, err error) {
47
	return doBuild(gopath, packagePath, nil, args...)
48
}
49

50
func doBuild(gopath, packagePath string, env []string, args ...string) (compiledPath string, err error) {
51
	executable, err := newExecutablePath(gopath, packagePath)
52
	if err != nil {
53
		return "", err
54
	}
55

56
	cmdArgs := append([]string{"build"}, args...)
57
	cmdArgs = append(cmdArgs, "-o", executable, packagePath)
58

59
	build := exec.Command("go", cmdArgs...)
60
	build.Env = replaceGoPath(os.Environ(), gopath)
61
	build.Env = append(build.Env, env...)
62

63
	output, err := build.CombinedOutput()
64
	if err != nil {
65
		return "", fmt.Errorf("Failed to build %s:\n\nError:\n%s\n\nOutput:\n%s", packagePath, err, string(output))
66
	}
67

68
	return executable, nil
69
}
70

71
/*
72
CompileTest uses go test to compile the test package at packagePath.  The resulting binary is saved off in a temporary directory.
73
A path pointing to this binary is returned.
74

75
CompileTest uses the $GOPATH set in your environment. If $GOPATH is not set and you are using Go 1.8+,
76
it will use the default GOPATH instead.  It passes the variadic args on to `go test`.
77
*/
78
func CompileTest(packagePath string, args ...string) (compiledPath string, err error) {
79
	return doCompileTest(build.Default.GOPATH, packagePath, nil, args...)
80
}
81

82
/*
83
GetAndCompileTest is identical to CompileTest but `go get` the package before compiling tests.
84
*/
85
func GetAndCompileTest(packagePath string, args ...string) (compiledPath string, err error) {
86
	if err := getForTest(build.Default.GOPATH, packagePath, []string{"GO111MODULE=off"}); err != nil {
87
		return "", err
88
	}
89

90
	return doCompileTest(build.Default.GOPATH, packagePath, []string{"GO111MODULE=off"}, args...)
91
}
92

93
/*
94
CompileTestWithEnvironment is identical to CompileTest but allows you to specify env vars to be set at build time.
95
*/
96
func CompileTestWithEnvironment(packagePath string, env []string, args ...string) (compiledPath string, err error) {
97
	return doCompileTest(build.Default.GOPATH, packagePath, env, args...)
98
}
99

100
/*
101
GetAndCompileTestWithEnvironment is identical to GetAndCompileTest but allows you to specify env vars to be set at build time.
102
*/
103
func GetAndCompileTestWithEnvironment(packagePath string, env []string, args ...string) (compiledPath string, err error) {
104
	if err := getForTest(build.Default.GOPATH, packagePath, append(env, "GO111MODULE=off")); err != nil {
105
		return "", err
106
	}
107

108
	return doCompileTest(build.Default.GOPATH, packagePath, append(env, "GO111MODULE=off"), args...)
109
}
110

111
/*
112
CompileTestIn is identical to CompileTest but allows you to specify a custom $GOPATH (the first argument).
113
*/
114
func CompileTestIn(gopath string, packagePath string, args ...string) (compiledPath string, err error) {
115
	return doCompileTest(gopath, packagePath, nil, args...)
116
}
117

118
/*
119
GetAndCompileTestIn is identical to GetAndCompileTest but allows you to specify a custom $GOPATH (the first argument).
120
*/
121
func GetAndCompileTestIn(gopath string, packagePath string, args ...string) (compiledPath string, err error) {
122
	if err := getForTest(gopath, packagePath, []string{"GO111MODULE=off"}); err != nil {
123
		return "", err
124
	}
125

126
	return doCompileTest(gopath, packagePath, []string{"GO111MODULE=off"}, args...)
127
}
128

129
func isLocalPackage(packagePath string) bool {
130
	return strings.HasPrefix(packagePath, ".")
131
}
132

133
func getForTest(gopath, packagePath string, env []string) error {
134
	if isLocalPackage(packagePath) {
135
		return nil
136
	}
137

138
	return doGet(gopath, packagePath, env, "-t")
139
}
140

141
func doGet(gopath, packagePath string, env []string, args ...string) error {
142
	args = append(args, packagePath)
143
	args = append([]string{"get"}, args...)
144

145
	goGet := exec.Command("go", args...)
146
	goGet.Dir = gopath
147
	goGet.Env = replaceGoPath(os.Environ(), gopath)
148
	goGet.Env = append(goGet.Env, env...)
149

150
	output, err := goGet.CombinedOutput()
151
	if err != nil {
152
		return fmt.Errorf("Failed to get %s:\n\nError:\n%s\n\nOutput:\n%s", packagePath, err, string(output))
153
	}
154

155
	return nil
156
}
157

158
func doCompileTest(gopath, packagePath string, env []string, args ...string) (compiledPath string, err error) {
159
	executable, err := newExecutablePath(gopath, packagePath, ".test")
160
	if err != nil {
161
		return "", err
162
	}
163

164
	cmdArgs := append([]string{"test", "-c"}, args...)
165
	cmdArgs = append(cmdArgs, "-o", executable, packagePath)
166

167
	build := exec.Command("go", cmdArgs...)
168
	build.Env = replaceGoPath(os.Environ(), gopath)
169
	build.Env = append(build.Env, env...)
170

171
	output, err := build.CombinedOutput()
172
	if err != nil {
173
		return "", fmt.Errorf("Failed to build %s:\n\nError:\n%s\n\nOutput:\n%s", packagePath, err, string(output))
174
	}
175

176
	return executable, nil
177
}
178

179
func replaceGoPath(environ []string, newGoPath string) []string {
180
	newEnviron := []string{}
181
	for _, v := range environ {
182
		if !strings.HasPrefix(v, "GOPATH=") {
183
			newEnviron = append(newEnviron, v)
184
		}
185
	}
186
	return append(newEnviron, "GOPATH="+newGoPath)
187
}
188

189
func newExecutablePath(gopath, packagePath string, suffixes ...string) (string, error) {
190
	tmpDir, err := temporaryDirectory()
191
	if err != nil {
192
		return "", err
193
	}
194

195
	if len(gopath) == 0 {
196
		return "", errors.New("$GOPATH not provided when building " + packagePath)
197
	}
198

199
	executable := filepath.Join(tmpDir, path.Base(packagePath))
200

201
	if runtime.GOOS == "windows" {
202
		executable += ".exe"
203
	}
204

205
	return executable, nil
206
}
207

208
/*
209
You should call CleanupBuildArtifacts before your test ends to clean up any temporary artifacts generated by
210
gexec. In Ginkgo this is typically done in an AfterSuite callback.
211
*/
212
func CleanupBuildArtifacts() {
213
	mu.Lock()
214
	defer mu.Unlock()
215
	if tmpDir != "" {
216
		os.RemoveAll(tmpDir)
217
		tmpDir = ""
218
	}
219
}
220

221
func temporaryDirectory() (string, error) {
222
	var err error
223
	mu.Lock()
224
	defer mu.Unlock()
225
	if tmpDir == "" {
226
		tmpDir, err = gutil.MkdirTemp("", "gexec_artifacts")
227
		if err != nil {
228
			return "", err
229
		}
230
	}
231

232
	return gutil.MkdirTemp(tmpDir, "g")
233
}
234

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.