From 8afb5eafe5ddd1eaba9f2a90ab50f2e636fad134 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Tue, 7 Sep 2021 15:43:06 -0300 Subject: [PATCH] feat: Add support for templating NFPM bindir (#2466) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Add support for templating NFPM bindir Example: Allow software to be deployed in '/usr/lib64' directory on x86_64 arch and in '/usr/lib' directory in i386 * test: invalid bindir template Signed-off-by: Carlos Alexandro Becker * docs: bindir template Signed-off-by: Carlos Alexandro Becker Co-authored-by: RĂ©mi Ferrand --- internal/pipe/nfpm/nfpm.go | 7 +++- internal/pipe/nfpm/nfpm_test.go | 71 +++++++++++++++++++++++++++++++++ www/docs/customization/nfpm.md | 3 +- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/internal/pipe/nfpm/nfpm.go b/internal/pipe/nfpm/nfpm.go index d6efe12a25f..d76f8294a43 100644 --- a/internal/pipe/nfpm/nfpm.go +++ b/internal/pipe/nfpm/nfpm.go @@ -130,6 +130,11 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries return err } + binDir, err := tmpl.Apply(fpm.Bindir) + if err != nil { + return err + } + homepage, err := tmpl.Apply(fpm.Homepage) if err != nil { return err @@ -179,7 +184,7 @@ func create(ctx *context.Context, fpm config.NFPM, format, arch string, binaries log := log.WithField("package", name+"."+format).WithField("arch", arch) for _, binary := range binaries { src := binary.Path - dst := filepath.Join(fpm.Bindir, filepath.Base(binary.Name)) + dst := filepath.Join(binDir, filepath.Base(binary.Name)) log.WithField("src", src).WithField("dst", dst).Debug("adding binary to package") contents = append(contents, &files.Content{ Source: filepath.ToSlash(src), diff --git a/internal/pipe/nfpm/nfpm_test.go b/internal/pipe/nfpm/nfpm_test.go index e249b4e4dd1..6f3e7d3e6b1 100644 --- a/internal/pipe/nfpm/nfpm_test.go +++ b/internal/pipe/nfpm/nfpm_test.go @@ -279,6 +279,12 @@ func TestInvalidTemplate(t *testing.T) { ctx.Config.NFPMs[0].APK.Signature.KeyFile = "{{ .NOPE_KEY_FILE }}" require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:3: executing "tmpl" at <.NOPE_KEY_FILE>: map has no entry for key "NOPE_KEY_FILE"`) }) + + t.Run("bindir", func(t *testing.T) { + ctx := makeCtx() + ctx.Config.NFPMs[0].Bindir = "/usr/local/{{ .NOPE }}" + require.Contains(t, Pipe{}.Run(ctx).Error(), `template: tmpl:1:14: executing "tmpl" at <.NOPE>: map has no entry for key "NOPE"`) + }) } func TestRunPipeInvalidContentsSourceTemplate(t *testing.T) { @@ -1052,6 +1058,71 @@ func TestSkipSign(t *testing.T) { }) } +func TestBinDirTemplating(t *testing.T) { + folder := t.TempDir() + dist := filepath.Join(folder, "dist") + require.NoError(t, os.Mkdir(dist, 0o755)) + require.NoError(t, os.Mkdir(filepath.Join(dist, "mybin"), 0o755)) + binPath := filepath.Join(dist, "mybin", "mybin") + f, err := os.Create(binPath) + require.NoError(t, err) + require.NoError(t, f.Close()) + ctx := context.New(config.Project{ + ProjectName: "mybin", + Dist: dist, + Env: []string{ + "PRO=pro", + "DESC=templates", + }, + NFPMs: []config.NFPM{ + { + ID: "someid", + // Bindir should pass through the template engine + Bindir: "/usr/lib/{{ .Env.PRO }}/nagios/plugins", + Builds: []string{"default"}, + Formats: []string{"rpm"}, + Section: "somesection", + Priority: "standard", + Description: "Some description with {{ .Env.DESC }}", + License: "MIT", + Maintainer: "me@me", + Vendor: "asdf", + Homepage: "https://goreleaser.com/{{ .Env.PRO }}", + NFPMOverridables: config.NFPMOverridables{ + PackageName: "foo", + }, + }, + }, + }) + ctx.Version = "1.0.0" + ctx.Git = context.GitInfo{CurrentTag: "v1.0.0"} + for _, goos := range []string{"linux"} { + for _, goarch := range []string{"amd64", "386"} { + ctx.Artifacts.Add(&artifact.Artifact{ + Name: "subdir/mybin", + Path: binPath, + Goarch: goarch, + Goos: goos, + Type: artifact.Binary, + Extra: map[string]interface{}{ + "ID": "default", + }, + }) + } + } + require.NoError(t, Pipe{}.Run(ctx)) + packages := ctx.Artifacts.Filter(artifact.ByType(artifact.LinuxPackage)).List() + + for _, pkg := range packages { + format := pkg.ExtraOr("Format", "").(string) + require.NotEmpty(t, format) + // the final binary should contain the evaluated bindir (after template eval) + require.ElementsMatch(t, []string{ + "/usr/lib/pro/nagios/plugins/mybin", + }, destinations(pkg.ExtraOr("Files", files.Contents{}).(files.Contents))) + } +} + func sources(contents files.Contents) []string { result := make([]string, 0, len(contents)) for _, f := range contents { diff --git a/www/docs/customization/nfpm.md b/www/docs/customization/nfpm.md index b6d9097f3df..1c2fc8e9ad0 100644 --- a/www/docs/customization/nfpm.md +++ b/www/docs/customization/nfpm.md @@ -90,7 +90,8 @@ nfpms: replaces: - fish - # Override default /usr/local/bin destination for binaries + # Template to the path that the binaries should be installed. + # Defaults to `/usr/local/bin`. bindir: /usr/bin # Version Epoch.