Repository: goreleaser/nfpm
Pull request #87 (2019-10-10 02:32:40)

chore: add stricter linting
These are the errors that were found and fixed

```
./bin/golangci-lint run --exclude-use-default=false --fix -v
INFO [config_reader] Config search paths: [./ /opt/projects/go/nfpm /opt/projects/go /opt/projects /opt /] 
INFO [config_reader] Used config file .golangci.yml 
INFO [lintersdb] Active 36 linters: [bodyclose deadcode depguard dogsled dupl errcheck funlen gochecknoglobals gochecknoinits gocognit goconst gocritic gocyclo gofmt goimports golint gosec gosimple govet ineffassign interfacer lll maligned misspell nakedret prealloc scopelint staticcheck structcheck stylecheck typecheck unconvert unparam unused varcheck whitespace] 
INFO [loader] Go packages loading at mode 575 (deps|exports_file|files|types_sizes|compiled_files|name|imports) took 339.823287ms 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 4.478827ms 
INFO [runner/max_same_issues] 12/15 issues with text "hugeParam: info is heavy (568 bytes); consider passing it by pointer" were hidden, use --max-same-issues 
INFO [runner] Issues before processing: 54, after processing: 14 
INFO [runner] Processors filtering stat (out/in): path_prettifier: 54/54, exclude: 54/54, diff: 26/26, max_from_linter: 14/14, skip_files: 54/54, autogenerated_exclude: 54/54, max_per_file_from_linter: 26/26, source_code: 14/14, cgo: 54/54, identifier_marker: 54/54, exclude-rules: 52/54, nolint: 26/52, uniq_by_line: 26/26, max_same_issues: 14/26, filename_unadjuster: 54/54, skip_dirs: 54/54, path_shortener: 14/14 
INFO [runner] processing took 11.387623ms with stages: nolint: 8.313388ms, identifier_marker: 1.988598ms, path_prettifier: 220.409µs, exclude-rules: 209.314µs, source_code: 193.796µs, autogenerated_exclude: 161.701µs, skip_dirs: 127.282µs, max_same_issues: 94.505µs, cgo: 25.195µs, uniq_by_line: 16.985µs, filename_unadjuster: 14.952µs, max_from_linter: 8.428µs, path_shortener: 6.739µs, max_per_file_from_linter: 4.724µs, exclude: 644ns, diff: 522ns, skip_files: 441ns 
INFO [runner] linters took 1.032264664s with stages: goanalysis_metalinter: 646.924839ms, unused: 373.810741ms 
INFO fixer took 0s with no stages                 
nfpm.go:56:8: shadow: declaration of "err" shadows declaration at line 41 (govet)
	if v, err := semver.NewVersion(config.Info.Version); err == nil {
	      ^
acceptance/placeholder.go:1:1: ST1000: at least one file in a package should have a package comment (stylecheck)
package acceptance
^
glob/glob.go:26:1: paramTypeCombine: func(a string, b string) string could be replaced with func(a, b string) string (gocritic)
func strlcp(a string, b string) string {
^
deb/deb.go:48:21: hugeParam: info is heavy (568 bytes); consider passing it by pointer (gocritic)
func (*Deb) Package(info nfpm.Info, deb io.Writer) (err error) {
                    ^
deb/deb.go:91:22: hugeParam: info is heavy (568 bytes); consider passing it by pointer (gocritic)
func createDataTarGz(info nfpm.Info) (dataTarGz, md5sums []byte, instSize int64, err error) {
                     ^
deb/deb.go:121:29: hugeParam: info is heavy (568 bytes); consider passing it by pointer (gocritic)
func createFilesInsideTarGz(info nfpm.Info, out *tar.Writer, created map[string]bool) (bytes.Buffer, int64, error) {
                            ^
deb/deb.go:245:58: hugeParam: header is heavy (216 bytes); consider passing it by pointer (gocritic)
func newItemInsideTarGz(out *tar.Writer, content []byte, header tar.Header) error {
                                                         ^
deb/deb.go:383:32: hugeParam: data is heavy (576 bytes); consider passing it by pointer (gocritic)
func writeControl(w io.Writer, data controlData) error {
                               ^
deb/deb.go:266:1: paramTypeCombine: func(out *tar.Writer, path string, dest string) error could be replaced with func(out *tar.Writer, path, dest string) error (gocritic)
func newScriptInsideTarGz(out *tar.Writer, path string, dest string) error {
^
rpm/rpm.go:182:2: builtinShadow: shadowing of predeclared identifier: copy (gocritic)
	copy := func(files map[string]string, config bool) error {
	^
rpm/rpm_test.go:102:12: Error return value of `os.Remove` is not checked (errcheck)
		os.Remove(f.Name())
		         ^
acceptance/acceptance_test.go:94:13: Error return value of `os.Setenv` is not checked (errcheck)
			os.Setenv("SEMVER", "v1.0.0-0.1.b1+git.abcdefgh")
			         ^
nfpm.go:64:2: naked return in func `Parse` with 24 lines of code (nakedret)
	return
	^
nfpm.go:105:2: naked return in func `Get` with 15 lines of code (nakedret)
	return
	^
INFO File cache stats: 18 entries of total size 80.1KiB 
INFO Memory: 15 samples, avg is 100.5MB, max is 136.5MB 
INFO Execution took 1.390817233s
```

djgilcrease: > loved it, loved the golangci config, will copy it to goreleaser as well!

ok will go fix the new issues found and get the build working :)


djgilcrease: This has breaking changes for those using `nfpm` as a library and since I will be away tomorrow (10/10) I will hold off on merging this myself.

eg https://github.com/goreleaser/goreleaser/blob/master/internal/pipe/nfpm/nfpm.go#L145 will need to change to `var info = &nfpm.Info{...}`
caarlos0: > This has breaking changes for those using `nfpm` as a library

its fine, I already bumped to 1.0.0-betax... 
codecov-io: # [Codecov](https://codecov.io/gh/goreleaser/nfpm/pull/87?src=pr&el=h1) Report
> Merging [#87](https://codecov.io/gh/goreleaser/nfpm/pull/87?src=pr&el=desc) into [master](https://codecov.io/gh/goreleaser/nfpm/commit/b47eac0b54451015ef7ca77060ad001dcb95fb5e?src=pr&el=desc) will **increase** coverage by `0.06%`.
> The diff coverage is `85.29%`.

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

```diff
@@            Coverage Diff             @@
##           master      #87      +/-   ##
==========================================
+ Coverage   71.45%   71.51%   +0.06%     
==========================================
  Files           5        5              
  Lines         473      474       +1     
==========================================
+ Hits          338      339       +1     
  Misses         84       84              
  Partials       51       51
```


| [Impacted Files](https://codecov.io/gh/goreleaser/nfpm/pull/87?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [cmd/nfpm/main.go](https://codecov.io/gh/goreleaser/nfpm/pull/87/diff?src=pr&el=tree#diff-Y21kL25mcG0vbWFpbi5nbw==) | `0% <ø> (ø)` | :arrow_up: |
| [glob/glob.go](https://codecov.io/gh/goreleaser/nfpm/pull/87/diff?src=pr&el=tree#diff-Z2xvYi9nbG9iLmdv) | `94.44% <100%> (ø)` | :arrow_up: |
| [rpm/rpm.go](https://codecov.io/gh/goreleaser/nfpm/pull/87/diff?src=pr&el=tree#diff-cnBtL3JwbS5nbw==) | `71.22% <100%> (ø)` | :arrow_up: |
| [nfpm.go](https://codecov.io/gh/goreleaser/nfpm/pull/87/diff?src=pr&el=tree#diff-bmZwbS5nbw==) | `91.04% <69.23%> (+0.13%)` | :arrow_up: |
| [deb/deb.go](https://codecov.io/gh/goreleaser/nfpm/pull/87/diff?src=pr&el=tree#diff-ZGViL2RlYi5nbw==) | `72.86% <90.9%> (ø)` | :arrow_up: |

------

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


Patch:
diff --git a/.githooks/pre-commit b/.githooks/pre-commit
new file mode 100755
index 0000000..5abb074
--- /dev/null
+++ b/.githooks/pre-commit
@@ -0,0 +1,4 @@
+#!/bin/bash
+FILES=$(git diff --staged --diff-filter=AM --no-renames --name-only)
+export TEST_PATTERN=TestSimple
+make fmt lint test && git add $FILES
diff --git a/.gitignore b/.gitignore
index 7242717..59d6cd6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,4 @@ nfpm.yaml
 .DS_Store
 bin
 coverage.out
-nfpm
+/nfpm
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 0000000..3d6c9bc
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,35 @@
+linters:
+  enable-all: true
+  disable:
+    - godox
+    - wsl
+linters-settings:
+  maligned:
+    # print struct with more effective memory layout or not, false by default
+    suggest-new: true
+  gocyclo:
+    # minimal code complexity to report, 30 by default (but we recommend 10-20)
+    min-complexity: 30
+  goimports:
+    # put imports beginning with prefix after 3rd-party packages;
+    # it's a comma-separated list of prefixes
+    local-prefixes: github.com/goreleaser/nfpm
+  govet:
+    check-shadowing: true
+  errcheck:
+    ignore: ^Close.*,fmt:.*,github.com/pkg/errors:^Wrap.*,os:^Setenv$
+  lll:
+    line-length: 200
+  golint:
+    min-confidence: .8
+  nakedret:
+    max-func-lines: 0
+  gocritic:
+    enabled-tags:
+      - style
+      - performance
+issues:
+  exclude-rules:
+    - text: "G104" # gosec G104 is caught by errcheck
+      linters:
+        - gosec
diff --git a/Makefile b/Makefile
index 897c32c..b60e665 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,7 @@ export GOPROXY := https://proxy.golang.org,https://gocenter.io,direct
 setup:
 	curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh
 	go mod tidy
+	git config core.hooksPath .githooks
 .PHONY: setup
 
 
@@ -31,7 +32,7 @@ fmt:
 .PHONY: fmt
 
 lint: check
-	./bin/golangci-lint run --disable wsl --disable godox --enable-all ./...
+	./bin/golangci-lint run --exclude-use-default=false --fix -v
 .PHONY: check
 
 ci: build lint test
@@ -41,6 +42,12 @@ build:
 	go build -o nfpm ./cmd/nfpm/main.go
 .PHONY: build
 
+deps:
+	go get -u
+	go mod tidy
+	go mod verify
+.PHONY: deps
+
 todo:
 	@grep \
 		--exclude-dir=vendor \
diff --git a/acceptance/placeholder.go b/acceptance/placeholder.go
index a98e8cf..4343761 100644
--- a/acceptance/placeholder.go
+++ b/acceptance/placeholder.go
@@ -1,3 +1,4 @@
+// Package acceptance contains acceptance tests
 package acceptance
 
 // This file only exists to make go test happy.
diff --git a/cmd/nfpm/main.go b/cmd/nfpm/main.go
index 9432fe6..2f494d0 100644
--- a/cmd/nfpm/main.go
+++ b/cmd/nfpm/main.go
@@ -8,6 +8,7 @@ import (
 	"path/filepath"
 
 	"github.com/alecthomas/kingpin"
+
 	"github.com/goreleaser/nfpm"
 	_ "github.com/goreleaser/nfpm/deb"
 	_ "github.com/goreleaser/nfpm/rpm"
diff --git a/deb/deb.go b/deb/deb.go
index 0388026..e8a9458 100644
--- a/deb/deb.go
+++ b/deb/deb.go
@@ -16,9 +16,10 @@ import (
 	"time"
 
 	"github.com/blakesmith/ar"
+	"github.com/pkg/errors"
+
 	"github.com/goreleaser/nfpm"
 	"github.com/goreleaser/nfpm/glob"
-	"github.com/pkg/errors"
 )
 
 // nolint: gochecknoinits
@@ -44,7 +45,7 @@ var Default = &Deb{}
 type Deb struct{}
 
 // Package writes a new deb package to the given writer using the given info
-func (*Deb) Package(info nfpm.Info, deb io.Writer) (err error) {
+func (*Deb) Package(info *nfpm.Info, deb io.Writer) (err error) {
 	arch, ok := archToDebian[info.Arch]
 	if ok {
 		info.Arch = arch
@@ -87,7 +88,7 @@ func addArFile(w *ar.Writer, name string, body []byte) error {
 	return err
 }
 
-func createDataTarGz(info nfpm.Info) (dataTarGz, md5sums []byte, instSize int64, err error) {
+func createDataTarGz(info *nfpm.Info) (dataTarGz, md5sums []byte, instSize int64, err error) {
 	var buf bytes.Buffer
 	var compress = gzip.NewWriter(&buf)
 	var out = tar.NewWriter(compress)
@@ -117,7 +118,7 @@ func createDataTarGz(info nfpm.Info) (dataTarGz, md5sums []byte, instSize int64,
 	return buf.Bytes(), md5buf.Bytes(), instSize, nil
 }
 
-func createFilesInsideTarGz(info nfpm.Info, out *tar.Writer, created map[string]bool) (bytes.Buffer, int64, error) {
+func createFilesInsideTarGz(info *nfpm.Info, out *tar.Writer, created map[string]bool) (bytes.Buffer, int64, error) {
 	var md5buf bytes.Buffer
 	var instSize int64
 	for _, files := range []map[string]string{
@@ -144,7 +145,7 @@ func createFilesInsideTarGz(info nfpm.Info, out *tar.Writer, created map[string]
 	return md5buf, instSize, nil
 }
 
-func createEmptyFoldersInsideTarGz(info nfpm.Info, out *tar.Writer, created map[string]bool) error {
+func createEmptyFoldersInsideTarGz(info *nfpm.Info, out *tar.Writer, created map[string]bool) error {
 	for _, folder := range info.EmptyFolders {
 		// this .nope is actually not created, because createTree ignore the
 		// last part of the path, assuming it is a file.
@@ -191,7 +192,7 @@ func copyToTarAndDigest(tarw *tar.Writer, md5w io.Writer, src, dst string) (int6
 	return info.Size(), nil
 }
 
-func createControl(instSize int64, md5sums []byte, info nfpm.Info) (controlTarGz []byte, err error) {
+func createControl(instSize int64, md5sums []byte, info *nfpm.Info) (controlTarGz []byte, err error) {
 	var buf bytes.Buffer
 	var compress = gzip.NewWriter(&buf)
 	var out = tar.NewWriter(compress)
@@ -241,8 +242,8 @@ func createControl(instSize int64, md5sums []byte, info nfpm.Info) (controlTarGz
 	return buf.Bytes(), nil
 }
 
-func newItemInsideTarGz(out *tar.Writer, content []byte, header tar.Header) error {
-	if err := out.WriteHeader(&header); err != nil {
+func newItemInsideTarGz(out *tar.Writer, content []byte, header *tar.Header) error {
+	if err := out.WriteHeader(header); err != nil {
 		return errors.Wrapf(err, "cannot write header of %s file to control.tar.gz", header.Name)
 	}
 	if _, err := out.Write(content); err != nil {
@@ -252,7 +253,7 @@ func newItemInsideTarGz(out *tar.Writer, content []byte, header tar.Header) erro
 }
 
 func newFileInsideTarGz(out *tar.Writer, name string, content []byte) error {
-	return newItemInsideTarGz(out, content, tar.Header{
+	return newItemInsideTarGz(out, content, &tar.Header{
 		Name:     filepath.ToSlash(name),
 		Size:     int64(len(content)),
 		Mode:     0644,
@@ -262,7 +263,7 @@ func newFileInsideTarGz(out *tar.Writer, name string, content []byte) error {
 	})
 }
 
-func newScriptInsideTarGz(out *tar.Writer, path string, dest string) error {
+func newScriptInsideTarGz(out *tar.Writer, path, dest string) error {
 	file, err := os.Open(path) //nolint:gosec
 	if err != nil {
 		return err
@@ -271,7 +272,7 @@ func newScriptInsideTarGz(out *tar.Writer, path string, dest string) error {
 	if err != nil {
 		return err
 	}
-	return newItemInsideTarGz(out, content, tar.Header{
+	return newItemInsideTarGz(out, content, &tar.Header{
 		Name:     filepath.ToSlash(dest),
 		Size:     int64(len(content)),
 		Mode:     0755,
@@ -323,7 +324,7 @@ func pathsToCreate(dst string) []string {
 	return result
 }
 
-func conffiles(info nfpm.Info) []byte {
+func conffiles(info *nfpm.Info) []byte {
 	// nolint: prealloc
 	var confs []string
 	for _, dst := range info.ConfigFiles {
@@ -375,7 +376,7 @@ Description: {{.Info.Description}}
 `
 
 type controlData struct {
-	Info          nfpm.Info
+	Info          *nfpm.Info
 	InstalledSize int64
 }
 
diff --git a/glob/glob.go b/glob/glob.go
index 5e71e83..f60fba5 100644
--- a/glob/glob.go
+++ b/glob/glob.go
@@ -23,7 +23,7 @@ func longestCommonPrefix(strs []string) string {
 	return lcp
 }
 
-func strlcp(a string, b string) string {
+func strlcp(a, b string) string {
 	var min int
 	if len(a) > len(b) {
 		min = len(b)
diff --git a/nfpm.go b/nfpm.go
index 41b3490..7a9fd6e 100644
--- a/nfpm.go
+++ b/nfpm.go
@@ -11,6 +11,7 @@ import (
 
 	"github.com/Masterminds/semver/v3"
 	"github.com/imdario/mergo"
+	"github.com/pkg/errors"
 
 	"gopkg.in/yaml.v2"
 )
@@ -53,7 +54,8 @@ func Parse(in io.Reader) (config Config, err error) {
 
 	config.Info.Version = os.ExpandEnv(config.Info.Version)
 	// parse the version as a semver so we can properly split the parts and support proper ordering for both rpm and deb
-	if v, err := semver.NewVersion(config.Info.Version); err == nil {
+	var v *semver.Version
+	if v, err = semver.NewVersion(config.Info.Version); err == nil {
 		config.Info.Version = fmt.Sprintf("%d.%d.%d", v.Major(), v.Minor(), v.Patch())
 		if config.Info.Release == "" {
 			config.Info.Release = v.Prerelease()
@@ -61,7 +63,7 @@ func Parse(in io.Reader) (config Config, err error) {
 		config.Info.Deb.VersionMetadata = v.Metadata()
 	}
 	err = config.Validate()
-	return
+	return config, err
 }
 
 // ParseFile decodes YAML data from a file path into a configuration struct
@@ -77,7 +79,7 @@ func ParseFile(path string) (config Config, err error) {
 
 // Packager represents any packager implementation
 type Packager interface {
-	Package(info Info, w io.Writer) error
+	Package(info *Info, w io.Writer) error
 }
 
 // Config contains the top level configuration for packages
@@ -88,21 +90,21 @@ type Config struct {
 
 // Get returns the Info struct for the given packager format. Overrides
 // for the given format are merged into the final struct
-func (c *Config) Get(format string) (info Info, err error) {
+func (c *Config) Get(format string) (info *Info, err error) {
+	info = &Info{}
 	// make a deep copy of info
-	if err = mergo.Merge(&info, c.Info); err != nil {
-		return
+	if err = mergo.Merge(info, c.Info); err != nil {
+		return nil, errors.Wrap(err, "failed to merge config into info")
 	}
 	override, ok := c.Overrides[format]
 	if !ok {
 		// no overrides
-		return
+		return info, nil
 	}
-	err = mergo.Merge(&info.Overridables, override, mergo.WithOverride)
-	if err != nil {
-		return
+	if err = mergo.Merge(&info.Overridables, override, mergo.WithOverride); err != nil {
+		return nil, errors.Wrap(err, "failed to merge overrides into info")
 	}
-	return
+	return info, nil
 }
 
 // Validate ensures that the config is well typed
@@ -178,7 +180,7 @@ type Scripts struct {
 }
 
 // Validate the given Info and returns an error if it is invalid.
-func Validate(info Info) error {
+func Validate(info *Info) error {
 	if info.Name == "" {
 		return fmt.Errorf("package name cannot be empty")
 	}
@@ -195,7 +197,7 @@ func Validate(info Info) error {
 }
 
 // WithDefaults set some sane defaults into the given Info
-func WithDefaults(info Info) Info {
+func WithDefaults(info *Info) *Info {
 	if info.Bindir == "" {
 		info.Bindir = "/usr/local/bin"
 	}
diff --git a/rpm/rpm.go b/rpm/rpm.go
index afc2e45..d0c8d71 100644
--- a/rpm/rpm.go
+++ b/rpm/rpm.go
@@ -8,9 +8,10 @@ import (
 	"os"
 
 	"github.com/google/rpmpack"
+	"github.com/pkg/errors"
+
 	"github.com/goreleaser/nfpm"
 	"github.com/goreleaser/nfpm/glob"
-	"github.com/pkg/errors"
 )
 
 // nolint: gochecknoinits
@@ -32,7 +33,7 @@ var archToRPM = map[string]string{
 	"arm64": "aarch64",
 }
 
-func ensureValidArch(info nfpm.Info) nfpm.Info {
+func ensureValidArch(info *nfpm.Info) *nfpm.Info {
 	arch, ok := archToRPM[info.Arch]
 	if ok {
 		info.Arch = arch
@@ -41,7 +42,7 @@ func ensureValidArch(info nfpm.Info) nfpm.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 {
+func (*RPM) Package(info *nfpm.Info, w io.Writer) error {
 	var (
 		err  error
 		meta *rpmpack.RPMMetaData
@@ -75,7 +76,7 @@ func (*RPM) Package(info nfpm.Info, w io.Writer) error {
 	return nil
 }
 
-func buildRPMMeta(info nfpm.Info) (*rpmpack.RPMMetaData, error) {
+func buildRPMMeta(info *nfpm.Info) (*rpmpack.RPMMetaData, error) {
 	var (
 		err error
 		provides,
@@ -131,7 +132,7 @@ func toRelation(items []string) (rpmpack.Relations, error) {
 	return relations, nil
 }
 
-func addScriptFiles(info nfpm.Info, rpm *rpmpack.RPM) error {
+func addScriptFiles(info *nfpm.Info, rpm *rpmpack.RPM) error {
 	if info.Scripts.PreInstall != "" {
 		data, err := ioutil.ReadFile(info.Scripts.PreInstall)
 		if err != nil {
@@ -167,7 +168,7 @@ func addScriptFiles(info nfpm.Info, rpm *rpmpack.RPM) error {
 	return nil
 }
 
-func addEmptyDirsRPM(info nfpm.Info, rpm *rpmpack.RPM) {
+func addEmptyDirsRPM(info *nfpm.Info, rpm *rpmpack.RPM) {
 	for _, dir := range info.EmptyFolders {
 		rpm.AddFile(
 			rpmpack.RPMFile{
@@ -177,8 +178,8 @@ func addEmptyDirsRPM(info nfpm.Info, rpm *rpmpack.RPM) {
 	}
 }
 
-func createFilesInsideRPM(info nfpm.Info, rpm *rpmpack.RPM) error {
-	copy := func(files map[string]string, config bool) error {
+func createFilesInsideRPM(info *nfpm.Info, rpm *rpmpack.RPM) error {
+	copyFunc := func(files map[string]string, config bool) error {
 		for srcglob, dstroot := range files {
 			globbed, err := glob.Glob(srcglob, dstroot)
 			if err != nil {
@@ -194,11 +195,11 @@ func createFilesInsideRPM(info nfpm.Info, rpm *rpmpack.RPM) error {
 
 		return nil
 	}
-	err := copy(info.Files, false)
+	err := copyFunc(info.Files, false)
 	if err != nil {
 		return err
 	}
-	err = copy(info.ConfigFiles, true)
+	err = copyFunc(info.ConfigFiles, true)
 	if err != nil {
 		return err
 	}


Test patch:
diff --git a/deb/deb_test.go b/deb/deb_test.go
index 0a0464e..b54f04b 100644
--- a/deb/deb_test.go
+++ b/deb/deb_test.go
@@ -9,16 +9,17 @@ import (
 	"strconv"
 	"testing"
 
-	"github.com/goreleaser/nfpm"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+
+	"github.com/goreleaser/nfpm"
 )
 
 // nolint: gochecknoglobals
 var update = flag.Bool("update", false, "update .golden files")
 
-func exampleInfo() nfpm.Info {
-	return nfpm.WithDefaults(nfpm.Info{
+func exampleInfo() *nfpm.Info {
+	return nfpm.WithDefaults(&nfpm.Info{
 		Name:        "foo",
 		Arch:        "amd64",
 		Description: "Foo does things",
@@ -119,7 +120,7 @@ func TestScripts(t *testing.T) {
 func TestNoJoinsControl(t *testing.T) {
 	var w bytes.Buffer
 	assert.NoError(t, writeControl(&w, controlData{
-		Info: nfpm.WithDefaults(nfpm.Info{
+		Info: nfpm.WithDefaults(&nfpm.Info{
 			Name:        "foo",
 			Arch:        "amd64",
 			Description: "Foo does things",
@@ -153,7 +154,7 @@ func TestNoJoinsControl(t *testing.T) {
 
 func TestDebFileDoesNotExist(t *testing.T) {
 	var err = Default.Package(
-		nfpm.WithDefaults(nfpm.Info{
+		nfpm.WithDefaults(&nfpm.Info{
 			Name:        "foo",
 			Arch:        "amd64",
 			Description: "Foo does things",
@@ -182,7 +183,7 @@ func TestDebFileDoesNotExist(t *testing.T) {
 
 func TestDebNoFiles(t *testing.T) {
 	var err = Default.Package(
-		nfpm.WithDefaults(nfpm.Info{
+		nfpm.WithDefaults(&nfpm.Info{
 			Name:        "foo",
 			Arch:        "amd64",
 			Description: "Foo does things",
@@ -204,12 +205,12 @@ func TestDebNoFiles(t *testing.T) {
 }
 
 func TestDebNoInfo(t *testing.T) {
-	var err = Default.Package(nfpm.WithDefaults(nfpm.Info{}), ioutil.Discard)
+	var err = Default.Package(nfpm.WithDefaults(&nfpm.Info{}), ioutil.Discard)
 	assert.NoError(t, err)
 }
 
 func TestConffiles(t *testing.T) {
-	out := conffiles(nfpm.Info{
+	out := conffiles(&nfpm.Info{
 		Overridables: nfpm.Overridables{
 			ConfigFiles: map[string]string{
 				"fake": "/etc/fake",
@@ -236,7 +237,7 @@ func TestPathsToCreate(t *testing.T) {
 func TestMinimalFields(t *testing.T) {
 	var w bytes.Buffer
 	assert.NoError(t, writeControl(&w, controlData{
-		Info: nfpm.WithDefaults(nfpm.Info{
+		Info: nfpm.WithDefaults(&nfpm.Info{
 			Name:        "minimal",
 			Arch:        "arm64",
 			Description: "Minimal does nothing",
@@ -257,7 +258,7 @@ func TestMinimalFields(t *testing.T) {
 func TestDebEpoch(t *testing.T) {
 	var w bytes.Buffer
 	assert.NoError(t, writeControl(&w, controlData{
-		Info: nfpm.WithDefaults(nfpm.Info{
+		Info: nfpm.WithDefaults(&nfpm.Info{
 			Name:        "withepoch",
 			Arch:        "arm64",
 			Description: "Has an epoch added to it's version",
@@ -279,7 +280,7 @@ func TestDebEpoch(t *testing.T) {
 func TestDebRules(t *testing.T) {
 	var w bytes.Buffer
 	assert.NoError(t, writeControl(&w, controlData{
-		Info: nfpm.WithDefaults(nfpm.Info{
+		Info: nfpm.WithDefaults(&nfpm.Info{
 			Name:        "lala",
 			Arch:        "arm64",
 			Description: "Has rules script",
diff --git a/nfpm_test.go b/nfpm_test.go
index 225a4df..1e3f790 100644
--- a/nfpm_test.go
+++ b/nfpm_test.go
@@ -34,7 +34,7 @@ func TestGet(t *testing.T) {
 }
 
 func TestDefaultsOnEmptyInfo(t *testing.T) {
-	info := Info{
+	info := &Info{
 		Version: "2.4.1",
 	}
 	info = WithDefaults(info)
@@ -44,7 +44,7 @@ func TestDefaultsOnEmptyInfo(t *testing.T) {
 }
 
 func TestDefaults(t *testing.T) {
-	info := Info{
+	info := &Info{
 		Bindir:      "/usr/bin",
 		Platform:    "darwin",
 		Version:     "2.4.1",
@@ -55,7 +55,7 @@ func TestDefaults(t *testing.T) {
 }
 
 func TestValidate(t *testing.T) {
-	require.NoError(t, Validate(Info{
+	require.NoError(t, Validate(&Info{
 		Name:    "as",
 		Arch:    "asd",
 		Version: "1.2.3",
@@ -65,7 +65,7 @@ func TestValidate(t *testing.T) {
 			},
 		},
 	}))
-	require.NoError(t, Validate(Info{
+	require.NoError(t, Validate(&Info{
 		Name:    "as",
 		Arch:    "asd",
 		Version: "1.2.3",
@@ -96,7 +96,7 @@ func TestValidateError(t *testing.T) {
 		err := err
 		info := info
 		t.Run(err, func(t *testing.T) {
-			require.EqualError(t, Validate(info), err)
+			require.EqualError(t, Validate(&info), err)
 		})
 	}
 }
@@ -146,11 +146,11 @@ func TestOverrides(t *testing.T) {
 	// no overrides
 	info, err := config.Get("doesnotexist")
 	assert.NoError(t, err)
-	assert.True(t, reflect.DeepEqual(config.Info, info))
+	assert.True(t, reflect.DeepEqual(&config.Info, info))
 }
 
 type fakePackager struct{}
 
-func (*fakePackager) Package(info Info, w io.Writer) error {
+func (*fakePackager) Package(info *Info, w io.Writer) error {
 	return nil
 }
diff --git a/rpm/rpm_test.go b/rpm/rpm_test.go
index c91fe3d..3fc415c 100644
--- a/rpm/rpm_test.go
+++ b/rpm/rpm_test.go
@@ -6,9 +6,10 @@ import (
 	"os"
 	"testing"
 
-	"github.com/goreleaser/nfpm"
 	"github.com/sassoftware/go-rpmutils"
 	"github.com/stretchr/testify/assert"
+
+	"github.com/goreleaser/nfpm"
 )
 
 const (
@@ -18,8 +19,8 @@ const (
 	tagPostun = 0x0402 // 1026
 )
 
-func exampleInfo() nfpm.Info {
-	return nfpm.WithDefaults(nfpm.Info{
+func exampleInfo() *nfpm.Info {
+	return nfpm.WithDefaults(&nfpm.Info{
 		Name:        "foo",
 		Arch:        "amd64",
 		Description: "Foo does things",
@@ -98,7 +99,8 @@ func TestRPMScripts(t *testing.T) {
 	f, err := ioutil.TempFile(".", fmt.Sprintf("%s-%s-*.rpm", info.Name, info.Version))
 	defer func() {
 		_ = f.Close()
-		os.Remove(f.Name())
+		err = os.Remove(f.Name())
+		assert.NoError(t, err)
 	}()
 	assert.NoError(t, err)
 	err = Default.Package(info, f)