github.phpd.cn/goreleaser/goreleaser@v0.92.0/internal/pipe/archive/archive_test.go (about)

     1  package archive
     2  
     3  import (
     4  	"archive/tar"
     5  	"archive/zip"
     6  	"compress/gzip"
     7  	"io"
     8  	"os"
     9  	"path/filepath"
    10  	"testing"
    11  
    12  	"github.com/goreleaser/goreleaser/internal/artifact"
    13  	"github.com/goreleaser/goreleaser/internal/testlib"
    14  	"github.com/goreleaser/goreleaser/pkg/config"
    15  	"github.com/goreleaser/goreleaser/pkg/context"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  func TestDescription(t *testing.T) {
    21  	assert.NotEmpty(t, Pipe{}.String())
    22  }
    23  
    24  func TestRunPipe(t *testing.T) {
    25  	folder, back := testlib.Mktmp(t)
    26  	defer back()
    27  	var dist = filepath.Join(folder, "dist")
    28  	assert.NoError(t, os.Mkdir(dist, 0755))
    29  	assert.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
    30  	assert.NoError(t, os.Mkdir(filepath.Join(dist, "windowsamd64"), 0755))
    31  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
    32  	assert.NoError(t, err)
    33  	_, err = os.Create(filepath.Join(dist, "windowsamd64", "mybin.exe"))
    34  	assert.NoError(t, err)
    35  	_, err = os.Create(filepath.Join(folder, "README.md"))
    36  	assert.NoError(t, err)
    37  	assert.NoError(t, os.MkdirAll(filepath.Join(folder, "foo", "bar", "foobar"), 0755))
    38  	_, err = os.Create(filepath.Join(filepath.Join(folder, "foo", "bar", "foobar", "blah.txt")))
    39  	assert.NoError(t, err)
    40  	for _, format := range []string{"tar.gz", "zip"} {
    41  		t.Run("Archive format "+format, func(tt *testing.T) {
    42  			var ctx = context.New(
    43  				config.Project{
    44  					Dist:        dist,
    45  					ProjectName: "foobar",
    46  					Archive: config.Archive{
    47  						NameTemplate: defaultNameTemplate,
    48  						Files: []string{
    49  							"README.*",
    50  							"./foo/**/*",
    51  						},
    52  						FormatOverrides: []config.FormatOverride{
    53  							{
    54  								Goos:   "windows",
    55  								Format: "zip",
    56  							},
    57  						},
    58  					},
    59  				},
    60  			)
    61  			ctx.Artifacts.Add(artifact.Artifact{
    62  				Goos:   "darwin",
    63  				Goarch: "amd64",
    64  				Name:   "mybin",
    65  				Path:   filepath.Join(dist, "darwinamd64", "mybin"),
    66  				Type:   artifact.Binary,
    67  				Extra: map[string]string{
    68  					"Binary": "mybin",
    69  				},
    70  			})
    71  			ctx.Artifacts.Add(artifact.Artifact{
    72  				Goos:   "windows",
    73  				Goarch: "amd64",
    74  				Name:   "mybin.exe",
    75  				Path:   filepath.Join(dist, "windowsamd64", "mybin.exe"),
    76  				Type:   artifact.Binary,
    77  				Extra: map[string]string{
    78  					"Binary":    "mybin",
    79  					"Extension": ".exe",
    80  				},
    81  			})
    82  			ctx.Version = "0.0.1"
    83  			ctx.Git.CurrentTag = "v0.0.1"
    84  			ctx.Config.Archive.Format = format
    85  			assert.NoError(tt, Pipe{}.Run(ctx))
    86  			var archives = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableArchive))
    87  			require.Len(tt, archives.List(), 2)
    88  			darwin := archives.Filter(artifact.ByGoos("darwin")).List()[0]
    89  			windows := archives.Filter(artifact.ByGoos("windows")).List()[0]
    90  			assert.Equal(tt, "foobar_0.0.1_darwin_amd64."+format, darwin.Name)
    91  			assert.Equal(tt, "foobar_0.0.1_windows_amd64.zip", windows.Name)
    92  		})
    93  	}
    94  
    95  	// Check archive contents
    96  	assert.Equal(
    97  		t,
    98  		[]string{
    99  			"README.md",
   100  			"foo/bar",
   101  			"foo/bar/foobar",
   102  			"foo/bar/foobar/blah.txt",
   103  			"mybin",
   104  		},
   105  		tarFiles(t, filepath.Join(dist, "foobar_0.0.1_darwin_amd64.tar.gz")),
   106  	)
   107  	assert.Equal(
   108  		t,
   109  		[]string{
   110  			"README.md",
   111  			"foo/bar/foobar/blah.txt",
   112  			"mybin.exe",
   113  		},
   114  		zipFiles(t, filepath.Join(dist, "foobar_0.0.1_windows_amd64.zip")),
   115  	)
   116  }
   117  
   118  func zipFiles(t *testing.T, path string) []string {
   119  	f, err := os.Open(path)
   120  	require.NoError(t, err)
   121  	info, err := f.Stat()
   122  	require.NoError(t, err)
   123  	r, err := zip.NewReader(f, info.Size())
   124  	require.NoError(t, err)
   125  	var paths = make([]string, len(r.File))
   126  	for i, zf := range r.File {
   127  		paths[i] = zf.Name
   128  	}
   129  	return paths
   130  }
   131  
   132  func tarFiles(t *testing.T, path string) []string {
   133  	f, err := os.Open(path)
   134  	require.NoError(t, err)
   135  	defer f.Close()
   136  	gr, err := gzip.NewReader(f)
   137  	require.NoError(t, err)
   138  	defer gr.Close()
   139  	var r = tar.NewReader(gr)
   140  	var paths []string
   141  	for {
   142  		next, err := r.Next()
   143  		if err == io.EOF {
   144  			break
   145  		}
   146  		require.NoError(t, err)
   147  		paths = append(paths, next.Name)
   148  	}
   149  	return paths
   150  }
   151  
   152  func TestRunPipeBinary(t *testing.T) {
   153  	folder, back := testlib.Mktmp(t)
   154  	defer back()
   155  	var dist = filepath.Join(folder, "dist")
   156  	assert.NoError(t, os.Mkdir(dist, 0755))
   157  	assert.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   158  	assert.NoError(t, os.Mkdir(filepath.Join(dist, "windowsamd64"), 0755))
   159  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   160  	assert.NoError(t, err)
   161  	_, err = os.Create(filepath.Join(dist, "windowsamd64", "mybin.exe"))
   162  	assert.NoError(t, err)
   163  	_, err = os.Create(filepath.Join(folder, "README.md"))
   164  	assert.NoError(t, err)
   165  	var ctx = context.New(
   166  		config.Project{
   167  			Dist: dist,
   168  			Archive: config.Archive{
   169  				Format:       "binary",
   170  				NameTemplate: defaultBinaryNameTemplate,
   171  			},
   172  		},
   173  	)
   174  	ctx.Version = "0.0.1"
   175  	ctx.Git.CurrentTag = "v0.0.1"
   176  	ctx.Artifacts.Add(artifact.Artifact{
   177  		Goos:   "darwin",
   178  		Goarch: "amd64",
   179  		Name:   "mybin",
   180  		Path:   filepath.Join(dist, "darwinamd64", "mybin"),
   181  		Type:   artifact.Binary,
   182  		Extra: map[string]string{
   183  			"Binary": "mybin",
   184  		},
   185  	})
   186  	ctx.Artifacts.Add(artifact.Artifact{
   187  		Goos:   "windows",
   188  		Goarch: "amd64",
   189  		Name:   "mybin.exe",
   190  		Path:   filepath.Join(dist, "windowsamd64", "mybin.exe"),
   191  		Type:   artifact.Binary,
   192  		Extra: map[string]string{
   193  			"Binary": "mybin",
   194  			"Ext":    ".exe",
   195  		},
   196  	})
   197  	assert.NoError(t, Pipe{}.Run(ctx))
   198  	var binaries = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableBinary))
   199  	darwin := binaries.Filter(artifact.ByGoos("darwin")).List()[0]
   200  	windows := binaries.Filter(artifact.ByGoos("windows")).List()[0]
   201  	assert.Equal(t, "mybin_0.0.1_darwin_amd64", darwin.Name)
   202  	assert.Equal(t, "mybin_0.0.1_windows_amd64.exe", windows.Name)
   203  	assert.Len(t, binaries.List(), 2)
   204  }
   205  
   206  func TestRunPipeDistRemoved(t *testing.T) {
   207  	var ctx = context.New(
   208  		config.Project{
   209  			Dist: "/path/nope",
   210  			Archive: config.Archive{
   211  				NameTemplate: "nope",
   212  				Format:       "zip",
   213  			},
   214  		},
   215  	)
   216  	ctx.Git.CurrentTag = "v0.0.1"
   217  	ctx.Artifacts.Add(artifact.Artifact{
   218  		Goos:   "windows",
   219  		Goarch: "amd64",
   220  		Name:   "mybin.exe",
   221  		Path:   filepath.Join("/path/to/nope", "windowsamd64", "mybin.exe"),
   222  		Type:   artifact.Binary,
   223  		Extra: map[string]string{
   224  			"Binary":    "mybin",
   225  			"Extension": ".exe",
   226  		},
   227  	})
   228  	assert.EqualError(t, Pipe{}.Run(ctx), `failed to create directory /path/nope/nope.zip: open /path/nope/nope.zip: no such file or directory`)
   229  }
   230  
   231  func TestRunPipeInvalidGlob(t *testing.T) {
   232  	folder, back := testlib.Mktmp(t)
   233  	defer back()
   234  	var dist = filepath.Join(folder, "dist")
   235  	assert.NoError(t, os.Mkdir(dist, 0755))
   236  	assert.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   237  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   238  	assert.NoError(t, err)
   239  	var ctx = context.New(
   240  		config.Project{
   241  			Dist: dist,
   242  			Archive: config.Archive{
   243  				NameTemplate: "foo",
   244  				Format:       "zip",
   245  				Files: []string{
   246  					"[x-]",
   247  				},
   248  			},
   249  		},
   250  	)
   251  	ctx.Git.CurrentTag = "v0.0.1"
   252  	ctx.Artifacts.Add(artifact.Artifact{
   253  		Goos:   "darwin",
   254  		Goarch: "amd64",
   255  		Name:   "mybin",
   256  		Path:   filepath.Join("dist", "darwinamd64", "mybin"),
   257  		Type:   artifact.Binary,
   258  		Extra: map[string]string{
   259  			"Binary": "mybin",
   260  		},
   261  	})
   262  	assert.EqualError(t, Pipe{}.Run(ctx), `failed to find files to archive: globbing failed for pattern [x-]: file does not exist`)
   263  }
   264  
   265  func TestRunPipeWrap(t *testing.T) {
   266  	folder, back := testlib.Mktmp(t)
   267  	defer back()
   268  	var dist = filepath.Join(folder, "dist")
   269  	assert.NoError(t, os.Mkdir(dist, 0755))
   270  	assert.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   271  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   272  	assert.NoError(t, err)
   273  	_, err = os.Create(filepath.Join(folder, "README.md"))
   274  	assert.NoError(t, err)
   275  	var ctx = context.New(
   276  		config.Project{
   277  			Dist: dist,
   278  			Archive: config.Archive{
   279  				NameTemplate:    "foo",
   280  				WrapInDirectory: true,
   281  				Format:          "tar.gz",
   282  				Files: []string{
   283  					"README.*",
   284  				},
   285  			},
   286  		},
   287  	)
   288  	ctx.Git.CurrentTag = "v0.0.1"
   289  	ctx.Artifacts.Add(artifact.Artifact{
   290  		Goos:   "darwin",
   291  		Goarch: "amd64",
   292  		Name:   "mybin",
   293  		Path:   filepath.Join("dist", "darwinamd64", "mybin"),
   294  		Type:   artifact.Binary,
   295  		Extra: map[string]string{
   296  			"Binary": "mybin",
   297  		},
   298  	})
   299  	assert.NoError(t, Pipe{}.Run(ctx))
   300  
   301  	// Check archive contents
   302  	f, err := os.Open(filepath.Join(dist, "foo.tar.gz"))
   303  	assert.NoError(t, err)
   304  	defer func() { assert.NoError(t, f.Close()) }()
   305  	gr, err := gzip.NewReader(f)
   306  	assert.NoError(t, err)
   307  	defer func() { assert.NoError(t, gr.Close()) }()
   308  	r := tar.NewReader(gr)
   309  	for _, n := range []string{"README.md", "mybin"} {
   310  		h, err := r.Next()
   311  		if err == io.EOF {
   312  			break
   313  		}
   314  		assert.NoError(t, err)
   315  		assert.Equal(t, filepath.Join("foo", n), h.Name)
   316  	}
   317  }
   318  
   319  func TestDefault(t *testing.T) {
   320  	var ctx = &context.Context{
   321  		Config: config.Project{
   322  			Archive: config.Archive{},
   323  		},
   324  	}
   325  	assert.NoError(t, Pipe{}.Default(ctx))
   326  	assert.NotEmpty(t, ctx.Config.Archive.NameTemplate)
   327  	assert.Equal(t, "tar.gz", ctx.Config.Archive.Format)
   328  	assert.NotEmpty(t, ctx.Config.Archive.Files)
   329  }
   330  
   331  func TestDefaultSet(t *testing.T) {
   332  	var ctx = &context.Context{
   333  		Config: config.Project{
   334  			Archive: config.Archive{
   335  				NameTemplate: "foo",
   336  				Format:       "zip",
   337  				Files: []string{
   338  					"foo",
   339  				},
   340  			},
   341  		},
   342  	}
   343  	assert.NoError(t, Pipe{}.Default(ctx))
   344  	assert.Equal(t, "foo", ctx.Config.Archive.NameTemplate)
   345  	assert.Equal(t, "zip", ctx.Config.Archive.Format)
   346  	assert.Equal(t, "foo", ctx.Config.Archive.Files[0])
   347  }
   348  
   349  func TestDefaultFormatBinary(t *testing.T) {
   350  	var ctx = &context.Context{
   351  		Config: config.Project{
   352  			Archive: config.Archive{
   353  				Format: "binary",
   354  			},
   355  		},
   356  	}
   357  	assert.NoError(t, Pipe{}.Default(ctx))
   358  	assert.Equal(t, defaultBinaryNameTemplate, ctx.Config.Archive.NameTemplate)
   359  }
   360  
   361  func TestFormatFor(t *testing.T) {
   362  	var ctx = &context.Context{
   363  		Config: config.Project{
   364  			Archive: config.Archive{
   365  				Format: "tar.gz",
   366  				FormatOverrides: []config.FormatOverride{
   367  					{
   368  						Goos:   "windows",
   369  						Format: "zip",
   370  					},
   371  				},
   372  			},
   373  		},
   374  	}
   375  	assert.Equal(t, "zip", packageFormat(ctx, "windows"))
   376  	assert.Equal(t, "tar.gz", packageFormat(ctx, "linux"))
   377  }
   378  
   379  func TestBinaryOverride(t *testing.T) {
   380  	folder, back := testlib.Mktmp(t)
   381  	defer back()
   382  	var dist = filepath.Join(folder, "dist")
   383  	assert.NoError(t, os.Mkdir(dist, 0755))
   384  	assert.NoError(t, os.Mkdir(filepath.Join(dist, "darwinamd64"), 0755))
   385  	assert.NoError(t, os.Mkdir(filepath.Join(dist, "windowsamd64"), 0755))
   386  	_, err := os.Create(filepath.Join(dist, "darwinamd64", "mybin"))
   387  	assert.NoError(t, err)
   388  	_, err = os.Create(filepath.Join(dist, "windowsamd64", "mybin.exe"))
   389  	assert.NoError(t, err)
   390  	_, err = os.Create(filepath.Join(folder, "README.md"))
   391  	assert.NoError(t, err)
   392  	for _, format := range []string{"tar.gz", "zip"} {
   393  		t.Run("Archive format "+format, func(tt *testing.T) {
   394  			var ctx = context.New(
   395  				config.Project{
   396  					Dist:        dist,
   397  					ProjectName: "foobar",
   398  					Archive: config.Archive{
   399  						NameTemplate: defaultNameTemplate,
   400  						Files: []string{
   401  							"README.*",
   402  						},
   403  						FormatOverrides: []config.FormatOverride{
   404  							{
   405  								Goos:   "windows",
   406  								Format: "binary",
   407  							},
   408  						},
   409  					},
   410  				},
   411  			)
   412  			ctx.Git.CurrentTag = "v0.0.1"
   413  			ctx.Artifacts.Add(artifact.Artifact{
   414  				Goos:   "darwin",
   415  				Goarch: "amd64",
   416  				Name:   "mybin",
   417  				Path:   filepath.Join(dist, "darwinamd64", "mybin"),
   418  				Type:   artifact.Binary,
   419  				Extra: map[string]string{
   420  					"Binary": "mybin",
   421  				},
   422  			})
   423  			ctx.Artifacts.Add(artifact.Artifact{
   424  				Goos:   "windows",
   425  				Goarch: "amd64",
   426  				Name:   "mybin.exe",
   427  				Path:   filepath.Join(dist, "windowsamd64", "mybin.exe"),
   428  				Type:   artifact.Binary,
   429  				Extra: map[string]string{
   430  					"Binary": "mybin",
   431  					"Ext":    ".exe",
   432  				},
   433  			})
   434  			ctx.Version = "0.0.1"
   435  			ctx.Config.Archive.Format = format
   436  
   437  			assert.NoError(tt, Pipe{}.Run(ctx))
   438  			var archives = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableArchive))
   439  			darwin := archives.Filter(artifact.ByGoos("darwin")).List()[0]
   440  			assert.Equal(tt, "foobar_0.0.1_darwin_amd64."+format, darwin.Name)
   441  
   442  			archives = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableBinary))
   443  			windows := archives.Filter(artifact.ByGoos("windows")).List()[0]
   444  			assert.Equal(tt, "foobar_0.0.1_windows_amd64.exe", windows.Name)
   445  
   446  		})
   447  	}
   448  }