Repository: goreleaser/goreleaser
Pull request #1964 (2020-12-23 18:45:27)

feat: ugprade nfpm
upgrade to nfpm v2

vercel[bot]: This pull request is being automatically deployed with Vercel ([learn more](https://vercel.link/github-learn-more)).  
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: [https://vercel.com/goreleaser/goreleaser/fwng0j8h6](https://vercel.com/goreleaser/goreleaser/fwng0j8h6)  
✅ Preview: [https://goreleaser-git-bump-nfpm.goreleaser.vercel.app](https://goreleaser-git-bump-nfpm.goreleaser.vercel.app)


codecov[bot]: # [Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/1964?src=pr&el=h1) Report
> Merging [#1964](https://codecov.io/gh/goreleaser/goreleaser/pull/1964?src=pr&el=desc) (af70ea3) into [master](https://codecov.io/gh/goreleaser/goreleaser/commit/f10873d9191b2cdb3863d6e9debab5bbc46a1f84?el=desc) (f10873d) will **decrease** coverage by `0.60%`.
> The diff coverage is `26.31%`.

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

```diff
@@            Coverage Diff             @@
##           master    #1964      +/-   ##
==========================================
- Coverage   82.50%   81.89%   -0.61%     
==========================================
  Files          74       74              
  Lines        3949     3972      +23     
==========================================
- Hits         3258     3253       -5     
- Misses        562      585      +23     
- Partials      129      134       +5     
```


| [Impacted Files](https://codecov.io/gh/goreleaser/goreleaser/pull/1964?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/config/config.go](https://codecov.io/gh/goreleaser/goreleaser/pull/1964/diff?src=pr&el=tree#diff-cGtnL2NvbmZpZy9jb25maWcuZ28=) | `93.75% <ø> (ø)` | |
| [internal/pipe/nfpm/nfpm.go](https://codecov.io/gh/goreleaser/goreleaser/pull/1964/diff?src=pr&el=tree#diff-aW50ZXJuYWwvcGlwZS9uZnBtL25mcG0uZ28=) | `81.55% <26.31%> (-12.99%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/goreleaser/goreleaser/pull/1964?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/goreleaser/pull/1964?src=pr&el=footer). Last update [f10873d...af70ea3](https://codecov.io/gh/goreleaser/goreleaser/pull/1964?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/go.mod b/go.mod
index 31254a28..410ad213 100644
--- a/go.mod
+++ b/go.mod
@@ -13,7 +13,7 @@ require (
 	github.com/golangci/golangci-lint v1.33.0
 	github.com/google/go-github/v28 v28.1.1
 	github.com/goreleaser/fileglob v0.3.1
-	github.com/goreleaser/nfpm v1.10.3
+	github.com/goreleaser/nfpm/v2 v2.0.0
 	github.com/imdario/mergo v0.3.11
 	github.com/jarcoal/httpmock v1.0.6
 	github.com/mattn/go-shellwords v1.0.10
@@ -30,3 +30,5 @@ require (
 
 // https://github.com/mattn/go-shellwords/pull/39
 replace github.com/mattn/go-shellwords => github.com/caarlos0/go-shellwords v1.0.11
+
+replace github.com/google/rpmpack => github.com/djgilcrease/rpmpack v0.0.0-20201221224521-5ac1d3b45cee
diff --git a/go.sum b/go.sum
index ca05788f..c007238d 100644
--- a/go.sum
+++ b/go.sum
@@ -198,6 +198,8 @@ github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TR
 github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
 github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
 github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
+github.com/djgilcrease/rpmpack v0.0.0-20201221224521-5ac1d3b45cee h1:2u15NiDCpocHztN+7rvPuklKbmzeZDXmRu6qk49bll8=
+github.com/djgilcrease/rpmpack v0.0.0-20201221224521-5ac1d3b45cee/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk=
 github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
 github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -378,8 +380,6 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
 github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/rpmpack v0.0.0-20201206194719-59e495f2b7e1 h1:BRIy5qQZKSC/nthA5ueW547F73BV5hMoIoxhPfhxa3k=
-github.com/google/rpmpack v0.0.0-20201206194719-59e495f2b7e1/go.mod h1:+y9lKiqDhR4zkLl+V9h4q0rdyrYVsWWm6LLCQP33DIk=
 github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
@@ -400,8 +400,8 @@ github.com/goreleaser/chglog v0.1.2 h1:tdzAb/ILeMnphzI9zQ7Nkq+T8R9qyXli8GydD8plF
 github.com/goreleaser/chglog v0.1.2/go.mod h1:tTZsFuSZK4epDXfjMkxzcGbrIOXprf0JFp47BjIr3B8=
 github.com/goreleaser/fileglob v0.3.1 h1:OTFDWqUUHjQazk2N5GdUqEbqT/grBnRARaAXsV07q1Y=
 github.com/goreleaser/fileglob v0.3.1/go.mod h1:kNcPrPzjCp+Ox3jmXLU5QEsjhqrtLBm6OnXAif8KRl8=
-github.com/goreleaser/nfpm v1.10.3 h1:NzpWKKzSFr7JOn55XN0SskyFOjP6BkvRt3JujoX8fws=
-github.com/goreleaser/nfpm v1.10.3/go.mod h1:EEC7YD5wi+ol0MiAshpgPANBOkjXDl7wqTLVk68OBsk=
+github.com/goreleaser/nfpm/v2 v2.0.0 h1:bsYhHEpJjLbgOuhKgPpdxVA6Ni7Zvrx6tRRkw3km2uo=
+github.com/goreleaser/nfpm/v2 v2.0.0/go.mod h1:CwZQFnLAUvqz3H1ijvb8SfTz1LYuw+DznSLOQ8uth8s=
 github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
diff --git a/internal/pipe/nfpm/nfpm.go b/internal/pipe/nfpm/nfpm.go
index e82a6e9e..35190a03 100644
--- a/internal/pipe/nfpm/nfpm.go
+++ b/internal/pipe/nfpm/nfpm.go
@@ -8,13 +8,15 @@ import (
 	"strings"
 
 	"github.com/apex/log"
-	"github.com/goreleaser/nfpm"
-	_ "github.com/goreleaser/nfpm/apk" // blank import to register the format
-	_ "github.com/goreleaser/nfpm/deb" // blank import to register the format
-	_ "github.com/goreleaser/nfpm/rpm" // blank import to register the format
+	"github.com/goreleaser/nfpm/v2"
+	_ "github.com/goreleaser/nfpm/v2/apk" // blank import to register the format
+	_ "github.com/goreleaser/nfpm/v2/deb" // blank import to register the format
+	"github.com/goreleaser/nfpm/v2/files"
+	_ "github.com/goreleaser/nfpm/v2/rpm" // blank import to register the format
 	"github.com/imdario/mergo"
 
 	"github.com/goreleaser/goreleaser/internal/artifact"
+	"github.com/goreleaser/goreleaser/internal/deprecate"
 	"github.com/goreleaser/goreleaser/internal/ids"
 	"github.com/goreleaser/goreleaser/internal/linux"
 	"github.com/goreleaser/goreleaser/internal/pipe"
@@ -50,9 +52,57 @@ func (Pipe) Default(ctx *context.Context) error {
 		if fpm.FileNameTemplate == "" {
 			fpm.FileNameTemplate = defaultNameTemplate
 		}
-		if fpm.Files == nil {
-			fpm.Files = map[string]string{}
+		if len(fpm.Files) > 0 {
+			for src, dst := range fpm.Files {
+				fpm.Contents = append(fpm.Contents, &files.Content{
+					Source:      src,
+					Destination: dst,
+				})
+			}
+			deprecate.Notice(ctx, "nfpms.files")
+		}
+		if len(fpm.ConfigFiles) > 0 {
+			for src, dst := range fpm.ConfigFiles {
+				fpm.Contents = append(fpm.Contents, &files.Content{
+					Source:      src,
+					Destination: dst,
+					Type:        "config",
+				})
+			}
+			deprecate.Notice(ctx, "nfpms.config_files")
+		}
+		if len(fpm.Symlinks) > 0 {
+			for src, dst := range fpm.Symlinks {
+				fpm.Contents = append(fpm.Contents, &files.Content{
+					Source:      src,
+					Destination: dst,
+					Type:        "symlink",
+				})
+			}
+			deprecate.Notice(ctx, "nfpms.symlinks")
+		}
+		if len(fpm.RPM.GhostFiles) > 0 {
+			for _, dst := range fpm.RPM.GhostFiles {
+				fpm.Contents = append(fpm.Contents, &files.Content{
+					Destination: dst,
+					Type:        "ghost",
+					Packager:    "rpm",
+				})
+			}
+			deprecate.Notice(ctx, "nfpms.rpm.ghost_files")
 		}
+		if len(fpm.RPM.ConfigNoReplaceFiles) > 0 {
+			for src, dst := range fpm.RPM.ConfigNoReplaceFiles {
+				fpm.Contents = append(fpm.Contents, &files.Content{
+					Source:      src,
+					Destination: dst,
+					Type:        "config|noreplace",
+					Packager:    "rpm",
+				})
+			}
+			deprecate.Notice(ctx, "nfpms.rpm.config_noreplace_files")
+		}
+
 		if len(fpm.Builds) == 0 {
 			for _, b := range ctx.Config.Builds {
 				fpm.Builds = append(fpm.Builds, b.ID)
@@ -130,10 +180,10 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries
 	if err != nil {
 		return err
 	}
-	var files = map[string]string{}
-	for k, v := range overridden.Files {
-		files[k] = v
-	}
+
+	var contents files.Contents
+	copy(overridden.Contents, contents)
+
 	// FPM meta package should not contain binaries at all
 	if !fpm.Meta {
 		var log = log.WithField("package", name+"."+format).WithField("arch", arch)
@@ -141,10 +191,14 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries
 			src := binary.Path
 			dst := filepath.Join(fpm.Bindir, binary.Name)
 			log.WithField("src", src).WithField("dst", dst).Debug("adding binary to package")
-			files[src] = dst
+			contents = append(contents, &files.Content{
+				Source:      src,
+				Destination: dst,
+			})
 		}
 	}
-	log.WithField("files", files).Debug("all archive files")
+
+	log.WithField("files", contents).Debug("all archive files")
 
 	var info = &nfpm.Info{
 		Arch:        arch,
@@ -167,9 +221,7 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries
 			Suggests:     overridden.Suggests,
 			Replaces:     overridden.Replaces,
 			EmptyFolders: overridden.EmptyFolders,
-			Files:        files,
-			ConfigFiles:  overridden.ConfigFiles,
-			Symlinks:     overridden.Symlinks,
+			Contents:     contents,
 			Scripts: nfpm.Scripts{
 				PreInstall:  overridden.Scripts.PreInstall,
 				PostInstall: overridden.Scripts.PostInstall,
@@ -198,11 +250,9 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries
 				},
 			},
 			RPM: nfpm.RPM{
-				Summary:              overridden.RPM.Summary,
-				Group:                overridden.RPM.Group,
-				Compression:          overridden.RPM.Compression,
-				GhostFiles:           overridden.RPM.GhostFiles,
-				ConfigNoReplaceFiles: overridden.RPM.ConfigNoReplaceFiles,
+				Summary:     overridden.RPM.Summary,
+				Group:       overridden.RPM.Group,
+				Compression: overridden.RPM.Compression,
 				Signature: nfpm.RPMSignature{
 					KeyFile:       overridden.RPM.Signature.KeyFile,
 					KeyPassphrase: getPassphraseFromEnv(ctx, "RPM", fpm.ID),
@@ -257,7 +307,7 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries
 			"Builds": binaries,
 			"ID":     fpm.ID,
 			"Format": format,
-			"Files":  files,
+			"Files":  contents,
 		},
 	})
 	return nil
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 513a21cd..d22b847e 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -9,6 +9,7 @@ import (
 	"strings"
 
 	"github.com/apex/log"
+	"github.com/goreleaser/nfpm/v2/files"
 	yaml "gopkg.in/yaml.v2"
 )
 
@@ -335,12 +336,11 @@ type NFPMRPMSignature struct {
 
 // NFPMRPM is custom configs that are only available on RPM packages.
 type NFPMRPM struct {
-	Summary     string `yaml:"summary,omitempty"`
-	Group       string `yaml:"group,omitempty"`
-	Compression string `yaml:"compression,omitempty"`
-	// https://www.cl.cam.ac.uk/~jw35/docs/rpm_config.html
-	ConfigNoReplaceFiles map[string]string `yaml:"config_noreplace_files,omitempty"`
-	GhostFiles           []string          `yaml:"ghost_files,omitempty"`
+	Summary              string            `yaml:"summary,omitempty"`
+	Group                string            `yaml:"group,omitempty"`
+	Compression          string            `yaml:"compression,omitempty"`
+	ConfigNoReplaceFiles map[string]string `yaml:"config_noreplace_files,omitempty"` // depreacated: use contents instead
+	GhostFiles           []string          `yaml:"ghost_files,omitempty"`            // depreacated: use contents instead
 	Signature            NFPMRPMSignature  `yaml:"signature,omitempty"`
 }
 
@@ -407,9 +407,10 @@ type NFPMOverridables struct {
 	Conflicts        []string          `yaml:",omitempty"`
 	Replaces         []string          `yaml:",omitempty"`
 	EmptyFolders     []string          `yaml:"empty_folders,omitempty"`
-	Files            map[string]string `yaml:",omitempty"`
-	ConfigFiles      map[string]string `yaml:"config_files,omitempty"`
-	Symlinks         map[string]string `yaml:"symlinks,omitempty"`
+	Contents         files.Contents    `yaml:"contents,omitempty"`
+	Files            map[string]string `yaml:",omitempty"`             // deprecated: use contents instead
+	ConfigFiles      map[string]string `yaml:"config_files,omitempty"` // deprecated: use contents instead
+	Symlinks         map[string]string `yaml:"symlinks,omitempty"`     // deprecated: use contents instead
 	Scripts          NFPMScripts       `yaml:"scripts,omitempty"`
 	RPM              NFPMRPM           `yaml:"rpm,omitempty"`
 	Deb              NFPMDeb           `yaml:"deb,omitempty"`
diff --git a/www/docs/customization/nfpm.md b/www/docs/customization/nfpm.md
index ce46052c..ee690e0a 100644
--- a/www/docs/customization/nfpm.md
+++ b/www/docs/customization/nfpm.md
@@ -111,26 +111,68 @@ nfpms:
     empty_folders:
       - /var/log/foobar
 
-    # Files to add to your package (beyond the binary).
-    # Keys are source paths/globs to get the files from.
-    # Values are the destination locations of the files in the package.
-    # Use globs to add all contents of a folder.
-    files:
-      "scripts/etc/init.d/**": "/etc/init.d"
-      "path/**/glob": "/var/foo/glob"
-
-    # Config files to add to your package. They are about the same as
-    # the files keyword, except package managers treat them differently (while
-    # uninstalling, mostly).
-    # Keys are source paths/globs to get the files from.
-    # Values are the destination locations of the files in the package.
-    config_files:
-      "tmp/app_generated.conf": "/etc/app.conf"
-      "conf/*.conf": "/etc/foo/"
-
-    # Symlinks mapping from symlink name inside package to target inside package (overridable)
-    symlinks:
-      /sbin/foo: /usr/local/bin/foo
+    # Contents to add to the package.
+    # GoReleaser will automatically add the binaries.
+    contents:
+      # Basic file that applies to all packagers
+      - src: path/to/local/foo
+        dst: /usr/local/bin/foo
+
+      # Simple config file
+      - src: path/to/local/foo.conf
+        dst: /etc/foo.conf
+        type: config
+
+      # Simple symlink
+      - src: /sbin/foo # link name
+        dst: /usr/local/bin/foo # real location
+        type: "symlink"
+
+      # Corresponds to %config(noreplace) if the packager is rpm, otherwise it is just a config file
+      - src: path/to/local/bar.conf
+        dst: /etc/bar.conf
+        type: "config|noreplace"
+
+      # These files are not actually present in the package, but the file names
+      # are added to the package header. From the RPM directives documentation:
+      #
+      # "There are times when a file should be owned by the package but not
+      # installed - log files and state files are good examples of cases you might
+      # desire this to happen."
+      #
+      # "The way to achieve this, is to use the %ghost directive. By adding this
+      # directive to the line containing a file, RPM will know about the ghosted
+      # file, but will not add it to the package."
+      #
+      # For non rpm packages ghost files are ignored at this time.
+      - dst: /etc/casper.conf
+        type: ghost
+      - dst: /var/log/boo.log
+        type: ghost
+
+      # You can user the packager field to add files that are unique to a specific packager
+      - src: path/to/rpm/file.conf
+        dst: /etc/file.conf
+        type: "config|noreplace"
+        packager: rpm
+      - src: path/to/deb/file.conf
+        dst: /etc/file.conf
+        type: "config|noreplace"
+        packager: deb
+      - src: path/to/apk/file.conf
+        dst: /etc/file.conf
+        type: "config|noreplace"
+        packager: apk
+
+      # Sometimes it is important to be able to set the mtime, mode, owner, or group for a file
+      # that differs from what is on the local build system at build time.
+      - src: path/to/foo
+        dst: /usr/local/foo
+        file_info:
+          mode: 0644
+          mtime: 2008-01-02T15:04:05Z
+          owner: notRoot
+          group: notRoot
 
     # Scripts to execute during the installation of the package.
     # Keys are the possible targets during the installation process
diff --git a/www/docs/deprecations.md b/www/docs/deprecations.md
index 764bd013..15886666 100644
--- a/www/docs/deprecations.md
+++ b/www/docs/deprecations.md
@@ -15,6 +15,140 @@ goreleaser check
 
 ## Active deprecation notices
 
+### nfpms.files
+
+> since 2020-12-21 (v0.149.0)
+
+`files` is deprecated in favor of `contents` (check [this page](https://goreleaser.com/customization/nfpm/) for more details):
+
+Change this:
+
+=== "Before"
+    ```yaml
+    nfpms:
+      -
+        files:
+          foo: bar
+    ```
+
+=== "After"
+    ```yaml
+    nfpms:
+      -
+        contents:
+          - src: foo
+            dst: bar
+    ```
+
+### nfpms.config_files
+
+> since 2020-12-21 (v0.149.0)
+
+`config_files` is deprecated in favor of `contents` (check [this page](https://goreleaser.com/customization/nfpm/) for more details):
+
+Change this:
+
+=== "Before"
+    ```yaml
+    nfpms:
+      -
+        config_files:
+          foo: bar
+    ```
+
+=== "After"
+    ```yaml
+    nfpms:
+      -
+        contents:
+          - src: foo
+            dst: bar
+            type: config
+    ```
+
+### nfpms.symlinks
+
+> since 2020-12-21 (v0.149.0)
+
+`symlinks` is deprecated in favor of `contents` (check [this page](https://goreleaser.com/customization/nfpm/) for more details):
+
+Change this:
+
+=== "Before"
+    ```yaml
+    nfpms:
+      -
+        symlinks:
+          foo: bar
+    ```
+
+=== "After"
+    ```yaml
+    nfpms:
+      -
+        contents:
+          - src: foo
+            dst: bar
+            type: symlink
+    ```
+
+
+### nfpms.rpm.ghost_files
+
+> since 2020-12-21 (v0.149.0)
+
+`rpm.ghost_files` is deprecated in favor of `contents` (check [this page](https://goreleaser.com/customization/nfpm/) for more details):
+
+Change this:
+
+=== "Before"
+    ```yaml
+    nfpms:
+      -
+        rpm:
+          ghost_files:
+            - foo
+    ```
+
+=== "After"
+    ```yaml
+    nfpms:
+      -
+        contents:
+          - dst: bar
+            type: ghost
+            packager: rpm # optional
+    ```
+
+### nfpms.rpm.config_noreplace_files
+
+> since 2020-12-21 (v0.149.0)
+
+`rpm.config_noreplace_files` is deprecated in favor of `contents` (check [this page](https://goreleaser.com/customization/nfpm/) for more details):
+
+Change this:
+
+=== "Before"
+    ```yaml
+    nfpms:
+      -
+        rpm:
+          config_noreplace_files:
+            foo: bar
+    ```
+
+=== "After"
+    ```yaml
+    nfpms:
+      -
+        contents:
+          - src: foo
+            dst: bar
+            type: config|noreplace
+            packager: rpm # optional
+    ```
+
+
 ### brews.github
 
 > since 2020-07-06 (v0.139.0)


Test patch:
diff --git a/internal/pipe/nfpm/nfpm_test.go b/internal/pipe/nfpm/nfpm_test.go
index 0bf6be35..661302d5 100644
--- a/internal/pipe/nfpm/nfpm_test.go
+++ b/internal/pipe/nfpm/nfpm_test.go
@@ -11,6 +11,7 @@ import (
 	"github.com/goreleaser/goreleaser/internal/testlib"
 	"github.com/goreleaser/goreleaser/pkg/config"
 	"github.com/goreleaser/goreleaser/pkg/context"
+	"github.com/goreleaser/nfpm/v2/files"
 	"github.com/stretchr/testify/require"
 )
 
@@ -46,7 +47,6 @@ func TestRunPipeInvalidFormat(t *testing.T) {
 				NFPMOverridables: config.NFPMOverridables{
 					PackageName:      "foo",
 					FileNameTemplate: defaultNameTemplate,
-					Files:            map[string]string{},
 				},
 			},
 		},
@@ -59,7 +59,7 @@ func TestRunPipeInvalidFormat(t *testing.T) {
 		for _, goarch := range []string{"amd64", "386"} {
 			ctx.Artifacts.Add(&artifact.Artifact{
 				Name:   "mybin",
-				Path:   "whatever",
+				Path:   "testdata/testfile.txt",
 				Goarch: goarch,
 				Goos:   goos,
 				Type:   artifact.Binary,
@@ -105,26 +105,32 @@ func TestRunPipe(t *testing.T) {
 					EmptyFolders:     []string{"/var/log/foobar"},
 					Release:          "10",
 					Epoch:            "20",
-					Files: map[string]string{
-						"./testdata/testfile.txt": "/usr/share/testfile.txt",
-					},
-					ConfigFiles: map[string]string{
-						"./testdata/testfile.txt": "/etc/nope.conf",
-					},
-					Symlinks: map[string]string{
-						"/etc/nope2.conf": "/etc/nope.conf",
+					Contents: []*files.Content{
+						{
+							Source:      "./testdata/testfile.txt",
+							Destination: "/usr/share/testfile.txt",
+						},
+						{
+							Source:      "./testdata/testfile.txt",
+							Destination: "/etc/nope.conf",
+							Type:        "config",
+						},
+						{
+							Source:      "./testdata/testfile.txt",
+							Destination: "/etc/nope-rpm.conf",
+							Type:        "config",
+							Packager:    "rpm",
+						},
+						{
+							Source:      "/etc/nope.conf",
+							Destination: "/etc/nope2.conf",
+							Type:        "symlink",
+						},
 					},
 					Replacements: map[string]string{
 						"linux": "Tux",
 					},
 				},
-				Overrides: map[string]config.NFPMOverridables{
-					"rpm": {
-						ConfigFiles: map[string]string{
-							"./testdata/testfile.txt": "/etc/nope-rpm.conf",
-						},
-					},
-				},
 			},
 		},
 	})
@@ -153,7 +159,8 @@ func TestRunPipe(t *testing.T) {
 		require.Equal(t, pkg.Name, "mybin_1.0.0_Tux_"+pkg.Goarch+"-10-20."+format)
 		require.Equal(t, pkg.ExtraOr("ID", ""), "someid")
 	}
-	require.Len(t, ctx.Config.NFPMs[0].Files, 1, "should not modify the config file list")
+	require.Len(t, ctx.Config.NFPMs[0].Contents, 4, "should not modify the config file list")
+
 }
 
 func TestInvalidNameTemplate(t *testing.T) {
@@ -224,8 +231,11 @@ func TestCreateFileDoesntExist(t *testing.T) {
 				Builds:  []string{"default"},
 				NFPMOverridables: config.NFPMOverridables{
 					PackageName: "foo",
-					Files: map[string]string{
-						"testdata/testfile.txt": "/var/lib/test/testfile.txt",
+					Contents: []*files.Content{
+						{
+							Source:      "testdata/testfile.txt",
+							Destination: "/var/lib/test/testfile.txt",
+						},
 					},
 				},
 			},
@@ -297,6 +307,51 @@ func TestDefault(t *testing.T) {
 	require.Equal(t, ctx.Config.ProjectName, ctx.Config.NFPMs[0].PackageName)
 }
 
+func TestDefaultDeprecatedOptions(t *testing.T) {
+	var ctx = &context.Context{
+		Config: config.Project{
+			ProjectName: "foobar",
+			NFPMs: []config.NFPM{
+				{
+					NFPMOverridables: config.NFPMOverridables{
+						Files: map[string]string{
+							"testdata/testfile.txt": "/bin/foo",
+						},
+						ConfigFiles: map[string]string{
+							"testdata/testfile.txt": "/etc/foo.conf",
+						},
+						Symlinks: map[string]string{
+							"/etc/foo.conf": "/etc/foov2.conf",
+						},
+						RPM: config.NFPMRPM{
+							GhostFiles: []string{"/etc/ghost.conf"},
+							ConfigNoReplaceFiles: map[string]string{
+								"testdata/testfile.txt": "/etc/foo_keep.conf",
+							},
+						},
+					},
+				},
+			},
+			Builds: []config.Build{
+				{ID: "foo"},
+				{ID: "bar"},
+			},
+		},
+	}
+	require.NoError(t, Pipe{}.Default(ctx))
+	require.Equal(t, "/usr/local/bin", ctx.Config.NFPMs[0].Bindir)
+	require.Equal(t, []string{"foo", "bar"}, ctx.Config.NFPMs[0].Builds)
+	require.ElementsMatch(t, []*files.Content{
+		{Source: "testdata/testfile.txt", Destination: "/bin/foo"},
+		{Source: "testdata/testfile.txt", Destination: "/etc/foo.conf", Type: "config"},
+		{Source: "/etc/foo.conf", Destination: "/etc/foov2.conf", Type: "symlink"},
+		{Destination: "/etc/ghost.conf", Type: "ghost", Packager: "rpm"},
+		{Source: "testdata/testfile.txt", Destination: "/etc/foo_keep.conf", Type: "config|noreplace", Packager: "rpm"},
+	}, ctx.Config.NFPMs[0].Contents)
+	require.Equal(t, defaultNameTemplate, ctx.Config.NFPMs[0].FileNameTemplate)
+	require.Equal(t, ctx.Config.ProjectName, ctx.Config.NFPMs[0].PackageName)
+}
+
 func TestDefaultSet(t *testing.T) {
 	var ctx = &context.Context{
 		Config: config.Project{
@@ -366,8 +421,11 @@ func TestDebSpecificConfig(t *testing.T) {
 				Formats: []string{"deb"},
 				NFPMOverridables: config.NFPMOverridables{
 					PackageName: "foo",
-					Files: map[string]string{
-						"./testdata/testfile.txt": "/usr/share/testfile.txt",
+					Contents: []*files.Content{
+						{
+							Source:      "testdata/testfile.txt",
+							Destination: "/usr/share/testfile.txt",
+						},
 					},
 					Deb: config.NFPMDeb{
 						Signature: config.NFPMDebSignature{
@@ -436,8 +494,11 @@ func TestRPMSpecificConfig(t *testing.T) {
 				Formats: []string{"rpm"},
 				NFPMOverridables: config.NFPMOverridables{
 					PackageName: "foo",
-					Files: map[string]string{
-						"./testdata/testfile.txt": "/usr/share/testfile.txt",
+					Contents: []*files.Content{
+						{
+							Source:      "testdata/testfile.txt",
+							Destination: "/usr/share/testfile.txt",
+						},
 					},
 					RPM: config.NFPMRPM{
 						Signature: config.NFPMRPMSignature{
@@ -507,8 +568,11 @@ func TestAPKSpecificConfig(t *testing.T) {
 				Formats:    []string{"apk"},
 				NFPMOverridables: config.NFPMOverridables{
 					PackageName: "foo",
-					Files: map[string]string{
-						"./testdata/testfile.txt": "/usr/share/testfile.txt",
+					Contents: []*files.Content{
+						{
+							Source:      "testdata/testfile.txt",
+							Destination: "/usr/share/testfile.txt",
+						},
 					},
 					APK: config.NFPMAPK{
 						Signature: config.NFPMAPKSignature{
@@ -609,23 +673,27 @@ func TestMeta(t *testing.T) {
 					EmptyFolders:     []string{"/var/log/foobar"},
 					Release:          "10",
 					Epoch:            "20",
-					Files: map[string]string{
-						"./testdata/testfile.txt": "/usr/share/testfile.txt",
-					},
-					ConfigFiles: map[string]string{
-						"./testdata/testfile.txt": "/etc/nope.conf",
+					Contents: []*files.Content{
+						{
+							Source:      "testdata/testfile.txt",
+							Destination: "/usr/share/testfile.txt",
+						},
+						{
+							Source:      "./testdata/testfile.txt",
+							Destination: "/etc/nope.conf",
+							Type:        "config",
+						},
+						{
+							Source:      "./testdata/testfile.txt",
+							Destination: "/etc/nope-rpm.conf",
+							Type:        "config",
+							Packager:    "rpm",
+						},
 					},
 					Replacements: map[string]string{
 						"linux": "Tux",
 					},
 				},
-				Overrides: map[string]config.NFPMOverridables{
-					"rpm": {
-						ConfigFiles: map[string]string{
-							"./testdata/testfile.txt": "/etc/nope-rpm.conf",
-						},
-					},
-				},
 			},
 		},
 	})
@@ -654,13 +722,14 @@ func TestMeta(t *testing.T) {
 		require.Equal(t, pkg.Name, "mybin_1.0.0_Tux_"+pkg.Goarch+"-10-20."+format)
 		require.Equal(t, pkg.ExtraOr("ID", ""), "someid")
 	}
-	require.Len(t, ctx.Config.NFPMs[0].Files, 1, "should not modify the config file list")
+
+	require.Len(t, ctx.Config.NFPMs[0].Contents, 3, "should not modify the config file list")
 
 	// ensure that no binaries added
 	for _, pkg := range packages {
-		files := pkg.ExtraOr("Files", map[string]string{}).(map[string]string)
-		for _, dest := range files {
-			require.NotEqual(t, "/usr/bin/mybin", dest, "binary file should not be added")
+		contents := pkg.ExtraOr("Files", files.Contents{}).(files.Contents)
+		for _, f := range contents {
+			require.NotEqual(t, "/usr/bin/mybin", f.Destination, "binary file should not be added")
 		}
 	}
 }
@@ -685,8 +754,11 @@ func TestSkipSign(t *testing.T) {
 				NFPMOverridables: config.NFPMOverridables{
 					PackageName:      "foo",
 					FileNameTemplate: defaultNameTemplate,
-					Files: map[string]string{
-						"./testdata/testfile.txt": "/usr/share/testfile.txt",
+					Contents: []*files.Content{
+						{
+							Source:      "testdata/testfile.txt",
+							Destination: "/usr/share/testfile.txt",
+						},
 					},
 					Deb: config.NFPMDeb{
 						Signature: config.NFPMDebSignature{