diff --git a/cmd/bursa/api.go b/cmd/bursa/api.go index 141f498..a032bf8 100644 --- a/cmd/bursa/api.go +++ b/cmd/bursa/api.go @@ -18,21 +18,30 @@ import ( "github.com/blinklabs-io/bursa/internal/api" "github.com/blinklabs-io/bursa/internal/config" "github.com/blinklabs-io/bursa/internal/logging" + "github.com/spf13/cobra" ) -func apiMain() { - cfg := config.GetConfig() - logger := logging.GetLogger() - // Start API listener - logger.Infof( - "starting API listener on %s:%d", - cfg.Api.ListenAddress, - cfg.Api.ListenPort, - ) - if err := api.Start(cfg); err != nil { - logger.Fatalf("failed to start API: %s", err) - } +func apiCommand() *cobra.Command { + apiCommand := cobra.Command{ + Use: "api", + Short: "Runs the api", + Run: func(cmd *cobra.Command, args []string) { + cfg := config.GetConfig() + // Start API listener + logger := logging.GetLogger() + // Start API listener + logger.Infof( + "starting API listener on %s:%d", + cfg.Api.ListenAddress, + cfg.Api.ListenPort, + ) + if err := api.Start(cfg); err != nil { + logger.Fatalf("failed to start API: %s", err) + } - // Wait forever - select {} + // Wait forever + select {} + }, + } + return &apiCommand } diff --git a/cmd/bursa/main.go b/cmd/bursa/main.go index d18ab8b..03fc8f6 100644 --- a/cmd/bursa/main.go +++ b/cmd/bursa/main.go @@ -15,57 +15,20 @@ package main import ( - "flag" - "fmt" "os" - "github.com/blinklabs-io/bursa/internal/config" "github.com/blinklabs-io/bursa/internal/logging" + "github.com/spf13/cobra" ) -func main() { - var appName string - if os.Args == nil { - appName = "bursa" - } else { - appName = os.Args[0] - } - fs := flag.NewFlagSet(appName, flag.ExitOnError) - fs.Usage = func() { - fmt.Fprintf( - flag.CommandLine.Output(), - "Usage: %s [-h] [args]\n\nSubcommands:\n\n", - appName, - ) - fmt.Fprintf( - flag.CommandLine.Output(), - " - %-18s %s\n", - "api", - "run an API server", - ) - fmt.Fprintf( - flag.CommandLine.Output(), - " - %-18s %s\n", - "cli", - "run a terminal command", - ) - } - if os.Args == nil { - fs.Usage() - os.Exit(1) - } - _ = fs.Parse(os.Args[1:]) // ignore parse errors +const ( + programName = "bursa" +) - // Load Config - _, err := config.LoadConfig() - if err != nil { - fmt.Printf("Failed to load config: %s\n", err) - os.Exit(1) - } +func main() { // Configure logging logging.Setup() logger := logging.GetLogger() - // Sync logger on exit defer func() { if err := logger.Sync(); err != nil { // ignore error @@ -73,22 +36,19 @@ func main() { } }() - var subCommand string - // Parse subcommand - if len(fs.Args()) < 1 { - fs.Usage() - os.Exit(1) - } else { - subCommand = fs.Arg(0) + rootCmd := &cobra.Command{ + Use: programName, + CompletionOptions: cobra.CompletionOptions{ + DisableDefaultCmd: true, + }, } - switch subCommand { - case "api": - apiMain() - case "cli": - cliMain() - default: - fmt.Printf("Unknown subcommand: %s\n", subCommand) + rootCmd.AddCommand( + walletCommand(), + apiCommand(), + ) + + if err := rootCmd.Execute(); err != nil { os.Exit(1) } } diff --git a/cmd/bursa/cli.go b/cmd/bursa/wallet.go similarity index 50% rename from cmd/bursa/cli.go rename to cmd/bursa/wallet.go index 56a3e29..a9328f2 100644 --- a/cmd/bursa/cli.go +++ b/cmd/bursa/wallet.go @@ -1,4 +1,4 @@ -// Copyright 2023 Blink Labs Software +// Copyright 2024 Blink Labs Software // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,8 +16,35 @@ package main import ( "github.com/blinklabs-io/bursa/internal/cli" + "github.com/spf13/cobra" ) -func cliMain() { - cli.Run() +var ( + output string +) + +func walletCommand() *cobra.Command { + walletCommand := cobra.Command{ + Use: "wallet", + Short: "Wallet commands", + } + + walletCommand.AddCommand( + walletCreateCommand(), + ) + return &walletCommand +} + +func walletCreateCommand() *cobra.Command { + walletCreateCommand := cobra.Command{ + Use: "create", + Short: "Creates a new wallet", + Run: func(cmd *cobra.Command, args []string) { + cli.Run(output) + }, + } + + walletCreateCommand.PersistentFlags().StringVar(&output, "output", "", "") + + return &walletCreateCommand } diff --git a/go.mod b/go.mod index d25dbe2..2c815b4 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/kelseyhightower/envconfig v1.4.0 github.com/penglongli/gin-metrics v0.1.10 + github.com/spf13/cobra v1.8.0 github.com/swaggo/files v1.0.1 github.com/swaggo/gin-swagger v1.6.0 github.com/swaggo/swag v1.16.3 @@ -40,6 +41,7 @@ require ( github.com/go-playground/validator/v10 v10.20.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/golang/protobuf v1.5.2 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect @@ -55,6 +57,7 @@ require ( github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect + github.com/spf13/pflag v1.0.5 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect github.com/x448/float16 v0.8.4 // indirect diff --git a/go.sum b/go.sum index 47fd68d..56a75f6 100644 --- a/go.sum +++ b/go.sum @@ -78,6 +78,7 @@ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJ github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -193,6 +194,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -283,9 +286,14 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= diff --git a/internal/api/api.go b/internal/api/api.go index 1de22b1..8e4ed4c 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -20,6 +20,7 @@ import ( "time" ginzap "github.com/gin-contrib/zap" + "github.com/gin-gonic/gin" "github.com/penglongli/gin-metrics/ginmetrics" swaggerFiles "github.com/swaggo/files" // swagger embed files @@ -53,7 +54,6 @@ func Start(cfg *config.Config) error { // Disable gin debug and color output gin.SetMode(gin.ReleaseMode) gin.DisableConsoleColor() - // Configure API router router := gin.New() // Catch panics and return a 500 diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 698c02e..d149d76 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -15,7 +15,6 @@ package cli import ( - "flag" "fmt" "os" "path/filepath" @@ -27,17 +26,7 @@ import ( "github.com/blinklabs-io/bursa/internal/logging" ) -func Run() { - fs := flag.NewFlagSet("cli", flag.ExitOnError) - flagOutput := fs.String( - "output", - "", - "output directory for files, otherwise uses STDOUT", - ) - if len(os.Args) >= 2 { - _ = fs.Parse(os.Args[2:]) // ignore parse errors - } - +func Run(output string) { cfg := config.GetConfig() logger := logging.GetLogger() // Load mnemonic @@ -54,9 +43,9 @@ func Run() { logger.Fatalf("failed to initialize wallet: %s", err) } - logger.Infof("Loaded mnemonic and generated address...") + logger.Info("Loaded mnemonic and generated address...") - if *flagOutput == "" { + if output == "" { fmt.Printf("MNEMONIC=%s\n", w.Mnemonic) fmt.Printf("PAYMENT_ADDRESS=%s\n", w.PaymentAddress) fmt.Printf("STAKE_ADDRESS=%s\n", w.StakeAddress) @@ -68,10 +57,10 @@ func Run() { fmt.Printf("stake.skey=%s\n", bursa.GetKeyFile(w.StakeSKey)) fmt.Printf("stakeExtended.skey=%s\n", bursa.GetKeyFile(w.StakeExtendedSKey)) } else { - fmt.Printf("Output dir: %v\n", *flagOutput) - _, err := os.Stat(*flagOutput) + fmt.Printf("Output dir: %v\n", output) + _, err := os.Stat(output) if os.IsNotExist(err) { - err = os.MkdirAll(*flagOutput, 0755) + err = os.MkdirAll(output, 0755) if err != nil { panic(err) } @@ -93,7 +82,7 @@ func Run() { k := k v := v g.Go(func() error { - path := filepath.Join(*flagOutput, k) + path := filepath.Join(output, k) err = os.WriteFile(path, []byte(v), 0666) if err != nil { return err @@ -107,7 +96,7 @@ func Run() { logger.Fatalf("error occurred: %s", err) os.Exit(1) } - logger.Infof("wrote output files to %s", *flagOutput) + logger.Infof("wrote output files to %s", output) } }