2018-07-09 05:47:30 +02:00
|
|
|
// Package tmpl provides templating utilities for goreleser
|
|
|
|
package tmpl
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2019-04-09 14:15:05 +02:00
|
|
|
"strings"
|
2018-07-09 05:47:30 +02:00
|
|
|
"text/template"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/goreleaser/goreleaser/internal/artifact"
|
2018-08-15 04:50:20 +02:00
|
|
|
"github.com/goreleaser/goreleaser/pkg/context"
|
2018-07-09 05:47:30 +02:00
|
|
|
)
|
|
|
|
|
2018-07-09 06:13:09 +02:00
|
|
|
// Template holds data that can be applied to a template string
|
2018-07-09 05:47:30 +02:00
|
|
|
type Template struct {
|
2020-03-22 18:54:47 +02:00
|
|
|
fields Fields
|
2018-07-09 05:47:30 +02:00
|
|
|
}
|
|
|
|
|
2020-03-22 18:54:47 +02:00
|
|
|
// Fields that will be available to the template engine.
|
|
|
|
type Fields map[string]interface{}
|
2018-07-09 05:47:30 +02:00
|
|
|
|
2018-07-09 07:35:44 +02:00
|
|
|
const (
|
|
|
|
// general keys
|
2018-07-09 09:01:06 +02:00
|
|
|
projectName = "ProjectName"
|
|
|
|
version = "Version"
|
|
|
|
tag = "Tag"
|
|
|
|
commit = "Commit"
|
2018-10-03 22:44:31 +02:00
|
|
|
shortCommit = "ShortCommit"
|
|
|
|
fullCommit = "FullCommit"
|
2018-10-04 14:38:19 +02:00
|
|
|
gitURL = "GitURL"
|
2018-07-09 09:01:06 +02:00
|
|
|
major = "Major"
|
|
|
|
minor = "Minor"
|
|
|
|
patch = "Patch"
|
|
|
|
env = "Env"
|
|
|
|
date = "Date"
|
|
|
|
timestamp = "Timestamp"
|
2018-07-09 07:35:44 +02:00
|
|
|
|
|
|
|
// artifact-only keys
|
2018-07-26 15:03:28 +02:00
|
|
|
os = "Os"
|
|
|
|
arch = "Arch"
|
|
|
|
arm = "Arm"
|
2020-02-06 03:08:18 +02:00
|
|
|
mips = "Mips"
|
2018-07-26 15:03:28 +02:00
|
|
|
binary = "Binary"
|
|
|
|
artifactName = "ArtifactName"
|
2019-08-13 20:28:03 +02:00
|
|
|
// gitlab only
|
|
|
|
artifactUploadHash = "ArtifactUploadHash"
|
2018-07-09 07:35:44 +02:00
|
|
|
)
|
2018-07-09 05:47:30 +02:00
|
|
|
|
2018-07-09 06:13:09 +02:00
|
|
|
// New Template
|
2018-07-09 05:47:30 +02:00
|
|
|
func New(ctx *context.Context) *Template {
|
|
|
|
return &Template{
|
2020-03-22 18:54:47 +02:00
|
|
|
fields: Fields{
|
2018-07-09 09:01:06 +02:00
|
|
|
projectName: ctx.Config.ProjectName,
|
|
|
|
version: ctx.Version,
|
|
|
|
tag: ctx.Git.CurrentTag,
|
|
|
|
commit: ctx.Git.Commit,
|
2018-10-03 22:44:31 +02:00
|
|
|
shortCommit: ctx.Git.ShortCommit,
|
|
|
|
fullCommit: ctx.Git.FullCommit,
|
2018-10-04 14:38:19 +02:00
|
|
|
gitURL: ctx.Git.URL,
|
2018-07-09 09:01:06 +02:00
|
|
|
env: ctx.Env,
|
|
|
|
date: time.Now().UTC().Format(time.RFC3339),
|
|
|
|
timestamp: time.Now().UTC().Unix(),
|
2019-01-19 20:57:58 +02:00
|
|
|
major: ctx.Semver.Major,
|
|
|
|
minor: ctx.Semver.Minor,
|
|
|
|
patch: ctx.Semver.Patch,
|
|
|
|
// TODO: no reason not to add prerelease here too I guess
|
2018-07-09 05:47:30 +02:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-09 14:15:05 +02:00
|
|
|
// WithEnvS overrides template's env field with the given KEY=VALUE list of
|
|
|
|
// environment variables
|
|
|
|
func (t *Template) WithEnvS(envs []string) *Template {
|
|
|
|
var result = map[string]string{}
|
|
|
|
for _, env := range envs {
|
|
|
|
var parts = strings.SplitN(env, "=", 2)
|
|
|
|
result[parts[0]] = parts[1]
|
|
|
|
}
|
|
|
|
return t.WithEnv(result)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithEnv overrides template's env field with the given environment map
|
|
|
|
func (t *Template) WithEnv(e map[string]string) *Template {
|
|
|
|
t.fields[env] = e
|
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
2020-03-22 18:54:47 +02:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithArtifact populates Fields from the artifact and replacements
|
2019-08-12 22:44:48 +02:00
|
|
|
func (t *Template) WithArtifact(a *artifact.Artifact, replacements map[string]string) *Template {
|
2018-07-09 09:29:15 +02:00
|
|
|
var bin = a.Extra[binary]
|
2019-01-01 18:40:17 +02:00
|
|
|
if bin == nil {
|
|
|
|
bin = t.fields[projectName]
|
2018-07-09 05:47:30 +02:00
|
|
|
}
|
2018-07-09 09:01:06 +02:00
|
|
|
t.fields[os] = replace(replacements, a.Goos)
|
|
|
|
t.fields[arch] = replace(replacements, a.Goarch)
|
|
|
|
t.fields[arm] = replace(replacements, a.Goarm)
|
2020-02-06 03:08:18 +02:00
|
|
|
t.fields[mips] = replace(replacements, a.Gomips)
|
2019-01-01 18:40:17 +02:00
|
|
|
t.fields[binary] = bin.(string)
|
2018-07-26 15:03:28 +02:00
|
|
|
t.fields[artifactName] = a.Name
|
2019-08-13 20:28:03 +02:00
|
|
|
if val, ok := a.Extra["ArtifactUploadHash"]; ok {
|
|
|
|
t.fields[artifactUploadHash] = val
|
|
|
|
} else {
|
|
|
|
t.fields[artifactUploadHash] = ""
|
|
|
|
}
|
2018-07-09 05:47:30 +02:00
|
|
|
return t
|
|
|
|
}
|
|
|
|
|
2020-03-22 18:54:47 +02:00
|
|
|
// Apply applies the given string against the Fields stored in the template.
|
2018-07-09 05:47:30 +02:00
|
|
|
func (t *Template) Apply(s string) (string, error) {
|
|
|
|
var out bytes.Buffer
|
|
|
|
tmpl, err := template.New("tmpl").
|
|
|
|
Option("missingkey=error").
|
|
|
|
Funcs(template.FuncMap{
|
2019-11-07 19:49:36 +02:00
|
|
|
"replace": strings.ReplaceAll,
|
2018-07-09 05:47:30 +02:00
|
|
|
"time": func(s string) string {
|
|
|
|
return time.Now().UTC().Format(s)
|
|
|
|
},
|
2019-11-07 19:49:36 +02:00
|
|
|
"tolower": strings.ToLower,
|
|
|
|
"toupper": strings.ToUpper,
|
|
|
|
"trim": strings.TrimSpace,
|
2018-07-09 05:47:30 +02:00
|
|
|
}).
|
|
|
|
Parse(s)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
err = tmpl.Execute(&out, t.fields)
|
|
|
|
return out.String(), err
|
|
|
|
}
|
|
|
|
|
|
|
|
func replace(replacements map[string]string, original string) string {
|
|
|
|
result := replacements[original]
|
|
|
|
if result == "" {
|
|
|
|
return original
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|