Templates: allow adding template from file (#19495)

This commit is contained in:
andig 2025-03-07 11:10:22 +01:00 • committed by GitHub
parent 835d527abd
commit 8d67a008b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 5 deletions

View file

@ -1,6 +1,10 @@
package cmd
import (
"strings"
"github.com/evcc-io/evcc/util/templates"
"github.com/samber/lo"
"github.com/spf13/cobra"
)
@ -11,6 +15,10 @@ const (
flagIgnoreDatabase = "ignore-db"
flagIgnoreDatabaseDescription = "Run command ignoring service database"
flagTemplate = "template"
flagTemplateDescription = "Add custom template (useful for debugging)"
flagTemplateType = "template-type"
flagDisableAuth = "disable-auth"
flagDisableAuthDescription = "Disable authentication (dangerous)"
@ -54,6 +62,11 @@ const (
flagForce = "force"
)
var flagTemplateTypeDescription = "Custom template type (" + strings.Join(
lo.Map([]templates.Class{templates.Charger, templates.Meter, templates.Tariff, templates.Vehicle}, func(t templates.Class, _ int) string {
return t.String()
}), ", ") + ")"
func bind(cmd *cobra.Command, key string, flagName ...string) {
name := key
if len(flagName) == 1 {

View file

@ -69,6 +69,8 @@ func init() {
rootCmd.PersistentFlags().BoolP("help", "h", false, "Help")
rootCmd.PersistentFlags().Bool(flagHeaders, false, flagHeadersDescription)
rootCmd.PersistentFlags().Bool(flagIgnoreDatabase, false, flagIgnoreDatabaseDescription)
rootCmd.PersistentFlags().String(flagTemplate, "", flagTemplateDescription)
rootCmd.PersistentFlags().String(flagTemplateType, "", flagTemplateTypeDescription)
// config file options
rootCmd.PersistentFlags().StringP("log", "l", "info", "Log level (fatal, error, warn, info, debug, trace)")

View file

@ -467,14 +467,28 @@ func configureSponsorship(token string) (err error) {
return sponsor.ConfigureSponsorship(token)
}
func configureEnvironment(cmd *cobra.Command, conf *globalconfig.All) (err error) {
func configureEnvironment(cmd *cobra.Command, conf *globalconfig.All) error {
// full http request log
if cmd.Flag(flagHeaders).Changed {
request.LogHeaders = true
}
// setup persistence
err = wrapErrorWithClass(ClassDatabase, configureDatabase(conf.Database))
err := wrapErrorWithClass(ClassDatabase, configureDatabase(conf.Database))
// setup additional templates
if err == nil {
if cmd.PersistentFlags().Changed(flagTemplate) {
class, err := templates.ClassString(cmd.PersistentFlags().Lookup(flagTemplateType).Value.String())
if err != nil {
return err
}
if err := templates.Register(class, cmd.Flag(flagTemplate).Value.String()); err != nil {
return err
}
}
}
// setup translations
if err == nil {
@ -519,7 +533,7 @@ func configureEnvironment(cmd *cobra.Command, conf *globalconfig.All) (err error
err = config.Init(db.Instance)
}
return
return err
}
// configureDatabase configures session database

View file

@ -5,6 +5,7 @@ import (
"embed"
"fmt"
"io/fs"
"os"
"slices"
"sync"
"text/template"
@ -37,7 +38,27 @@ func init() {
}
}
func FromBytes(b []byte) (Template, error) {
func Register(class Class, filepath string) error {
b, err := os.ReadFile(filepath)
if err != nil {
return err
}
tmpl, err := fromBytes(b)
if err != nil {
return fmt.Errorf("processing template '%s' failed: %w", filepath, err)
}
if slices.ContainsFunc(templates[class], func(t Template) bool { return t.Template == tmpl.Template }) {
return fmt.Errorf("duplicate template name '%s' found in file '%s'", tmpl.Template, filepath)
}
templates[class] = append(templates[class], tmpl)
return nil
}
func fromBytes(b []byte) (Template, error) {
// panic if template definition contains unknown fields
dec := yaml.NewDecoder(bytes.NewReader(b))
dec.KnownFields(true)
@ -79,7 +100,7 @@ func load(class Class) (res []Template) {
return err
}
tmpl, err := FromBytes(b)
tmpl, err := fromBytes(b)
if err != nil {
return fmt.Errorf("processing template '%s' failed: %w", filepath, err)
}