Skip to content

Commit

Permalink
refactor: move template renderer to its own file (#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tieske authored Jun 21, 2024
1 parent ac65306 commit 6d3c2b3
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 96 deletions.
96 changes: 0 additions & 96 deletions pkg/file/readfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@ package file

import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"strconv"
"strings"
"text/template"

"dario.cat/mergo"
"github.com/kong/go-database-reconciler/pkg/utils"
Expand Down Expand Up @@ -149,95 +145,3 @@ func readContent(reader io.Reader, mockEnvVars bool) (*Content, error) {
func yamlUnmarshal(bytes []byte, v interface{}) error {
return yaml.Unmarshal(bytes, v)
}

func getPrefixedEnvVar(key string) (string, error) {
const envVarPrefix = "DECK_"
if !strings.HasPrefix(key, envVarPrefix) {
return "", fmt.Errorf("environment variables in the state file must "+
"be prefixed with 'DECK_', found: '%s'", key)
}
value, exists := os.LookupEnv(key)
if !exists {
return "", fmt.Errorf("environment variable '%s' present in state file but not set", key)
}
return value, nil
}

// getPrefixedEnvVarMocked is used when we mock the env variables while rendering a template.
// It will always return the name of the environment variable in this case.
func getPrefixedEnvVarMocked(key string) (string, error) {
const envVarPrefix = "DECK_"
if !strings.HasPrefix(key, envVarPrefix) {
return "", fmt.Errorf("environment variables in the state file must "+
"be prefixed with 'DECK_', found: '%s'", key)
}
return key, nil
}

func toBool(key string) (bool, error) {
return strconv.ParseBool(key)
}

// toBoolMocked is used when we mock the env variables while rendering a template.
// It will always return false in this case.
func toBoolMocked(_ string) (bool, error) {
return false, nil
}

func toInt(key string) (int, error) {
return strconv.Atoi(key)
}

// toIntMocked is used when we mock the env variables while rendering a template.
// It will always return 42 in this case.
func toIntMocked(_ string) (int, error) {
return 42, nil
}

func toFloat(key string) (float64, error) {
return strconv.ParseFloat(key, 64)
}

// toFloatMocked is used when we mock the env variables while rendering a template.
// It will always return 42 in this case.
func toFloatMocked(_ string) (float64, error) {
return 42, nil
}

func indent(spaces int, v string) string {
pad := strings.Repeat(" ", spaces)
return strings.Replace(v, "\n", "\n"+pad, -1)
}

func renderTemplate(content string, mockEnvVars bool) (string, error) {
var templateFuncs template.FuncMap
if mockEnvVars {
templateFuncs = template.FuncMap{
"env": getPrefixedEnvVarMocked,
"toBool": toBoolMocked,
"toInt": toIntMocked,
"toFloat": toFloatMocked,
"indent": indent,
}
} else {
templateFuncs = template.FuncMap{
"env": getPrefixedEnvVar,
"toBool": toBool,
"toInt": toInt,
"toFloat": toFloat,
"indent": indent,
}
}
t := template.New("state").Funcs(templateFuncs).Delims("${{", "}}")

t, err := t.Parse(content)
if err != nil {
return "", err
}
var buffer bytes.Buffer
err = t.Execute(&buffer, nil)
if err != nil {
return "", err
}
return buffer.String(), nil
}
102 changes: 102 additions & 0 deletions pkg/file/template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package file

import (
"bytes"
"fmt"
"os"
"strconv"
"strings"
"text/template"
)

func getPrefixedEnvVar(key string) (string, error) {
const envVarPrefix = "DECK_"
if !strings.HasPrefix(key, envVarPrefix) {
return "", fmt.Errorf("environment variables in the state file must "+
"be prefixed with 'DECK_', found: '%s'", key)
}
value, exists := os.LookupEnv(key)
if !exists {
return "", fmt.Errorf("environment variable '%s' present in state file but not set", key)
}
return value, nil
}

// getPrefixedEnvVarMocked is used when we mock the env variables while rendering a template.
// It will always return the name of the environment variable in this case.
func getPrefixedEnvVarMocked(key string) (string, error) {
const envVarPrefix = "DECK_"
if !strings.HasPrefix(key, envVarPrefix) {
return "", fmt.Errorf("environment variables in the state file must "+
"be prefixed with 'DECK_', found: '%s'", key)
}
return key, nil
}

func toBool(key string) (bool, error) {
return strconv.ParseBool(key)
}

// toBoolMocked is used when we mock the env variables while rendering a template.
// It will always return false in this case.
func toBoolMocked(_ string) (bool, error) {
return false, nil
}

func toInt(key string) (int, error) {
return strconv.Atoi(key)
}

// toIntMocked is used when we mock the env variables while rendering a template.
// It will always return 42 in this case.
func toIntMocked(_ string) (int, error) {
return 42, nil
}

func toFloat(key string) (float64, error) {
return strconv.ParseFloat(key, 64)
}

// toFloatMocked is used when we mock the env variables while rendering a template.
// It will always return 42 in this case.
func toFloatMocked(_ string) (float64, error) {
return 42, nil
}

func indent(spaces int, v string) string {
pad := strings.Repeat(" ", spaces)
return strings.Replace(v, "\n", "\n"+pad, -1)
}

func renderTemplate(content string, mockEnvVars bool) (string, error) {
var templateFuncs template.FuncMap
if mockEnvVars {
templateFuncs = template.FuncMap{
"env": getPrefixedEnvVarMocked,
"toBool": toBoolMocked,
"toInt": toIntMocked,
"toFloat": toFloatMocked,
"indent": indent,
}
} else {
templateFuncs = template.FuncMap{
"env": getPrefixedEnvVar,
"toBool": toBool,
"toInt": toInt,
"toFloat": toFloat,
"indent": indent,
}
}
t := template.New("state").Funcs(templateFuncs).Delims("${{", "}}")

t, err := t.Parse(content)
if err != nil {
return "", err
}
var buffer bytes.Buffer
err = t.Execute(&buffer, nil)
if err != nil {
return "", err
}
return buffer.String(), nil
}

0 comments on commit 6d3c2b3

Please sign in to comment.