diff --git a/internal/tmpl/tmpl.go b/internal/tmpl/tmpl.go index 7493d8a42..7ddb60ecd 100644 --- a/internal/tmpl/tmpl.go +++ b/internal/tmpl/tmpl.go @@ -4,6 +4,7 @@ package tmpl import ( "bytes" "fmt" + "maps" "path/filepath" "regexp" "strings" @@ -141,6 +142,16 @@ func New(ctx *context.Context) *Template { } } +// WithExtraFields allows to add new more custom fields to the template. +// It will override fields with the same name. +func (t *Template) WithExtraFields(f Fields) *Template { + tt := t.copying() + for k, v := range f { + tt.fields[k] = v + } + return tt +} + // WithEnvS overrides template's env field with the given KEY=VALUE list of // environment variables. func (t *Template) WithEnvS(envs []string) *Template { @@ -157,35 +168,28 @@ func (t *Template) WithEnvS(envs []string) *Template { // WithEnv overrides template's env field with the given environment map. func (t *Template) WithEnv(e map[string]string) *Template { - t.fields[env] = context.Env(e) - return t -} - -// WithExtraFields allows to add new more custom fields to the template. -// It will override fields with the same name. -func (t *Template) WithExtraFields(f Fields) *Template { - for k, v := range f { - t.fields[k] = v - } - return t + return t.WithExtraFields(Fields{ + env: context.Env(e), + }) } // WithArtifact populates Fields from the artifact. func (t *Template) WithArtifact(a *artifact.Artifact) *Template { - t.fields[osKey] = a.Goos - t.fields[arch] = a.Goarch - t.fields[amd64] = a.Goamd64 - t.fields[go386] = a.Go386 - t.fields[arm] = a.Goarm - t.fields[arm64] = a.Goarm64 - t.fields[mips] = a.Gomips - t.fields[ppc64] = a.Goppc64 - t.fields[riscv64] = a.Goriscv64 - t.fields[binary] = artifact.ExtraOr(*a, binary, t.fields[projectName].(string)) - t.fields[artifactName] = a.Name - t.fields[artifactExt] = artifact.ExtraOr(*a, artifact.ExtraExt, "") - t.fields[artifactPath] = a.Path - return t + return t.WithExtraFields(Fields{ + osKey: a.Goos, + arch: a.Goarch, + amd64: a.Goamd64, + go386: a.Go386, + arm: a.Goarm, + arm64: a.Goarm64, + mips: a.Gomips, + ppc64: a.Goppc64, + riscv64: a.Goriscv64, + binary: artifact.ExtraOr(*a, binary, t.fields[projectName].(string)), + artifactName: a.Name, + artifactExt: artifact.ExtraOr(*a, artifact.ExtraExt, ""), + artifactPath: a.Path, + }) } func (t *Template) WithBuildOptions(opts build.Options) *Template { @@ -284,6 +288,14 @@ func (t *Template) envOrDefault(name, value string) string { return s } +func (t *Template) copying() *Template { + tpl := &Template{ + fields: Fields{}, + } + maps.Copy(tpl.fields, t.fields) + return tpl +} + type ExpectedSingleEnvErr struct{} func (e ExpectedSingleEnvErr) Error() string { diff --git a/internal/tmpl/tmpl_test.go b/internal/tmpl/tmpl_test.go index c26fa590f..768a5af63 100644 --- a/internal/tmpl/tmpl_test.go +++ b/internal/tmpl/tmpl_test.go @@ -471,3 +471,20 @@ func TestWithBuildOptions(t *testing.T) { require.NoError(t, err) require.Equal(t, "name_./path_.ext_target_os_arch_amd64_arm_mips", out) } + +func TestReuseTpl(t *testing.T) { + tp := New(testctx.New()).WithExtraFields(Fields{ + "foo": "bar", + }) + s1, err := tp.Apply("{{.foo}}") + require.NoError(t, err) + require.Equal(t, "bar", s1) + + s2, err := tp.WithExtraFields(Fields{"foo": "not-bar"}).Apply("{{.foo}}") + require.NoError(t, err) + require.Equal(t, "not-bar", s2) + + s3, err := tp.Apply("{{.foo}}") + require.NoError(t, err) + require.Equal(t, "bar", s3) +}