From 8db935ff15974be530d440059aeee4b32cc43848 Mon Sep 17 00:00:00 2001 From: Marc Auberer <marc.auberer@chillibits.com> Date: Thu, 20 May 2021 19:21:48 +0200 Subject: [PATCH] feat: add support for name templates to NFPM contents (#2229) --- internal/pipe/nfpm/nfpm.go | 21 +++++-- internal/pipe/nfpm/nfpm_test.go | 57 ++++++++++++++++++- internal/pipe/nfpm/testdata/testfile-386.txt | 1 + .../pipe/nfpm/testdata/testfile-amd64.txt | 1 + www/docs/customization/nfpm.md | 4 ++ 5 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 internal/pipe/nfpm/testdata/testfile-386.txt create mode 100644 internal/pipe/nfpm/testdata/testfile-amd64.txt diff --git a/internal/pipe/nfpm/nfpm.go b/internal/pipe/nfpm/nfpm.go index 380906bab..baed637d5 100644 --- a/internal/pipe/nfpm/nfpm.go +++ b/internal/pipe/nfpm/nfpm.go @@ -174,19 +174,32 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries if err != nil { return err } - name, err := tmpl.New(ctx). + tmpl := tmpl.New(ctx). WithArtifact(binaries[0], overridden.Replacements). WithExtraFields(tmpl.Fields{ "Release": fpm.Release, "Epoch": fpm.Epoch, "PackageName": fpm.PackageName, - }). - Apply(overridden.FileNameTemplate) + }) + name, err := tmpl.Apply(overridden.FileNameTemplate) if err != nil { return err } - contents := append(files.Contents{}, overridden.Contents...) + contents := files.Contents{} + for _, content := range overridden.Contents { + src, err := tmpl.Apply(content.Source) + if err != nil { + return err + } + contents = append(contents, &files.Content{ + Source: src, + Destination: content.Destination, + Type: content.Type, + Packager: content.Packager, + FileInfo: content.FileInfo, + }) + } // FPM meta package should not contain binaries at all if !fpm.Meta { diff --git a/internal/pipe/nfpm/nfpm_test.go b/internal/pipe/nfpm/nfpm_test.go index eaee27f84..ae3cde1a1 100644 --- a/internal/pipe/nfpm/nfpm_test.go +++ b/internal/pipe/nfpm/nfpm_test.go @@ -129,6 +129,10 @@ func TestRunPipe(t *testing.T) { Destination: "/etc/nope2.conf", Type: "symlink", }, + { + Source: "./testdata/testfile-{{ .Arch }}.txt", + Destination: "/etc/nope3.conf", + }, }, Replacements: map[string]string{ "linux": "Tux", @@ -161,15 +165,24 @@ func TestRunPipe(t *testing.T) { require.NotEmpty(t, format) require.Equal(t, pkg.Name, "foo_1.0.0_Tux_"+pkg.Goarch+"-10-20."+format) require.Equal(t, pkg.ExtraOr("ID", ""), "someid") + require.ElementsMatch(t, []string{ + "./testdata/testfile.txt", + "./testdata/testfile.txt", + "./testdata/testfile.txt", + "/etc/nope.conf", + "./testdata/testfile-" + pkg.Goarch + ".txt", + binPath, + }, sources(pkg.ExtraOr("Files", files.Contents{}).(files.Contents))) require.ElementsMatch(t, []string{ "/usr/share/testfile.txt", "/etc/nope.conf", "/etc/nope-rpm.conf", "/etc/nope2.conf", + "/etc/nope3.conf", "/usr/bin/mybin", }, destinations(pkg.ExtraOr("Files", files.Contents{}).(files.Contents))) } - require.Len(t, ctx.Config.NFPMs[0].Contents, 4, "should not modify the config file list") + require.Len(t, ctx.Config.NFPMs[0].Contents, 5, "should not modify the config file list") } func TestInvalidNameTemplate(t *testing.T) { @@ -201,6 +214,40 @@ func TestInvalidNameTemplate(t *testing.T) { require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1: unexpected "}" in operand`) } +func TestRunPipeInvalidContentsSourceTemplate(t *testing.T) { + ctx := &context.Context{ + Parallelism: runtime.NumCPU(), + Artifacts: artifact.New(), + Config: config.Project{ + NFPMs: []config.NFPM{ + { + NFPMOverridables: config.NFPMOverridables{ + PackageName: "foo", + Contents: []*files.Content{ + { + Source: "{{.asdsd}", + Destination: "testfile", + }, + }, + }, + Formats: []string{"deb"}, + Builds: []string{"default"}, + }, + }, + }, + } + ctx.Artifacts.Add(&artifact.Artifact{ + Name: "mybin", + Goos: "linux", + Goarch: "amd64", + Type: artifact.Binary, + Extra: map[string]interface{}{ + "ID": "default", + }, + }) + require.EqualError(t, Pipe{}.Run(ctx), `template: tmpl:1: unexpected "}" in operand`) +} + func TestNoBuildsFound(t *testing.T) { ctx := &context.Context{ Parallelism: runtime.NumCPU(), @@ -902,3 +949,11 @@ func TestSkipSign(t *testing.T) { require.NoError(t, Pipe{}.Run(ctx)) }) } + +func sources(contents files.Contents) []string { + result := make([]string, 0, len(contents)) + for _, f := range contents { + result = append(result, f.Source) + } + return result +} diff --git a/internal/pipe/nfpm/testdata/testfile-386.txt b/internal/pipe/nfpm/testdata/testfile-386.txt new file mode 100644 index 000000000..68a4528a6 --- /dev/null +++ b/internal/pipe/nfpm/testdata/testfile-386.txt @@ -0,0 +1 @@ +this is a test file \ No newline at end of file diff --git a/internal/pipe/nfpm/testdata/testfile-amd64.txt b/internal/pipe/nfpm/testdata/testfile-amd64.txt new file mode 100644 index 000000000..68a4528a6 --- /dev/null +++ b/internal/pipe/nfpm/testdata/testfile-amd64.txt @@ -0,0 +1 @@ +this is a test file \ No newline at end of file diff --git a/www/docs/customization/nfpm.md b/www/docs/customization/nfpm.md index d1531111c..1ff4a12ae 100644 --- a/www/docs/customization/nfpm.md +++ b/www/docs/customization/nfpm.md @@ -148,6 +148,10 @@ nfpms: dst: /etc/bar.conf type: "config|noreplace" + # The src attribute also supports name templates + - src: path/{{ .Os }}-{{ .Arch }}/bar.conf + dst: /etc/foo/bar.conf + # These files are not actually present in the package, but the file names # are added to the package header. From the RPM directives documentation: #