Repository: goreleaser/nfpm
Pull request #49 (2019-03-29 17:14:43)

feat: added support for "rules" debian package file
This adds support for a "rules" debian package script.

codecov-io: # [Codecov](https://codecov.io/gh/goreleaser/nfpm/pull/49?src=pr&el=h1) Report
> Merging [#49](https://codecov.io/gh/goreleaser/nfpm/pull/49?src=pr&el=desc) into [master](https://codecov.io/gh/goreleaser/nfpm/commit/21aa86065385f2c769cb56f151344d46e8c6c5da?src=pr&el=desc) will **increase** coverage by `0.05%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/goreleaser/nfpm/pull/49/graphs/tree.svg?width=650&token=9QKGIxn7wg&height=150&src=pr)](https://codecov.io/gh/goreleaser/nfpm/pull/49?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master      #49      +/-   ##
==========================================
+ Coverage   71.28%   71.34%   +0.05%     
==========================================
  Files           5        5              
  Lines         491      492       +1     
==========================================
+ Hits          350      351       +1     
  Misses         87       87              
  Partials       54       54
```


| [Impacted Files](https://codecov.io/gh/goreleaser/nfpm/pull/49?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [nfpm.go](https://codecov.io/gh/goreleaser/nfpm/pull/49/diff?src=pr&el=tree#diff-bmZwbS5nbw==) | `89.65% <ø> (ø)` | :arrow_up: |
| [deb/deb.go](https://codecov.io/gh/goreleaser/nfpm/pull/49/diff?src=pr&el=tree#diff-ZGViL2RlYi5nbw==) | `72.86% <100%> (+0.13%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/nfpm/pull/49?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/goreleaser/nfpm/pull/49?src=pr&el=footer). Last update [21aa860...63ecd24](https://codecov.io/gh/goreleaser/nfpm/pull/49?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

caarlos0: thanks! Can you add some tests too?

Patch:
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..c21eb91
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,2 @@
+github: [caarlos0]
+open_collective: goreleaser
diff --git a/.travis.yml b/.travis.yml
index fc0b9d1..c8bca05 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,4 +1,6 @@
-addons:
+# acceptance does not work with current default trusty
+dist: xenial
+addons:     
   apt:
     packages:
     - rpm
@@ -6,6 +8,8 @@ language: go
 go: '1.12.x'
 services:
   - docker
+before_install:
+  - sudo docker run --privileged linuxkit/binfmt:v0.7
 install:
   - make setup
 before_script:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 75378a4..12eaaa6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -11,7 +11,7 @@ Prerequisites:
 
 * `make`
 * [Go 1.11+](https://golang.org/doc/install)
-* rpm (`apt-get intall rpm`/`brew install rpm`)
+* rpm (`apt-get install rpm`/`brew install rpm`)
 
 Clone `nfpm` from source:
 
diff --git a/deb/deb.go b/deb/deb.go
index f9ffbf3..b1be898 100644
--- a/deb/deb.go
+++ b/deb/deb.go
@@ -223,6 +223,7 @@ func createControl(instSize int64, md5sums []byte, info nfpm.Info) (controlTarGz
 		info.Scripts.PostInstall: "postinst",
 		info.Scripts.PreRemove:   "prerm",
 		info.Scripts.PostRemove:  "postrm",
+		info.Scripts.Rules:       "rules",
 	} {
 		if script != "" {
 			if err := newScriptInsideTarGz(out, script, dest); err != nil {
@@ -334,7 +335,11 @@ func conffiles(info nfpm.Info) []byte {
 const controlTemplate = `
 {{- /* Mandatory fields */ -}}
 Package: {{.Info.Name}}
+{{- if .Info.Epoch}}
+Version: {{ .Info.Epoch }}:{{.Info.Version}}
+{{- else }}
 Version: {{.Info.Version}}
+{{- end }}
 Section: {{.Info.Section}}
 Priority: {{.Info.Priority}}
 Architecture: {{.Info.Arch}}
@@ -345,7 +350,7 @@ Maintainer: {{.Info.Maintainer}}
 {{- if .Info.Vendor}}
 Vendor: {{.Info.Vendor}}
 {{- end }}
-Installed-Size: {{.InstalledSize}}
+Installed-Size: {{.InstalledSize}}	
 {{- with .Info.Replaces}}
 Replaces: {{join .}}
 {{- end }}
diff --git a/nfpm.go b/nfpm.go
index fb81b21..8486d4a 100644
--- a/nfpm.go
+++ b/nfpm.go
@@ -11,7 +11,7 @@ import (
 
 	"github.com/imdario/mergo"
 
-	yaml "gopkg.in/yaml.v2"
+	"gopkg.in/yaml.v2"
 )
 
 // nolint: gochecknoglobals
@@ -106,6 +106,7 @@ type Info struct {
 	Name         string `yaml:"name,omitempty"`
 	Arch         string `yaml:"arch,omitempty"`
 	Platform     string `yaml:"platform,omitempty"`
+	Epoch        string `yaml:"epoch,omitempty"`
 	Version      string `yaml:"version,omitempty"`
 	Section      string `yaml:"section,omitempty"`
 	Priority     string `yaml:"priority,omitempty"`
@@ -115,6 +116,7 @@ type Info struct {
 	Homepage     string `yaml:"homepage,omitempty"`
 	License      string `yaml:"license,omitempty"`
 	Bindir       string `yaml:"bindir,omitempty"`
+	RPM          RPM    `yaml:"rpm,omitempty"`
 }
 
 // Overridables contain the field which are overridable in a package
@@ -131,12 +133,20 @@ type Overridables struct {
 	Scripts      Scripts           `yaml:"scripts,omitempty"`
 }
 
+type RPM struct {
+	Group       string `yaml:"group,omitempty"`
+	Prefix      string `yaml:"prefix,omitempty"`
+	Compression string `yaml:"compression,omitempty"`
+	Release     string `yaml:"release,omitempty"`
+}
+
 // Scripts contains information about maintainer scripts for packages
 type Scripts struct {
 	PreInstall  string `yaml:"preinstall,omitempty"`
 	PostInstall string `yaml:"postinstall,omitempty"`
 	PreRemove   string `yaml:"preremove,omitempty"`
 	PostRemove  string `yaml:"postremove,omitempty"`
+	Rules       string `yaml:"rules,omitempty"`
 }
 
 // Validate the given Info and returns an error if it is invalid.
diff --git a/rpm/rpm.go b/rpm/rpm.go
index 3247052..26beae8 100644
--- a/rpm/rpm.go
+++ b/rpm/rpm.go
@@ -26,7 +26,7 @@ func init() {
 	nfpm.Register("rpm", Default)
 }
 
-// Default deb packager
+// Default RPM packager
 // nolint: gochecknoglobals
 var Default = &RPM{}
 
@@ -37,14 +37,20 @@ type RPM struct{}
 var archToRPM = map[string]string{
 	"amd64": "x86_64",
 	"386":   "i386",
+	"arm64": "aarch64",
 }
 
-// Package writes a new RPM package to the given writer using the given info
-func (*RPM) Package(info nfpm.Info, w io.Writer) error {
+func ensureValidArch(info nfpm.Info) nfpm.Info {
 	arch, ok := archToRPM[info.Arch]
 	if ok {
 		info.Arch = arch
 	}
+	return info
+}
+
+// Package writes a new RPM package to the given writer using the given info
+func (*RPM) Package(info nfpm.Info, w io.Writer) error {
+	info = ensureValidArch(info)
 	info.Version = strings.Replace(info.Version, "-", "_", -1)
 	_, err := exec.LookPath("rpmbuild")
 	if err != nil {
@@ -54,6 +60,7 @@ func (*RPM) Package(info nfpm.Info, w io.Writer) error {
 	if err != nil {
 		return err
 	}
+	defer os.RemoveAll(temps.Root)
 	if err = createTarGz(info, temps.Folder, temps.Source); err != nil {
 		return err
 	}
@@ -65,6 +72,8 @@ func (*RPM) Package(info nfpm.Info, w io.Writer) error {
 		"--verbose",
 		"--define", fmt.Sprintf("_topdir %s", temps.Root),
 		"--define", fmt.Sprintf("_tmppath %s/tmp", temps.Root),
+		"--define", fmt.Sprintf("_rpmfilename %s", filepath.Join(info.Arch, filepath.Base(temps.RPM))),
+		"--define", fmt.Sprintf("_sourcedir %s", filepath.Dir(temps.Source)),
 		"--target", fmt.Sprintf("%s-unknown-%s", info.Arch, info.Platform),
 		"-ba",
 		"SPECS/" + info.Name + ".spec",
@@ -84,6 +93,7 @@ func (*RPM) Package(info nfpm.Info, w io.Writer) error {
 	if err != nil {
 		return errors.Wrap(err, "failed open rpm file")
 	}
+	defer rpm.Close()
 	_, err = io.Copy(w, rpm)
 	return errors.Wrap(err, "failed to copy rpm file to writer")
 }
@@ -219,7 +229,7 @@ func setupTempFiles(info nfpm.Info) (tempFiles, error) {
 		Folder: folder,
 		Source: filepath.Join(root, "SOURCES", folder+".tar.gz"),
 		Spec:   filepath.Join(root, "SPECS", info.Name+".spec"),
-		RPM:    filepath.Join(root, "RPMS", info.Arch, fmt.Sprintf("%s-1.%s.rpm", folder, info.Arch)),
+		RPM:    filepath.Join(root, "RPMS", info.Arch, fmt.Sprintf("%s-%s.%s.rpm", folder, info.RPM.Release, info.Arch)),
 	}, nil
 }
 
@@ -309,20 +319,49 @@ const specTemplate = `
 %define __os_install_post %{_dbpath}/brp-compress
 %define _arch {{ .Info.Arch }}
 %define _bindir {{ .Info.Bindir }}
+{{- if eq .Info.RPM.Compression "gzip"}}
+%define _source_payload w9.gzdio
+%define _binary_payload w9.gzdio
+{{- end}}
+{{- if eq .Info.RPM.Compression "xz"}}
+%define _source_payload w6.xzdio
+%define _binary_payload w6.xzdio
+{{- end}}
+{{- if eq .Info.RPM.Compression "lzma"}}
+%define _source_payload w6.lzdio
+%define _binary_payload w6.lzdio
+{{- end}}
 
 Name: {{ .Info.Name }}
 Summary: {{ first_line .Info.Description }}
+{{- with .Info.Epoch}}
+Epoch: {{ . }}
+{{- end }}
 Version: {{ .Info.Version }}
+{{- with .Info.RPM.Release }}
+Release: {{ . }}
+{{- else }}
 Release: 1
+{{- end }}
 {{- with .Info.License }}
 License: {{ . }}
 {{- end }}
+{{- with .Info.RPM.Group }}
+Group: {{ . }}
+{{- else }}
 Group: Development/Tools
+{{- end }}
 SOURCE0 : %{name}-%{version}.tar.gz
 {{- with .Info.Homepage }}
 URL: {{ . }}
 {{- end }}
+{{- with .Info.Maintainer}}
+Packager: {{ . }}
+{{- end }}
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+{{- with .Info.RPM.Prefix }}
+Prefix: {{ . }}
+{{- end }}
 
 {{ range $index, $element := .Info.Replaces }}
 Obsoletes: {{ . }}


Test patch:
diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go
index 48eaf33..8876ba2 100644
--- a/acceptance/acceptance_test.go
+++ b/acceptance/acceptance_test.go
@@ -49,6 +49,15 @@ func TestSimple(t *testing.T) {
 				Dockerfile: fmt.Sprintf("%s.ppc64le.dockerfile", format),
 			})
 		})
+		t.Run("arm64", func(t *testing.T) {
+			t.Parallel()
+			accept(t, acceptParms{
+				Name:       fmt.Sprintf("simple_%s_arm64", format),
+				Conf:       "simple.arm64.yaml",
+				Format:     format,
+				Dockerfile: fmt.Sprintf("%s.arm64.dockerfile", format),
+			})
+		})
 	}
 }
 
@@ -106,6 +115,31 @@ func TestMinDeb(t *testing.T) {
 	}
 }
 
+func TestRPMCompression(t *testing.T) {
+	compressFormats := []string{"gzip", "xz", "lzma"}
+	for _, format := range compressFormats {
+		format := format
+		t.Run(format, func(t *testing.T) {
+			t.Parallel()
+			accept(t, acceptParms{
+				Name:       fmt.Sprintf("%s_compression_rpm", format),
+				Conf:       fmt.Sprintf("%s.compression.yaml", format),
+				Format:     "rpm",
+				Dockerfile: fmt.Sprintf("%s.rpm.compression.dockerfile", format),
+			})
+		})
+	}
+}
+
+func TestRPMRelease(t *testing.T) {
+	accept(t, acceptParms{
+		Name:       "release_rpm",
+		Conf:       "release.rpm.yaml",
+		Format:     "rpm",
+		Dockerfile: "release.rpm.dockerfile",
+	})
+}
+
 type acceptParms struct {
 	Name       string
 	Conf       string
diff --git a/acceptance/testdata/deb.arm64.dockerfile b/acceptance/testdata/deb.arm64.dockerfile
new file mode 100644
index 0000000..683e89c
--- /dev/null
+++ b/acceptance/testdata/deb.arm64.dockerfile
@@ -0,0 +1,10 @@
+FROM arm64v8/ubuntu
+ARG package
+COPY ${package} /tmp/foo.deb
+RUN dpkg -i /tmp/foo.deb
+RUN test -e /usr/local/bin/fake
+RUN test -f /etc/foo/whatever.conf
+RUN echo wat >> /etc/foo/whatever.conf
+RUN dpkg -r foo
+RUN test -f /etc/foo/whatever.conf
+RUN test ! -f /usr/local/bin/fake
diff --git a/acceptance/testdata/gzip.compression.yaml b/acceptance/testdata/gzip.compression.yaml
new file mode 100644
index 0000000..cb0bdf9
--- /dev/null
+++ b/acceptance/testdata/gzip.compression.yaml
@@ -0,0 +1,17 @@
+name: "foo"
+arch: "amd64"
+platform: "linux"
+version: "v1.2.3"
+maintainer: "Foo Bar"
+description: |
+  Foo bar
+    Multiple lines
+vendor: "foobar"
+homepage: "https://foobar.org"
+license: "MIT"
+files:
+  ../testdata/fake: "/usr/local/bin/fake"
+config_files:
+  ../testdata/whatever.conf: "/etc/foo/whatever.conf"
+rpm:
+  compression: "gzip"
\ No newline at end of file
diff --git a/acceptance/testdata/gzip.rpm.compression.dockerfile b/acceptance/testdata/gzip.rpm.compression.dockerfile
new file mode 100644
index 0000000..13fedb0
--- /dev/null
+++ b/acceptance/testdata/gzip.rpm.compression.dockerfile
@@ -0,0 +1,11 @@
+FROM fedora
+ARG package
+COPY ${package} /tmp/foo.rpm
+RUN test "gzip" = "$(rpm -qp --qf '%{PAYLOADCOMPRESSOR}' /tmp/foo.rpm)"
+RUN rpm -ivh /tmp/foo.rpm
+RUN test -e /usr/local/bin/fake
+RUN test -f /etc/foo/whatever.conf
+RUN echo wat >> /etc/foo/whatever.conf
+RUN rpm -e foo
+RUN test -f /etc/foo/whatever.conf.rpmsave
+RUN test ! -f /usr/local/bin/fake
\ No newline at end of file
diff --git a/acceptance/testdata/lzma.compression.yaml b/acceptance/testdata/lzma.compression.yaml
new file mode 100644
index 0000000..5b8de57
--- /dev/null
+++ b/acceptance/testdata/lzma.compression.yaml
@@ -0,0 +1,17 @@
+name: "foo"
+arch: "amd64"
+platform: "linux"
+version: "v1.2.3"
+maintainer: "Foo Bar"
+description: |
+  Foo bar
+    Multiple lines
+vendor: "foobar"
+homepage: "https://foobar.org"
+license: "MIT"
+files:
+  ../testdata/fake: "/usr/local/bin/fake"
+config_files:
+  ../testdata/whatever.conf: "/etc/foo/whatever.conf"
+rpm:
+  compression: "lzma"
\ No newline at end of file
diff --git a/acceptance/testdata/lzma.rpm.compression.dockerfile b/acceptance/testdata/lzma.rpm.compression.dockerfile
new file mode 100644
index 0000000..fc60e69
--- /dev/null
+++ b/acceptance/testdata/lzma.rpm.compression.dockerfile
@@ -0,0 +1,11 @@
+FROM fedora
+ARG package
+COPY ${package} /tmp/foo.rpm
+RUN test "lzma" = "$(rpm -qp --qf '%{PAYLOADCOMPRESSOR}' /tmp/foo.rpm)"
+RUN rpm -ivh /tmp/foo.rpm
+RUN test -e /usr/local/bin/fake
+RUN test -f /etc/foo/whatever.conf
+RUN echo wat >> /etc/foo/whatever.conf
+RUN rpm -e foo
+RUN test -f /etc/foo/whatever.conf.rpmsave
+RUN test ! -f /usr/local/bin/fake
\ No newline at end of file
diff --git a/acceptance/testdata/release.rpm.dockerfile b/acceptance/testdata/release.rpm.dockerfile
new file mode 100644
index 0000000..17a0ba1
--- /dev/null
+++ b/acceptance/testdata/release.rpm.dockerfile
@@ -0,0 +1,10 @@
+FROM fedora
+ARG package
+COPY ${package} /tmp/foo.rpm
+RUN rpm -ivh /tmp/foo.rpm
+RUN test -e /usr/local/bin/fake
+RUN test -f /etc/foo/whatever.conf
+RUN echo wat >> /etc/foo/whatever.conf
+RUN rpm -e foo
+RUN test -f /etc/foo/whatever.conf.rpmsave
+RUN test ! -f /usr/local/bin/fake
diff --git a/acceptance/testdata/release.rpm.yaml b/acceptance/testdata/release.rpm.yaml
new file mode 100644
index 0000000..522a181
--- /dev/null
+++ b/acceptance/testdata/release.rpm.yaml
@@ -0,0 +1,17 @@
+name: "foo"
+arch: "amd64"
+platform: "linux"
+version: "v1.2.3"
+maintainer: "Foo Bar"
+description: |
+  Foo bar
+    Multiple lines
+vendor: "foobar"
+homepage: "https://foobar.org"
+license: "MIT"
+files:
+  ../testdata/fake: "/usr/local/bin/fake"
+config_files:
+  ../testdata/whatever.conf: "/etc/foo/whatever.conf"
+rpm:
+  release: "4"
diff --git a/acceptance/testdata/rpm.arm64.dockerfile b/acceptance/testdata/rpm.arm64.dockerfile
new file mode 100644
index 0000000..24550c4
--- /dev/null
+++ b/acceptance/testdata/rpm.arm64.dockerfile
@@ -0,0 +1,10 @@
+FROM arm64v8/centos
+ARG package
+COPY ${package} /tmp/foo.rpm
+RUN rpm -ivh /tmp/foo.rpm
+RUN test -e /usr/local/bin/fake
+RUN test -f /etc/foo/whatever.conf
+RUN echo wat >> /etc/foo/whatever.conf
+RUN rpm -e foo
+RUN test -f /etc/foo/whatever.conf.rpmsave
+RUN test ! -f /usr/local/bin/fake
diff --git a/acceptance/testdata/simple.arm64.yaml b/acceptance/testdata/simple.arm64.yaml
new file mode 100644
index 0000000..0ad2bec
--- /dev/null
+++ b/acceptance/testdata/simple.arm64.yaml
@@ -0,0 +1,15 @@
+name: "foo"
+arch: "arm64"
+platform: "linux"
+version: "v1.2.3"
+maintainer: "Foo Bar"
+description: |
+  Foo bar
+    Multiple lines
+vendor: "foobar"
+homepage: "https://foobar.org"
+license: "MIT"
+files:
+  ../testdata/fake: "/usr/local/bin/fake"
+config_files:
+  ../testdata/whatever.conf: "/etc/foo/whatever.conf"
diff --git a/acceptance/testdata/xz.compression.yaml b/acceptance/testdata/xz.compression.yaml
new file mode 100644
index 0000000..f064775
--- /dev/null
+++ b/acceptance/testdata/xz.compression.yaml
@@ -0,0 +1,17 @@
+name: "foo"
+arch: "amd64"
+platform: "linux"
+version: "v1.2.3"
+maintainer: "Foo Bar"
+description: |
+  Foo bar
+    Multiple lines
+vendor: "foobar"
+homepage: "https://foobar.org"
+license: "MIT"
+files:
+  ../testdata/fake: "/usr/local/bin/fake"
+config_files:
+  ../testdata/whatever.conf: "/etc/foo/whatever.conf"
+rpm:
+  compression: "xz"
\ No newline at end of file
diff --git a/acceptance/testdata/xz.rpm.compression.dockerfile b/acceptance/testdata/xz.rpm.compression.dockerfile
new file mode 100644
index 0000000..b6e2ef1
--- /dev/null
+++ b/acceptance/testdata/xz.rpm.compression.dockerfile
@@ -0,0 +1,11 @@
+FROM fedora
+ARG package
+COPY ${package} /tmp/foo.rpm
+RUN test "xz" = "$(rpm -qp --qf '%{PAYLOADCOMPRESSOR}' /tmp/foo.rpm)"
+RUN rpm -ivh /tmp/foo.rpm
+RUN test -e /usr/local/bin/fake
+RUN test -f /etc/foo/whatever.conf
+RUN echo wat >> /etc/foo/whatever.conf
+RUN rpm -e foo
+RUN test -f /etc/foo/whatever.conf.rpmsave
+RUN test ! -f /usr/local/bin/fake
\ No newline at end of file
diff --git a/deb/deb_test.go b/deb/deb_test.go
index 33fa024..49ac53d 100644
--- a/deb/deb_test.go
+++ b/deb/deb_test.go
@@ -253,3 +253,25 @@ func TestMinimalFields(t *testing.T) {
 	assert.NoError(t, err)
 	assert.Equal(t, string(bts), w.String())
 }
+
+func TestDebEpoch(t *testing.T) {
+	var w bytes.Buffer
+	assert.NoError(t, writeControl(&w, controlData{
+		Info: nfpm.WithDefaults(nfpm.Info{
+			Name:        "withepoch",
+			Arch:        "arm64",
+			Description: "Has an epoch added to it's version",
+			Priority:    "extra",
+			Epoch:       "2",
+			Version:     "1.0.0",
+			Section:     "default",
+		}),
+	}))
+	var golden = "testdata/withepoch.golden"
+	if *update {
+		require.NoError(t, ioutil.WriteFile(golden, w.Bytes(), 0655))
+	}
+	bts, err := ioutil.ReadFile(golden) //nolint:gosec
+	assert.NoError(t, err)
+	assert.Equal(t, string(bts), w.String())
+}
diff --git a/deb/testdata/withepoch.golden b/deb/testdata/withepoch.golden
new file mode 100644
index 0000000..15612a7
--- /dev/null
+++ b/deb/testdata/withepoch.golden
@@ -0,0 +1,7 @@
+Package: withepoch
+Version: 2:1.0.0
+Section: default
+Priority: extra
+Architecture: arm64
+Installed-Size: 0
+Description: Has an epoch added to it's version
diff --git a/rpm/rpm_test.go b/rpm/rpm_test.go
index 0dce7e6..b608888 100644
--- a/rpm/rpm_test.go
+++ b/rpm/rpm_test.go
@@ -94,6 +94,38 @@ func TestRPM(t *testing.T) {
 	assert.NoError(t, err)
 }
 
+func TestWithRPMTags(t *testing.T) {
+	var info = exampleInfo()
+	info.RPM = nfpm.RPM{
+		Group:   "default",
+		Prefix:  "/usr",
+		Release: "3",
+	}
+	var err = Default.Package(info, ioutil.Discard)
+	assert.NoError(t, err)
+}
+
+func TestRPMTagsSpec(t *testing.T) {
+	var info = exampleInfo()
+	info.RPM = nfpm.RPM{
+		Group:   "default",
+		Prefix:  "/usr",
+		Release: "5",
+	}
+
+	vs := rpmbuildVersion{Major: 4, Minor: 15, Patch: 2}
+	golden := "testdata/spec_4.15.x.golden"
+
+	var w bytes.Buffer
+	assert.NoError(t, writeSpec(&w, info, vs))
+	if *update {
+		require.NoError(t, ioutil.WriteFile(golden, w.Bytes(), 0655))
+	}
+	bts, err := ioutil.ReadFile(golden)
+	assert.NoError(t, err)
+	assert.Equal(t, string(bts), w.String())
+}
+
 func TestRPMVersionWithDash(t *testing.T) {
 	info := exampleInfo()
 	info.Version = "1.0.0-beta"
@@ -111,8 +143,8 @@ func TestRPMScripts(t *testing.T) {
 		scripts.Preun:  info.Scripts.PreRemove,
 		scripts.Postun: info.Scripts.PostRemove,
 	} {
-		data, err := ioutil.ReadFile(src)          //nolint:gosec
-		fmt.Sprintf("%s %s %s", actual, src, data) //nolint.govet
+		data, err := ioutil.ReadFile(src)         //nolint:gosec
+		fmt.Printf("%s %s %s", actual, src, data) //nolint.govet
 		assert.NoError(t, err)
 	}
 }
@@ -189,3 +221,13 @@ func TestParseRpmbuildVersionError(t *testing.T) {
 		})
 	}
 }
+
+func TestRPMMultiArch(t *testing.T) {
+	info := exampleInfo()
+
+	for k := range archToRPM {
+		info.Arch = k
+		info = ensureValidArch(info)
+		assert.Equal(t, archToRPM[k], info.Arch)
+	}
+}
diff --git a/rpm/testdata/spec_4.12.x.golden b/rpm/testdata/spec_4.12.x.golden
index c32bd11..57ec967 100644
--- a/rpm/testdata/spec_4.12.x.golden
+++ b/rpm/testdata/spec_4.12.x.golden
@@ -13,6 +13,7 @@ License: MIT
 Group: Development/Tools
 SOURCE0 : %{name}-%{version}.tar.gz
 URL: http://carlosbecker.com
+Packager: Carlos A Becker <pkg@carlosbecker.com>
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 
 
diff --git a/rpm/testdata/spec_4.13.x.golden b/rpm/testdata/spec_4.13.x.golden
index 0a78508..4c110a1 100644
--- a/rpm/testdata/spec_4.13.x.golden
+++ b/rpm/testdata/spec_4.13.x.golden
@@ -13,6 +13,7 @@ License: MIT
 Group: Development/Tools
 SOURCE0 : %{name}-%{version}.tar.gz
 URL: http://carlosbecker.com
+Packager: Carlos A Becker <pkg@carlosbecker.com>
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 
 
diff --git a/rpm/testdata/spec_4.14.x.golden b/rpm/testdata/spec_4.14.x.golden
index 0a78508..4c110a1 100644
--- a/rpm/testdata/spec_4.14.x.golden
+++ b/rpm/testdata/spec_4.14.x.golden
@@ -13,6 +13,7 @@ License: MIT
 Group: Development/Tools
 SOURCE0 : %{name}-%{version}.tar.gz
 URL: http://carlosbecker.com
+Packager: Carlos A Becker <pkg@carlosbecker.com>
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 
 
diff --git a/rpm/testdata/spec_4.15.x.golden b/rpm/testdata/spec_4.15.x.golden
new file mode 100644
index 0000000..098ca42
--- /dev/null
+++ b/rpm/testdata/spec_4.15.x.golden
@@ -0,0 +1,113 @@
+
+%define __spec_install_post %{nil}
+%define debug_package %{nil}
+%define __os_install_post %{_dbpath}/brp-compress
+%define _arch amd64
+%define _bindir /usr/local/bin
+
+Name: foo
+Summary: Foo does things
+Version: 1.0.0
+Release: 5
+License: MIT
+Group: default
+SOURCE0 : %{name}-%{version}.tar.gz
+URL: http://carlosbecker.com
+Packager: Carlos A Becker <pkg@carlosbecker.com>
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+Prefix: /usr
+
+
+Obsoletes: svn
+
+
+
+Conflicts: zsh
+
+
+
+Provides: bzr
+
+
+
+Requires: bash
+
+
+
+
+Recommends: git
+
+
+
+Suggests: bash
+
+
+
+%description
+Foo does things
+
+%prep
+%setup -q
+
+%build
+# Empty section.
+
+%install
+rm -rf %{buildroot}
+mkdir -vp %{buildroot}
+
+mkdir -vp %{buildroot}/var/log/whatever
+
+mkdir -vp %{buildroot}/usr/share/whatever
+
+
+# in builddir
+cp -a * %{buildroot}
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root,-)
+
+/usr/local/bin/fake
+
+%{_bindir}/*
+
+/etc/fake/fake.conf
+
+
+%config(noreplace) /etc/fake/fake.conf
+
+
+/var/log/whatever
+
+/usr/share/whatever
+
+
+%pre
+#!/bin/bash
+
+echo "Preinstall" > /dev/null
+
+
+%post
+#!/bin/bash
+
+echo "Postinstall" > /dev/null
+
+
+%preun
+#!/bin/bash
+
+echo "Preremove" > /dev/null
+
+
+%postun
+#!/bin/bash
+
+echo "Postremove" > /dev/null
+
+
+%changelog
+# noop