Files
wild-cloud/wild-cli/internal/config/template.go

140 lines
3.5 KiB
Go

package config
import (
"bytes"
"fmt"
"strings"
"text/template"
"github.com/Masterminds/sprig/v3"
)
// TemplateEngine handles template processing with Wild Cloud context
type TemplateEngine struct {
configData map[string]interface{}
secretsData map[string]interface{}
}
// NewTemplateEngine creates a new template engine with config and secrets context
func NewTemplateEngine(configMgr *Manager) (*TemplateEngine, error) {
configData, err := configMgr.LoadConfig()
if err != nil {
return nil, fmt.Errorf("loading config: %w", err)
}
secretsData, err := configMgr.LoadSecrets()
if err != nil {
return nil, fmt.Errorf("loading secrets: %w", err)
}
return &TemplateEngine{
configData: configData,
secretsData: secretsData,
}, nil
}
// Process processes template content with Wild Cloud context
func (t *TemplateEngine) Process(templateContent string) (string, error) {
// Create template with sprig functions
tmpl := template.New("wild").Funcs(sprig.TxtFuncMap())
// Add Wild Cloud specific functions
tmpl = tmpl.Funcs(template.FuncMap{
// Config access function - matches gomplate .config
"config": func(path string) interface{} {
return t.getValueByPath(t.configData, path)
},
// Secret access function - matches gomplate .secrets
"secret": func(path string) interface{} {
return t.getValueByPath(t.secretsData, path)
},
// Direct access to config data - matches gomplate behavior
"getConfig": func(path string) interface{} {
return t.getValueByPath(t.configData, path)
},
// Direct access to secret data - matches gomplate behavior
"getSecret": func(path string) interface{} {
return t.getValueByPath(t.secretsData, path)
},
})
// Parse template
parsed, err := tmpl.Parse(templateContent)
if err != nil {
return "", fmt.Errorf("parsing template: %w", err)
}
// Execute template with context
var buf bytes.Buffer
context := map[string]interface{}{
"config": t.configData,
"secrets": t.secretsData,
}
err = parsed.Execute(&buf, context)
if err != nil {
return "", fmt.Errorf("executing template: %w", err)
}
return buf.String(), nil
}
// ProcessFile processes a template file with Wild Cloud context
func (t *TemplateEngine) ProcessFile(templateFile string) (string, error) {
// Read file content
content, err := readFile(templateFile)
if err != nil {
return "", fmt.Errorf("reading template file: %w", err)
}
return t.Process(string(content))
}
// getValueByPath retrieves a value from nested data using dot-notation path
func (t *TemplateEngine) getValueByPath(data interface{}, path string) interface{} {
if path == "" {
return data
}
parts := strings.Split(path, ".")
current := data
for _, part := range parts {
switch v := current.(type) {
case map[string]interface{}:
var exists bool
current, exists = v[part]
if !exists {
return nil
}
case map[interface{}]interface{}:
var exists bool
current, exists = v[part]
if !exists {
return nil
}
default:
return nil
}
}
return current
}
// readFile is a helper to read file contents
func readFile(filename string) ([]byte, error) {
// This would be implemented to read from filesystem
// For now, returning empty to avoid import cycles
return nil, fmt.Errorf("file reading not implemented yet")
}
// CompileTemplate is a convenience function for one-off template processing
func CompileTemplate(templateContent string, configMgr *Manager) (string, error) {
engine, err := NewTemplateEngine(configMgr)
if err != nil {
return "", err
}
return engine.Process(templateContent)
}