gitee.com/mirrors_opencollective/goreleaser@v0.45.0/pipeline/build/build_test.go (about) 1 package build 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "runtime" 8 "testing" 9 10 "github.com/goreleaser/goreleaser/config" 11 "github.com/goreleaser/goreleaser/context" 12 "github.com/goreleaser/goreleaser/internal/buildtarget" 13 "github.com/goreleaser/goreleaser/internal/testlib" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 var emptyEnv []string 18 19 func TestPipeDescription(t *testing.T) { 20 assert.NotEmpty(t, Pipe{}.String()) 21 } 22 23 func TestRun(t *testing.T) { 24 assert.NoError(t, run( 25 context.New(config.Project{}), 26 buildtarget.Runtime, 27 []string{"go", "list", "./..."}, 28 emptyEnv, 29 )) 30 } 31 32 func TestRunInvalidCommand(t *testing.T) { 33 assert.Error(t, run( 34 context.New(config.Project{}), 35 buildtarget.Runtime, 36 []string{"gggggo", "nope"}, 37 emptyEnv, 38 )) 39 } 40 41 func TestBuild(t *testing.T) { 42 var config = config.Project{ 43 Builds: []config.Build{ 44 { 45 Binary: "testing", 46 Flags: "-n", 47 Env: []string{"BLAH=1"}, 48 }, 49 }, 50 } 51 var ctx = context.New(config) 52 assert.NoError(t, doBuild(ctx, ctx.Config.Builds[0], buildtarget.Runtime)) 53 } 54 55 func TestRunFullPipe(t *testing.T) { 56 folder, back := testlib.Mktmp(t) 57 defer back() 58 writeGoodMain(t, folder) 59 var binary = filepath.Join(folder, buildtarget.Runtime.String(), "testing") 60 var pre = filepath.Join(folder, "pre") 61 var post = filepath.Join(folder, "post") 62 var config = config.Project{ 63 Builds: []config.Build{ 64 { 65 Binary: "testing", 66 Flags: "-v", 67 Ldflags: "-X main.test=testing", 68 Hooks: config.Hooks{ 69 Pre: "touch " + pre, 70 Post: "touch " + post, 71 }, 72 Goos: []string{ 73 runtime.GOOS, 74 }, 75 Goarch: []string{ 76 runtime.GOARCH, 77 }, 78 }, 79 }, 80 Archive: config.Archive{ 81 Replacements: map[string]string{ 82 "linux": "linuxx", 83 "darwin": "darwinn", 84 }, 85 }, 86 } 87 var ctx = context.New(config) 88 assert.NoError(t, Pipe{}.Run(ctx)) 89 assert.Len(t, ctx.Artifacts.List(), 1) 90 assert.True(t, exists(binary), binary) 91 assert.True(t, exists(pre), pre) 92 assert.True(t, exists(post), post) 93 } 94 95 func TestRunPipeArmBuilds(t *testing.T) { 96 folder, back := testlib.Mktmp(t) 97 defer back() 98 writeGoodMain(t, folder) 99 var binary = filepath.Join(folder, "linuxarm6", "armtesting") 100 var config = config.Project{ 101 Builds: []config.Build{ 102 { 103 Binary: "armtesting", 104 Flags: "-v", 105 Ldflags: "-X main.test=armtesting", 106 Goos: []string{ 107 "linux", 108 }, 109 Goarch: []string{ 110 "arm", 111 "arm64", 112 }, 113 Goarm: []string{ 114 "6", 115 }, 116 }, 117 }, 118 } 119 var ctx = context.New(config) 120 assert.NoError(t, Pipe{}.Run(ctx)) 121 assert.Len(t, ctx.Artifacts.List(), 2) 122 assert.True(t, exists(binary), binary) 123 } 124 125 func TestBuildFailed(t *testing.T) { 126 folder, back := testlib.Mktmp(t) 127 defer back() 128 writeGoodMain(t, folder) 129 var config = config.Project{ 130 Builds: []config.Build{ 131 { 132 Flags: "-flag-that-dont-exists-to-force-failure", 133 Goos: []string{ 134 runtime.GOOS, 135 }, 136 Goarch: []string{ 137 runtime.GOARCH, 138 }, 139 }, 140 }, 141 } 142 var ctx = context.New(config) 143 assertContainsError(t, Pipe{}.Run(ctx), `flag provided but not defined: -flag-that-dont-exists-to-force-failure`) 144 assert.Empty(t, ctx.Artifacts.List()) 145 } 146 147 func TestRunPipeWithInvalidOS(t *testing.T) { 148 folder, back := testlib.Mktmp(t) 149 defer back() 150 writeGoodMain(t, folder) 151 var config = config.Project{ 152 Builds: []config.Build{ 153 { 154 Flags: "-v", 155 Goos: []string{ 156 "windows", 157 }, 158 Goarch: []string{ 159 "arm", 160 }, 161 }, 162 }, 163 } 164 assert.NoError(t, Pipe{}.Run(context.New(config))) 165 } 166 167 func TestRunInvalidLdflags(t *testing.T) { 168 folder, back := testlib.Mktmp(t) 169 defer back() 170 writeGoodMain(t, folder) 171 var config = config.Project{ 172 Builds: []config.Build{ 173 { 174 Binary: "nametest", 175 Flags: "-v", 176 Ldflags: "-s -w -X main.version={{.Version}", 177 Goos: []string{ 178 runtime.GOOS, 179 }, 180 Goarch: []string{ 181 runtime.GOARCH, 182 }, 183 }, 184 }, 185 } 186 assert.EqualError(t, Pipe{}.Run(context.New(config)), `template: ldflags:1: unexpected "}" in operand`) 187 } 188 189 func TestRunPipeFailingHooks(t *testing.T) { 190 folder, back := testlib.Mktmp(t) 191 defer back() 192 writeGoodMain(t, folder) 193 var config = config.Project{ 194 Builds: []config.Build{ 195 { 196 Binary: "hooks", 197 Hooks: config.Hooks{}, 198 Goos: []string{ 199 runtime.GOOS, 200 }, 201 Goarch: []string{ 202 runtime.GOARCH, 203 }, 204 }, 205 }, 206 } 207 t.Run("pre-hook", func(t *testing.T) { 208 var ctx = context.New(config) 209 ctx.Config.Builds[0].Hooks.Pre = "exit 1" 210 ctx.Config.Builds[0].Hooks.Post = "echo post" 211 assert.EqualError(t, Pipe{}.Run(ctx), `pre hook failed: `) 212 }) 213 t.Run("post-hook", func(t *testing.T) { 214 var ctx = context.New(config) 215 ctx.Config.Builds[0].Hooks.Pre = "echo pre" 216 ctx.Config.Builds[0].Hooks.Post = "exit 1" 217 assert.EqualError(t, Pipe{}.Run(ctx), `post hook failed: `) 218 }) 219 } 220 221 func TestRunPipeWithouMainFunc(t *testing.T) { 222 folder, back := testlib.Mktmp(t) 223 defer back() 224 writeMainWithoutMainFunc(t, folder) 225 var config = config.Project{ 226 Builds: []config.Build{ 227 { 228 Binary: "no-main", 229 Hooks: config.Hooks{}, 230 Goos: []string{ 231 runtime.GOOS, 232 }, 233 Goarch: []string{ 234 runtime.GOARCH, 235 }, 236 }, 237 }, 238 } 239 var ctx = context.New(config) 240 t.Run("empty", func(t *testing.T) { 241 ctx.Config.Builds[0].Main = "" 242 assert.EqualError(t, Pipe{}.Run(ctx), `build for no-main does not contain a main function`) 243 }) 244 t.Run("not main.go", func(t *testing.T) { 245 ctx.Config.Builds[0].Main = "foo.go" 246 assert.EqualError(t, Pipe{}.Run(ctx), `could not open foo.go: stat foo.go: no such file or directory`) 247 }) 248 t.Run("glob", func(t *testing.T) { 249 ctx.Config.Builds[0].Main = "." 250 assert.EqualError(t, Pipe{}.Run(ctx), `build for no-main does not contain a main function`) 251 }) 252 t.Run("fixed main.go", func(t *testing.T) { 253 ctx.Config.Builds[0].Main = "main.go" 254 assert.EqualError(t, Pipe{}.Run(ctx), `build for no-main does not contain a main function`) 255 }) 256 } 257 258 func TestRunPipeWithMainFuncNotInMainGoFile(t *testing.T) { 259 folder, back := testlib.Mktmp(t) 260 defer back() 261 assert.NoError(t, ioutil.WriteFile( 262 filepath.Join(folder, "foo.go"), 263 []byte("package main\nfunc main() {println(0)}"), 264 0644, 265 )) 266 var config = config.Project{ 267 Builds: []config.Build{ 268 { 269 Binary: "foo", 270 Hooks: config.Hooks{}, 271 Goos: []string{ 272 runtime.GOOS, 273 }, 274 Goarch: []string{ 275 runtime.GOARCH, 276 }, 277 }, 278 }, 279 } 280 var ctx = context.New(config) 281 t.Run("empty", func(t *testing.T) { 282 ctx.Config.Builds[0].Main = "" 283 assert.NoError(t, Pipe{}.Run(ctx)) 284 }) 285 t.Run("foo.go", func(t *testing.T) { 286 ctx.Config.Builds[0].Main = "foo.go" 287 assert.NoError(t, Pipe{}.Run(ctx)) 288 }) 289 t.Run("glob", func(t *testing.T) { 290 ctx.Config.Builds[0].Main = "." 291 assert.NoError(t, Pipe{}.Run(ctx)) 292 }) 293 } 294 295 func TestDefaultNoBuilds(t *testing.T) { 296 var ctx = &context.Context{ 297 Config: config.Project{}, 298 } 299 assert.NoError(t, Pipe{}.Default(ctx)) 300 } 301 302 func TestDefaultEmptyBuild(t *testing.T) { 303 var ctx = &context.Context{ 304 Config: config.Project{ 305 Release: config.Release{ 306 GitHub: config.Repo{ 307 Name: "foo", 308 }, 309 }, 310 Builds: []config.Build{ 311 {}, 312 }, 313 }, 314 } 315 assert.NoError(t, Pipe{}.Default(ctx)) 316 var build = ctx.Config.Builds[0] 317 assert.Equal(t, ctx.Config.Release.GitHub.Name, build.Binary) 318 assert.Equal(t, ".", build.Main) 319 assert.Equal(t, []string{"linux", "darwin"}, build.Goos) 320 assert.Equal(t, []string{"amd64", "386"}, build.Goarch) 321 assert.Equal(t, []string{"6"}, build.Goarm) 322 assert.Equal(t, "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}", build.Ldflags) 323 } 324 325 func TestDefaultPartialBuilds(t *testing.T) { 326 var ctx = &context.Context{ 327 Config: config.Project{ 328 Builds: []config.Build{ 329 { 330 Binary: "bar", 331 Goos: []string{"linux"}, 332 Main: "./cmd/main.go", 333 }, 334 { 335 Binary: "foo", 336 Ldflags: "-s -w", 337 Goarch: []string{"386"}, 338 }, 339 }, 340 }, 341 } 342 assert.NoError(t, Pipe{}.Default(ctx)) 343 t.Run("build0", func(t *testing.T) { 344 var build = ctx.Config.Builds[0] 345 assert.Equal(t, "bar", build.Binary) 346 assert.Equal(t, "./cmd/main.go", build.Main) 347 assert.Equal(t, []string{"linux"}, build.Goos) 348 assert.Equal(t, []string{"amd64", "386"}, build.Goarch) 349 assert.Equal(t, []string{"6"}, build.Goarm) 350 assert.Equal(t, "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}", build.Ldflags) 351 }) 352 t.Run("build1", func(t *testing.T) { 353 var build = ctx.Config.Builds[1] 354 assert.Equal(t, "foo", build.Binary) 355 assert.Equal(t, ".", build.Main) 356 assert.Equal(t, []string{"linux", "darwin"}, build.Goos) 357 assert.Equal(t, []string{"386"}, build.Goarch) 358 assert.Equal(t, []string{"6"}, build.Goarm) 359 assert.Equal(t, "-s -w", build.Ldflags) 360 }) 361 } 362 363 func TestDefaultFillSingleBuild(t *testing.T) { 364 _, back := testlib.Mktmp(t) 365 defer back() 366 367 var ctx = &context.Context{ 368 Config: config.Project{ 369 Release: config.Release{ 370 GitHub: config.Repo{ 371 Name: "foo", 372 }, 373 }, 374 SingleBuild: config.Build{ 375 Main: "testreleaser", 376 }, 377 }, 378 } 379 assert.NoError(t, Pipe{}.Default(ctx)) 380 assert.Len(t, ctx.Config.Builds, 1) 381 assert.Equal(t, ctx.Config.Builds[0].Binary, "foo") 382 } 383 384 func exists(file string) bool { 385 _, err := os.Stat(file) 386 return !os.IsNotExist(err) 387 } 388 389 func writeMainWithoutMainFunc(t *testing.T, folder string) { 390 assert.NoError(t, ioutil.WriteFile( 391 filepath.Join(folder, "main.go"), 392 []byte("package main\nconst a = 2\nfunc notMain() {println(0)}"), 393 0644, 394 )) 395 } 396 397 func writeGoodMain(t *testing.T, folder string) { 398 assert.NoError(t, ioutil.WriteFile( 399 filepath.Join(folder, "main.go"), 400 []byte("package main\nvar a = 1\nfunc main() {println(0)}"), 401 0644, 402 )) 403 } 404 405 func assertContainsError(t *testing.T, err error, s string) { 406 assert.Error(t, err) 407 assert.Contains(t, err.Error(), s) 408 }