From 5d3efcc64fc9664e061b44659f85aeec03a56685 Mon Sep 17 00:00:00 2001 From: DJ O'Leary Date: Sun, 6 Sep 2026 23:53:43 +0200 Subject: feat(cli): add cli flags to call api --- main.go | 91 +++++++++++++++++++++++++++++++++++++++------ src/cli/subcommand_group.go | 56 ++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 12 deletions(-) create mode 100644 src/cli/subcommand_group.go diff --git a/main.go b/main.go index 313a57c..68e4adf 100644 --- a/main.go +++ b/main.go @@ -2,12 +2,15 @@ package main import ( "context" + "encoding/json" + "flag" + "fmt" "io" - "log" "log/slog" "os" "codeberg.org/dijitol/trading_post/src/cardmarket" + "codeberg.org/dijitol/trading_post/src/cli" "codeberg.org/dijitol/trading_post/src/config" "codeberg.org/dijitol/trading_post/src/oauth" ) @@ -15,7 +18,8 @@ import ( func main() { conf, err := config.NewConfigFromEnv() if err != nil { - log.Fatalln(err.Error()) + fmt.Println(err.Error()) + os.Exit(1) } if err := Run( @@ -24,24 +28,92 @@ func main() { os.Stdout, os.Stderr, conf, + os.Args, ); err != nil { - log.Fatalln(err.Error()) + fmt.Println(err.Error()) + os.Exit(1) } } func Run( ctx context.Context, - in io.Reader, - out, err io.Writer, + stdin io.Reader, + stdout, stderr io.Writer, conf config.Config, + args []string, ) error { + flag.CommandLine.SetOutput(stderr) + + _ = initLogger(ctx, stderr, conf) + client := initAPIClient(conf) + + sg := cli.NewSubcommandGroup(stderr, flag.ContinueOnError) + sg.AddSubcommand( + "account", + "[account] outputs information about the owner of the credentials", + func(_ *flag.FlagSet) error { + account, err := client.GetAccountInformation(ctx) + if err != nil { + return err + } + + out, err := json.Marshal(account) + if err != nil { + return err + } + + fmt.Fprintln(stdout, string(out)) + + return nil + }, + ) + sg.AddSubcommand( + "games", + "[games] outputs all the games", + func(_ *flag.FlagSet) error { + games, err := client.GetGames(ctx) + if err != nil { + return err + } + + out, err := json.Marshal(games) + if err != nil { + return err + } + + fmt.Fprintln(stdout, string(out)) + + return nil + }, + ) + + if len(args) < 2 { // 1st if program name, 2nd is subcommand + return fmt.Errorf("error: missing subcommand - usage: `trading_post [command]`\n%s", sg.Usage()) + } + + if err := sg.ExecSubcommand(args[1]); err != nil { + return err + } + + return nil +} + +func initLogger( + ctx context.Context, + stderr io.Writer, + conf config.Config, +) *slog.Logger { l := slog.New( - slog.NewJSONHandler(err, &slog.HandlerOptions{Level: conf.AppLogLevel}), + slog.NewJSONHandler(stderr, &slog.HandlerOptions{Level: conf.AppLogLevel}), ) slog.SetDefault(l) slog.DebugContext(ctx, conf.String()) + return l +} + +func initAPIClient(conf config.Config) *cardmarket.ApiClient { oauthClient := oauth.NewClient( oauth.Tokens{ Consumer: oauth.ConsumerToken{ @@ -60,10 +132,5 @@ func Run( oauthClient, ) - _, accErr := client.GetAccountInformation(ctx) - if accErr != nil { - return accErr - } - - return nil + return client } diff --git a/src/cli/subcommand_group.go b/src/cli/subcommand_group.go new file mode 100644 index 0000000..957e759 --- /dev/null +++ b/src/cli/subcommand_group.go @@ -0,0 +1,56 @@ +package cli + +import ( + "errors" + "flag" + "fmt" + "io" + "strings" +) + +var ErrUnknownCommand = errors.New("error: unknown command") + +type SubcommandFunc = func(*flag.FlagSet) error + +type Subcommand struct { + FlagSet *flag.FlagSet + Usage string + Func SubcommandFunc +} + +type SubcommandGroup struct { + subcommands map[string]Subcommand + output io.Writer + errorHandling flag.ErrorHandling +} + +func NewSubcommandGroup(output io.Writer, errorHandling flag.ErrorHandling) SubcommandGroup { + return SubcommandGroup{subcommands: make(map[string]Subcommand), output: output, errorHandling: errorHandling} +} + +func (sg *SubcommandGroup) AddSubcommand(name string, usage string, fn SubcommandFunc) { + fs := flag.NewFlagSet(name, sg.errorHandling) + fs.SetOutput(sg.output) + sg.subcommands[name] = Subcommand{ + FlagSet: fs, + Usage: usage, + Func: fn, + } +} + +func (sg SubcommandGroup) ExecSubcommand(name string) error { + cmd, ok := sg.subcommands[name] + if !ok { + return ErrUnknownCommand + } + return cmd.Func(cmd.FlagSet) +} + +func (sg SubcommandGroup) Usage() string { + var b strings.Builder + b.WriteString(" subcommands:\n") + for _, cmd := range sg.subcommands { + fmt.Fprintf(&b, " %s: %s\n", cmd.FlagSet.Name(), cmd.Usage) + } + return b.String() +} -- cgit v1.2.3