Repository: goreleaser/nfpm
Pull request #409 (2021-11-30 16:30:02)

feat: custom packager configuration for rpm pkg
Atm rpm `Packager` uses the maintainer value which is sometimes not true when another entity wants to redistribute a package:

> ```
> #
> # Example spec file for cdplayer app...
> #
> Summary: A CD player app that rocks!
> Name: cdplayer
> Version: 1.0
> Release: 1
> License: GPL
> Group: Applications/Sound
> Source: ftp://ftp.gnomovision.com/pub/cdplayer/cdplayer-1.0.tgz
> URL: http://www.gnomovision.com/cdplayer/cdplayer.html
> Distribution: WSS Linux
> Vendor: White Socks Software, Inc.
> Packager: Santa Claus <sclaus@northpole.com>
> 
> %description
> It slices!  It dices!  It's a CD player app that
> can't be beat.  By using the resonant frequency
> of the CD itself, it is able to simulate 20X
> oversampling.  This leads to sound quality that
> cannot be equaled with more mundane software...
> ```
>
> The **vendor** line identifies the organization that distributes the software. Maintaining our fictional motif, we've invented fictional company, White Socks Software, to add to our spec file. Individuals will probably omit this as well. 
>
> The **packager** line is used to identify the organization that actually packaged the software, as opposed to the author of the software. In our example, we've chosen the greatest packager of them all, Santa Claus, to work at White Socks Software. Note that we've included contact information, in the form of an e-mail address.

This PR allows to customize this field and also to expand env var for it.

codecov[bot]: # [Codecov](https://codecov.io/gh/goreleaser/nfpm/pull/409?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) Report
> Merging [#409](https://codecov.io/gh/goreleaser/nfpm/pull/409?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (40c0589) into [main](https://codecov.io/gh/goreleaser/nfpm/commit/1de91949f55eae477f999e45171586a26b702109?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) (1de9194) will **increase** coverage by `0.09%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/goreleaser/nfpm/pull/409/graphs/tree.svg?width=650&height=150&src=pr&token=9QKGIxn7wg&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)](https://codecov.io/gh/goreleaser/nfpm/pull/409?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)

```diff
@@            Coverage Diff             @@
##             main     #409      +/-   ##
==========================================
+ Coverage   66.18%   66.27%   +0.09%     
==========================================
  Files          15       15              
  Lines        1854     1859       +5     
==========================================
+ Hits         1227     1232       +5     
  Misses        488      488              
  Partials      139      139              
```


| [Impacted Files](https://codecov.io/gh/goreleaser/nfpm/pull/409?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser) | Coverage Δ | |
|---|---|---|
| [nfpm.go](https://codecov.io/gh/goreleaser/nfpm/pull/409/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-bmZwbS5nbw==) | `86.29% <100.00%> (+0.06%)` | :arrow_up: |
| [rpm/rpm.go](https://codecov.io/gh/goreleaser/nfpm/pull/409/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser#diff-cnBtL3JwbS5nbw==) | `69.51% <100.00%> (+0.46%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/nfpm/pull/409?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/goreleaser/nfpm/pull/409?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Last update [1de9194...40c0589](https://codecov.io/gh/goreleaser/nfpm/pull/409?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=goreleaser).

crazy-max: Looks like there is an issue on the Windows runner: https://github.com/goreleaser/nfpm/runs/4370360116?check_suite_focus=true#step:7:8

```
task: [test] go test  -failfast -race -coverpkg=./... -covermode=atomic -coverprofile=coverage.txt ./... -run . -timeout=5m
# runtime/cgo
cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in %PATH%
FAIL	github.com/goreleaser/nfpm/v2 [build failed]
FAIL	github.com/goreleaser/nfpm/v2/apk [build failed]
FAIL	github.com/goreleaser/nfpm/v2/deb [build failed]
FAIL	github.com/goreleaser/nfpm/v2/deprecation [build failed]
FAIL	github.com/goreleaser/nfpm/v2/files [build failed]
FAIL	github.com/goreleaser/nfpm/v2/internal/glob [build failed]
FAIL	github.com/goreleaser/nfpm/v2/internal/sign [build failed]
FAIL	github.com/goreleaser/nfpm/v2/rpm [build failed]
task: Failed to run task "test": exit status 2
Error: Process completed with exit code 1.
```

Patch:
diff --git a/nfpm.go b/nfpm.go
index 5c46e8c..89a0ccf 100644
--- a/nfpm.go
+++ b/nfpm.go
@@ -185,6 +185,9 @@ func (c *Config) expandEnvVars() {
 	if apkPassphrase != "" {
 		c.Info.APK.Signature.KeyPassphrase = apkPassphrase
 	}
+
+	// RPM specific
+	c.Info.RPM.Packager = os.Expand(c.RPM.Packager, c.envMappingFunc)
 }
 
 // Info contains information about a single package.
@@ -273,6 +276,7 @@ type RPM struct {
 	Summary     string       `yaml:"summary,omitempty" jsonschema:"title=package summary"`
 	Compression string       `yaml:"compression,omitempty" jsonschema:"title=compression algorithm to be used,enum=gzip,enum=lzma,enum=xz,default=gzip"`
 	Signature   RPMSignature `yaml:"signature,omitempty" jsonschema:"title=rpm signature"`
+	Packager    string       `yaml:"packager,omitempty" jsonschema:"title=organization that actually packaged the software"`
 }
 
 // RPMScripts represents scripts only available on RPM packages.
diff --git a/rpm/rpm.go b/rpm/rpm.go
index 28f4356..3740872 100644
--- a/rpm/rpm.go
+++ b/rpm/rpm.go
@@ -228,7 +228,7 @@ func buildRPMMeta(info *nfpm.Info) (*rpmpack.RPMMetaData, error) {
 		Licence:     info.License,
 		URL:         info.Homepage,
 		Vendor:      info.Vendor,
-		Packager:    info.Maintainer,
+		Packager:    defaultTo(info.RPM.Packager, info.Maintainer),
 		Group:       info.RPM.Group,
 		Provides:    provides,
 		Recommends:  recommends,
diff --git a/www/docs/configuration.md b/www/docs/configuration.md
index 70dc350..a4b9a82 100644
--- a/www/docs/configuration.md
+++ b/www/docs/configuration.md
@@ -233,6 +233,12 @@ rpm:
   # description, but can be explicitly provided here.
   summary: Explicit Summary for Sample Package
 
+  # The packager is used to identify the organization that actually packaged
+  # the software, as opposed to the author of the software.
+  # `maintainer` will be used as fallback if not specified.
+  # This will expand any env var you set in the field, eg packager: ${PACKAGER}
+  packager: GoReleaser <staff@goreleaser.com>
+
   # Compression algorithm (gzip (default), lzma or xz).
   compression: lzma
 


Test patch:
diff --git a/nfpm_test.go b/nfpm_test.go
index 55b67a2..1c1d74f 100644
--- a/nfpm_test.go
+++ b/nfpm_test.go
@@ -244,6 +244,7 @@ func TestOptionsFromEnvironment(t *testing.T) {
 		release    = "3"
 		version    = "1.0.0"
 		vendor     = "GoReleaser"
+		packager   = "nope"
 	)
 
 	t.Run("version", func(t *testing.T) {
@@ -292,6 +293,14 @@ func TestOptionsFromEnvironment(t *testing.T) {
 		require.Equal(t, rpmPass, info.RPM.Signature.KeyPassphrase)
 		require.Equal(t, apkPass, info.APK.Signature.KeyPassphrase)
 	})
+
+	t.Run("packager", func(t *testing.T) {
+		os.Clearenv()
+		os.Setenv("PACKAGER", packager)
+		info, err := nfpm.Parse(strings.NewReader("name: foo\nrpm:\n  packager: $PACKAGER"))
+		require.NoError(t, err)
+		require.Equal(t, packager, info.RPM.Packager)
+	})
 }
 
 func TestOverrides(t *testing.T) {
diff --git a/rpm/rpm_test.go b/rpm/rpm_test.go
index 9315783..d51d9c3 100644
--- a/rpm/rpm_test.go
+++ b/rpm/rpm_test.go
@@ -183,6 +183,33 @@ func TestRPMSummary(t *testing.T) {
 	require.Equal(t, customSummary, summary)
 }
 
+func TestRPMPackager(t *testing.T) {
+	f, err := ioutil.TempFile("", "test.rpm")
+	require.NoError(t, err)
+
+	customPackager := "GoReleaser <staff@goreleaser.com>"
+	info := exampleInfo()
+	info.RPM.Group = "Unspecified"
+	info.RPM.Packager = customPackager
+
+	require.NoError(t, Default.Package(info, f))
+
+	file, err := os.OpenFile(f.Name(), os.O_RDONLY, 0o600) //nolint:gosec
+	require.NoError(t, err)
+	defer func() {
+		f.Close()
+		file.Close()
+		err = os.Remove(file.Name())
+		require.NoError(t, err)
+	}()
+	rpm, err := rpmutils.ReadRpm(file)
+	require.NoError(t, err)
+
+	packager, err := rpm.Header.GetString(rpmutils.PACKAGER)
+	require.NoError(t, err)
+	require.Equal(t, customPackager, packager)
+}
+
 func TestWithRPMTags(t *testing.T) {
 	f, err := ioutil.TempFile("", "test.rpm")
 	require.NoError(t, err)