github.com/joselitofilho/goreleaser@v0.155.1-0.20210123221854-e4891856c593/internal/pipe/archive/archive_test.go (about)

     1  package archive
     2  
     3  import (
     4  	"archive/tar"
     5  	"archive/zip"
     6  	"compress/gzip"
     7  	"fmt"
     8  	"io"
     9  	"io/ioutil"
    10  	"os"
    11  	"path/filepath"
    12  	"testing"
    13  
    14  	"github.com/goreleaser/goreleaser/internal/artifact"
    15  	"github.com/goreleaser/goreleaser/internal/testlib"
    16  	"github.com/goreleaser/goreleaser/pkg/archive"
    17  	"github.com/goreleaser/goreleaser/pkg/config"
    18  	"github.com/goreleaser/goreleaser/pkg/context"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func TestDescription(t *testing.T) {
    23  	require.NotEmpty(t, Pipe{}.String())
    24  }
    25  
    26  func createFakeBinary(t *testing.T, dist, arch, bin string) {
    27  	t.Helper()
    28  	var path = filepath.Join(dist, arch, bin)
    29  	require.NoError(t, os.MkdirAll(filepath.Dir(path), 0755))
    30  	_, err := os.Create(path)
    31  	require.NoError(t, err)
    32  }
    33  
    34  func TestRunPipe(t *testing.T) {
    35  	var folder = testlib.Mktmp(t)
    36  	for _, format := range []string{"tar.gz", "zip"} {
    37  		t.Run("Archive format "+format, func(t *testing.T) {
    38  			var dist = filepath.Join(folder, format+"_dist")
    39  			require.NoError(t, os.Mkdir(dist, 0755))
    40  			for _, arch := range []string{"darwinamd64", "linux386", "linuxarm7", "linuxmipssoftfloat"} {
    41  				createFakeBinary(t, dist, arch, "bin/mybin")
    42  			}
    43  			createFakeBinary(t, dist, "windowsamd64", "bin/mybin.exe")
    44  			for _, tt := range []string{"darwin", "linux", "windows"} {
    45  				_, err := os.Create(filepath.Join(folder, fmt.Sprintf("README.%s.md", tt)))
    46  				require.NoError(t, err)
    47  			}
    48  			require.NoError(t, os.MkdirAll(filepath.Join(folder, "foo", "bar", "foobar"), 0755))
    49  			_, err := os.Create(filepath.Join(filepath.Join(folder, "foo", "bar", "foobar", "blah.txt")))
    50  			require.NoError(t, err)
    51  			var ctx = context.New(
    52  				config.Project{
    53  					Dist:        dist,
    54  					ProjectName: "foobar",
    55  					Archives: []config.Archive{
    56  						{
    57  							ID:           "myid",
    58  							Builds:       []string{"default"},
    59  							NameTemplate: defaultNameTemplate,
    60  							Files: []string{
    61  								"README.{{.Os}}.*",
    62  								"./foo/**/*",
    63  							},
    64  							FormatOverrides: []config.FormatOverride{
    65  								{
    66  									Goos:   "windows",
    67  									Format: "zip",
    68  								},
    69  							},
    70  						},
    71  					},
    72  				},
    73  			)
    74  			var darwinBuild = &artifact.Artifact{
    75  				Goos:   "darwin",
    76  				Goarch: "amd64",
    77  				Name:   "bin/mybin",
    78  				Path:   filepath.Join(dist, "darwinamd64", "bin", "mybin"),
    79  				Type:   artifact.Binary,
    80  				Extra: map[string]interface{}{
    81  					"Binary": "bin/mybin",
    82  					"ID":     "default",
    83  				},
    84  			}
    85  			var linux386Build = &artifact.Artifact{
    86  				Goos:   "linux",
    87  				Goarch: "386",
    88  				Name:   "bin/mybin",
    89  				Path:   filepath.Join(dist, "linux386", "bin", "mybin"),
    90  				Type:   artifact.Binary,
    91  				Extra: map[string]interface{}{
    92  					"Binary": "bin/mybin",
    93  					"ID":     "default",
    94  				},
    95  			}
    96  			var linuxArmBuild = &artifact.Artifact{
    97  				Goos:   "linux",
    98  				Goarch: "arm",
    99  				Goarm:  "7",
   100  				Name:   "bin/mybin",
   101  				Path:   filepath.Join(dist, "linuxarm7", "bin", "mybin"),
   102  				Type:   artifact.Binary,
   103  				Extra: map[string]interface{}{
   104  					"Binary": "bin/mybin",
   105  					"ID":     "default",
   106  				},
   107  			}
   108  			var linuxMipsBuild = &artifact.Artifact{
   109  				Goos:   "linux",
   110  				Goarch: "mips",
   111  				Gomips: "softfloat",
   112  				Name:   "bin/mybin",
   113  				Path:   filepath.Join(dist, "linuxmipssoftfloat", "bin", "mybin"),
   114  				Type:   artifact.Binary,
   115  				Extra: map[string]interface{}{
   116  					"Binary": "mybin",
   117  					"ID":     "default",
   118  				},
   119  			}
   120  			var windowsBuild = &artifact.Artifact{
   121  				Goos:   "windows",
   122  				Goarch: "amd64",
   123  				Name:   "bin/mybin.exe",
   124  				Path:   filepath.Join(dist, "windowsamd64", "bin", "mybin.exe"),
   125  				Type:   artifact.Binary,
   126  				Extra: map[string]interface{}{
   127  					"Binary":    "mybin",
   128  					"Extension": ".exe",
   129  					"ID":        "default",
   130  				},
   131  			}
   132  			ctx.Artifacts.Add(darwinBuild)
   133  			ctx.Artifacts.Add(linux386Build)
   134  			ctx.Artifacts.Add(linuxArmBuild)
   135  			ctx.Artifacts.Add(linuxMipsBuild)
   136  			ctx.Artifacts.Add(windowsBuild)
   137  			ctx.Version = "0.0.1"
   138  			ctx.Git.CurrentTag = "v0.0.1"
   139  			ctx.Config.Archives[0].Format = format
   140  			require.NoError(t, Pipe{}.Run(ctx))
   141  			var archives = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableArchive)).List()
   142  			for _, arch := range archives {
   143  				require.Equal(t, "myid", arch.Extra["ID"].(string), "all archives should have the archive ID set")
   144  			}
   145  			require.Len(t, archives, 5)
   146  			// TODO: should verify the artifact fields here too
   147  
   148  			if format == "tar.gz" {
   149  				// Check archive contents
   150  				for name, os := range map[string]string{
   151  					"foobar_0.0.1_darwin_amd64.tar.gz":         "darwin",
   152  					"foobar_0.0.1_linux_386.tar.gz":            "linux",
   153  					"foobar_0.0.1_linux_armv7.tar.gz":          "linux",
   154  					"foobar_0.0.1_linux_mips_softfloat.tar.gz": "linux",
   155  				} {
   156  					require.Equal(
   157  						t,
   158  						[]string{
   159  							fmt.Sprintf("README.%s.md", os),
   160  							"foo/bar/foobar/blah.txt",
   161  							"bin/mybin",
   162  						},
   163  						tarFiles(t, filepath.Join(dist, name)),
   164  					)
   165  				}
   166  			}
   167  			if format == "zip" {
   168  				require.Equal(
   169  					t,
   170  					[]string{
   171  						"README.windows.md",
   172  						"foo/bar/foobar/blah.txt",
   173  						"bin/mybin.exe",
   174  					},
   175  					zipFiles(t, filepath.Join(dist, "foobar_0.0.1_windows_amd64.zip")),
   176  				)
   177  			}
   178  		})
   179  	}
   180  }
   181  
   182  func TestRunPipeDifferentBinaryCount(t *testing.T) {
   183  	var folder = testlib.Mktmp(t)
   184  	var dist = filepath.Join(folder, "dist")
   185  	require.NoError(t, os.Mkdir(dist, 0755))
   186  	for _, arch := range []string{"darwinamd64", "linuxamd64"} {
   187  		createFakeBinary(t, dist, arch, "bin/mybin")
   188  	}
   189  	createFakeBinary(t, dist, "darwinamd64", "bin/foobar")
   190  	var ctx = context.New(config.Project{
   191  		Dist:        dist,
   192  		ProjectName: "foobar",
   193  		Archives: []config.Archive{
   194  			{
   195  				ID:           "myid",
   196  				Format:       "tar.gz",
   197  				Builds:       []string{"default", "foobar"},
   198  				NameTemplate: defaultNameTemplate,
   199  			},
   200  		},
   201  	})
   202  	var darwinBuild = &artifact.Artifact{
   203  		Goos:   "darwin",
   204  		Goarch: "amd64",
   205  		Name:   "bin/mybin",
   206  		Path:   filepath.Join(dist, "darwinamd64", "bin", "mybin"),
   207  		Type:   artifact.Binary,
   208  		Extra: map[string]interface{}{
   209  			"Binary": "bin/mybin",
   210  			"ID":     "default",
   211  		},
   212  	}
   213  	var darwinBuild2 = &artifact.Artifact{
   214  		Goos:   "darwin",
   215  		Goarch: "amd64",
   216  		Name:   "bin/foobar",
   217  		Path:   filepath.Join(dist, "darwinamd64", "bin", "foobar"),
   218  		Type:   artifact.Binary,
   219  		Extra: map[string]interface{}{
   220  			"Binary": "bin/foobar",
   221  			"ID":     "foobar",
   222  		},
   223  	}
   224  	var linuxArmBuild = &artifact.Artifact{
   225  		Goos:   "linux",
   226  		Goarch: "amd64",
   227  		Name:   "bin/mybin",
   228  		Path:   filepath.Join(dist, "linuxamd64", "bin", "mybin"),
   229  		Type:   artifact.Binary,
   230  		Extra: map[string]interface{}{
   231  			"Binary": "bin/mybin",
   232  			"ID":     "default",
   233  		},
   234  	}
   235  
   236  	ctx.Artifacts.Add(darwinBuild)
   237  	ctx.Artifacts.Add(darwinBuild2)
   238  	ctx.Artifacts.Add(linuxArmBuild)
   239  	ctx.Version = "0.0.1"
   240  	ctx.Git.CurrentTag = "v0.0.1"
   241  
   242  	t.Run("check enabled", func(t *testing.T) {
   243  		ctx.Config.Archives[0].AllowDifferentBinaryCount = false
   244  		require.EqualError(t, Pipe{}.Run(ctx), "invalid archive: 0: "+ErrArchiveDifferentBinaryCount.Error())
   245  	})
   246  
   247  	t.Run("check disabled", func(t *testing.T) {
   248  		ctx.Config.Archives[0].AllowDifferentBinaryCount = true
   249  		require.NoError(t, Pipe{}.Run(ctx))
   250  	})
   251  }
   252  
   253  func TestRunPipeNoBinaries(t *testing.T) {
   254  	var folder = testlib.Mktmp(t)
   255  	var dist = filepath.Join(folder, "dist")
   256  	require.NoError(t, os.Mkdir(dist, 0755))
   257  	var ctx = context.New(config.Project{
   258  		Dist:        dist,
   259  		ProjectName: "foobar",
   260  		Archives:    []config.Archive{{}},
   261  	})
   262  	ctx.Version = "0.0.1"
   263  	ctx.Git.CurrentTag = "v0.0.1"
   264  	require.NoError(t, Pipe{}.Run(ctx))
   265  }
   266  
   267  func zipFiles(t *testing.T, path string) []string {
   268  	t.Helper()
   269  	f, err := os.Open(path)
   270  	require.NoError(t, err)
   271  	info, err := f.Stat()
   272  	require.NoError(t, err)
   273  	r, err := zip.NewReader(f, info.Size())
   274  	require.NoError(t, err)
   275  	var paths = make([]string, len(r.File))
   276  	for i, zf := range r.File {
   277  		paths[i] = zf.Name
   278  	}
   279  	return paths
   280  }
   281  
   282  func tarFiles(t *testing.T, path string) []string {
   283  	t.Helper()
   284  	f, err := os.Open(path)
   285  	require.NoError(t, err)
   286  	defer f.Close()
   287  	gr, err := gzip.NewReader(f)
   288  	require.NoError(t, err)
   289  	defer gr.Close()
   290  	var r = tar.NewReader(gr)
   291  	var paths []string
   292  	for {
   293  		next, err := r.Next()
   294  		if err == io.EOF {
   295  			break
   296  		}
   297  		require.NoError(t, err)
   298  		paths = append(paths, next.Name)
   299  	}
   300  	return paths
   301  }
   302  
   303  func TestRunPipeBinary(t *testing.T) {
   304  	var folder = testlib.Mktmp(t)
   305  	var dist = filepath.Join(folder, "dist")
   306  	require.NoError(t, os.Mkdir(dist, 0755))
   307  	require.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   308  	require.NoError(t, os.Mkdir(filepath.Join(dist, "windowsamd64"), 0755))
   309  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   310  	require.NoError(t, err)
   311  	_, err = os.Create(filepath.Join(dist, "windowsamd64", "mybin.exe"))
   312  	require.NoError(t, err)
   313  	_, err = os.Create(filepath.Join(folder, "README.md"))
   314  	require.NoError(t, err)
   315  	var ctx = context.New(
   316  		config.Project{
   317  			Dist: dist,
   318  			Archives: []config.Archive{
   319  				{
   320  					Format:       "binary",
   321  					NameTemplate: defaultBinaryNameTemplate,
   322  					Builds:       []string{"default"},
   323  				},
   324  			},
   325  		},
   326  	)
   327  	ctx.Version = "0.0.1"
   328  	ctx.Git.CurrentTag = "v0.0.1"
   329  	ctx.Artifacts.Add(&artifact.Artifact{
   330  		Goos:   "darwin",
   331  		Goarch: "amd64",
   332  		Name:   "mybin",
   333  		Path:   filepath.Join(dist, "darwinamd64", "mybin"),
   334  		Type:   artifact.Binary,
   335  		Extra: map[string]interface{}{
   336  			"Binary": "mybin",
   337  			"ID":     "default",
   338  		},
   339  	})
   340  	ctx.Artifacts.Add(&artifact.Artifact{
   341  		Goos:   "windows",
   342  		Goarch: "amd64",
   343  		Name:   "mybin.exe",
   344  		Path:   filepath.Join(dist, "windowsamd64", "mybin.exe"),
   345  		Type:   artifact.Binary,
   346  		Extra: map[string]interface{}{
   347  			"Binary": "mybin",
   348  			"Ext":    ".exe",
   349  			"ID":     "default",
   350  		},
   351  	})
   352  	require.NoError(t, Pipe{}.Run(ctx))
   353  	var binaries = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableBinary))
   354  	darwin := binaries.Filter(artifact.ByGoos("darwin")).List()[0]
   355  	windows := binaries.Filter(artifact.ByGoos("windows")).List()[0]
   356  	require.Equal(t, "mybin_0.0.1_darwin_amd64", darwin.Name)
   357  	require.Equal(t, "mybin_0.0.1_windows_amd64.exe", windows.Name)
   358  	require.Len(t, binaries.List(), 2)
   359  }
   360  
   361  func TestRunPipeDistRemoved(t *testing.T) {
   362  	var ctx = context.New(
   363  		config.Project{
   364  			Dist: "/tmp/path/to/nope",
   365  			Archives: []config.Archive{
   366  				{
   367  					NameTemplate: "nope",
   368  					Format:       "zip",
   369  					Builds:       []string{"default"},
   370  				},
   371  			},
   372  		},
   373  	)
   374  	ctx.Git.CurrentTag = "v0.0.1"
   375  	ctx.Artifacts.Add(&artifact.Artifact{
   376  		Goos:   "windows",
   377  		Goarch: "amd64",
   378  		Name:   "mybin.exe",
   379  		Path:   filepath.Join("/tmp/path/to/nope", "windowsamd64", "mybin.exe"),
   380  		Type:   artifact.Binary,
   381  		Extra: map[string]interface{}{
   382  			"Binary":    "mybin",
   383  			"Extension": ".exe",
   384  			"ID":        "default",
   385  		},
   386  	})
   387  	// not checking on error msg because it may change depending on OS/version
   388  	require.Error(t, Pipe{}.Run(ctx))
   389  }
   390  
   391  func TestRunPipeInvalidGlob(t *testing.T) {
   392  	var folder = testlib.Mktmp(t)
   393  	var dist = filepath.Join(folder, "dist")
   394  	require.NoError(t, os.Mkdir(dist, 0755))
   395  	require.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   396  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   397  	require.NoError(t, err)
   398  	var ctx = context.New(
   399  		config.Project{
   400  			Dist: dist,
   401  			Archives: []config.Archive{
   402  				{
   403  					Builds:       []string{"default"},
   404  					NameTemplate: "foo",
   405  					Format:       "zip",
   406  					Files: []string{
   407  						"[x-]",
   408  					},
   409  				},
   410  			},
   411  		},
   412  	)
   413  	ctx.Git.CurrentTag = "v0.0.1"
   414  	ctx.Artifacts.Add(&artifact.Artifact{
   415  		Goos:   "darwin",
   416  		Goarch: "amd64",
   417  		Name:   "mybin",
   418  		Path:   filepath.Join("dist", "darwinamd64", "mybin"),
   419  		Type:   artifact.Binary,
   420  		Extra: map[string]interface{}{
   421  			"Binary": "mybin",
   422  			"ID":     "default",
   423  		},
   424  	})
   425  	require.EqualError(t, Pipe{}.Run(ctx), `failed to find files to archive: globbing failed for pattern [x-]: compile glob pattern: unexpected end of input`)
   426  }
   427  
   428  func TestRunPipeInvalidNameTemplate(t *testing.T) {
   429  	var folder = testlib.Mktmp(t)
   430  	var dist = filepath.Join(folder, "dist")
   431  	require.NoError(t, os.Mkdir(dist, 0755))
   432  	require.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   433  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   434  	require.NoError(t, err)
   435  	var ctx = context.New(
   436  		config.Project{
   437  			Dist: dist,
   438  			Archives: []config.Archive{
   439  				{
   440  					Builds:       []string{"default"},
   441  					NameTemplate: "foo{{ .fff }",
   442  					Format:       "zip",
   443  				},
   444  			},
   445  		},
   446  	)
   447  	ctx.Git.CurrentTag = "v0.0.1"
   448  	ctx.Artifacts.Add(&artifact.Artifact{
   449  		Goos:   "darwin",
   450  		Goarch: "amd64",
   451  		Name:   "mybin",
   452  		Path:   filepath.Join("dist", "darwinamd64", "mybin"),
   453  		Type:   artifact.Binary,
   454  		Extra: map[string]interface{}{
   455  			"Binary": "mybin",
   456  			"ID":     "default",
   457  		},
   458  	})
   459  	require.EqualError(t, Pipe{}.Run(ctx), `template: tmpl:1: unexpected "}" in operand`)
   460  }
   461  
   462  func TestRunPipeInvalidFilesNameTemplate(t *testing.T) {
   463  	var folder = testlib.Mktmp(t)
   464  	var dist = filepath.Join(folder, "dist")
   465  	require.NoError(t, os.Mkdir(dist, 0755))
   466  	require.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   467  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   468  	require.NoError(t, err)
   469  	var ctx = context.New(
   470  		config.Project{
   471  			Dist: dist,
   472  			Archives: []config.Archive{
   473  				{
   474  					Builds:       []string{"default"},
   475  					NameTemplate: "foo",
   476  					Format:       "zip",
   477  					Files: []string{
   478  						"{{.asdsd}",
   479  					},
   480  				},
   481  			},
   482  		},
   483  	)
   484  	ctx.Git.CurrentTag = "v0.0.1"
   485  	ctx.Artifacts.Add(&artifact.Artifact{
   486  		Goos:   "darwin",
   487  		Goarch: "amd64",
   488  		Name:   "mybin",
   489  		Path:   filepath.Join("dist", "darwinamd64", "mybin"),
   490  		Type:   artifact.Binary,
   491  		Extra: map[string]interface{}{
   492  			"Binary": "mybin",
   493  			"ID":     "default",
   494  		},
   495  	})
   496  	require.EqualError(t, Pipe{}.Run(ctx), `failed to find files to archive: failed to apply template {{.asdsd}: template: tmpl:1: unexpected "}" in operand`)
   497  }
   498  
   499  func TestRunPipeInvalidWrapInDirectoryTemplate(t *testing.T) {
   500  	var folder = testlib.Mktmp(t)
   501  	var dist = filepath.Join(folder, "dist")
   502  	require.NoError(t, os.Mkdir(dist, 0755))
   503  	require.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   504  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   505  	require.NoError(t, err)
   506  	var ctx = context.New(
   507  		config.Project{
   508  			Dist: dist,
   509  			Archives: []config.Archive{
   510  				{
   511  					Builds:          []string{"default"},
   512  					NameTemplate:    "foo",
   513  					WrapInDirectory: "foo{{ .fff }",
   514  					Format:          "zip",
   515  				},
   516  			},
   517  		},
   518  	)
   519  	ctx.Git.CurrentTag = "v0.0.1"
   520  	ctx.Artifacts.Add(&artifact.Artifact{
   521  		Goos:   "darwin",
   522  		Goarch: "amd64",
   523  		Name:   "mybin",
   524  		Path:   filepath.Join("dist", "darwinamd64", "mybin"),
   525  		Type:   artifact.Binary,
   526  		Extra: map[string]interface{}{
   527  			"Binary": "mybin",
   528  			"ID":     "default",
   529  		},
   530  	})
   531  	require.EqualError(t, Pipe{}.Run(ctx), `template: tmpl:1: unexpected "}" in operand`)
   532  }
   533  
   534  func TestRunPipeWrap(t *testing.T) {
   535  	var folder = testlib.Mktmp(t)
   536  	var dist = filepath.Join(folder, "dist")
   537  	require.NoError(t, os.Mkdir(dist, 0755))
   538  	require.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   539  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   540  	require.NoError(t, err)
   541  	_, err = os.Create(filepath.Join(folder, "README.md"))
   542  	require.NoError(t, err)
   543  	var ctx = context.New(
   544  		config.Project{
   545  			Dist: dist,
   546  			Archives: []config.Archive{
   547  				{
   548  					Builds:          []string{"default"},
   549  					NameTemplate:    "foo",
   550  					WrapInDirectory: "foo_{{ .Os }}",
   551  					Format:          "tar.gz",
   552  					Replacements: map[string]string{
   553  						"darwin": "macOS",
   554  					},
   555  					Files: []string{
   556  						"README.*",
   557  					},
   558  				},
   559  			},
   560  		},
   561  	)
   562  	ctx.Git.CurrentTag = "v0.0.1"
   563  	ctx.Artifacts.Add(&artifact.Artifact{
   564  		Goos:   "darwin",
   565  		Goarch: "amd64",
   566  		Name:   "mybin",
   567  		Path:   filepath.Join("dist", "darwinamd64", "mybin"),
   568  		Type:   artifact.Binary,
   569  		Extra: map[string]interface{}{
   570  			"Binary": "mybin",
   571  			"ID":     "default",
   572  		},
   573  	})
   574  	require.NoError(t, Pipe{}.Run(ctx))
   575  
   576  	var archives = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableArchive)).List()
   577  	require.Len(t, archives, 1)
   578  	require.Equal(t, "foo_macOS", archives[0].ExtraOr("WrappedIn", ""))
   579  
   580  	// Check archive contents
   581  	f, err := os.Open(filepath.Join(dist, "foo.tar.gz"))
   582  	require.NoError(t, err)
   583  	defer func() { require.NoError(t, f.Close()) }()
   584  	gr, err := gzip.NewReader(f)
   585  	require.NoError(t, err)
   586  	defer func() { require.NoError(t, gr.Close()) }()
   587  	r := tar.NewReader(gr)
   588  	for _, n := range []string{"README.md", "mybin"} {
   589  		h, err := r.Next()
   590  		if err == io.EOF {
   591  			break
   592  		}
   593  		require.NoError(t, err)
   594  		require.Equal(t, filepath.Join("foo_macOS", n), h.Name)
   595  	}
   596  }
   597  
   598  func TestDefault(t *testing.T) {
   599  	var ctx = &context.Context{
   600  		Config: config.Project{
   601  			Archives: []config.Archive{},
   602  		},
   603  	}
   604  	require.NoError(t, Pipe{}.Default(ctx))
   605  	require.NotEmpty(t, ctx.Config.Archives[0].NameTemplate)
   606  	require.Equal(t, "tar.gz", ctx.Config.Archives[0].Format)
   607  	require.NotEmpty(t, ctx.Config.Archives[0].Files)
   608  }
   609  
   610  func TestDefaultSet(t *testing.T) {
   611  	var ctx = &context.Context{
   612  		Config: config.Project{
   613  			Archives: []config.Archive{
   614  				{
   615  					Builds:       []string{"default"},
   616  					NameTemplate: "foo",
   617  					Format:       "zip",
   618  					Files: []string{
   619  						"foo",
   620  					},
   621  				},
   622  			},
   623  		},
   624  	}
   625  	require.NoError(t, Pipe{}.Default(ctx))
   626  	require.Equal(t, "foo", ctx.Config.Archives[0].NameTemplate)
   627  	require.Equal(t, "zip", ctx.Config.Archives[0].Format)
   628  	require.Equal(t, "foo", ctx.Config.Archives[0].Files[0])
   629  }
   630  
   631  func TestDefaultFormatBinary(t *testing.T) {
   632  	var ctx = &context.Context{
   633  		Config: config.Project{
   634  			Archives: []config.Archive{
   635  				{
   636  					Format: "binary",
   637  				},
   638  			},
   639  		},
   640  	}
   641  	require.NoError(t, Pipe{}.Default(ctx))
   642  	require.Equal(t, defaultBinaryNameTemplate, ctx.Config.Archives[0].NameTemplate)
   643  }
   644  
   645  func TestFormatFor(t *testing.T) {
   646  	var ctx = &context.Context{
   647  		Config: config.Project{
   648  			Archives: []config.Archive{
   649  				{
   650  					Builds: []string{"default"},
   651  					Format: "tar.gz",
   652  					FormatOverrides: []config.FormatOverride{
   653  						{
   654  							Goos:   "windows",
   655  							Format: "zip",
   656  						},
   657  					},
   658  				},
   659  			},
   660  		},
   661  	}
   662  	require.Equal(t, "zip", packageFormat(ctx.Config.Archives[0], "windows"))
   663  	require.Equal(t, "tar.gz", packageFormat(ctx.Config.Archives[0], "linux"))
   664  }
   665  
   666  func TestBinaryOverride(t *testing.T) {
   667  	var folder = testlib.Mktmp(t)
   668  	var dist = filepath.Join(folder, "dist")
   669  	require.NoError(t, os.Mkdir(dist, 0755))
   670  	require.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   671  	require.NoError(t, os.Mkdir(filepath.Join(dist, "windowsamd64"), 0755))
   672  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   673  	require.NoError(t, err)
   674  	_, err = os.Create(filepath.Join(dist, "windowsamd64", "mybin.exe"))
   675  	require.NoError(t, err)
   676  	_, err = os.Create(filepath.Join(folder, "README.md"))
   677  	require.NoError(t, err)
   678  	for _, format := range []string{"tar.gz", "zip"} {
   679  		t.Run("Archive format "+format, func(t *testing.T) {
   680  			var ctx = context.New(
   681  				config.Project{
   682  					Dist:        dist,
   683  					ProjectName: "foobar",
   684  					Archives: []config.Archive{
   685  						{
   686  							Builds:       []string{"default"},
   687  							NameTemplate: defaultNameTemplate,
   688  							Files: []string{
   689  								"README.*",
   690  							},
   691  							FormatOverrides: []config.FormatOverride{
   692  								{
   693  									Goos:   "windows",
   694  									Format: "binary",
   695  								},
   696  							},
   697  						},
   698  					},
   699  				},
   700  			)
   701  			ctx.Git.CurrentTag = "v0.0.1"
   702  			ctx.Artifacts.Add(&artifact.Artifact{
   703  				Goos:   "darwin",
   704  				Goarch: "amd64",
   705  				Name:   "mybin",
   706  				Path:   filepath.Join(dist, "darwinamd64", "mybin"),
   707  				Type:   artifact.Binary,
   708  				Extra: map[string]interface{}{
   709  					"Binary": "mybin",
   710  					"ID":     "default",
   711  				},
   712  			})
   713  			ctx.Artifacts.Add(&artifact.Artifact{
   714  				Goos:   "windows",
   715  				Goarch: "amd64",
   716  				Name:   "mybin.exe",
   717  				Path:   filepath.Join(dist, "windowsamd64", "mybin.exe"),
   718  				Type:   artifact.Binary,
   719  				Extra: map[string]interface{}{
   720  					"Binary": "mybin",
   721  					"Ext":    ".exe",
   722  					"ID":     "default",
   723  				},
   724  			})
   725  			ctx.Version = "0.0.1"
   726  			ctx.Config.Archives[0].Format = format
   727  
   728  			require.NoError(t, Pipe{}.Run(ctx))
   729  			var archives = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableArchive))
   730  			darwin := archives.Filter(artifact.ByGoos("darwin")).List()[0]
   731  			require.Equal(t, "foobar_0.0.1_darwin_amd64."+format, darwin.Name)
   732  			require.Equal(t, format, darwin.ExtraOr("Format", ""))
   733  			require.Empty(t, darwin.ExtraOr("WrappedIn", ""))
   734  
   735  			archives = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableBinary))
   736  			windows := archives.Filter(artifact.ByGoos("windows")).List()[0]
   737  			require.Equal(t, "foobar_0.0.1_windows_amd64.exe", windows.Name)
   738  			require.Empty(t, windows.ExtraOr("WrappedIn", ""))
   739  		})
   740  	}
   741  }
   742  
   743  func TestRunPipeSameArchiveFilename(t *testing.T) {
   744  	var folder = testlib.Mktmp(t)
   745  	var dist = filepath.Join(folder, "dist")
   746  	require.NoError(t, os.Mkdir(dist, 0755))
   747  	require.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   748  	require.NoError(t, os.Mkdir(filepath.Join(dist, "windowsamd64"), 0755))
   749  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   750  	require.NoError(t, err)
   751  	_, err = os.Create(filepath.Join(dist, "windowsamd64", "mybin.exe"))
   752  	require.NoError(t, err)
   753  	var ctx = context.New(
   754  		config.Project{
   755  			Dist:        dist,
   756  			ProjectName: "foobar",
   757  			Archives: []config.Archive{
   758  				{
   759  					Builds:       []string{"default"},
   760  					NameTemplate: "same-filename",
   761  					Files: []string{
   762  						"README.*",
   763  						"./foo/**/*",
   764  					},
   765  					Format: "tar.gz",
   766  				},
   767  			},
   768  		},
   769  	)
   770  	ctx.Artifacts.Add(&artifact.Artifact{
   771  		Goos:   "darwin",
   772  		Goarch: "amd64",
   773  		Name:   "mybin",
   774  		Path:   filepath.Join(dist, "darwinamd64", "mybin"),
   775  		Type:   artifact.Binary,
   776  		Extra: map[string]interface{}{
   777  			"Binary": "mybin",
   778  			"ID":     "default",
   779  		},
   780  	})
   781  	ctx.Artifacts.Add(&artifact.Artifact{
   782  		Goos:   "windows",
   783  		Goarch: "amd64",
   784  		Name:   "mybin.exe",
   785  		Path:   filepath.Join(dist, "windowsamd64", "mybin.exe"),
   786  		Type:   artifact.Binary,
   787  		Extra: map[string]interface{}{
   788  			"Binary":    "mybin",
   789  			"Extension": ".exe",
   790  			"ID":        "default",
   791  		},
   792  	})
   793  	ctx.Version = "0.0.1"
   794  	ctx.Git.CurrentTag = "v0.0.1"
   795  	err = Pipe{}.Run(ctx)
   796  	require.Error(t, err)
   797  	require.Contains(t, err.Error(), "same-filename.tar.gz already exists. Check your archive name template")
   798  }
   799  
   800  func TestDuplicateFilesInsideArchive(t *testing.T) {
   801  	var folder = t.TempDir()
   802  
   803  	f, err := ioutil.TempFile(folder, "")
   804  	require.NoError(t, err)
   805  	defer f.Close()
   806  
   807  	ff, err := ioutil.TempFile(folder, "")
   808  	require.NoError(t, err)
   809  	defer ff.Close()
   810  
   811  	a := NewEnhancedArchive(archive.New(f), "")
   812  	defer a.Close()
   813  
   814  	require.NoError(t, a.Add("foo", ff.Name()))
   815  	require.EqualError(t, a.Add("foo", ff.Name()), "file foo already exists in the archive")
   816  }
   817  
   818  func TestWrapInDirectory(t *testing.T) {
   819  	t.Run("false", func(t *testing.T) {
   820  		require.Equal(t, "", wrapFolder(config.Archive{
   821  			WrapInDirectory: "false",
   822  		}))
   823  	})
   824  	t.Run("true", func(t *testing.T) {
   825  		require.Equal(t, "foo", wrapFolder(config.Archive{
   826  			WrapInDirectory: "true",
   827  			NameTemplate:    "foo",
   828  		}))
   829  	})
   830  	t.Run("custom", func(t *testing.T) {
   831  		require.Equal(t, "foobar", wrapFolder(config.Archive{
   832  			WrapInDirectory: "foobar",
   833  		}))
   834  	})
   835  }
   836  
   837  func TestSeveralArchivesWithTheSameID(t *testing.T) {
   838  	var ctx = &context.Context{
   839  		Config: config.Project{
   840  			Archives: []config.Archive{
   841  				{
   842  					ID: "a",
   843  				},
   844  				{
   845  					ID: "a",
   846  				},
   847  			},
   848  		},
   849  	}
   850  	require.EqualError(t, Pipe{}.Default(ctx), "found 2 archives with the ID 'a', please fix your config")
   851  }