123 lines
3.1 KiB
Go
123 lines
3.1 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
"os"
|
|
"slices"
|
|
"strings"
|
|
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces"
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/core/interfaces/params"
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/core/output"
|
|
"git.bissendorf.co/bissendorf/unifood/m/v2/core/services/jlog"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
type VerbItem struct {
|
|
Name interfaces.Verb
|
|
Aliases []string
|
|
Description string
|
|
RunFn func(ctx context.Context, config *AppConfig, handler interfaces.ResourceHandler, params params.Container) error
|
|
}
|
|
|
|
var verbs = []VerbItem{
|
|
{
|
|
Name: interfaces.VerbGet,
|
|
Description: "Retrieve resource information",
|
|
RunFn: func(ctx context.Context, config *AppConfig, handler interfaces.ResourceHandler, params params.Container) error {
|
|
h, ok := handler.(interfaces.GetHandler)
|
|
if !ok {
|
|
return fmt.Errorf("resource does not support GET")
|
|
}
|
|
|
|
// Get items
|
|
items, err := h.Get(ctx, params)
|
|
if err != nil {
|
|
return fmt.Errorf("retrieving item failed: %w", err)
|
|
}
|
|
|
|
formatterName := strings.ToLower(config.OutputFormatter)
|
|
formatter, exists := output.Formatters[formatterName]
|
|
if !exists {
|
|
return fmt.Errorf("could not find output formatter '%s'", formatterName)
|
|
}
|
|
|
|
// Format and output
|
|
formatted, err := formatter.Format(items)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to format output: %w", err)
|
|
}
|
|
_, err = io.Copy(os.Stdout, formatted)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to write output: %w", err)
|
|
}
|
|
|
|
return nil
|
|
},
|
|
},
|
|
}
|
|
|
|
func getVerbs(ctx context.Context, config *AppConfig) (commands []*cobra.Command) {
|
|
for _, v := range verbs {
|
|
verbCommand := &cobra.Command{
|
|
Use: strings.ToLower(string(v.Name)),
|
|
Aliases: v.Aliases,
|
|
Short: v.Description,
|
|
}
|
|
|
|
// Add all resources that can handle this verb
|
|
for _, r := range availableResources {
|
|
if !slices.Contains(r.Verbs, v.Name) {
|
|
continue
|
|
}
|
|
|
|
var params params.Container
|
|
|
|
resourceCommand := &cobra.Command{
|
|
Use: r.Name,
|
|
Aliases: r.Aliases,
|
|
Short: r.Description,
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
// Configure log
|
|
var logLevel = slog.LevelWarn
|
|
if config.OutputVerbose {
|
|
logLevel = slog.LevelDebug
|
|
}
|
|
logger := jlog.New(logLevel)
|
|
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)
|
|
if err != nil {
|
|
logger.ErrorContext(ctx, fmt.Sprintf("%s %s failed", strings.ToUpper(string(v.Name)), r.Name), "error", err.Error())
|
|
os.Exit(1)
|
|
}
|
|
},
|
|
}
|
|
|
|
// Register parameters
|
|
for _, param := range r.Handler.GetParametersForVerb(v.Name) {
|
|
resourceCommand.Flags().StringVarP(
|
|
params.Register(param.Name, param.ParseFunc),
|
|
param.Name,
|
|
param.ShortHand,
|
|
param.DefaultFunc(),
|
|
param.Description,
|
|
)
|
|
}
|
|
verbCommand.AddCommand(resourceCommand)
|
|
}
|
|
|
|
commands = append(commands, verbCommand)
|
|
}
|
|
|
|
return
|
|
}
|