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