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  }