1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-09-16 09:26:52 +02:00

refactor: add function to apply template multiple times (#4158)

If applied, this commit simplifies the code required to support
templated fields in configuration files. This should make it easier to
add more templated fields in the future.

As [discussed first on
Discord](https://discord.com/channels/890434333251362866/1032457293687685191/1124033219747127316).
This commit is contained in:
Tom Payne
2023-06-30 19:46:53 +02:00
committed by GitHub
parent 5f7be841d8
commit c57cdab0c6
10 changed files with 88 additions and 172 deletions

View File

@@ -70,20 +70,15 @@ func Eval(template *tmpl.Template, files []config.File) ([]config.File, error) {
} }
func tmplInfo(template *tmpl.Template, info *config.FileInfo) error { func tmplInfo(template *tmpl.Template, info *config.FileInfo) error {
var err error if err := template.ApplyAll(
info.Owner, err = template.Apply(info.Owner) &info.Owner,
if err != nil { &info.Group,
return fmt.Errorf("failed to apply template %s: %w", info.Owner, err) &info.MTime,
} ); err != nil {
info.Group, err = template.Apply(info.Group) return err
if err != nil {
return fmt.Errorf("failed to apply template %s: %w", info.Group, err)
}
info.MTime, err = template.Apply(info.MTime)
if err != nil {
return fmt.Errorf("failed to apply template %s: %w", info.MTime, err)
} }
if info.MTime != "" { if info.MTime != "" {
var err error
info.ParsedMTime, err = time.Parse(time.RFC3339Nano, info.MTime) info.ParsedMTime, err = time.Parse(time.RFC3339Nano, info.MTime)
if err != nil { if err != nil {
return fmt.Errorf("failed to parse %s: %w", info.MTime, err) return fmt.Errorf("failed to parse %s: %w", info.MTime, err)

View File

@@ -218,18 +218,12 @@ func doPush(ctx *context.Context, art *artifact.Artifact) error {
func buildNuspec(ctx *context.Context, choco config.Chocolatey) ([]byte, error) { func buildNuspec(ctx *context.Context, choco config.Chocolatey) ([]byte, error) {
tpl := tmpl.New(ctx) tpl := tmpl.New(ctx)
summary, err := tpl.Apply(choco.Summary)
if err != nil {
return nil, err
}
description, err := tpl.Apply(choco.Description) if err := tpl.ApplyAll(
if err != nil { &choco.Summary,
return nil, err &choco.Description,
} &choco.ReleaseNotes,
); err != nil {
releaseNotes, err := tpl.Apply(choco.ReleaseNotes)
if err != nil {
return nil, err return nil, err
} }
@@ -251,9 +245,9 @@ func buildNuspec(ctx *context.Context, choco config.Chocolatey) ([]byte, error)
DocsURL: choco.DocsURL, DocsURL: choco.DocsURL,
BugTrackerURL: choco.BugTrackerURL, BugTrackerURL: choco.BugTrackerURL,
Tags: choco.Tags, Tags: choco.Tags,
Summary: summary, Summary: choco.Summary,
Description: description, Description: choco.Description,
ReleaseNotes: releaseNotes, ReleaseNotes: choco.ReleaseNotes,
}, },
Files: Files{File: []File{ Files: Files{File: []File{
{Source: "tools\\**", Target: "tools"}, {Source: "tools\\**", Target: "tools"},

View File

@@ -159,31 +159,17 @@ func doRun(ctx *context.Context, krew config.Krew, cl client.ReleaserURLTemplate
func templateFields(ctx *context.Context, krew config.Krew) (config.Krew, error) { func templateFields(ctx *context.Context, krew config.Krew) (config.Krew, error) {
t := tmpl.New(ctx) t := tmpl.New(ctx)
var err error
krew.Name, err = t.Apply(krew.Name) if err := t.ApplyAll(
if err != nil { &krew.Name,
&krew.Homepage,
&krew.Description,
&krew.Caveats,
&krew.ShortDescription,
); err != nil {
return config.Krew{}, err return config.Krew{}, err
} }
krew.Homepage, err = t.Apply(krew.Homepage)
if err != nil {
return config.Krew{}, err
}
krew.Description, err = t.Apply(krew.Description)
if err != nil {
return config.Krew{}, err
}
krew.Caveats, err = t.Apply(krew.Caveats)
if err != nil {
return config.Krew{}, err
}
krew.ShortDescription, err = t.Apply(krew.ShortDescription)
if err != nil {
return config.Krew{}, err
}
return krew, nil return krew, nil
} }

View File

@@ -183,7 +183,7 @@ func TestFullPipe(t *testing.T) {
ctx.Config.Krews[0].Repository.Name = "test" ctx.Config.Krews[0].Repository.Name = "test"
ctx.Config.Krews[0].Description = "{{ .Asdsa }" ctx.Config.Krews[0].Description = "{{ .Asdsa }"
}, },
expectedRunError: `template: tmpl:1: unexpected "}" in operand`, expectedRunError: `failed to apply template: {{ .Asdsa }: template: tmpl:1: unexpected "}" in operand`,
}, },
"invalid short desc": { "invalid short desc": {
prepare: func(ctx *context.Context) { prepare: func(ctx *context.Context) {
@@ -191,7 +191,7 @@ func TestFullPipe(t *testing.T) {
ctx.Config.Krews[0].Repository.Name = "test" ctx.Config.Krews[0].Repository.Name = "test"
ctx.Config.Krews[0].ShortDescription = "{{ .Asdsa }" ctx.Config.Krews[0].ShortDescription = "{{ .Asdsa }"
}, },
expectedRunError: `template: tmpl:1: unexpected "}" in operand`, expectedRunError: `failed to apply template: {{ .Asdsa }: template: tmpl:1: unexpected "}" in operand`,
}, },
"invalid homepage": { "invalid homepage": {
prepare: func(ctx *context.Context) { prepare: func(ctx *context.Context) {
@@ -199,7 +199,7 @@ func TestFullPipe(t *testing.T) {
ctx.Config.Krews[0].Repository.Name = "test" ctx.Config.Krews[0].Repository.Name = "test"
ctx.Config.Krews[0].Homepage = "{{ .Asdsa }" ctx.Config.Krews[0].Homepage = "{{ .Asdsa }"
}, },
expectedRunError: `template: tmpl:1: unexpected "}" in operand`, expectedRunError: `failed to apply template: {{ .Asdsa }: template: tmpl:1: unexpected "}" in operand`,
}, },
"invalid name": { "invalid name": {
prepare: func(ctx *context.Context) { prepare: func(ctx *context.Context) {
@@ -207,7 +207,7 @@ func TestFullPipe(t *testing.T) {
ctx.Config.Krews[0].Repository.Name = "test" ctx.Config.Krews[0].Repository.Name = "test"
ctx.Config.Krews[0].Name = "{{ .Asdsa }" ctx.Config.Krews[0].Name = "{{ .Asdsa }"
}, },
expectedRunError: `template: tmpl:1: unexpected "}" in operand`, expectedRunError: `failed to apply template: {{ .Asdsa }: template: tmpl:1: unexpected "}" in operand`,
}, },
"invalid caveats": { "invalid caveats": {
prepare: func(ctx *context.Context) { prepare: func(ctx *context.Context) {
@@ -215,7 +215,7 @@ func TestFullPipe(t *testing.T) {
ctx.Config.Krews[0].Repository.Name = "test" ctx.Config.Krews[0].Repository.Name = "test"
ctx.Config.Krews[0].Caveats = "{{ .Asdsa }" ctx.Config.Krews[0].Caveats = "{{ .Asdsa }"
}, },
expectedRunError: `template: tmpl:1: unexpected "}" in operand`, expectedRunError: `failed to apply template: {{ .Asdsa }: template: tmpl:1: unexpected "}" in operand`,
}, },
"no short desc": { "no short desc": {
prepare: func(ctx *context.Context) { prepare: func(ctx *context.Context) {

View File

@@ -149,7 +149,6 @@ func create(ctx *context.Context, fpm config.NFPM, format string, binaries []*ar
} }
} }
bindDir := fpm.Bindir
if format == termuxFormat { if format == termuxFormat {
if !isSupportedTermuxArch(arch) { if !isSupportedTermuxArch(arch) {
log.Debugf("skipping termux.deb for %s as its not supported by termux", arch) log.Debugf("skipping termux.deb for %s as its not supported by termux", arch)
@@ -163,7 +162,7 @@ func create(ctx *context.Context, fpm config.NFPM, format string, binaries []*ar
) )
infoArch = replacer.Replace(infoArch) infoArch = replacer.Replace(infoArch)
arch = replacer.Replace(arch) arch = replacer.Replace(arch)
bindDir = filepath.Join("/data/data/com.termux/files", bindDir) fpm.Bindir = filepath.Join("/data/data/com.termux/files", fpm.Bindir)
} }
overridden, err := mergeOverrides(fpm, format) overridden, err := mergeOverrides(fpm, format)
@@ -184,25 +183,17 @@ func create(ctx *context.Context, fpm config.NFPM, format string, binaries []*ar
"PackageName": packageName, "PackageName": packageName,
}) })
binDir, err := t.Apply(bindDir) if err := t.ApplyAll(
if err != nil { &fpm.Bindir,
&fpm.Homepage,
&fpm.Description,
&fpm.Maintainer,
); err != nil {
return err return err
} }
homepage, err := t.Apply(fpm.Homepage) // We cannot use t.ApplyAll on the following fields as they are shared
if err != nil { // across multiple nfpms.
return err
}
description, err := t.Apply(fpm.Description)
if err != nil {
return err
}
maintainer, err := t.Apply(fpm.Maintainer)
if err != nil {
return err
}
debKeyFile, err := t.Apply(overridden.Deb.Signature.KeyFile) debKeyFile, err := t.Apply(overridden.Deb.Signature.KeyFile)
if err != nil { if err != nil {
@@ -257,7 +248,7 @@ func create(ctx *context.Context, fpm config.NFPM, format string, binaries []*ar
if !fpm.Meta { if !fpm.Meta {
for _, binary := range binaries { for _, binary := range binaries {
src := binary.Path src := binary.Path
dst := filepath.Join(binDir, binary.Name) dst := filepath.Join(fpm.Bindir, binary.Name)
log.WithField("src", src).WithField("dst", dst).Debug("adding binary to package") log.WithField("src", src).WithField("dst", dst).Debug("adding binary to package")
contents = append(contents, &files.Content{ contents = append(contents, &files.Content{
Source: filepath.ToSlash(src), Source: filepath.ToSlash(src),
@@ -282,10 +273,10 @@ func create(ctx *context.Context, fpm config.NFPM, format string, binaries []*ar
Release: fpm.Release, Release: fpm.Release,
Prerelease: fpm.Prerelease, Prerelease: fpm.Prerelease,
VersionMetadata: fpm.VersionMetadata, VersionMetadata: fpm.VersionMetadata,
Maintainer: maintainer, Maintainer: fpm.Maintainer,
Description: description, Description: fpm.Description,
Vendor: fpm.Vendor, Vendor: fpm.Vendor,
Homepage: homepage, Homepage: fpm.Homepage,
License: fpm.License, License: fpm.License,
Changelog: fpm.Changelog, Changelog: fpm.Changelog,
Overridables: nfpm.Overridables{ Overridables: nfpm.Overridables{

View File

@@ -130,9 +130,15 @@ func (p Pipe) doRun(ctx *context.Context, nix config.Nix, cl client.ReleaserURLT
return errNoRepoName return errNoRepoName
} }
var err error tp := tmpl.New(ctx)
nix.Name, err = tmpl.New(ctx).Apply(nix.Name) err := tp.ApplyAll(
&nix.Name,
&nix.SkipUpload,
&nix.Homepage,
&nix.Description,
&nix.Path,
)
if err != nil { if err != nil {
return err return err
} }
@@ -142,25 +148,6 @@ func (p Pipe) doRun(ctx *context.Context, nix config.Nix, cl client.ReleaserURLT
return err return err
} }
nix.SkipUpload, err = tmpl.New(ctx).Apply(nix.SkipUpload)
if err != nil {
return err
}
nix.Homepage, err = tmpl.New(ctx).Apply(nix.Homepage)
if err != nil {
return err
}
nix.Description, err = tmpl.New(ctx).Apply(nix.Description)
if err != nil {
return err
}
nix.Path, err = tmpl.New(ctx).Apply(nix.Path)
if err != nil {
return err
}
if nix.Path == "" { if nix.Path == "" {
nix.Path = path.Join("pkgs", nix.Name, "default.nix") nix.Path = path.Join("pkgs", nix.Name, "default.nix")
} }

View File

@@ -150,23 +150,16 @@ func doRun(ctx *context.Context, scoop config.Scoop, cl client.ReleaserURLTempla
return ErrIncorrectArchiveCount{scoop.Goamd64, scoop.IDs, archives} return ErrIncorrectArchiveCount{scoop.Goamd64, scoop.IDs, archives}
} }
name, err := tmpl.New(ctx).Apply(scoop.Name) tp := tmpl.New(ctx)
if err != nil {
return err
}
scoop.Name = name
description, err := tmpl.New(ctx).Apply(scoop.Description) if err := tp.ApplyAll(
if err != nil { &scoop.Name,
&scoop.Description,
&scoop.Homepage,
&scoop.SkipUpload,
); err != nil {
return err return err
} }
scoop.Description = description
homepage, err := tmpl.New(ctx).Apply(scoop.Homepage)
if err != nil {
return err
}
scoop.Homepage = homepage
ref, err := client.TemplateRef(tmpl.New(ctx).Apply, scoop.Repository) ref, err := client.TemplateRef(tmpl.New(ctx).Apply, scoop.Repository)
if err != nil { if err != nil {
@@ -174,12 +167,6 @@ func doRun(ctx *context.Context, scoop config.Scoop, cl client.ReleaserURLTempla
} }
scoop.Repository = ref scoop.Repository = ref
skipUpload, err := tmpl.New(ctx).Apply(scoop.SkipUpload)
if err != nil {
return err
}
scoop.SkipUpload = skipUpload
data, err := dataFor(ctx, scoop, cl, archives) data, err := dataFor(ctx, scoop, cl, archives)
if err != nil { if err != nil {
return err return err

View File

@@ -154,16 +154,12 @@ func (Pipe) Run(ctx *context.Context) error {
func doRun(ctx *context.Context, snap config.Snapcraft) error { func doRun(ctx *context.Context, snap config.Snapcraft) error {
tpl := tmpl.New(ctx) tpl := tmpl.New(ctx)
summary, err := tpl.Apply(snap.Summary) if err := tpl.ApplyAll(
if err != nil { &snap.Summary,
&snap.Description,
); err != nil {
return err return err
} }
description, err := tpl.Apply(snap.Description)
if err != nil {
return err
}
snap.Summary = summary
snap.Description = description
if snap.Summary == "" && snap.Description == "" { if snap.Summary == "" && snap.Description == "" {
return pipe.Skip("no summary nor description were provided") return pipe.Skip("no summary nor description were provided")
} }
@@ -173,8 +169,7 @@ func doRun(ctx *context.Context, snap config.Snapcraft) error {
if snap.Description == "" { if snap.Description == "" {
return ErrNoDescription return ErrNoDescription
} }
_, err = exec.LookPath("snapcraft") if _, err := exec.LookPath("snapcraft"); err != nil {
if err != nil {
return ErrNoSnapcraft return ErrNoSnapcraft
} }

View File

@@ -104,11 +104,22 @@ func (p Pipe) doRun(ctx *context.Context, winget config.Winget, cl client.Releas
tp := tmpl.New(ctx) tp := tmpl.New(ctx)
var err error err := tp.ApplyAll(
winget.Publisher, err = tp.Apply(winget.Publisher) &winget.Publisher,
&winget.Name,
&winget.Author,
&winget.PublisherURL,
&winget.Homepage,
&winget.SkipUpload,
&winget.Description,
&winget.ShortDescription,
&winget.ReleaseNotesURL,
&winget.Path,
)
if err != nil { if err != nil {
return err return err
} }
if winget.Publisher == "" { if winget.Publisher == "" {
return errNoPublisher return errNoPublisher
} }
@@ -117,55 +128,15 @@ func (p Pipe) doRun(ctx *context.Context, winget config.Winget, cl client.Releas
return errNoLicense return errNoLicense
} }
winget.Name, err = tp.Apply(winget.Name)
if err != nil {
return err
}
winget.Author, err = tp.Apply(winget.Author)
if err != nil {
return err
}
winget.PublisherURL, err = tp.Apply(winget.PublisherURL)
if err != nil {
return err
}
winget.Homepage, err = tp.Apply(winget.Homepage)
if err != nil {
return err
}
winget.Repository, err = client.TemplateRef(tp.Apply, winget.Repository) winget.Repository, err = client.TemplateRef(tp.Apply, winget.Repository)
if err != nil { if err != nil {
return err return err
} }
winget.SkipUpload, err = tp.Apply(winget.SkipUpload)
if err != nil {
return err
}
winget.Description, err = tp.Apply(winget.Description)
if err != nil {
return err
}
winget.ShortDescription, err = tp.Apply(winget.ShortDescription)
if err != nil {
return err
}
if winget.ShortDescription == "" { if winget.ShortDescription == "" {
return errNoShortDescription return errNoShortDescription
} }
winget.ReleaseNotesURL, err = tp.Apply(winget.ReleaseNotesURL)
if err != nil {
return err
}
winget.ReleaseNotes, err = tp.WithExtraFields(tmpl.Fields{ winget.ReleaseNotes, err = tp.WithExtraFields(tmpl.Fields{
"Changelog": ctx.ReleaseNotes, "Changelog": ctx.ReleaseNotes,
}).Apply(winget.ReleaseNotes) }).Apply(winget.ReleaseNotes)
@@ -180,10 +151,6 @@ func (p Pipe) doRun(ctx *context.Context, winget config.Winget, cl client.Releas
} }
} }
winget.Path, err = tp.Apply(winget.Path)
if err != nil {
return err
}
if winget.Path == "" { if winget.Path == "" {
winget.Path = filepath.Join("manifests", strings.ToLower(string(winget.Publisher[0])), winget.Publisher, winget.Name, ctx.Version) winget.Path = filepath.Join("manifests", strings.ToLower(string(winget.Publisher[0])), winget.Publisher, winget.Name, ctx.Version)
} }

View File

@@ -230,6 +230,20 @@ func (t *Template) Apply(s string) (string, error) {
return out.String(), err return out.String(), err
} }
// ApplyAll applies all the given strings against the Fields stored in the
// template. Application stops as soon as an error is encountered.
func (t *Template) ApplyAll(sps ...*string) error {
for _, sp := range sps {
s := *sp
result, err := t.Apply(s)
if err != nil {
return fmt.Errorf("failed to apply template: %s: %w", s, err)
}
*sp = result
}
return nil
}
func (t *Template) envOrDefault(name, value string) string { func (t *Template) envOrDefault(name, value string) string {
s, ok := t.fields[env].(context.Env)[name] s, ok := t.fields[env].(context.Env)[name]
if !ok { if !ok {