github.com/ahmet2mir/goreleaser@v0.180.3-0.20210927151101-8e5ee5a9b8c5/internal/pipe/nfpm/nfpm_test.go (about)

     1  package nfpm
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"runtime"
     8  	"testing"
     9  
    10  	"github.com/goreleaser/goreleaser/internal/artifact"
    11  	"github.com/goreleaser/goreleaser/internal/testlib"
    12  	"github.com/goreleaser/goreleaser/pkg/config"
    13  	"github.com/goreleaser/goreleaser/pkg/context"
    14  	"github.com/goreleaser/nfpm/v2/files"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestDescription(t *testing.T) {
    19  	require.NotEmpty(t, Pipe{}.String())
    20  }
    21  
    22  func TestRunPipeNoFormats(t *testing.T) {
    23  	ctx := &context.Context{
    24  		Version: "1.0.0",
    25  		Git: context.GitInfo{
    26  			CurrentTag: "v1.0.0",
    27  		},
    28  		Config: config.Project{
    29  			NFPMs: []config.NFPM{
    30  				{},
    31  			},
    32  		},
    33  		Parallelism: runtime.NumCPU(),
    34  	}
    35  	require.NoError(t, Pipe{}.Default(ctx))
    36  	testlib.AssertSkipped(t, Pipe{}.Run(ctx))
    37  }
    38  
    39  func TestRunPipeInvalidFormat(t *testing.T) {
    40  	ctx := context.New(config.Project{
    41  		ProjectName: "nope",
    42  		NFPMs: []config.NFPM{
    43  			{
    44  				Bindir:  "/usr/bin",
    45  				Formats: []string{"nope"},
    46  				Builds:  []string{"foo"},
    47  				NFPMOverridables: config.NFPMOverridables{
    48  					PackageName:      "foo",
    49  					FileNameTemplate: defaultNameTemplate,
    50  				},
    51  			},
    52  		},
    53  	})
    54  	ctx.Version = "1.2.3"
    55  	ctx.Git = context.GitInfo{
    56  		CurrentTag: "v1.2.3",
    57  	}
    58  	for _, goos := range []string{"linux", "darwin"} {
    59  		for _, goarch := range []string{"amd64", "386"} {
    60  			ctx.Artifacts.Add(&artifact.Artifact{
    61  				Name:   "mybin",
    62  				Path:   "testdata/testfile.txt",
    63  				Goarch: goarch,
    64  				Goos:   goos,
    65  				Type:   artifact.Binary,
    66  				Extra: map[string]interface{}{
    67  					"ID": "foo",
    68  				},
    69  			})
    70  		}
    71  	}
    72  	require.Contains(t, Pipe{}.Run(ctx).Error(), `no packager registered for the format nope`)
    73  }
    74  
    75  func TestRunPipe(t *testing.T) {
    76  	folder := t.TempDir()
    77  	dist := filepath.Join(folder, "dist")
    78  	require.NoError(t, os.Mkdir(dist, 0o755))
    79  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
    80  	binPath := filepath.Join(dist, "mybin", "mybin")
    81  	f, err := os.Create(binPath)
    82  	require.NoError(t, err)
    83  	require.NoError(t, f.Close())
    84  	ctx := context.New(config.Project{
    85  		ProjectName: "mybin",
    86  		Dist:        dist,
    87  		Env: []string{
    88  			"PRO=pro",
    89  			"DESC=templates",
    90  		},
    91  		NFPMs: []config.NFPM{
    92  			{
    93  				ID:          "someid",
    94  				Bindir:      "/usr/bin",
    95  				Builds:      []string{"default"},
    96  				Formats:     []string{"deb", "rpm", "apk"},
    97  				Section:     "somesection",
    98  				Priority:    "standard",
    99  				Description: "Some description with {{ .Env.DESC }}",
   100  				License:     "MIT",
   101  				Maintainer:  "me@me",
   102  				Vendor:      "asdf",
   103  				Homepage:    "https://goreleaser.com/{{ .Env.PRO }}",
   104  				NFPMOverridables: config.NFPMOverridables{
   105  					FileNameTemplate: defaultNameTemplate + "-{{ .Release }}-{{ .Epoch }}",
   106  					PackageName:      "foo",
   107  					Dependencies:     []string{"make"},
   108  					Recommends:       []string{"svn"},
   109  					Suggests:         []string{"bzr"},
   110  					Replaces:         []string{"fish"},
   111  					Conflicts:        []string{"git"},
   112  					EmptyFolders:     []string{"/var/log/foobar"},
   113  					Release:          "10",
   114  					Epoch:            "20",
   115  					Contents: []*files.Content{
   116  						{
   117  							Source:      "./testdata/testfile.txt",
   118  							Destination: "/usr/share/testfile.txt",
   119  						},
   120  						{
   121  							Source:      "./testdata/testfile.txt",
   122  							Destination: "/etc/nope.conf",
   123  							Type:        "config",
   124  						},
   125  						{
   126  							Source:      "./testdata/testfile.txt",
   127  							Destination: "/etc/nope-rpm.conf",
   128  							Type:        "config",
   129  							Packager:    "rpm",
   130  						},
   131  						{
   132  							Source:      "/etc/nope.conf",
   133  							Destination: "/etc/nope2.conf",
   134  							Type:        "symlink",
   135  						},
   136  						{
   137  							Source:      "./testdata/testfile-{{ .Arch }}.txt",
   138  							Destination: "/etc/nope3_{{ .ProjectName }}.conf",
   139  						},
   140  					},
   141  					Replacements: map[string]string{
   142  						"linux": "Tux",
   143  					},
   144  				},
   145  			},
   146  		},
   147  	})
   148  	ctx.Version = "1.0.0"
   149  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
   150  	for _, goos := range []string{"linux", "darwin"} {
   151  		for _, goarch := range []string{"amd64", "386"} {
   152  			ctx.Artifacts.Add(&artifact.Artifact{
   153  				Name:   "subdir/mybin",
   154  				Path:   binPath,
   155  				Goarch: goarch,
   156  				Goos:   goos,
   157  				Type:   artifact.Binary,
   158  				Extra: map[string]interface{}{
   159  					"ID": "default",
   160  				},
   161  			})
   162  		}
   163  	}
   164  	require.NoError(t, Pipe{}.Run(ctx))
   165  	packages := ctx.Artifacts.Filter(artifact.ByType(artifact.LinuxPackage)).List()
   166  	require.Len(t, packages, 6)
   167  	for _, pkg := range packages {
   168  		format := pkg.ExtraOr("Format", "").(string)
   169  		require.NotEmpty(t, format)
   170  		require.Equal(t, pkg.Name, "foo_1.0.0_Tux_"+pkg.Goarch+"-10-20."+format)
   171  		require.Equal(t, pkg.ExtraOr("ID", ""), "someid")
   172  		require.ElementsMatch(t, []string{
   173  			"./testdata/testfile.txt",
   174  			"./testdata/testfile.txt",
   175  			"./testdata/testfile.txt",
   176  			"/etc/nope.conf",
   177  			"./testdata/testfile-" + pkg.Goarch + ".txt",
   178  			binPath,
   179  		}, sources(pkg.ExtraOr("Files", files.Contents{}).(files.Contents)))
   180  		require.ElementsMatch(t, []string{
   181  			"/usr/share/testfile.txt",
   182  			"/etc/nope.conf",
   183  			"/etc/nope-rpm.conf",
   184  			"/etc/nope2.conf",
   185  			"/etc/nope3_mybin.conf",
   186  			"/usr/bin/subdir/mybin",
   187  		}, destinations(pkg.ExtraOr("Files", files.Contents{}).(files.Contents)))
   188  	}
   189  	require.Len(t, ctx.Config.NFPMs[0].Contents, 5, "should not modify the config file list")
   190  }
   191  
   192  func TestInvalidTemplate(t *testing.T) {
   193  	makeCtx := func() *context.Context {
   194  		ctx := &context.Context{
   195  			Version:     "1.2.3",
   196  			Parallelism: runtime.NumCPU(),
   197  			Artifacts:   artifact.New(),
   198  			Config: config.Project{
   199  				NFPMs: []config.NFPM{
   200  					{
   201  						Formats: []string{"deb"},
   202  						Builds:  []string{"default"},
   203  					},
   204  				},
   205  			},
   206  		}
   207  		ctx.Artifacts.Add(&artifact.Artifact{
   208  			Name:   "mybin",
   209  			Goos:   "linux",
   210  			Goarch: "amd64",
   211  			Type:   artifact.Binary,
   212  			Extra: map[string]interface{}{
   213  				"ID": "default",
   214  			},
   215  		})
   216  		return ctx
   217  	}
   218  
   219  	t.Run("filename_template", func(t *testing.T) {
   220  		ctx := makeCtx()
   221  		ctx.Config.NFPMs[0].NFPMOverridables = config.NFPMOverridables{
   222  			FileNameTemplate: "{{.Foo}",
   223  		}
   224  		require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1: unexpected "}" in operand`)
   225  	})
   226  
   227  	t.Run("source", func(t *testing.T) {
   228  		ctx := makeCtx()
   229  		ctx.Config.NFPMs[0].NFPMOverridables = config.NFPMOverridables{
   230  			Contents: files.Contents{
   231  				{
   232  					Source:      "{{ .NOPE_SOURCE }}",
   233  					Destination: "/foo",
   234  				},
   235  			},
   236  		}
   237  		require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:3: executing "tmpl" at <.NOPE_SOURCE>: map has no entry for key "NOPE_SOURCE"`)
   238  	})
   239  
   240  	t.Run("target", func(t *testing.T) {
   241  		ctx := makeCtx()
   242  		ctx.Config.NFPMs[0].NFPMOverridables = config.NFPMOverridables{
   243  			Contents: files.Contents{
   244  				{
   245  					Source:      "./testdata/testfile.txt",
   246  					Destination: "{{ .NOPE_TARGET }}",
   247  				},
   248  			},
   249  		}
   250  		require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:3: executing "tmpl" at <.NOPE_TARGET>: map has no entry for key "NOPE_TARGET"`)
   251  	})
   252  
   253  	t.Run("description", func(t *testing.T) {
   254  		ctx := makeCtx()
   255  		ctx.Config.NFPMs[0].Description = "{{ .NOPE_DESC }}"
   256  		require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:3: executing "tmpl" at <.NOPE_DESC>: map has no entry for key "NOPE_DESC"`)
   257  	})
   258  
   259  	t.Run("homepage", func(t *testing.T) {
   260  		ctx := makeCtx()
   261  		ctx.Config.NFPMs[0].Homepage = "{{ .NOPE_HOMEPAGE }}"
   262  		require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:3: executing "tmpl" at <.NOPE_HOMEPAGE>: map has no entry for key "NOPE_HOMEPAGE"`)
   263  	})
   264  
   265  	t.Run("deb key file", func(t *testing.T) {
   266  		ctx := makeCtx()
   267  		ctx.Config.NFPMs[0].Deb.Signature.KeyFile = "{{ .NOPE_KEY_FILE }}"
   268  		require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:3: executing "tmpl" at <.NOPE_KEY_FILE>: map has no entry for key "NOPE_KEY_FILE"`)
   269  	})
   270  
   271  	t.Run("rpm key file", func(t *testing.T) {
   272  		ctx := makeCtx()
   273  		ctx.Config.NFPMs[0].RPM.Signature.KeyFile = "{{ .NOPE_KEY_FILE }}"
   274  		require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:3: executing "tmpl" at <.NOPE_KEY_FILE>: map has no entry for key "NOPE_KEY_FILE"`)
   275  	})
   276  
   277  	t.Run("apk key file", func(t *testing.T) {
   278  		ctx := makeCtx()
   279  		ctx.Config.NFPMs[0].APK.Signature.KeyFile = "{{ .NOPE_KEY_FILE }}"
   280  		require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:3: executing "tmpl" at <.NOPE_KEY_FILE>: map has no entry for key "NOPE_KEY_FILE"`)
   281  	})
   282  
   283  	t.Run("bindir", func(t *testing.T) {
   284  		ctx := makeCtx()
   285  		ctx.Config.NFPMs[0].Bindir = "/usr/local/{{ .NOPE }}"
   286  		require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:14: executing "tmpl" at <.NOPE>: map has no entry for key "NOPE"`)
   287  	})
   288  }
   289  
   290  func TestRunPipeInvalidContentsSourceTemplate(t *testing.T) {
   291  	ctx := &context.Context{
   292  		Parallelism: runtime.NumCPU(),
   293  		Artifacts:   artifact.New(),
   294  		Config: config.Project{
   295  			NFPMs: []config.NFPM{
   296  				{
   297  					NFPMOverridables: config.NFPMOverridables{
   298  						PackageName: "foo",
   299  						Contents: []*files.Content{
   300  							{
   301  								Source:      "{{.asdsd}",
   302  								Destination: "testfile",
   303  							},
   304  						},
   305  					},
   306  					Formats: []string{"deb"},
   307  					Builds:  []string{"default"},
   308  				},
   309  			},
   310  		},
   311  	}
   312  	ctx.Artifacts.Add(&artifact.Artifact{
   313  		Name:   "mybin",
   314  		Goos:   "linux",
   315  		Goarch: "amd64",
   316  		Type:   artifact.Binary,
   317  		Extra: map[string]interface{}{
   318  			"ID": "default",
   319  		},
   320  	})
   321  	require.EqualError(t, Pipe{}.Run(ctx), `template: tmpl:1: unexpected "}" in operand`)
   322  }
   323  
   324  func TestNoBuildsFound(t *testing.T) {
   325  	ctx := &context.Context{
   326  		Parallelism: runtime.NumCPU(),
   327  		Artifacts:   artifact.New(),
   328  		Config: config.Project{
   329  			NFPMs: []config.NFPM{
   330  				{
   331  					Formats: []string{"deb"},
   332  					Builds:  []string{"nope"},
   333  				},
   334  			},
   335  		},
   336  	}
   337  	ctx.Artifacts.Add(&artifact.Artifact{
   338  		Name:   "mybin",
   339  		Goos:   "linux",
   340  		Goarch: "amd64",
   341  		Type:   artifact.Binary,
   342  		Extra: map[string]interface{}{
   343  			"ID": "default",
   344  		},
   345  	})
   346  	require.EqualError(t, Pipe{}.Run(ctx), `no linux binaries found for builds [nope]`)
   347  }
   348  
   349  func TestCreateFileDoesntExist(t *testing.T) {
   350  	folder := t.TempDir()
   351  	dist := filepath.Join(folder, "dist")
   352  	require.NoError(t, os.Mkdir(dist, 0o755))
   353  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
   354  	ctx := context.New(config.Project{
   355  		Dist:        dist,
   356  		ProjectName: "asd",
   357  		NFPMs: []config.NFPM{
   358  			{
   359  				Formats: []string{"deb", "rpm"},
   360  				Builds:  []string{"default"},
   361  				NFPMOverridables: config.NFPMOverridables{
   362  					PackageName: "foo",
   363  					Contents: []*files.Content{
   364  						{
   365  							Source:      "testdata/testfile.txt",
   366  							Destination: "/var/lib/test/testfile.txt",
   367  						},
   368  					},
   369  				},
   370  			},
   371  		},
   372  	})
   373  	ctx.Version = "1.2.3"
   374  	ctx.Git = context.GitInfo{
   375  		CurrentTag: "v1.2.3",
   376  	}
   377  	ctx.Artifacts.Add(&artifact.Artifact{
   378  		Name:   "mybin",
   379  		Path:   filepath.Join(dist, "mybin", "mybin"),
   380  		Goos:   "linux",
   381  		Goarch: "amd64",
   382  		Type:   artifact.Binary,
   383  		Extra: map[string]interface{}{
   384  			"ID": "default",
   385  		},
   386  	})
   387  	require.Contains(t, Pipe{}.Run(ctx).Error(), `dist/mybin/mybin": file does not exist`)
   388  }
   389  
   390  func TestInvalidConfig(t *testing.T) {
   391  	folder := t.TempDir()
   392  	dist := filepath.Join(folder, "dist")
   393  	require.NoError(t, os.Mkdir(dist, 0o755))
   394  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
   395  	ctx := context.New(config.Project{
   396  		Dist: dist,
   397  		NFPMs: []config.NFPM{
   398  			{
   399  				Formats: []string{"deb"},
   400  				Builds:  []string{"default"},
   401  			},
   402  		},
   403  	})
   404  	ctx.Git.CurrentTag = "v1.2.3"
   405  	ctx.Version = "v1.2.3"
   406  	ctx.Artifacts.Add(&artifact.Artifact{
   407  		Name:   "mybin",
   408  		Path:   filepath.Join(dist, "mybin", "mybin"),
   409  		Goos:   "linux",
   410  		Goarch: "amd64",
   411  		Type:   artifact.Binary,
   412  		Extra: map[string]interface{}{
   413  			"ID": "default",
   414  		},
   415  	})
   416  	require.Contains(t, Pipe{}.Run(ctx).Error(), `invalid nfpm config: package name must be provided`)
   417  }
   418  
   419  func TestDefault(t *testing.T) {
   420  	ctx := &context.Context{
   421  		Config: config.Project{
   422  			ProjectName: "foobar",
   423  			NFPMs: []config.NFPM{
   424  				{},
   425  			},
   426  			Builds: []config.Build{
   427  				{ID: "foo"},
   428  				{ID: "bar"},
   429  			},
   430  		},
   431  	}
   432  	require.NoError(t, Pipe{}.Default(ctx))
   433  	require.Equal(t, "/usr/local/bin", ctx.Config.NFPMs[0].Bindir)
   434  	require.Equal(t, []string{"foo", "bar"}, ctx.Config.NFPMs[0].Builds)
   435  	require.Equal(t, defaultNameTemplate, ctx.Config.NFPMs[0].FileNameTemplate)
   436  	require.Equal(t, ctx.Config.ProjectName, ctx.Config.NFPMs[0].PackageName)
   437  }
   438  
   439  func TestDefaultSet(t *testing.T) {
   440  	ctx := &context.Context{
   441  		Config: config.Project{
   442  			Builds: []config.Build{
   443  				{ID: "foo"},
   444  				{ID: "bar"},
   445  			},
   446  			NFPMs: []config.NFPM{
   447  				{
   448  					Builds: []string{"foo"},
   449  					Bindir: "/bin",
   450  					NFPMOverridables: config.NFPMOverridables{
   451  						FileNameTemplate: "foo",
   452  					},
   453  				},
   454  			},
   455  		},
   456  	}
   457  	require.NoError(t, Pipe{}.Default(ctx))
   458  	require.Equal(t, "/bin", ctx.Config.NFPMs[0].Bindir)
   459  	require.Equal(t, "foo", ctx.Config.NFPMs[0].FileNameTemplate)
   460  	require.Equal(t, []string{"foo"}, ctx.Config.NFPMs[0].Builds)
   461  	require.Equal(t, config.NFPMRPMScripts{}, ctx.Config.NFPMs[0].RPM.Scripts)
   462  }
   463  
   464  func TestOverrides(t *testing.T) {
   465  	ctx := &context.Context{
   466  		Config: config.Project{
   467  			NFPMs: []config.NFPM{
   468  				{
   469  					Bindir: "/bin",
   470  					NFPMOverridables: config.NFPMOverridables{
   471  						FileNameTemplate: "foo",
   472  					},
   473  					Overrides: map[string]config.NFPMOverridables{
   474  						"deb": {
   475  							FileNameTemplate: "bar",
   476  						},
   477  					},
   478  				},
   479  			},
   480  		},
   481  	}
   482  	require.NoError(t, Pipe{}.Default(ctx))
   483  	merged, err := mergeOverrides(ctx.Config.NFPMs[0], "deb")
   484  	require.NoError(t, err)
   485  	require.Equal(t, "/bin", ctx.Config.NFPMs[0].Bindir)
   486  	require.Equal(t, "foo", ctx.Config.NFPMs[0].FileNameTemplate)
   487  	require.Equal(t, "bar", ctx.Config.NFPMs[0].Overrides["deb"].FileNameTemplate)
   488  	require.Equal(t, "bar", merged.FileNameTemplate)
   489  }
   490  
   491  func TestDebSpecificConfig(t *testing.T) {
   492  	folder := t.TempDir()
   493  	dist := filepath.Join(folder, "dist")
   494  	require.NoError(t, os.Mkdir(dist, 0o755))
   495  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
   496  	binPath := filepath.Join(dist, "mybin", "mybin")
   497  	f, err := os.Create(binPath)
   498  	require.NoError(t, err)
   499  	require.NoError(t, f.Close())
   500  	ctx := context.New(config.Project{
   501  		ProjectName: "mybin",
   502  		Dist:        dist,
   503  		NFPMs: []config.NFPM{
   504  			{
   505  				ID:      "someid",
   506  				Builds:  []string{"default"},
   507  				Formats: []string{"deb"},
   508  				NFPMOverridables: config.NFPMOverridables{
   509  					PackageName: "foo",
   510  					Contents: []*files.Content{
   511  						{
   512  							Source:      "testdata/testfile.txt",
   513  							Destination: "/usr/share/testfile.txt",
   514  						},
   515  					},
   516  					Deb: config.NFPMDeb{
   517  						Signature: config.NFPMDebSignature{
   518  							KeyFile: "./testdata/privkey.gpg",
   519  						},
   520  					},
   521  				},
   522  			},
   523  		},
   524  	})
   525  	ctx.Version = "1.0.0"
   526  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
   527  	for _, goos := range []string{"linux", "darwin"} {
   528  		for _, goarch := range []string{"amd64", "386"} {
   529  			ctx.Artifacts.Add(&artifact.Artifact{
   530  				Name:   "mybin",
   531  				Path:   binPath,
   532  				Goarch: goarch,
   533  				Goos:   goos,
   534  				Type:   artifact.Binary,
   535  				Extra: map[string]interface{}{
   536  					"ID": "default",
   537  				},
   538  			})
   539  		}
   540  	}
   541  
   542  	t.Run("no passphrase set", func(t *testing.T) {
   543  		require.Contains(
   544  			t,
   545  			Pipe{}.Run(ctx).Error(),
   546  			`key is encrypted but no passphrase was provided`,
   547  		)
   548  	})
   549  
   550  	t.Run("general passphrase set", func(t *testing.T) {
   551  		ctx.Env = map[string]string{
   552  			"NFPM_SOMEID_PASSPHRASE": "hunter2",
   553  		}
   554  		require.NoError(t, Pipe{}.Run(ctx))
   555  	})
   556  
   557  	t.Run("packager specific passphrase set", func(t *testing.T) {
   558  		ctx.Env = map[string]string{
   559  			"NFPM_SOMEID_DEB_PASSPHRASE": "hunter2",
   560  		}
   561  		require.NoError(t, Pipe{}.Run(ctx))
   562  	})
   563  }
   564  
   565  func TestRPMSpecificConfig(t *testing.T) {
   566  	folder := t.TempDir()
   567  	dist := filepath.Join(folder, "dist")
   568  	require.NoError(t, os.Mkdir(dist, 0o755))
   569  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
   570  	binPath := filepath.Join(dist, "mybin", "mybin")
   571  	f, err := os.Create(binPath)
   572  	require.NoError(t, err)
   573  	require.NoError(t, f.Close())
   574  	ctx := context.New(config.Project{
   575  		ProjectName: "mybin",
   576  		Dist:        dist,
   577  		NFPMs: []config.NFPM{
   578  			{
   579  				ID:      "someid",
   580  				Builds:  []string{"default"},
   581  				Formats: []string{"rpm"},
   582  				NFPMOverridables: config.NFPMOverridables{
   583  					PackageName: "foo",
   584  					Contents: []*files.Content{
   585  						{
   586  							Source:      "testdata/testfile.txt",
   587  							Destination: "/usr/share/testfile.txt",
   588  						},
   589  					},
   590  					RPM: config.NFPMRPM{
   591  						Signature: config.NFPMRPMSignature{
   592  							KeyFile: "./testdata/privkey.gpg",
   593  						},
   594  					},
   595  				},
   596  			},
   597  		},
   598  	})
   599  	ctx.Version = "1.0.0"
   600  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
   601  	for _, goos := range []string{"linux", "darwin"} {
   602  		for _, goarch := range []string{"amd64", "386"} {
   603  			ctx.Artifacts.Add(&artifact.Artifact{
   604  				Name:   "mybin",
   605  				Path:   binPath,
   606  				Goarch: goarch,
   607  				Goos:   goos,
   608  				Type:   artifact.Binary,
   609  				Extra: map[string]interface{}{
   610  					"ID": "default",
   611  				},
   612  			})
   613  		}
   614  	}
   615  
   616  	t.Run("no passphrase set", func(t *testing.T) {
   617  		require.Contains(
   618  			t,
   619  			Pipe{}.Run(ctx).Error(),
   620  			`key is encrypted but no passphrase was provided`,
   621  		)
   622  	})
   623  
   624  	t.Run("general passphrase set", func(t *testing.T) {
   625  		ctx.Env = map[string]string{
   626  			"NFPM_SOMEID_PASSPHRASE": "hunter2",
   627  		}
   628  		require.NoError(t, Pipe{}.Run(ctx))
   629  	})
   630  
   631  	t.Run("packager specific passphrase set", func(t *testing.T) {
   632  		ctx.Env = map[string]string{
   633  			"NFPM_SOMEID_RPM_PASSPHRASE": "hunter2",
   634  		}
   635  		require.NoError(t, Pipe{}.Run(ctx))
   636  	})
   637  }
   638  
   639  func TestRPMSpecificScriptsConfig(t *testing.T) {
   640  	folder := t.TempDir()
   641  	dist := filepath.Join(folder, "dist")
   642  	require.NoError(t, os.Mkdir(dist, 0o755))
   643  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
   644  	binPath := filepath.Join(dist, "mybin", "mybin")
   645  	f, err := os.Create(binPath)
   646  	require.NoError(t, err)
   647  	require.NoError(t, f.Close())
   648  	ctx := context.New(config.Project{
   649  		ProjectName: "mybin",
   650  		Dist:        dist,
   651  		NFPMs: []config.NFPM{
   652  			{
   653  				ID:      "someid",
   654  				Builds:  []string{"default"},
   655  				Formats: []string{"rpm"},
   656  				NFPMOverridables: config.NFPMOverridables{
   657  					PackageName: "foo",
   658  					RPM: config.NFPMRPM{
   659  						Scripts: config.NFPMRPMScripts{
   660  							PreTrans:  "/does/not/exist_pretrans.sh",
   661  							PostTrans: "/does/not/exist_posttrans.sh",
   662  						},
   663  					},
   664  				},
   665  			},
   666  		},
   667  	})
   668  	ctx.Version = "1.0.0"
   669  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
   670  	for _, goos := range []string{"linux", "darwin"} {
   671  		for _, goarch := range []string{"amd64", "386"} {
   672  			ctx.Artifacts.Add(&artifact.Artifact{
   673  				Name:   "mybin",
   674  				Path:   binPath,
   675  				Goarch: goarch,
   676  				Goos:   goos,
   677  				Type:   artifact.Binary,
   678  				Extra: map[string]interface{}{
   679  					"ID": "default",
   680  				},
   681  			})
   682  		}
   683  	}
   684  
   685  	t.Run("PreTrans script file does not exist", func(t *testing.T) {
   686  		require.Contains(
   687  			t,
   688  			Pipe{}.Run(ctx).Error(),
   689  			`nfpm failed: open /does/not/exist_pretrans.sh: no such file or directory`,
   690  		)
   691  	})
   692  
   693  	t.Run("PostTrans script file does not exist", func(t *testing.T) {
   694  		ctx.Config.NFPMs[0].RPM.Scripts.PreTrans = "testdata/testfile.txt"
   695  
   696  		require.Contains(
   697  			t,
   698  			Pipe{}.Run(ctx).Error(),
   699  			`nfpm failed: open /does/not/exist_posttrans.sh: no such file or directory`,
   700  		)
   701  	})
   702  
   703  	t.Run("pretrans and posttrans scriptlets set", func(t *testing.T) {
   704  		ctx.Config.NFPMs[0].RPM.Scripts.PreTrans = "testdata/testfile.txt"
   705  		ctx.Config.NFPMs[0].RPM.Scripts.PostTrans = "testdata/testfile.txt"
   706  
   707  		require.NoError(t, Pipe{}.Run(ctx))
   708  	})
   709  }
   710  
   711  func TestAPKSpecificConfig(t *testing.T) {
   712  	folder := t.TempDir()
   713  	dist := filepath.Join(folder, "dist")
   714  	require.NoError(t, os.Mkdir(dist, 0o755))
   715  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
   716  	binPath := filepath.Join(dist, "mybin", "mybin")
   717  	f, err := os.Create(binPath)
   718  	require.NoError(t, err)
   719  	require.NoError(t, f.Close())
   720  	ctx := context.New(config.Project{
   721  		ProjectName: "mybin",
   722  		Dist:        dist,
   723  		NFPMs: []config.NFPM{
   724  			{
   725  				ID:         "someid",
   726  				Maintainer: "me@me",
   727  				Builds:     []string{"default"},
   728  				Formats:    []string{"apk"},
   729  				NFPMOverridables: config.NFPMOverridables{
   730  					PackageName: "foo",
   731  					Contents: []*files.Content{
   732  						{
   733  							Source:      "testdata/testfile.txt",
   734  							Destination: "/usr/share/testfile.txt",
   735  						},
   736  					},
   737  					APK: config.NFPMAPK{
   738  						Signature: config.NFPMAPKSignature{
   739  							KeyFile: "./testdata/rsa.priv",
   740  						},
   741  					},
   742  				},
   743  			},
   744  		},
   745  	})
   746  	ctx.Version = "1.0.0"
   747  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
   748  	for _, goos := range []string{"linux", "darwin"} {
   749  		for _, goarch := range []string{"amd64", "386"} {
   750  			ctx.Artifacts.Add(&artifact.Artifact{
   751  				Name:   "mybin",
   752  				Path:   binPath,
   753  				Goarch: goarch,
   754  				Goos:   goos,
   755  				Type:   artifact.Binary,
   756  				Extra: map[string]interface{}{
   757  					"ID": "default",
   758  				},
   759  			})
   760  		}
   761  	}
   762  
   763  	t.Run("no passphrase set", func(t *testing.T) {
   764  		require.Contains(
   765  			t,
   766  			Pipe{}.Run(ctx).Error(),
   767  			`key is encrypted but no passphrase was provided`,
   768  		)
   769  	})
   770  
   771  	t.Run("general passphrase set", func(t *testing.T) {
   772  		ctx.Env = map[string]string{
   773  			"NFPM_SOMEID_PASSPHRASE": "hunter2",
   774  		}
   775  		require.NoError(t, Pipe{}.Run(ctx))
   776  	})
   777  
   778  	t.Run("packager specific passphrase set", func(t *testing.T) {
   779  		ctx.Env = map[string]string{
   780  			"NFPM_SOMEID_APK_PASSPHRASE": "hunter2",
   781  		}
   782  		require.NoError(t, Pipe{}.Run(ctx))
   783  	})
   784  }
   785  
   786  func TestAPKSpecificScriptsConfig(t *testing.T) {
   787  	folder := t.TempDir()
   788  	dist := filepath.Join(folder, "dist")
   789  	require.NoError(t, os.Mkdir(dist, 0o755))
   790  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
   791  	binPath := filepath.Join(dist, "mybin", "mybin")
   792  	f, err := os.Create(binPath)
   793  	require.NoError(t, err)
   794  	require.NoError(t, f.Close())
   795  	scripts := config.NFPMAPKScripts{
   796  		PreUpgrade:  "/does/not/exist_preupgrade.sh",
   797  		PostUpgrade: "/does/not/exist_postupgrade.sh",
   798  	}
   799  	ctx := context.New(config.Project{
   800  		ProjectName: "mybin",
   801  		Dist:        dist,
   802  		NFPMs: []config.NFPM{
   803  			{
   804  				ID:         "someid",
   805  				Maintainer: "me@me",
   806  				Builds:     []string{"default"},
   807  				Formats:    []string{"apk"},
   808  				NFPMOverridables: config.NFPMOverridables{
   809  					PackageName: "foo",
   810  					Contents: []*files.Content{
   811  						{
   812  							Source:      "testdata/testfile.txt",
   813  							Destination: "/usr/share/testfile.txt",
   814  						},
   815  					},
   816  					APK: config.NFPMAPK{
   817  						Scripts: scripts,
   818  					},
   819  				},
   820  			},
   821  		},
   822  	})
   823  	ctx.Version = "1.0.0"
   824  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
   825  	for _, goos := range []string{"linux", "darwin"} {
   826  		for _, goarch := range []string{"amd64", "386"} {
   827  			ctx.Artifacts.Add(&artifact.Artifact{
   828  				Name:   "mybin",
   829  				Path:   binPath,
   830  				Goarch: goarch,
   831  				Goos:   goos,
   832  				Type:   artifact.Binary,
   833  				Extra: map[string]interface{}{
   834  					"ID": "default",
   835  				},
   836  			})
   837  		}
   838  	}
   839  
   840  	t.Run("PreUpgrade script file does not exist", func(t *testing.T) {
   841  		ctx.Config.NFPMs[0].APK.Scripts = scripts
   842  		ctx.Config.NFPMs[0].APK.Scripts.PostUpgrade = "testdata/testfile.txt"
   843  
   844  		require.Contains(
   845  			t,
   846  			Pipe{}.Run(ctx).Error(),
   847  			`nfpm failed: stat /does/not/exist_preupgrade.sh: no such file or directory`,
   848  		)
   849  	})
   850  
   851  	t.Run("PostUpgrade script file does not exist", func(t *testing.T) {
   852  		ctx.Config.NFPMs[0].APK.Scripts = scripts
   853  		ctx.Config.NFPMs[0].APK.Scripts.PreUpgrade = "testdata/testfile.txt"
   854  
   855  		require.Contains(
   856  			t,
   857  			Pipe{}.Run(ctx).Error(),
   858  			`nfpm failed: stat /does/not/exist_postupgrade.sh: no such file or directory`,
   859  		)
   860  	})
   861  
   862  	t.Run("preupgrade and postupgrade scriptlets set", func(t *testing.T) {
   863  		ctx.Config.NFPMs[0].APK.Scripts.PreUpgrade = "testdata/testfile.txt"
   864  		ctx.Config.NFPMs[0].APK.Scripts.PostUpgrade = "testdata/testfile.txt"
   865  
   866  		require.NoError(t, Pipe{}.Run(ctx))
   867  	})
   868  }
   869  
   870  func TestSeveralNFPMsWithTheSameID(t *testing.T) {
   871  	ctx := &context.Context{
   872  		Config: config.Project{
   873  			NFPMs: []config.NFPM{
   874  				{
   875  					ID: "a",
   876  				},
   877  				{
   878  					ID: "a",
   879  				},
   880  			},
   881  		},
   882  	}
   883  	require.EqualError(t, Pipe{}.Default(ctx), "found 2 nfpms with the ID 'a', please fix your config")
   884  }
   885  
   886  func TestMeta(t *testing.T) {
   887  	folder := t.TempDir()
   888  	dist := filepath.Join(folder, "dist")
   889  	require.NoError(t, os.Mkdir(dist, 0o755))
   890  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
   891  	binPath := filepath.Join(dist, "mybin", "mybin")
   892  	f, err := os.Create(binPath)
   893  	require.NoError(t, err)
   894  	require.NoError(t, f.Close())
   895  	ctx := context.New(config.Project{
   896  		ProjectName: "mybin",
   897  		Dist:        dist,
   898  		NFPMs: []config.NFPM{
   899  			{
   900  				ID:          "someid",
   901  				Bindir:      "/usr/bin",
   902  				Builds:      []string{"default"},
   903  				Formats:     []string{"deb", "rpm"},
   904  				Section:     "somesection",
   905  				Priority:    "standard",
   906  				Description: "Some description",
   907  				License:     "MIT",
   908  				Maintainer:  "me@me",
   909  				Vendor:      "asdf",
   910  				Homepage:    "https://goreleaser.github.io",
   911  				Meta:        true,
   912  				NFPMOverridables: config.NFPMOverridables{
   913  					FileNameTemplate: defaultNameTemplate + "-{{ .Release }}-{{ .Epoch }}",
   914  					PackageName:      "foo",
   915  					Dependencies:     []string{"make"},
   916  					Recommends:       []string{"svn"},
   917  					Suggests:         []string{"bzr"},
   918  					Replaces:         []string{"fish"},
   919  					Conflicts:        []string{"git"},
   920  					EmptyFolders:     []string{"/var/log/foobar"},
   921  					Release:          "10",
   922  					Epoch:            "20",
   923  					Contents: []*files.Content{
   924  						{
   925  							Source:      "testdata/testfile.txt",
   926  							Destination: "/usr/share/testfile.txt",
   927  						},
   928  						{
   929  							Source:      "./testdata/testfile.txt",
   930  							Destination: "/etc/nope.conf",
   931  							Type:        "config",
   932  						},
   933  						{
   934  							Source:      "./testdata/testfile.txt",
   935  							Destination: "/etc/nope-rpm.conf",
   936  							Type:        "config",
   937  							Packager:    "rpm",
   938  						},
   939  					},
   940  					Replacements: map[string]string{
   941  						"linux": "Tux",
   942  					},
   943  				},
   944  			},
   945  		},
   946  	})
   947  	ctx.Version = "1.0.0"
   948  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
   949  	for _, goos := range []string{"linux", "darwin"} {
   950  		for _, goarch := range []string{"amd64", "386"} {
   951  			ctx.Artifacts.Add(&artifact.Artifact{
   952  				Name:   "mybin",
   953  				Path:   binPath,
   954  				Goarch: goarch,
   955  				Goos:   goos,
   956  				Type:   artifact.Binary,
   957  				Extra: map[string]interface{}{
   958  					"ID": "default",
   959  				},
   960  			})
   961  		}
   962  	}
   963  	require.NoError(t, Pipe{}.Run(ctx))
   964  	packages := ctx.Artifacts.Filter(artifact.ByType(artifact.LinuxPackage)).List()
   965  	require.Len(t, packages, 4)
   966  	for _, pkg := range packages {
   967  		format := pkg.ExtraOr("Format", "").(string)
   968  		require.NotEmpty(t, format)
   969  		require.Equal(t, pkg.Name, "foo_1.0.0_Tux_"+pkg.Goarch+"-10-20."+format)
   970  		require.Equal(t, pkg.ExtraOr("ID", ""), "someid")
   971  		require.ElementsMatch(t, []string{
   972  			"/usr/share/testfile.txt",
   973  			"/etc/nope.conf",
   974  			"/etc/nope-rpm.conf",
   975  		}, destinations(pkg.ExtraOr("Files", files.Contents{}).(files.Contents)))
   976  	}
   977  
   978  	require.Len(t, ctx.Config.NFPMs[0].Contents, 3, "should not modify the config file list")
   979  }
   980  
   981  func TestSkipSign(t *testing.T) {
   982  	folder, err := ioutil.TempDir("", "archivetest")
   983  	require.NoError(t, err)
   984  	dist := filepath.Join(folder, "dist")
   985  	require.NoError(t, os.Mkdir(dist, 0o755))
   986  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
   987  	binPath := filepath.Join(dist, "mybin", "mybin")
   988  	_, err = os.Create(binPath)
   989  	require.NoError(t, err)
   990  	ctx := context.New(config.Project{
   991  		ProjectName: "mybin",
   992  		Dist:        dist,
   993  		NFPMs: []config.NFPM{
   994  			{
   995  				ID:      "someid",
   996  				Builds:  []string{"default"},
   997  				Formats: []string{"deb", "rpm", "apk"},
   998  				NFPMOverridables: config.NFPMOverridables{
   999  					PackageName:      "foo",
  1000  					FileNameTemplate: defaultNameTemplate,
  1001  					Contents: []*files.Content{
  1002  						{
  1003  							Source:      "testdata/testfile.txt",
  1004  							Destination: "/usr/share/testfile.txt",
  1005  						},
  1006  					},
  1007  					Deb: config.NFPMDeb{
  1008  						Signature: config.NFPMDebSignature{
  1009  							KeyFile: "/does/not/exist.gpg",
  1010  						},
  1011  					},
  1012  					RPM: config.NFPMRPM{
  1013  						Signature: config.NFPMRPMSignature{
  1014  							KeyFile: "/does/not/exist.gpg",
  1015  						},
  1016  					},
  1017  					APK: config.NFPMAPK{
  1018  						Signature: config.NFPMAPKSignature{
  1019  							KeyFile: "/does/not/exist.gpg",
  1020  						},
  1021  					},
  1022  				},
  1023  			},
  1024  		},
  1025  	})
  1026  	ctx.Version = "1.0.0"
  1027  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
  1028  	for _, goos := range []string{"linux", "darwin"} {
  1029  		for _, goarch := range []string{"amd64", "386"} {
  1030  			ctx.Artifacts.Add(&artifact.Artifact{
  1031  				Name:   "mybin",
  1032  				Path:   binPath,
  1033  				Goarch: goarch,
  1034  				Goos:   goos,
  1035  				Type:   artifact.Binary,
  1036  				Extra: map[string]interface{}{
  1037  					"ID": "default",
  1038  				},
  1039  			})
  1040  		}
  1041  	}
  1042  
  1043  	t.Run("skip sign not set", func(t *testing.T) {
  1044  		contains := "open /does/not/exist.gpg: no such file or directory"
  1045  		if runtime.GOOS == "windows" {
  1046  			contains = "open /does/not/exist.gpg: The system cannot find the path specified."
  1047  		}
  1048  		require.Contains(
  1049  			t,
  1050  			Pipe{}.Run(ctx).Error(),
  1051  			contains,
  1052  		)
  1053  	})
  1054  
  1055  	t.Run("skip sign set", func(t *testing.T) {
  1056  		ctx.SkipSign = true
  1057  		require.NoError(t, Pipe{}.Run(ctx))
  1058  	})
  1059  }
  1060  
  1061  func TestBinDirTemplating(t *testing.T) {
  1062  	folder := t.TempDir()
  1063  	dist := filepath.Join(folder, "dist")
  1064  	require.NoError(t, os.Mkdir(dist, 0o755))
  1065  	require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755))
  1066  	binPath := filepath.Join(dist, "mybin", "mybin")
  1067  	f, err := os.Create(binPath)
  1068  	require.NoError(t, err)
  1069  	require.NoError(t, f.Close())
  1070  	ctx := context.New(config.Project{
  1071  		ProjectName: "mybin",
  1072  		Dist:        dist,
  1073  		Env: []string{
  1074  			"PRO=pro",
  1075  			"DESC=templates",
  1076  		},
  1077  		NFPMs: []config.NFPM{
  1078  			{
  1079  				ID: "someid",
  1080  				// Bindir should pass through the template engine
  1081  				Bindir:      "/usr/lib/{{ .Env.PRO }}/nagios/plugins",
  1082  				Builds:      []string{"default"},
  1083  				Formats:     []string{"rpm"},
  1084  				Section:     "somesection",
  1085  				Priority:    "standard",
  1086  				Description: "Some description with {{ .Env.DESC }}",
  1087  				License:     "MIT",
  1088  				Maintainer:  "me@me",
  1089  				Vendor:      "asdf",
  1090  				Homepage:    "https://goreleaser.com/{{ .Env.PRO }}",
  1091  				NFPMOverridables: config.NFPMOverridables{
  1092  					PackageName: "foo",
  1093  				},
  1094  			},
  1095  		},
  1096  	})
  1097  	ctx.Version = "1.0.0"
  1098  	ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"}
  1099  	for _, goos := range []string{"linux"} {
  1100  		for _, goarch := range []string{"amd64", "386"} {
  1101  			ctx.Artifacts.Add(&artifact.Artifact{
  1102  				Name:   "subdir/mybin",
  1103  				Path:   binPath,
  1104  				Goarch: goarch,
  1105  				Goos:   goos,
  1106  				Type:   artifact.Binary,
  1107  				Extra: map[string]interface{}{
  1108  					"ID": "default",
  1109  				},
  1110  			})
  1111  		}
  1112  	}
  1113  	require.NoError(t, Pipe{}.Run(ctx))
  1114  	packages := ctx.Artifacts.Filter(artifact.ByType(artifact.LinuxPackage)).List()
  1115  
  1116  	for _, pkg := range packages {
  1117  		format := pkg.ExtraOr("Format", "").(string)
  1118  		require.NotEmpty(t, format)
  1119  		// the final binary should contain the evaluated bindir (after template eval)
  1120  		require.ElementsMatch(t, []string{
  1121  			"/usr/lib/pro/nagios/plugins/subdir/mybin",
  1122  		}, destinations(pkg.ExtraOr("Files", files.Contents{}).(files.Contents)))
  1123  	}
  1124  }
  1125  
  1126  func TestSkip(t *testing.T) {
  1127  	t.Run("skip", func(t *testing.T) {
  1128  		require.True(t, Pipe{}.Skip(context.New(config.Project{})))
  1129  	})
  1130  
  1131  	t.Run("dont skip", func(t *testing.T) {
  1132  		ctx := context.New(config.Project{
  1133  			NFPMs: []config.NFPM{
  1134  				{},
  1135  			},
  1136  		})
  1137  		require.False(t, Pipe{}.Skip(ctx))
  1138  	})
  1139  }
  1140  
  1141  func sources(contents files.Contents) []string {
  1142  	result := make([]string, 0, len(contents))
  1143  	for _, f := range contents {
  1144  		result = append(result, f.Source)
  1145  	}
  1146  	return result
  1147  }