2021-02-07 01:54:36 -08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2021-04-11 06:24:03 -07:00
|
|
|
"errors"
|
2022-01-12 14:39:34 -08:00
|
|
|
"fmt"
|
2021-05-26 12:12:58 -07:00
|
|
|
"strings"
|
2021-02-07 01:54:36 -08:00
|
|
|
"text/template"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// Errors to show when the template handling fails
|
|
|
|
invalidTemplate = "invalid template text"
|
|
|
|
incorrectTemplate = "unable to create text based on template"
|
|
|
|
)
|
|
|
|
|
|
|
|
type textTemplate struct {
|
|
|
|
Template string
|
|
|
|
Context interface{}
|
2022-01-01 11:09:52 -08:00
|
|
|
Env Environment
|
2021-02-07 01:54:36 -08:00
|
|
|
}
|
|
|
|
|
2022-01-12 14:39:34 -08:00
|
|
|
type Data interface{}
|
|
|
|
|
|
|
|
type Context struct {
|
2022-01-18 00:48:47 -08:00
|
|
|
templateCache
|
|
|
|
|
|
|
|
// Simple container to hold ANY object
|
|
|
|
Data
|
|
|
|
}
|
|
|
|
|
|
|
|
type templateCache struct {
|
2022-01-17 04:16:04 -08:00
|
|
|
Root bool
|
|
|
|
PWD string
|
|
|
|
Folder string
|
|
|
|
Shell string
|
|
|
|
UserName string
|
|
|
|
HostName string
|
|
|
|
Code int
|
|
|
|
Env map[string]string
|
|
|
|
OS string
|
2022-01-22 10:46:56 -08:00
|
|
|
WSL bool
|
2022-01-12 14:39:34 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Context) init(t *textTemplate) {
|
|
|
|
c.Data = t.Context
|
2022-01-18 00:48:47 -08:00
|
|
|
if cache := t.Env.templateCache(); cache != nil {
|
|
|
|
c.templateCache = *cache
|
2022-01-12 14:39:34 -08:00
|
|
|
return
|
2021-06-15 12:23:08 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-11 06:24:03 -07:00
|
|
|
func (t *textTemplate) render() (string, error) {
|
2022-01-12 14:39:34 -08:00
|
|
|
t.cleanTemplate()
|
2021-12-11 08:31:58 -08:00
|
|
|
tmpl, err := template.New("title").Funcs(funcMap()).Parse(t.Template)
|
2021-02-07 01:54:36 -08:00
|
|
|
if err != nil {
|
2021-04-11 06:24:03 -07:00
|
|
|
return "", errors.New(invalidTemplate)
|
2021-02-07 01:54:36 -08:00
|
|
|
}
|
2022-01-12 14:39:34 -08:00
|
|
|
context := &Context{}
|
|
|
|
context.init(t)
|
2021-02-07 01:54:36 -08:00
|
|
|
buffer := new(bytes.Buffer)
|
|
|
|
defer buffer.Reset()
|
2022-01-12 14:39:34 -08:00
|
|
|
err = tmpl.Execute(buffer, context)
|
2021-02-07 01:54:36 -08:00
|
|
|
if err != nil {
|
2021-04-11 06:24:03 -07:00
|
|
|
return "", errors.New(incorrectTemplate)
|
2021-02-07 01:54:36 -08:00
|
|
|
}
|
2021-05-26 12:12:58 -07:00
|
|
|
text := buffer.String()
|
|
|
|
// issue with missingkey=zero ignored for map[string]interface{}
|
|
|
|
// https://github.com/golang/go/issues/24963
|
|
|
|
text = strings.ReplaceAll(text, "<no value>", "")
|
|
|
|
return text, nil
|
|
|
|
}
|
|
|
|
|
2022-01-12 14:39:34 -08:00
|
|
|
func (t *textTemplate) cleanTemplate() {
|
|
|
|
unknownVariable := func(variable string, knownVariables *[]string) (string, bool) {
|
|
|
|
variable = strings.TrimPrefix(variable, ".")
|
|
|
|
splitted := strings.Split(variable, ".")
|
|
|
|
if len(splitted) == 0 {
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
for _, b := range *knownVariables {
|
|
|
|
if b == splitted[0] {
|
|
|
|
return "", false
|
|
|
|
}
|
2021-05-26 12:12:58 -07:00
|
|
|
}
|
2022-01-12 14:39:34 -08:00
|
|
|
*knownVariables = append(*knownVariables, splitted[0])
|
|
|
|
return splitted[0], true
|
2021-05-26 12:12:58 -07:00
|
|
|
}
|
2022-01-22 10:46:56 -08:00
|
|
|
knownVariables := []string{"Root", "PWD", "Folder", "Shell", "UserName", "HostName", "Env", "Data", "Code", "OS", "WSL"}
|
2022-01-18 00:55:27 -08:00
|
|
|
matches := findAllNamedRegexMatch(`(?: |{|\()(?P<var>(\.[a-zA-Z_][a-zA-Z0-9]*)+)`, t.Template)
|
2021-05-26 12:12:58 -07:00
|
|
|
for _, match := range matches {
|
2022-01-12 14:39:34 -08:00
|
|
|
if variable, OK := unknownVariable(match["var"], &knownVariables); OK {
|
|
|
|
pattern := fmt.Sprintf(`\.%s\b`, variable)
|
|
|
|
dataVar := fmt.Sprintf(".Data.%s", variable)
|
|
|
|
t.Template = replaceAllString(pattern, t.Template, dataVar)
|
2021-05-27 22:55:57 -07:00
|
|
|
}
|
2021-05-26 12:12:58 -07:00
|
|
|
}
|
2021-02-07 01:54:36 -08:00
|
|
|
}
|