feat: go output formatter

This commit is contained in:
2025-07-20 15:19:47 +02:00
parent 0b0f0c9f0a
commit ef07dd1b86
6 changed files with 50 additions and 11 deletions

View File

@ -2,5 +2,6 @@ package cmd
type AppConfig struct { type AppConfig struct {
OutputVerbose bool OutputVerbose bool
OutputMode string OutputFormatter string
PrintConfig bool
} }

View File

@ -31,12 +31,13 @@ func initRootCmd() {
var appConfig AppConfig var appConfig AppConfig
rootCmd.PersistentFlags().BoolVarP(&appConfig.OutputVerbose, "verbose", "v", false, "Enable verbose output") rootCmd.PersistentFlags().BoolVarP(&appConfig.OutputVerbose, "verbose", "v", false, "Enable verbose output")
rootCmd.PersistentFlags().StringVarP(&appConfig.OutputMode, "output", "o", "json", "Set output format") rootCmd.PersistentFlags().StringVarP(&appConfig.OutputFormatter, "output", "o", "json", "Set output format")
rootCmd.PersistentFlags().BoolVar(&appConfig.PrintConfig, "print-config", false, "Enable printing the application config")
logger := jlog.New(slog.LevelDebug) logger := jlog.New(slog.LevelDebug)
ctx := jlog.ContextWith(context.Background(), logger) ctx := jlog.ContextWith(context.Background(), logger)
logger.Debug("Register verb commands") logger.Debug("Register verb commands")
rootCmd.AddCommand(getVerbs(ctx, appConfig)...) rootCmd.AddCommand(getVerbs(ctx, &appConfig)...)
logger.Debug("Verb commands registered successfully") logger.Debug("Verb commands registered successfully")
} }

View File

@ -20,14 +20,14 @@ type VerbItem struct {
Name interfaces.Verb Name interfaces.Verb
Aliases []string Aliases []string
Description string Description string
RunFn func(ctx context.Context, config AppConfig, handler interfaces.ResourceHandler, params params.Container) error RunFn func(ctx context.Context, config *AppConfig, handler interfaces.ResourceHandler, params params.Container) error
} }
var verbs = []VerbItem{ var verbs = []VerbItem{
{ {
Name: interfaces.VerbGet, Name: interfaces.VerbGet,
Description: "Retrieve resource information", Description: "Retrieve resource information",
RunFn: func(ctx context.Context, config AppConfig, handler interfaces.ResourceHandler, params params.Container) error { RunFn: func(ctx context.Context, config *AppConfig, handler interfaces.ResourceHandler, params params.Container) error {
h, ok := handler.(interfaces.GetHandler) h, ok := handler.(interfaces.GetHandler)
if !ok { if !ok {
return fmt.Errorf("resource does not support GET") return fmt.Errorf("resource does not support GET")
@ -39,7 +39,7 @@ var verbs = []VerbItem{
return fmt.Errorf("retrieving item failed: %w", err) return fmt.Errorf("retrieving item failed: %w", err)
} }
formatterName := strings.ToLower(config.OutputMode) formatterName := strings.ToLower(config.OutputFormatter)
formatter, exists := output.Formatters[formatterName] formatter, exists := output.Formatters[formatterName]
if !exists { if !exists {
return fmt.Errorf("could not find output formatter '%s'", formatterName) return fmt.Errorf("could not find output formatter '%s'", formatterName)
@ -60,7 +60,7 @@ var verbs = []VerbItem{
}, },
} }
func getVerbs(ctx context.Context, config AppConfig) (commands []*cobra.Command) { func getVerbs(ctx context.Context, config *AppConfig) (commands []*cobra.Command) {
logger := jlog.FromContext(ctx) logger := jlog.FromContext(ctx)
for _, v := range verbs { for _, v := range verbs {
@ -83,8 +83,19 @@ func getVerbs(ctx context.Context, config AppConfig) (commands []*cobra.Command)
Aliases: r.Aliases, Aliases: r.Aliases,
Short: r.Description, Short: r.Description,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
logger := jlog.New(slog.LevelInfo) // Configure log
var logLevel = slog.LevelWarn
if config.OutputVerbose {
logLevel = slog.LevelDebug
}
logger := jlog.New(logLevel)
ctx := jlog.ContextWith(context.Background(), logger) ctx := jlog.ContextWith(context.Background(), logger)
// Print config
if config.PrintConfig {
logger.WarnContext(ctx, "Printing app config", slog.Any("config", config), slog.Any("parameters", params.ToMap()))
}
err := v.RunFn(ctx, config, r.Handler, params) err := v.RunFn(ctx, config, r.Handler, params)
if err != nil { if err != nil {
logger.ErrorContext(ctx, fmt.Sprintf("%s %s failed", strings.ToUpper(string(v.Name)), r.Name), "error", err.Error()) logger.ErrorContext(ctx, fmt.Sprintf("%s %s failed", strings.ToUpper(string(v.Name)), r.Name), "error", err.Error())

View File

@ -54,3 +54,16 @@ func (c *Container) GetValue(key string) (any, error) {
return item.parseFn(*item.value) return item.parseFn(*item.value)
} }
// Returns a map of all parameters. Parameters that produce errors during parsing are ignored.
func (c *Container) ToMap() (out map[string]any) {
out = make(map[string]any)
for key := range c.params {
v, err := c.GetValue(key)
if err == nil {
out[key] = v
}
}
return
}

View File

@ -6,7 +6,7 @@ import (
var Formatters = map[string]interfaces.Formatter{ var Formatters = map[string]interfaces.Formatter{
"json": &JsonFormatter{}, "json": &JsonFormatter{},
"go": nil, "yaml": nil,
"go": &GoFormatter{},
"table": nil, "table": nil,
"xml": nil,
} }

13
core/output/go.go Normal file
View File

@ -0,0 +1,13 @@
package output
import (
"fmt"
"io"
"strings"
)
type GoFormatter struct{}
func (f *GoFormatter) Format(object any) (io.Reader, error) {
return strings.NewReader(fmt.Sprintf("%#v", object)), nil
}