summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDJ O'Leary <dijitol@proton.me>2026-09-06 23:53:43 +0200
committerDJ O'Leary <dijitol@proton.me>2026-09-06 23:53:43 +0200
commit5d3efcc64fc9664e061b44659f85aeec03a56685 (patch)
tree588cbdce311460860fd9058ffd76ae154969e257
parent142ab324b3c02be49358bb1a38d13b1e6b34d081 (diff)
feat(cli): add cli flags to call api
-rw-r--r--main.go91
-rw-r--r--src/cli/subcommand_group.go56
2 files changed, 135 insertions, 12 deletions
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()
+}