From 7717f91a8d5218758e0a2811f5e82ec150c481d8 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Wed, 1 Jun 2022 00:34:45 +0200 Subject: [PATCH 01/23] wip: console --- cmd/console.go | 20 ++++++++++++++ cmd/root.go | 6 ++++- internal/console/console.go | 52 +++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 cmd/console.go create mode 100644 internal/console/console.go diff --git a/cmd/console.go b/cmd/console.go new file mode 100644 index 0000000..6a7f1d2 --- /dev/null +++ b/cmd/console.go @@ -0,0 +1,20 @@ +package cmd + +import ( + "github.com/spf13/cobra" + "github.com/stratumfarm/derocli/internal/console" +) + +var consoleCmd = &cobra.Command{ + Use: "console", + Short: "Start an interactive console", + PreRunE: connectNode, + PostRun: func(cmd *cobra.Command, args []string) { client.Close() }, + RunE: runConsole, +} + +func runConsole(cmd *cobra.Command, args []string) error { + c := console.New(console.WithClient(client)) + return c.Read() + // return nil +} diff --git a/cmd/root.go b/cmd/root.go index 84de505..cbadaa3 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -34,7 +34,11 @@ var rootCmd = &cobra.Command{ } func init() { - rootCmd.AddCommand(versionCmd, manCmd, allCmd, heightCmd, infoCmd, peersCmd, txPoolCmd) + rootCmd.AddCommand( + versionCmd, manCmd, allCmd, + heightCmd, infoCmd, peersCmd, + txPoolCmd, consoleCmd, + ) rootCmd.PersistentFlags().StringVarP(&rootCmdFlags.config, "config", "c", "", "path to the config file") rootCmd.PersistentFlags().StringP("rpc", "r", "localhost:10102", "address of the node") diff --git a/internal/console/console.go b/internal/console/console.go new file mode 100644 index 0000000..acd20c4 --- /dev/null +++ b/internal/console/console.go @@ -0,0 +1,52 @@ +package console + +import ( + "bufio" + "fmt" + "os" + + "github.com/stratumfarm/derocli/pkg/dero" +) + +type Opts func(*Console) + +func WithClient(client *dero.Client) Opts { + return func(c *Console) { + c.client = client + } +} + +type Console struct { + stdin *os.File + stdout *os.File + stderr *os.File + + client *dero.Client +} + +func New(opts ...Opts) *Console { + c := &Console{ + stdin: os.Stdin, + stdout: os.Stdout, + stderr: os.Stderr, + } + for _, opt := range opts { + opt(c) + } + return c +} + +func (c *Console) Read() error { + scanner := bufio.NewScanner(c.stdin) + for scanner.Scan() { + c.handleInput(scanner.Text()) + } + if err := scanner.Err(); err != nil { + fmt.Fprintln(c.stderr, "reading standard input:", err) + } + return nil +} + +func (c *Console) handleInput(input string) error { + return nil +} From 93f6b35db63c65f395a594a4193602ce5895a8e9 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Wed, 1 Jun 2022 03:16:51 +0200 Subject: [PATCH 02/23] feat: very basic console --- cmd/console.go | 35 +++++++++- go.mod | 5 ++ go.sum | 10 +++ internal/console/commands.go | 69 ++++++++++++++++++++ internal/console/console.go | 120 ++++++++++++++++++++++++++++++++--- 5 files changed, 228 insertions(+), 11 deletions(-) create mode 100644 internal/console/commands.go diff --git a/cmd/console.go b/cmd/console.go index 6a7f1d2..4518bbb 100644 --- a/cmd/console.go +++ b/cmd/console.go @@ -1,6 +1,13 @@ package cmd import ( + "context" + "log" + "os" + "os/signal" + "sync" + "syscall" + "github.com/spf13/cobra" "github.com/stratumfarm/derocli/internal/console" ) @@ -14,7 +21,29 @@ var consoleCmd = &cobra.Command{ } func runConsole(cmd *cobra.Command, args []string) error { - c := console.New(console.WithClient(client)) - return c.Read() - // return nil + done := make(chan os.Signal, 1) + signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + c, err := console.New(console.WithClient(client)) + if err != nil { + log.Fatalln(err) + } + + ctx, cancel := context.WithCancel(cmd.Context()) + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + if err := c.Start(ctx); err != nil { + log.Fatalln(err) + } + }() + defer c.Close() + go func() { + <-done + cancel() + }() + wg.Wait() + + return nil } diff --git a/go.mod b/go.mod index d90905c..9c6e381 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/gorilla/websocket v1.5.0 github.com/muesli/mango-cobra v1.1.0 github.com/muesli/roff v0.1.0 + github.com/muesli/termenv v0.11.0 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.12.0 ) @@ -23,13 +24,17 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/klauspost/compress v1.10.3 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/muesli/mango v0.1.0 // indirect github.com/muesli/mango-pflag v0.1.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect diff --git a/go.sum b/go.sum index 916a5ee..89ae333 100644 --- a/go.sum +++ b/go.sum @@ -179,10 +179,15 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -197,6 +202,8 @@ github.com/muesli/mango-pflag v0.1.0 h1:UADqbYgpUyRoBja3g6LUL+3LErjpsOwaC9ywvBWe github.com/muesli/mango-pflag v0.1.0/go.mod h1:YEQomTxaCUp8PrbhFh10UfbhbQrM/xJ4i2PB8VTLLW0= github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8= github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig= +github.com/muesli/termenv v0.11.0 h1:fwNUbu2mfWlgicwG7qYzs06aOI8Z/zKPAv8J4uKbT+o= +github.com/muesli/termenv v0.11.0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= @@ -206,6 +213,8 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -378,6 +387,7 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/console/commands.go b/internal/console/commands.go new file mode 100644 index 0000000..5630298 --- /dev/null +++ b/internal/console/commands.go @@ -0,0 +1,69 @@ +package console + +import ( + "fmt" + + "github.com/muesli/termenv" +) + +type Cmd struct { + Name string + Description string + IgnorePipe bool + Matcher func(cmd string) bool + Handler func(c *Console, cmd string) error + Console *Console +} + +func (c *Cmd) Match(cmd string) bool { + return c.Matcher(cmd) +} + +func (c *Cmd) Handle(cmd string) error { + if c.Console.isPipe && c.IgnorePipe { + return nil + } + return c.Handler(c.Console, cmd) +} + +var HelpCmd = &Cmd{ + Name: "help", + Description: "Show the help", + Matcher: func(cmd string) bool { return cmd == "help" }, + Handler: func(c *Console, cmd string) error { + fmt.Fprintln(c.stdout, helpView(c)) + return nil + }, +} + +func helpView(c *Console) string { + s := "Available commands:" + for _, cmd := range c.cmds { + if cmd.Name != "" && cmd.Description != "" { + s += fmt.Sprintf("\n %s - %s", cmd.Name, cmd.Description) + } + } + return s +} + +var QuitCmd = &Cmd{ + Name: "quit", + Description: "Quit the console", + IgnorePipe: true, + Matcher: func(cmd string) bool { return cmd == "quit" || cmd == "exit" }, + Handler: func(c *Console, cmd string) error { + c.cancel() + return nil + }, +} + +var ClearCmd = &Cmd{ + Name: "clear", + Description: "Clear the screen", + IgnorePipe: true, + Matcher: func(cmd string) bool { return cmd == "clear" }, + Handler: func(c *Console, cmd string) error { + termenv.ClearScreen() + return nil + }, +} diff --git a/internal/console/console.go b/internal/console/console.go index acd20c4..5bc7067 100644 --- a/internal/console/console.go +++ b/internal/console/console.go @@ -2,9 +2,13 @@ package console import ( "bufio" + "context" "fmt" + "io" "os" + "strings" + "github.com/muesli/termenv" "github.com/stratumfarm/derocli/pkg/dero" ) @@ -17,15 +21,23 @@ func WithClient(client *dero.Client) Opts { } type Console struct { + ctx context.Context + cancel context.CancelFunc + stdin *os.File + isPipe bool stdout *os.File stderr *os.File + cmds []*Cmd client *dero.Client } -func New(opts ...Opts) *Console { +func New(opts ...Opts) (*Console, error) { + ctx, cancel := context.WithCancel(context.Background()) c := &Console{ + ctx: ctx, + cancel: cancel, stdin: os.Stdin, stdout: os.Stdout, stderr: os.Stderr, @@ -33,20 +45,112 @@ func New(opts ...Opts) *Console { for _, opt := range opts { opt(c) } - return c + ok, err := fileIsPipe(c.stdin) + if err != nil { + return nil, err + } + c.isPipe = ok + + c.registerCommands( + HelpCmd, + QuitCmd, + ClearCmd, + ) + + return c, nil } -func (c *Console) Read() error { - scanner := bufio.NewScanner(c.stdin) - for scanner.Scan() { - c.handleInput(scanner.Text()) +func fileIsPipe(in *os.File) (bool, error) { + if fi, _ := in.Stat(); (fi.Mode() & os.ModeNamedPipe) != 0 { + return true, nil + } + return false, nil +} + +func (c *Console) registerCommands(cmds ...*Cmd) { + for _, cmd := range cmds { + cmd.Console = c } - if err := scanner.Err(); err != nil { - fmt.Fprintln(c.stderr, "reading standard input:", err) + c.cmds = cmds +} + +func (c *Console) Start(ctx context.Context) error { + if !c.isPipe { + termenv.AltScreen() + termenv.ClearScreen() + defer termenv.ExitAltScreen() } + c.welcomeMsg() + return c.read(ctx) +} + +func (c *Console) Close() error { + c.cancel() return nil } +func (c *Console) welcomeMsg() { + fmt.Fprintf(c.stdout, "Welcome to dero-cli!\n> ") +} + +func (c *Console) read(ctx context.Context) error { + if c.isPipe { + msg, err := c.readFromPipe() + if err != nil { + fmt.Fprintln(c.stderr, "reading pipe input:", err) + } + c.stdout.Write([]byte(msg)) + return c.handleInput(msg) + } + scanner := bufio.NewScanner(c.stdin) + inch := make(chan string) + go func() { + defer close(inch) + for scanner.Scan() { + inch <- scanner.Text() + } + if err := scanner.Err(); err != nil { + if err == io.EOF { + return + } + fmt.Fprintln(c.stderr, "reading standard input:", err) + } + }() + for { + select { + case in, ok := <-inch: + if !ok { + return nil + } + if err := c.handleInput(in); err != nil { + fmt.Fprintln(c.stderr, err) + } + case <-ctx.Done(): + return nil + case <-c.ctx.Done(): + return nil + } + } +} + +func (c *Console) readFromPipe() (string, error) { + defer c.stdin.Close() + data, err := io.ReadAll(c.stdin) + if err != nil { + return "", err + } + return string(data), nil +} + func (c *Console) handleInput(input string) error { + input = strings.TrimSpace(input) + if !c.isPipe { + defer fmt.Fprintf(c.stdout, "\n> ") + } + for _, cmd := range c.cmds { + if cmd.Match(input) { + cmd.Handle(input) + } + } return nil } From bfe70c69f14d458a09dedab5daa308e689086f26 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sat, 4 Jun 2022 00:23:50 +0200 Subject: [PATCH 03/23] feat: a bit a better console --- cmd/console.go | 11 ++- go.mod | 5 +- go.sum | 14 ++- internal/console/commands.go | 34 +++++-- internal/console/console.go | 167 +++++++++++++++++++---------------- internal/console/style.go | 5 ++ 6 files changed, 149 insertions(+), 87 deletions(-) create mode 100644 internal/console/style.go diff --git a/cmd/console.go b/cmd/console.go index 4518bbb..76073d9 100644 --- a/cmd/console.go +++ b/cmd/console.go @@ -24,17 +24,22 @@ func runConsole(cmd *cobra.Command, args []string) error { done := make(chan os.Signal, 1) signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) - c, err := console.New(console.WithClient(client)) + ctx, cancel := context.WithCancel(cmd.Context()) + defer cancel() + + c, err := console.New( + console.WithClient(client), + console.WithContext(ctx), + ) if err != nil { log.Fatalln(err) } - ctx, cancel := context.WithCancel(cmd.Context()) var wg sync.WaitGroup wg.Add(1) go func() { defer wg.Done() - if err := c.Start(ctx); err != nil { + if err := c.Start(); err != nil { log.Fatalln(err) } }() diff --git a/go.mod b/go.mod index 9c6e381..08cd02d 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,14 @@ module github.com/stratumfarm/derocli go 1.18 require ( + github.com/charmbracelet/lipgloss v0.5.0 github.com/creachadair/jrpc2 v0.41.0 github.com/deroproject/derohe v0.0.0-20220523042906-db7eba4be8ae github.com/gorilla/websocket v1.5.0 github.com/muesli/mango-cobra v1.1.0 github.com/muesli/roff v0.1.0 - github.com/muesli/termenv v0.11.0 + github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 + github.com/peterh/liner v1.2.2 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.12.0 ) @@ -31,6 +33,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/muesli/mango v0.1.0 // indirect github.com/muesli/mango-pflag v0.1.0 // indirect + github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index 89ae333..413c2ae 100644 --- a/go.sum +++ b/go.sum @@ -43,6 +43,8 @@ github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2y github.com/caarlos0/env/v6 v6.9.2 h1:vYTmP7KPtHf3LqaQH5Z2AkUY8GmanDrTelXnFzxSK44= github.com/caarlos0/env/v6 v6.9.2/go.mod h1:hvp/ryKXKipEkcuYjs9mI4bBCg+UI0Yhgm5Zu0ddvwc= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/charmbracelet/lipgloss v0.5.0 h1:lulQHuVeodSgDez+3rGiuxlPVXSnhth442DATR2/8t8= +github.com/charmbracelet/lipgloss v0.5.0/go.mod h1:EZLha/HbzEt7cYqdFPovlqy5FZPj0xFhg5SaqxScmgs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -186,6 +188,8 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -200,19 +204,24 @@ github.com/muesli/mango-cobra v1.1.0 h1:j/mM5omhC2Vw8pim716aMJVElIRln089XZJ2JY7X github.com/muesli/mango-cobra v1.1.0/go.mod h1:lotV+49eKrAV0tTw/ONhLsiyKwM5uW5QP2OkYw4xlNc= github.com/muesli/mango-pflag v0.1.0 h1:UADqbYgpUyRoBja3g6LUL+3LErjpsOwaC9ywvBWe7Sg= github.com/muesli/mango-pflag v0.1.0/go.mod h1:YEQomTxaCUp8PrbhFh10UfbhbQrM/xJ4i2PB8VTLLW0= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 h1:y1p/ycavWjGT9FnmSjdbWUlLGvcxrY0Rw3ATltrxOhk= +github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ= github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8= github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig= -github.com/muesli/termenv v0.11.0 h1:fwNUbu2mfWlgicwG7qYzs06aOI8Z/zKPAv8J4uKbT+o= -github.com/muesli/termenv v0.11.0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 h1:STjmj0uFfRryL9fzRA/OupNppeAID6QJYPMavTL7jtY= +github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw= +github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -388,6 +397,7 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/console/commands.go b/internal/console/commands.go index 5630298..b1b2f77 100644 --- a/internal/console/commands.go +++ b/internal/console/commands.go @@ -1,11 +1,16 @@ package console import ( + "context" + "encoding/json" "fmt" + "time" "github.com/muesli/termenv" ) +var requestTimeout = 5 * time.Second + type Cmd struct { Name string Description string @@ -20,9 +25,6 @@ func (c *Cmd) Match(cmd string) bool { } func (c *Cmd) Handle(cmd string) error { - if c.Console.isPipe && c.IgnorePipe { - return nil - } return c.Handler(c.Console, cmd) } @@ -31,7 +33,7 @@ var HelpCmd = &Cmd{ Description: "Show the help", Matcher: func(cmd string) bool { return cmd == "help" }, Handler: func(c *Console, cmd string) error { - fmt.Fprintln(c.stdout, helpView(c)) + fmt.Println(helpView(c)) return nil }, } @@ -52,7 +54,7 @@ var QuitCmd = &Cmd{ IgnorePipe: true, Matcher: func(cmd string) bool { return cmd == "quit" || cmd == "exit" }, Handler: func(c *Console, cmd string) error { - c.cancel() + c.Close() return nil }, } @@ -67,3 +69,25 @@ var ClearCmd = &Cmd{ return nil }, } + +var InfoCmd = &Cmd{ + Name: "info", + Description: "Get info about the dero node", + Matcher: func(cmd string) bool { return cmd == "info" }, + Handler: handleInfoCmd, +} + +func handleInfoCmd(c *Console, cmd string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + info, err := c.client.GetInfo(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(info, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/console/console.go b/internal/console/console.go index 5bc7067..3eeb640 100644 --- a/internal/console/console.go +++ b/internal/console/console.go @@ -1,17 +1,19 @@ package console import ( - "bufio" "context" "fmt" "io" "os" + "path/filepath" "strings" - "github.com/muesli/termenv" + "github.com/peterh/liner" "github.com/stratumfarm/derocli/pkg/dero" ) +var historyFn = filepath.Join(os.TempDir(), ".derocli_history") + type Opts func(*Console) func WithClient(client *dero.Client) Opts { @@ -20,51 +22,46 @@ func WithClient(client *dero.Client) Opts { } } -type Console struct { - ctx context.Context - cancel context.CancelFunc +func WithContext(ctx context.Context) Opts { + return func(c *Console) { + c.parentCtx = ctx + } +} - stdin *os.File - isPipe bool - stdout *os.File - stderr *os.File +type Console struct { + parentCtx context.Context + ctx context.Context + cancel context.CancelFunc + liner *liner.State cmds []*Cmd client *dero.Client } func New(opts ...Opts) (*Console, error) { - ctx, cancel := context.WithCancel(context.Background()) c := &Console{ - ctx: ctx, - cancel: cancel, - stdin: os.Stdin, - stdout: os.Stdout, - stderr: os.Stderr, + parentCtx: context.Background(), + liner: liner.NewLiner(), } for _, opt := range opts { opt(c) } - ok, err := fileIsPipe(c.stdin) - if err != nil { - return nil, err - } - c.isPipe = ok + + ctx, cancel := context.WithCancel(c.parentCtx) + c.ctx = ctx + c.cancel = cancel c.registerCommands( HelpCmd, QuitCmd, ClearCmd, + InfoCmd, ) + c.setCompleter() - return c, nil -} + c.liner.SetCtrlCAborts(true) -func fileIsPipe(in *os.File) (bool, error) { - if fi, _ := in.Stat(); (fi.Mode() & os.ModeNamedPipe) != 0 { - return true, nil - } - return false, nil + return c, nil } func (c *Console) registerCommands(cmds ...*Cmd) { @@ -74,82 +71,100 @@ func (c *Console) registerCommands(cmds ...*Cmd) { c.cmds = cmds } -func (c *Console) Start(ctx context.Context) error { - if !c.isPipe { - termenv.AltScreen() - termenv.ClearScreen() - defer termenv.ExitAltScreen() - } +func (c *Console) Start() error { + c.readHistory() c.welcomeMsg() - return c.read(ctx) + return c.read() } func (c *Console) Close() error { c.cancel() + c.writeHistory() + c.liner.Close() return nil } +func (c *Console) setCompleter() { + c.liner.SetCompleter(func(line string) (s []string) { + for _, n := range c.cmds { + if strings.HasPrefix(n.Name, strings.ToLower(line)) { + s = append(s, n.Name) + } + } + return + }) +} + func (c *Console) welcomeMsg() { - fmt.Fprintf(c.stdout, "Welcome to dero-cli!\n> ") + fmt.Println("Welcome to derocli!\n> ") } -func (c *Console) read(ctx context.Context) error { - if c.isPipe { - msg, err := c.readFromPipe() - if err != nil { - fmt.Fprintln(c.stderr, "reading pipe input:", err) - } - c.stdout.Write([]byte(msg)) - return c.handleInput(msg) - } - scanner := bufio.NewScanner(c.stdin) - inch := make(chan string) +func (c *Console) read() error { + doneC := make(chan struct{}) go func() { - defer close(inch) - for scanner.Scan() { - inch <- scanner.Text() - } - if err := scanner.Err(); err != nil { - if err == io.EOF { - return + defer close(doneC) + for { + if in, err := c.liner.Prompt("> "); err == nil { + c.liner.AppendHistory(in) + if err := c.handleInput(in); err != nil { + fmt.Println(styleError.Render(err.Error())) + } + if QuitCmd.Matcher(in) { // special case to prevent an unnecessary newline + break + } + } else if err == liner.ErrPromptAborted { + fmt.Println("Aborted") + break + } else if err == io.EOF { + break + } else { + fmt.Println(styleError.Render(fmt.Sprintf("Error reading line: %s", err))) + break } - fmt.Fprintln(c.stderr, "reading standard input:", err) } }() - for { - select { - case in, ok := <-inch: - if !ok { - return nil - } - if err := c.handleInput(in); err != nil { - fmt.Fprintln(c.stderr, err) - } - case <-ctx.Done(): - return nil - case <-c.ctx.Done(): - return nil + + select { + case <-doneC: + return nil + case <-c.ctx.Done(): + return nil + } +} + +func (c *Console) readHistory() { + f, err := os.Open(historyFn) + if err != nil { + if os.IsNotExist(err) { + return } + fmt.Println(styleError.Render(fmt.Sprintf("Error opening history file: %s", err))) + } + defer f.Close() + if _, err := c.liner.ReadHistory(f); err != nil { + fmt.Println(styleError.Render(fmt.Sprintf("Error reading history file: %s", err))) } } -func (c *Console) readFromPipe() (string, error) { - defer c.stdin.Close() - data, err := io.ReadAll(c.stdin) +func (c *Console) writeHistory() { + f, err := os.Create(historyFn) if err != nil { - return "", err + fmt.Println(styleError.Render(fmt.Sprintf("Error creating history file: %s", err))) + } + defer f.Close() + if _, err := c.liner.WriteHistory(f); err != nil { + fmt.Println(styleError.Render(fmt.Sprintf("Error writing history file: %s", err))) } - return string(data), nil } func (c *Console) handleInput(input string) error { input = strings.TrimSpace(input) - if !c.isPipe { - defer fmt.Fprintf(c.stdout, "\n> ") - } for _, cmd := range c.cmds { if cmd.Match(input) { - cmd.Handle(input) + if err := cmd.Handle(input); err != nil { + fmt.Println(styleError.Render(fmt.Sprintf("error running command %s: %s\n", cmd.Name, err))) + } + return nil } } return nil diff --git a/internal/console/style.go b/internal/console/style.go new file mode 100644 index 0000000..a8d7e7f --- /dev/null +++ b/internal/console/style.go @@ -0,0 +1,5 @@ +package console + +import "github.com/charmbracelet/lipgloss" + +var styleError = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "#FF4672", Dark: "#FF4672"}) From bf8f79137b10b529be9f2dddd2b0b4391749417a Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sat, 4 Jun 2022 02:13:10 +0200 Subject: [PATCH 04/23] feat: peers command, refactor: command registration --- go.mod | 2 +- go.sum | 6 ++++-- internal/console/commands.go | 30 ++++++++++++++++++++++++++++++ internal/console/console.go | 5 +---- pkg/dero/rpc.go | 24 ++++++++++++++++-------- 5 files changed, 52 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 08cd02d..66a52c1 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.18 require ( github.com/charmbracelet/lipgloss v0.5.0 github.com/creachadair/jrpc2 v0.41.0 - github.com/deroproject/derohe v0.0.0-20220523042906-db7eba4be8ae github.com/gorilla/websocket v1.5.0 github.com/muesli/mango-cobra v1.1.0 github.com/muesli/roff v0.1.0 @@ -13,6 +12,7 @@ require ( github.com/peterh/liner v1.2.2 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.12.0 + github.com/stratumfarm/derohe v0.0.0-20220603233726-87b22b6757f8 ) require ( diff --git a/go.sum b/go.sum index 413c2ae..5f6c6b8 100644 --- a/go.sum +++ b/go.sum @@ -58,8 +58,6 @@ github.com/creachadair/jrpc2 v0.41.0/go.mod h1:SwEPHK3zqbc5j6AVBVdGoc2QYwYDQUBGn github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deroproject/derohe v0.0.0-20220523042906-db7eba4be8ae h1:DRc6Ah1FlynghElpl++IOWTBQiOIYf2O2HmcifAj3HA= -github.com/deroproject/derohe v0.0.0-20220523042906-db7eba4be8ae/go.mod h1:EWHh1VkXRnCHvyGML98kXhngDFYebmOhk/9kZ1ATJ1c= github.com/deroproject/graviton v0.0.0-20220130070622-2c248a53b2e1 h1:nsiNx83HYmRmYpYO37pUzSTmB7p9PFtGBl4FyD+a0jg= github.com/deroproject/graviton v0.0.0-20220130070622-2c248a53b2e1/go.mod h1:a4u6QJtGGIADg1JwujD77UtaAyhIxg14+I0C7xjyQcc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -241,6 +239,10 @@ 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/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/stratumfarm/derohe v0.0.0-20220603195355-37b0a28e4dbe h1:C38QIxJxtelZbXCSRafAXjxI/EXS7OmNlWb7KbKoAxc= +github.com/stratumfarm/derohe v0.0.0-20220603195355-37b0a28e4dbe/go.mod h1:1fq6tvob4JwDQhdxuUX81DdlID1wYkx4TyJH2ve0J9A= +github.com/stratumfarm/derohe v0.0.0-20220603233726-87b22b6757f8 h1:5iETeDNBTrIZj/RecN/WfRtCaanhXlTdfYyR4q2I/18= +github.com/stratumfarm/derohe v0.0.0-20220603233726-87b22b6757f8/go.mod h1:1fq6tvob4JwDQhdxuUX81DdlID1wYkx4TyJH2ve0J9A= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/internal/console/commands.go b/internal/console/commands.go index b1b2f77..e416d88 100644 --- a/internal/console/commands.go +++ b/internal/console/commands.go @@ -11,6 +11,14 @@ import ( var requestTimeout = 5 * time.Second +var Cmds = []*Cmd{ + HelpCmd, + QuitCmd, + ClearCmd, + InfoCmd, + PeersCmd, +} + type Cmd struct { Name string Description string @@ -91,3 +99,25 @@ func handleInfoCmd(c *Console, cmd string) error { fmt.Println(string(data)) return nil } + +var PeersCmd = &Cmd{ + Name: "peers", + Description: "Get info about the peers", + Matcher: func(cmd string) bool { return cmd == "peers" }, + Handler: handlePeersCmd, +} + +func handlePeersCmd(c *Console, cmd string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + peers, err := c.client.GetPeers(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(peers, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/console/console.go b/internal/console/console.go index 3eeb640..97284fd 100644 --- a/internal/console/console.go +++ b/internal/console/console.go @@ -52,10 +52,7 @@ func New(opts ...Opts) (*Console, error) { c.cancel = cancel c.registerCommands( - HelpCmd, - QuitCmd, - ClearCmd, - InfoCmd, + Cmds..., ) c.setCompleter() diff --git a/pkg/dero/rpc.go b/pkg/dero/rpc.go index a760985..ddcfd36 100644 --- a/pkg/dero/rpc.go +++ b/pkg/dero/rpc.go @@ -7,9 +7,9 @@ import ( "github.com/creachadair/jrpc2" "github.com/creachadair/jrpc2/channel" - "github.com/deroproject/derohe/glue/rwc" - derorpc "github.com/deroproject/derohe/rpc" "github.com/gorilla/websocket" + "github.com/stratumfarm/derohe/glue/rwc" + derorpc "github.com/stratumfarm/derohe/rpc" ) type Client struct { @@ -60,18 +60,26 @@ func (c *Client) GetInfo(ctx context.Context) (*derorpc.GetInfo_Result, error) { return res, nil } -/* func (c *Client) GetPeers(ctx context.Context) (*derop2p.PeersInfo, error) { - res := new(derop2p.PeersInfo) +func (c *Client) GetPeers(ctx context.Context) (*derorpc.GetPeersResult, error) { + res := new(derorpc.GetPeersResult) if err := c.rpc.CallResult(context.Background(), "DERO.GetPeers", nil, res); err != nil { return nil, fmt.Errorf("failed to call: %w", err) } return res, nil -} */ +} -func (c *Client) GetTxPool(ctx context.Context) (derorpc.GetTxPool_Result, error) { +func (c *Client) GetTxPool(ctx context.Context) (*derorpc.GetTxPool_Result, error) { res := new(derorpc.GetTxPool_Result) if err := c.rpc.CallResult(context.Background(), "DERO.GetTxPool", nil, res); err != nil { - return *res, fmt.Errorf("failed to call: %w", err) + return nil, fmt.Errorf("failed to call: %w", err) + } + return res, nil +} + +func (c *Client) GetConnections(ctx context.Context) (*derorpc.GetConnectionResult, error) { + res := new(derorpc.GetConnectionResult) + if err := c.rpc.CallResult(context.Background(), "DERO.GetConnections", nil, res); err != nil { + return nil, fmt.Errorf("failed to call: %w", err) } - return *res, nil + return nil, nil } From e8ec5ed677db3cdd53c14c0b062b1ee8a0c4fbc1 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sat, 4 Jun 2022 02:14:56 +0200 Subject: [PATCH 05/23] fix: sanitize input --- internal/console/console.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/console/console.go b/internal/console/console.go index 97284fd..fd8d289 100644 --- a/internal/console/console.go +++ b/internal/console/console.go @@ -102,6 +102,10 @@ func (c *Console) read() error { defer close(doneC) for { if in, err := c.liner.Prompt("> "); err == nil { + in = strings.TrimSpace(in) + if in == "" { + continue + } c.liner.AppendHistory(in) if err := c.handleInput(in); err != nil { fmt.Println(styleError.Render(err.Error())) From 6413505dce083facb7904643c1e5acc4232c88ec Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sat, 4 Jun 2022 02:30:05 +0200 Subject: [PATCH 06/23] fix: improve auto complete and command matching --- internal/console/commands.go | 29 +++++++++++++++++++++++------ internal/console/console.go | 8 +++++++- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/internal/console/commands.go b/internal/console/commands.go index e416d88..b08185b 100644 --- a/internal/console/commands.go +++ b/internal/console/commands.go @@ -21,6 +21,7 @@ var Cmds = []*Cmd{ type Cmd struct { Name string + Aliases []string Description string IgnorePipe bool Matcher func(cmd string) bool @@ -28,8 +29,26 @@ type Cmd struct { Console *Console } +func (c *Cmd) defaultMatcher(cmd string) bool { + if cmd == c.Name { + return true + } + for _, alias := range c.Aliases { + if cmd == alias { + return true + } + } + return false +} + func (c *Cmd) Match(cmd string) bool { - return c.Matcher(cmd) + if c.defaultMatcher(cmd) { + return true + } + if c.Matcher != nil { + return c.Matcher(cmd) + } + return false } func (c *Cmd) Handle(cmd string) error { @@ -39,7 +58,6 @@ func (c *Cmd) Handle(cmd string) error { var HelpCmd = &Cmd{ Name: "help", Description: "Show the help", - Matcher: func(cmd string) bool { return cmd == "help" }, Handler: func(c *Console, cmd string) error { fmt.Println(helpView(c)) return nil @@ -58,9 +76,9 @@ func helpView(c *Console) string { var QuitCmd = &Cmd{ Name: "quit", + Aliases: []string{"exit"}, Description: "Quit the console", IgnorePipe: true, - Matcher: func(cmd string) bool { return cmd == "quit" || cmd == "exit" }, Handler: func(c *Console, cmd string) error { c.Close() return nil @@ -71,7 +89,6 @@ var ClearCmd = &Cmd{ Name: "clear", Description: "Clear the screen", IgnorePipe: true, - Matcher: func(cmd string) bool { return cmd == "clear" }, Handler: func(c *Console, cmd string) error { termenv.ClearScreen() return nil @@ -80,8 +97,8 @@ var ClearCmd = &Cmd{ var InfoCmd = &Cmd{ Name: "info", + Aliases: []string{"get_info"}, Description: "Get info about the dero node", - Matcher: func(cmd string) bool { return cmd == "info" }, Handler: handleInfoCmd, } @@ -102,8 +119,8 @@ func handleInfoCmd(c *Console, cmd string) error { var PeersCmd = &Cmd{ Name: "peers", + Aliases: []string{"get_peers"}, Description: "Get info about the peers", - Matcher: func(cmd string) bool { return cmd == "peers" }, Handler: handlePeersCmd, } diff --git a/internal/console/console.go b/internal/console/console.go index fd8d289..b4adbd0 100644 --- a/internal/console/console.go +++ b/internal/console/console.go @@ -86,6 +86,12 @@ func (c *Console) setCompleter() { for _, n := range c.cmds { if strings.HasPrefix(n.Name, strings.ToLower(line)) { s = append(s, n.Name) + continue + } + for _, a := range n.Aliases { + if strings.HasPrefix(a, strings.ToLower(line)) { + s = append(s, a) + } } } return @@ -110,7 +116,7 @@ func (c *Console) read() error { if err := c.handleInput(in); err != nil { fmt.Println(styleError.Render(err.Error())) } - if QuitCmd.Matcher(in) { // special case to prevent an unnecessary newline + if QuitCmd.Match(in) { // special case to prevent an unnecessary newline break } } else if err == liner.ErrPromptAborted { From 7d468ba2d29e554014216ae613c42033efafd1b8 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sat, 4 Jun 2022 02:31:59 +0200 Subject: [PATCH 07/23] feat: connections command --- internal/console/commands.go | 25 ++++++++++++++++++++++++- pkg/dero/rpc.go | 2 +- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/internal/console/commands.go b/internal/console/commands.go index b08185b..96516a2 100644 --- a/internal/console/commands.go +++ b/internal/console/commands.go @@ -17,6 +17,7 @@ var Cmds = []*Cmd{ ClearCmd, InfoCmd, PeersCmd, + ConnectionsCmd, } type Cmd struct { @@ -120,7 +121,7 @@ func handleInfoCmd(c *Console, cmd string) error { var PeersCmd = &Cmd{ Name: "peers", Aliases: []string{"get_peers"}, - Description: "Get info about the peers", + Description: "Get all peers connected to the dero node", Handler: handlePeersCmd, } @@ -138,3 +139,25 @@ func handlePeersCmd(c *Console, cmd string) error { fmt.Println(string(data)) return nil } + +var ConnectionsCmd = &Cmd{ + Name: "connections", + Aliases: []string{"get_connections"}, + Description: "Get all connections from the dero node", + Handler: handleConnectionsCmd, +} + +func handleConnectionsCmd(c *Console, cmd string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + connections, err := c.client.GetConnections(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(connections.Connections, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/pkg/dero/rpc.go b/pkg/dero/rpc.go index ddcfd36..112c82c 100644 --- a/pkg/dero/rpc.go +++ b/pkg/dero/rpc.go @@ -81,5 +81,5 @@ func (c *Client) GetConnections(ctx context.Context) (*derorpc.GetConnectionResu if err := c.rpc.CallResult(context.Background(), "DERO.GetConnections", nil, res); err != nil { return nil, fmt.Errorf("failed to call: %w", err) } - return nil, nil + return res, nil } From f615db9dd61a337328fdb8d6784adefd5c472ea8 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sat, 4 Jun 2022 05:40:18 +0200 Subject: [PATCH 08/23] refactor: use console library --- cmd/console.go | 7 +- go.mod | 9 +- go.sum | 4 +- internal/console/commands.go | 163 -------------------------------- internal/console/console.go | 178 ----------------------------------- internal/console/style.go | 5 - internal/derocli/derocli.go | 131 ++++++++++++++++++++++++++ 7 files changed, 141 insertions(+), 356 deletions(-) delete mode 100644 internal/console/commands.go delete mode 100644 internal/console/console.go delete mode 100644 internal/console/style.go create mode 100644 internal/derocli/derocli.go diff --git a/cmd/console.go b/cmd/console.go index 76073d9..e2c46a6 100644 --- a/cmd/console.go +++ b/cmd/console.go @@ -9,7 +9,7 @@ import ( "syscall" "github.com/spf13/cobra" - "github.com/stratumfarm/derocli/internal/console" + "github.com/stratumfarm/derocli/internal/derocli" ) var consoleCmd = &cobra.Command{ @@ -27,10 +27,7 @@ func runConsole(cmd *cobra.Command, args []string) error { ctx, cancel := context.WithCancel(cmd.Context()) defer cancel() - c, err := console.New( - console.WithClient(client), - console.WithContext(ctx), - ) + c, err := derocli.New(ctx, client) if err != nil { log.Fatalln(err) } diff --git a/go.mod b/go.mod index 66a52c1..1278330 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,11 @@ module github.com/stratumfarm/derocli go 1.18 require ( - github.com/charmbracelet/lipgloss v0.5.0 github.com/creachadair/jrpc2 v0.41.0 github.com/gorilla/websocket v1.5.0 + github.com/jon4hz/console v0.1.1 github.com/muesli/mango-cobra v1.1.0 github.com/muesli/roff v0.1.0 - github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 - github.com/peterh/liner v1.2.2 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.12.0 github.com/stratumfarm/derohe v0.0.0-20220603233726-87b22b6757f8 @@ -18,6 +16,7 @@ require ( require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/caarlos0/env/v6 v6.9.2 // indirect + github.com/charmbracelet/lipgloss v0.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deroproject/graviton v0.0.0-20220130070622-2c248a53b2e1 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect @@ -34,8 +33,10 @@ require ( github.com/muesli/mango v0.1.0 // indirect github.com/muesli/mango-pflag v0.1.0 // indirect github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68 // indirect + github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.1 // indirect + github.com/peterh/liner v1.2.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/satori/go.uuid v1.2.0 // indirect @@ -56,3 +57,5 @@ require ( gopkg.in/yaml.v3 v3.0.0 // indirect nhooyr.io/websocket v1.8.7 // indirect ) + +//replace github.com/jon4hz/console => ../../console diff --git a/go.sum b/go.sum index 5f6c6b8..03746a5 100644 --- a/go.sum +++ b/go.sum @@ -164,6 +164,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jon4hz/console v0.1.1 h1:OvJXA9S0pMfqtGPu93XGRv7fIbzKV8Z2XI22M42Cz68= +github.com/jon4hz/console v0.1.1/go.mod h1:jbgPOODlMTW1IxpQpVzk4rcWMYnEneyaeCPdmk3Vd0w= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -239,8 +241,6 @@ 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/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/stratumfarm/derohe v0.0.0-20220603195355-37b0a28e4dbe h1:C38QIxJxtelZbXCSRafAXjxI/EXS7OmNlWb7KbKoAxc= -github.com/stratumfarm/derohe v0.0.0-20220603195355-37b0a28e4dbe/go.mod h1:1fq6tvob4JwDQhdxuUX81DdlID1wYkx4TyJH2ve0J9A= github.com/stratumfarm/derohe v0.0.0-20220603233726-87b22b6757f8 h1:5iETeDNBTrIZj/RecN/WfRtCaanhXlTdfYyR4q2I/18= github.com/stratumfarm/derohe v0.0.0-20220603233726-87b22b6757f8/go.mod h1:1fq6tvob4JwDQhdxuUX81DdlID1wYkx4TyJH2ve0J9A= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/internal/console/commands.go b/internal/console/commands.go deleted file mode 100644 index 96516a2..0000000 --- a/internal/console/commands.go +++ /dev/null @@ -1,163 +0,0 @@ -package console - -import ( - "context" - "encoding/json" - "fmt" - "time" - - "github.com/muesli/termenv" -) - -var requestTimeout = 5 * time.Second - -var Cmds = []*Cmd{ - HelpCmd, - QuitCmd, - ClearCmd, - InfoCmd, - PeersCmd, - ConnectionsCmd, -} - -type Cmd struct { - Name string - Aliases []string - Description string - IgnorePipe bool - Matcher func(cmd string) bool - Handler func(c *Console, cmd string) error - Console *Console -} - -func (c *Cmd) defaultMatcher(cmd string) bool { - if cmd == c.Name { - return true - } - for _, alias := range c.Aliases { - if cmd == alias { - return true - } - } - return false -} - -func (c *Cmd) Match(cmd string) bool { - if c.defaultMatcher(cmd) { - return true - } - if c.Matcher != nil { - return c.Matcher(cmd) - } - return false -} - -func (c *Cmd) Handle(cmd string) error { - return c.Handler(c.Console, cmd) -} - -var HelpCmd = &Cmd{ - Name: "help", - Description: "Show the help", - Handler: func(c *Console, cmd string) error { - fmt.Println(helpView(c)) - return nil - }, -} - -func helpView(c *Console) string { - s := "Available commands:" - for _, cmd := range c.cmds { - if cmd.Name != "" && cmd.Description != "" { - s += fmt.Sprintf("\n %s - %s", cmd.Name, cmd.Description) - } - } - return s -} - -var QuitCmd = &Cmd{ - Name: "quit", - Aliases: []string{"exit"}, - Description: "Quit the console", - IgnorePipe: true, - Handler: func(c *Console, cmd string) error { - c.Close() - return nil - }, -} - -var ClearCmd = &Cmd{ - Name: "clear", - Description: "Clear the screen", - IgnorePipe: true, - Handler: func(c *Console, cmd string) error { - termenv.ClearScreen() - return nil - }, -} - -var InfoCmd = &Cmd{ - Name: "info", - Aliases: []string{"get_info"}, - Description: "Get info about the dero node", - Handler: handleInfoCmd, -} - -func handleInfoCmd(c *Console, cmd string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) - defer cancel() - info, err := c.client.GetInfo(ctx) - if err != nil { - return err - } - data, err := json.MarshalIndent(info, "", " ") - if err != nil { - return err - } - fmt.Println(string(data)) - return nil -} - -var PeersCmd = &Cmd{ - Name: "peers", - Aliases: []string{"get_peers"}, - Description: "Get all peers connected to the dero node", - Handler: handlePeersCmd, -} - -func handlePeersCmd(c *Console, cmd string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) - defer cancel() - peers, err := c.client.GetPeers(ctx) - if err != nil { - return err - } - data, err := json.MarshalIndent(peers, "", " ") - if err != nil { - return err - } - fmt.Println(string(data)) - return nil -} - -var ConnectionsCmd = &Cmd{ - Name: "connections", - Aliases: []string{"get_connections"}, - Description: "Get all connections from the dero node", - Handler: handleConnectionsCmd, -} - -func handleConnectionsCmd(c *Console, cmd string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) - defer cancel() - connections, err := c.client.GetConnections(ctx) - if err != nil { - return err - } - data, err := json.MarshalIndent(connections.Connections, "", " ") - if err != nil { - return err - } - fmt.Println(string(data)) - return nil -} diff --git a/internal/console/console.go b/internal/console/console.go deleted file mode 100644 index b4adbd0..0000000 --- a/internal/console/console.go +++ /dev/null @@ -1,178 +0,0 @@ -package console - -import ( - "context" - "fmt" - "io" - "os" - "path/filepath" - "strings" - - "github.com/peterh/liner" - "github.com/stratumfarm/derocli/pkg/dero" -) - -var historyFn = filepath.Join(os.TempDir(), ".derocli_history") - -type Opts func(*Console) - -func WithClient(client *dero.Client) Opts { - return func(c *Console) { - c.client = client - } -} - -func WithContext(ctx context.Context) Opts { - return func(c *Console) { - c.parentCtx = ctx - } -} - -type Console struct { - parentCtx context.Context - ctx context.Context - cancel context.CancelFunc - liner *liner.State - - cmds []*Cmd - client *dero.Client -} - -func New(opts ...Opts) (*Console, error) { - c := &Console{ - parentCtx: context.Background(), - liner: liner.NewLiner(), - } - for _, opt := range opts { - opt(c) - } - - ctx, cancel := context.WithCancel(c.parentCtx) - c.ctx = ctx - c.cancel = cancel - - c.registerCommands( - Cmds..., - ) - c.setCompleter() - - c.liner.SetCtrlCAborts(true) - - return c, nil -} - -func (c *Console) registerCommands(cmds ...*Cmd) { - for _, cmd := range cmds { - cmd.Console = c - } - c.cmds = cmds -} - -func (c *Console) Start() error { - c.readHistory() - c.welcomeMsg() - return c.read() -} - -func (c *Console) Close() error { - c.cancel() - c.writeHistory() - c.liner.Close() - return nil -} - -func (c *Console) setCompleter() { - c.liner.SetCompleter(func(line string) (s []string) { - for _, n := range c.cmds { - if strings.HasPrefix(n.Name, strings.ToLower(line)) { - s = append(s, n.Name) - continue - } - for _, a := range n.Aliases { - if strings.HasPrefix(a, strings.ToLower(line)) { - s = append(s, a) - } - } - } - return - }) -} - -func (c *Console) welcomeMsg() { - fmt.Println("Welcome to derocli!\n> ") -} - -func (c *Console) read() error { - doneC := make(chan struct{}) - go func() { - defer close(doneC) - for { - if in, err := c.liner.Prompt("> "); err == nil { - in = strings.TrimSpace(in) - if in == "" { - continue - } - c.liner.AppendHistory(in) - if err := c.handleInput(in); err != nil { - fmt.Println(styleError.Render(err.Error())) - } - if QuitCmd.Match(in) { // special case to prevent an unnecessary newline - break - } - } else if err == liner.ErrPromptAborted { - fmt.Println("Aborted") - break - } else if err == io.EOF { - break - } else { - fmt.Println(styleError.Render(fmt.Sprintf("Error reading line: %s", err))) - break - } - } - }() - - select { - case <-doneC: - return nil - case <-c.ctx.Done(): - return nil - } -} - -func (c *Console) readHistory() { - f, err := os.Open(historyFn) - if err != nil { - if os.IsNotExist(err) { - return - } - fmt.Println(styleError.Render(fmt.Sprintf("Error opening history file: %s", err))) - } - defer f.Close() - if _, err := c.liner.ReadHistory(f); err != nil { - fmt.Println(styleError.Render(fmt.Sprintf("Error reading history file: %s", err))) - } -} - -func (c *Console) writeHistory() { - f, err := os.Create(historyFn) - if err != nil { - fmt.Println(styleError.Render(fmt.Sprintf("Error creating history file: %s", err))) - } - defer f.Close() - if _, err := c.liner.WriteHistory(f); err != nil { - fmt.Println(styleError.Render(fmt.Sprintf("Error writing history file: %s", err))) - } -} - -func (c *Console) handleInput(input string) error { - input = strings.TrimSpace(input) - for _, cmd := range c.cmds { - if cmd.Match(input) { - if err := cmd.Handle(input); err != nil { - fmt.Println(styleError.Render(fmt.Sprintf("error running command %s: %s\n", cmd.Name, err))) - } - return nil - } - } - return nil -} diff --git a/internal/console/style.go b/internal/console/style.go deleted file mode 100644 index a8d7e7f..0000000 --- a/internal/console/style.go +++ /dev/null @@ -1,5 +0,0 @@ -package console - -import "github.com/charmbracelet/lipgloss" - -var styleError = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "#FF4672", Dark: "#FF4672"}) diff --git a/internal/derocli/derocli.go b/internal/derocli/derocli.go new file mode 100644 index 0000000..211d6bb --- /dev/null +++ b/internal/derocli/derocli.go @@ -0,0 +1,131 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + "time" + + "github.com/jon4hz/console" + "github.com/stratumfarm/derocli/pkg/dero" +) + +var requestTimeout = 5 * time.Second + +type Console struct { + deroClient *dero.Client + console *console.Console +} + +func New(ctx context.Context, client *dero.Client) (*Console, error) { + if client == nil { + return nil, fmt.Errorf("client is nil") + } + con, err := console.New( + console.WithWelcomeMsg("Welcome to derocli!"), + console.WithHandleCtrlC(true), + console.WithContext(ctx), + ) + if err != nil { + return nil, err + } + c := &Console{ + console: con, + deroClient: client, + } + if err := con.RegisterCommands(c.getCmds()...); err != nil { + return nil, err + } + return c, nil +} + +func (c *Console) Start() error { + return c.console.Start() +} + +func (c *Console) Close() error { + if err := c.deroClient.Close(); err != nil { + return err + } + return c.console.Close() +} + +func (c *Console) getCmds() []*console.Cmd { + return []*console.Cmd{ + c.InfoCmd(), + c.PeersCmd(), + c.ConnectionsCmd(), + } +} + +func (c *Console) InfoCmd() *console.Cmd { + return &console.Cmd{ + Name: "info", + Aliases: []string{"get_info"}, + Description: "Get info about the dero node", + Handler: c.handleInfoCmd, + } +} + +func (c *Console) handleInfoCmd(con *console.Console, cmd string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + info, err := c.deroClient.GetInfo(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(info, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} + +func (c *Console) PeersCmd() *console.Cmd { + return &console.Cmd{ + Name: "peers", + Aliases: []string{"get_peers"}, + Description: "Get all peers connected to the dero node", + Handler: c.handlePeersCmd, + } +} + +func (c *Console) handlePeersCmd(con *console.Console, cmd string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + peers, err := c.deroClient.GetPeers(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(peers, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} + +func (c *Console) ConnectionsCmd() *console.Cmd { + return &console.Cmd{ + Name: "connections", + Aliases: []string{"get_connections"}, + Description: "Get all connections from the dero node", + Handler: c.handleConnectionsCmd, + } +} + +func (c *Console) handleConnectionsCmd(con *console.Console, cmd string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + connections, err := c.deroClient.GetConnections(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(connections.Connections, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} From 7c98e15a46d5d2348db0d74e1dae49a1b16f82d6 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sat, 4 Jun 2022 05:46:05 +0200 Subject: [PATCH 09/23] refactor: dercli package --- internal/derocli/connections.go | 33 +++++++++++++++ internal/derocli/derocli.go | 73 --------------------------------- internal/derocli/info.go | 33 +++++++++++++++ internal/derocli/peers.go | 33 +++++++++++++++ 4 files changed, 99 insertions(+), 73 deletions(-) create mode 100644 internal/derocli/connections.go create mode 100644 internal/derocli/info.go create mode 100644 internal/derocli/peers.go diff --git a/internal/derocli/connections.go b/internal/derocli/connections.go new file mode 100644 index 0000000..bdd74c7 --- /dev/null +++ b/internal/derocli/connections.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) ConnectionsCmd() *console.Cmd { + return &console.Cmd{ + Name: "connections", + Aliases: []string{"get_connections"}, + Description: "Get all connections from the dero node", + Handler: c.handleConnectionsCmd, + } +} + +func (c *Console) handleConnectionsCmd(con *console.Console, cmd string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + connections, err := c.deroClient.GetConnections(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(connections.Connections, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/derocli/derocli.go b/internal/derocli/derocli.go index 211d6bb..ab1d569 100644 --- a/internal/derocli/derocli.go +++ b/internal/derocli/derocli.go @@ -2,7 +2,6 @@ package derocli import ( "context" - "encoding/json" "fmt" "time" @@ -57,75 +56,3 @@ func (c *Console) getCmds() []*console.Cmd { c.ConnectionsCmd(), } } - -func (c *Console) InfoCmd() *console.Cmd { - return &console.Cmd{ - Name: "info", - Aliases: []string{"get_info"}, - Description: "Get info about the dero node", - Handler: c.handleInfoCmd, - } -} - -func (c *Console) handleInfoCmd(con *console.Console, cmd string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) - defer cancel() - info, err := c.deroClient.GetInfo(ctx) - if err != nil { - return err - } - data, err := json.MarshalIndent(info, "", " ") - if err != nil { - return err - } - fmt.Println(string(data)) - return nil -} - -func (c *Console) PeersCmd() *console.Cmd { - return &console.Cmd{ - Name: "peers", - Aliases: []string{"get_peers"}, - Description: "Get all peers connected to the dero node", - Handler: c.handlePeersCmd, - } -} - -func (c *Console) handlePeersCmd(con *console.Console, cmd string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) - defer cancel() - peers, err := c.deroClient.GetPeers(ctx) - if err != nil { - return err - } - data, err := json.MarshalIndent(peers, "", " ") - if err != nil { - return err - } - fmt.Println(string(data)) - return nil -} - -func (c *Console) ConnectionsCmd() *console.Cmd { - return &console.Cmd{ - Name: "connections", - Aliases: []string{"get_connections"}, - Description: "Get all connections from the dero node", - Handler: c.handleConnectionsCmd, - } -} - -func (c *Console) handleConnectionsCmd(con *console.Console, cmd string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) - defer cancel() - connections, err := c.deroClient.GetConnections(ctx) - if err != nil { - return err - } - data, err := json.MarshalIndent(connections.Connections, "", " ") - if err != nil { - return err - } - fmt.Println(string(data)) - return nil -} diff --git a/internal/derocli/info.go b/internal/derocli/info.go new file mode 100644 index 0000000..272822d --- /dev/null +++ b/internal/derocli/info.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) InfoCmd() *console.Cmd { + return &console.Cmd{ + Name: "info", + Aliases: []string{"get_info"}, + Description: "Get info about the dero node", + Handler: c.handleInfoCmd, + } +} + +func (c *Console) handleInfoCmd(con *console.Console, cmd string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + info, err := c.deroClient.GetInfo(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(info, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/derocli/peers.go b/internal/derocli/peers.go new file mode 100644 index 0000000..b5db866 --- /dev/null +++ b/internal/derocli/peers.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) PeersCmd() *console.Cmd { + return &console.Cmd{ + Name: "peers", + Aliases: []string{"get_peers"}, + Description: "Get all peers connected to the dero node", + Handler: c.handlePeersCmd, + } +} + +func (c *Console) handlePeersCmd(con *console.Console, cmd string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + peers, err := c.deroClient.GetPeers(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(peers, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} From 8dbdc34c7d8ee7732a62a7be95917266e3addaa6 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sat, 4 Jun 2022 06:57:37 +0200 Subject: [PATCH 10/23] deps: update jon4hz/console to v0.2.0 --- go.mod | 2 +- go.sum | 4 ++-- internal/derocli/connections.go | 2 +- internal/derocli/info.go | 2 +- internal/derocli/peers.go | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 1278330..41e63a6 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/creachadair/jrpc2 v0.41.0 github.com/gorilla/websocket v1.5.0 - github.com/jon4hz/console v0.1.1 + github.com/jon4hz/console v0.2.0 github.com/muesli/mango-cobra v1.1.0 github.com/muesli/roff v0.1.0 github.com/spf13/cobra v1.4.0 diff --git a/go.sum b/go.sum index 03746a5..80ed800 100644 --- a/go.sum +++ b/go.sum @@ -164,8 +164,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jon4hz/console v0.1.1 h1:OvJXA9S0pMfqtGPu93XGRv7fIbzKV8Z2XI22M42Cz68= -github.com/jon4hz/console v0.1.1/go.mod h1:jbgPOODlMTW1IxpQpVzk4rcWMYnEneyaeCPdmk3Vd0w= +github.com/jon4hz/console v0.2.0 h1:nDOPH8WFdrc6I9m9ofNO8YXIR82N8biZjY7b8i4hvmo= +github.com/jon4hz/console v0.2.0/go.mod h1:jbgPOODlMTW1IxpQpVzk4rcWMYnEneyaeCPdmk3Vd0w= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= diff --git a/internal/derocli/connections.go b/internal/derocli/connections.go index bdd74c7..564f185 100644 --- a/internal/derocli/connections.go +++ b/internal/derocli/connections.go @@ -17,7 +17,7 @@ func (c *Console) ConnectionsCmd() *console.Cmd { } } -func (c *Console) handleConnectionsCmd(con *console.Console, cmd string) error { +func (c *Console) handleConnectionsCmd(con *console.Console, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) defer cancel() connections, err := c.deroClient.GetConnections(ctx) diff --git a/internal/derocli/info.go b/internal/derocli/info.go index 272822d..168cd16 100644 --- a/internal/derocli/info.go +++ b/internal/derocli/info.go @@ -17,7 +17,7 @@ func (c *Console) InfoCmd() *console.Cmd { } } -func (c *Console) handleInfoCmd(con *console.Console, cmd string) error { +func (c *Console) handleInfoCmd(con *console.Console, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) defer cancel() info, err := c.deroClient.GetInfo(ctx) diff --git a/internal/derocli/peers.go b/internal/derocli/peers.go index b5db866..1b28f2b 100644 --- a/internal/derocli/peers.go +++ b/internal/derocli/peers.go @@ -17,7 +17,7 @@ func (c *Console) PeersCmd() *console.Cmd { } } -func (c *Console) handlePeersCmd(con *console.Console, cmd string) error { +func (c *Console) handlePeersCmd(con *console.Console, args []string) error { ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) defer cancel() peers, err := c.deroClient.GetPeers(ctx) From 80b3f4591cc946f6d2716fb050ba167c04e2201f Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sat, 4 Jun 2022 06:59:18 +0200 Subject: [PATCH 11/23] feat: height command --- internal/derocli/derocli.go | 1 + internal/derocli/height.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 internal/derocli/height.go diff --git a/internal/derocli/derocli.go b/internal/derocli/derocli.go index ab1d569..18c3d48 100644 --- a/internal/derocli/derocli.go +++ b/internal/derocli/derocli.go @@ -54,5 +54,6 @@ func (c *Console) getCmds() []*console.Cmd { c.InfoCmd(), c.PeersCmd(), c.ConnectionsCmd(), + c.HeightCmd(), } } diff --git a/internal/derocli/height.go b/internal/derocli/height.go new file mode 100644 index 0000000..0240d67 --- /dev/null +++ b/internal/derocli/height.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) HeightCmd() *console.Cmd { + return &console.Cmd{ + Name: "height", + Aliases: []string{"get_height"}, + Description: "Get the height of the dero node", + Handler: c.heightCmd, + } +} + +func (c *Console) heightCmd(con *console.Console, args []string) error { + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + height, err := c.deroClient.GetHeight(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(height, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} From 15a714e9d94fe3ab967ca3996e00e41b82fb909d Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 00:37:32 +0200 Subject: [PATCH 12/23] feat: blockHeaderByTopoHeight command --- internal/derocli/blockheader.go | 42 +++++++++++++++++++++++++++++++++ internal/derocli/derocli.go | 1 + pkg/dero/rpc.go | 11 +++++++++ 3 files changed, 54 insertions(+) create mode 100644 internal/derocli/blockheader.go diff --git a/internal/derocli/blockheader.go b/internal/derocli/blockheader.go new file mode 100644 index 0000000..85cb9ca --- /dev/null +++ b/internal/derocli/blockheader.go @@ -0,0 +1,42 @@ +package derocli + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strconv" + + "github.com/jon4hz/console" +) + +func (c *Console) BlockHeaderByTopoHeight() *console.Cmd { + return &console.Cmd{ + Name: "block_header_by_topo_height", + Aliases: []string{"get_block_header_by_topo_height"}, + Description: "Get the height of the dero node", + Handler: c.blockHeaderByTopoHeightCmd, + } +} + +func (c *Console) blockHeaderByTopoHeightCmd(con *console.Console, args []string) error { + if len(args) != 1 { + return errors.New("exactly one arg is required") + } + height := uint64(0) + if len(args) > 0 { + height, _ = strconv.ParseUint(args[0], 10, 64) + } + ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + defer cancel() + blockHeader, err := c.deroClient.GetBlockHeaderByTopoHeight(ctx, height) + if err != nil { + return err + } + data, err := json.MarshalIndent(blockHeader, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} diff --git a/internal/derocli/derocli.go b/internal/derocli/derocli.go index 18c3d48..6f3530b 100644 --- a/internal/derocli/derocli.go +++ b/internal/derocli/derocli.go @@ -55,5 +55,6 @@ func (c *Console) getCmds() []*console.Cmd { c.PeersCmd(), c.ConnectionsCmd(), c.HeightCmd(), + c.BlockHeaderByTopoHeight(), } } diff --git a/pkg/dero/rpc.go b/pkg/dero/rpc.go index 112c82c..0583aa1 100644 --- a/pkg/dero/rpc.go +++ b/pkg/dero/rpc.go @@ -83,3 +83,14 @@ func (c *Client) GetConnections(ctx context.Context) (*derorpc.GetConnectionResu } return res, nil } + +func (c *Client) GetBlockHeaderByTopoHeight(ctx context.Context, height uint64) (*derorpc.GetBlockHeaderByHeight_Result, error) { + res := new(derorpc.GetBlockHeaderByHeight_Result) + req := derorpc.GetBlockHeaderByTopoHeight_Params{ + TopoHeight: height, + } + if err := c.rpc.CallResult(context.Background(), "DERO.GetBlockHeaderByTopoHeight", req, res); err != nil { + return nil, fmt.Errorf("failed to call: %w", err) + } + return res, nil +} From dc1d729a106e7468a74ac8e1500df31abfb6c66a Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 00:52:50 +0200 Subject: [PATCH 13/23] fix: dont exit on ctrl+c --- internal/derocli/derocli.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/derocli/derocli.go b/internal/derocli/derocli.go index 6f3530b..9c6d7a5 100644 --- a/internal/derocli/derocli.go +++ b/internal/derocli/derocli.go @@ -22,7 +22,7 @@ func New(ctx context.Context, client *dero.Client) (*Console, error) { } con, err := console.New( console.WithWelcomeMsg("Welcome to derocli!"), - console.WithHandleCtrlC(true), + console.WithHandleCtrlC(false), console.WithContext(ctx), ) if err != nil { From 8d88ae5bf13643f125e0a6253d25be0c61e32046 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 00:53:03 +0200 Subject: [PATCH 14/23] fix: improve start process --- cmd/console.go | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/cmd/console.go b/cmd/console.go index e2c46a6..5726135 100644 --- a/cmd/console.go +++ b/cmd/console.go @@ -5,7 +5,6 @@ import ( "log" "os" "os/signal" - "sync" "syscall" "github.com/spf13/cobra" @@ -32,20 +31,24 @@ func runConsole(cmd *cobra.Command, args []string) error { log.Fatalln(err) } - var wg sync.WaitGroup - wg.Add(1) + errc := make(chan error, 1) go func() { - defer wg.Done() + defer c.Close() + defer close(errc) if err := c.Start(); err != nil { - log.Fatalln(err) + errc <- err } }() - defer c.Close() - go func() { - <-done + + select { + case <-done: cancel() - }() - wg.Wait() + case err, ok := <-errc: + if !ok { + break + } + log.Fatalln(err) + } return nil } From 21e930618c3d48376c0f2e998225c508673b1afb Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 00:54:51 +0200 Subject: [PATCH 15/23] fix: close channel after closing client --- cmd/console.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/console.go b/cmd/console.go index 5726135..b758bd2 100644 --- a/cmd/console.go +++ b/cmd/console.go @@ -33,8 +33,8 @@ func runConsole(cmd *cobra.Command, args []string) error { errc := make(chan error, 1) go func() { - defer c.Close() defer close(errc) + defer c.Close() if err := c.Start(); err != nil { errc <- err } From df72521870f9bac379552db22fa5528e1ef0831a Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 00:57:45 +0200 Subject: [PATCH 16/23] fix: arg parsing --- internal/derocli/blockheader.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/derocli/blockheader.go b/internal/derocli/blockheader.go index 85cb9ca..75c9ebb 100644 --- a/internal/derocli/blockheader.go +++ b/internal/derocli/blockheader.go @@ -23,9 +23,9 @@ func (c *Console) blockHeaderByTopoHeightCmd(con *console.Console, args []string if len(args) != 1 { return errors.New("exactly one arg is required") } - height := uint64(0) - if len(args) > 0 { - height, _ = strconv.ParseUint(args[0], 10, 64) + height, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return err } ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) defer cancel() From cdb6c3d4677505a97662e6854994511edec02f1c Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 01:09:01 +0200 Subject: [PATCH 17/23] refactor: remove all cmd --- cmd/all.go | 48 ------------------------------------------------ cmd/root.go | 2 +- 2 files changed, 1 insertion(+), 49 deletions(-) delete mode 100644 cmd/all.go diff --git a/cmd/all.go b/cmd/all.go deleted file mode 100644 index 9c9e49e..0000000 --- a/cmd/all.go +++ /dev/null @@ -1,48 +0,0 @@ -package cmd - -import ( - "context" - "time" - - "github.com/spf13/cobra" -) - -var timeout = time.Second * 5 - -var allCmd = &cobra.Command{ - Use: "all", - Short: "Get all information from the node", - PreRunE: connectNode, - PostRun: func(cmd *cobra.Command, args []string) { client.Close() }, - RunE: all, -} - -func all(cmd *cobra.Command, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - - height, err := client.GetHeight(ctx) - if err != nil { - return err - } - prettyPrint(height) - - info, err := client.GetInfo(ctx) - if err != nil { - return err - } - prettyPrint(info) - - /* peers, err := client.GetPeers(ctx) - if err != nil { - return err - } - prettyPrint(peers) */ - - txPool, err := client.GetTxPool(ctx) - if err != nil { - return err - } - prettyPrint(txPool) - return nil -} diff --git a/cmd/root.go b/cmd/root.go index cbadaa3..a251588 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -35,7 +35,7 @@ var rootCmd = &cobra.Command{ func init() { rootCmd.AddCommand( - versionCmd, manCmd, allCmd, + versionCmd, manCmd, heightCmd, infoCmd, peersCmd, txPoolCmd, consoleCmd, ) From ecfc5c7111469e97f328f553a1988b984f7af699 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 01:48:05 +0200 Subject: [PATCH 18/23] docs: update readme --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 680cf3d..30ec628 100644 --- a/README.md +++ b/README.md @@ -14,16 +14,19 @@ Usage: derocli [command] Available Commands: - all Get all information from the node completion Generate the autocompletion script for the specified shell + console Start an interactive console height Get the current height of the blockchain help Help about any command info Get information about the node peers Get the connected peers from the node + txpool Get the transaction pool + version Print the version info Flags: - -r, --rpc string address of the node (default "localhost:10102") - -h, --help help for derocli + -c, --config string path to the config file + -h, --help help for derocli + -r, --rpc string address of the node (default "localhost:10102") Use "derocli [command] --help" for more information about a command. ``` \ No newline at end of file From cb79527dca3e0562f8a2f8ba4ee9679a9d0b079b Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 01:51:06 +0200 Subject: [PATCH 19/23] feat: update console --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 41e63a6..511920b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/creachadair/jrpc2 v0.41.0 github.com/gorilla/websocket v1.5.0 - github.com/jon4hz/console v0.2.0 + github.com/jon4hz/console v0.2.1 github.com/muesli/mango-cobra v1.1.0 github.com/muesli/roff v0.1.0 github.com/spf13/cobra v1.4.0 diff --git a/go.sum b/go.sum index 80ed800..9de3271 100644 --- a/go.sum +++ b/go.sum @@ -164,8 +164,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jon4hz/console v0.2.0 h1:nDOPH8WFdrc6I9m9ofNO8YXIR82N8biZjY7b8i4hvmo= -github.com/jon4hz/console v0.2.0/go.mod h1:jbgPOODlMTW1IxpQpVzk4rcWMYnEneyaeCPdmk3Vd0w= +github.com/jon4hz/console v0.2.1 h1:gTnkJnHaqHKGxUjyl0Uz8phc7IJYznVSzt1gHVAGTJY= +github.com/jon4hz/console v0.2.1/go.mod h1:jbgPOODlMTW1IxpQpVzk4rcWMYnEneyaeCPdmk3Vd0w= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= From a93634d368a0cdd3d01bebf501388c57711c35e5 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 01:52:21 +0200 Subject: [PATCH 20/23] feat: use console context --- internal/derocli/blockheader.go | 2 +- internal/derocli/connections.go | 2 +- internal/derocli/height.go | 2 +- internal/derocli/info.go | 2 +- internal/derocli/peers.go | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/derocli/blockheader.go b/internal/derocli/blockheader.go index 75c9ebb..f225adc 100644 --- a/internal/derocli/blockheader.go +++ b/internal/derocli/blockheader.go @@ -27,7 +27,7 @@ func (c *Console) blockHeaderByTopoHeightCmd(con *console.Console, args []string if err != nil { return err } - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) defer cancel() blockHeader, err := c.deroClient.GetBlockHeaderByTopoHeight(ctx, height) if err != nil { diff --git a/internal/derocli/connections.go b/internal/derocli/connections.go index 564f185..76625f8 100644 --- a/internal/derocli/connections.go +++ b/internal/derocli/connections.go @@ -18,7 +18,7 @@ func (c *Console) ConnectionsCmd() *console.Cmd { } func (c *Console) handleConnectionsCmd(con *console.Console, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) defer cancel() connections, err := c.deroClient.GetConnections(ctx) if err != nil { diff --git a/internal/derocli/height.go b/internal/derocli/height.go index 0240d67..169df1d 100644 --- a/internal/derocli/height.go +++ b/internal/derocli/height.go @@ -18,7 +18,7 @@ func (c *Console) HeightCmd() *console.Cmd { } func (c *Console) heightCmd(con *console.Console, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) defer cancel() height, err := c.deroClient.GetHeight(ctx) if err != nil { diff --git a/internal/derocli/info.go b/internal/derocli/info.go index 168cd16..afe78cf 100644 --- a/internal/derocli/info.go +++ b/internal/derocli/info.go @@ -18,7 +18,7 @@ func (c *Console) InfoCmd() *console.Cmd { } func (c *Console) handleInfoCmd(con *console.Console, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) defer cancel() info, err := c.deroClient.GetInfo(ctx) if err != nil { diff --git a/internal/derocli/peers.go b/internal/derocli/peers.go index 1b28f2b..a75d3f4 100644 --- a/internal/derocli/peers.go +++ b/internal/derocli/peers.go @@ -18,7 +18,7 @@ func (c *Console) PeersCmd() *console.Cmd { } func (c *Console) handlePeersCmd(con *console.Console, args []string) error { - ctx, cancel := context.WithTimeout(context.Background(), requestTimeout) + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) defer cancel() peers, err := c.deroClient.GetPeers(ctx) if err != nil { From 891c7402a116dd739afc8786ec05467f3172fb5e Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 01:59:05 +0200 Subject: [PATCH 21/23] feat: txpool console cmd --- internal/derocli/derocli.go | 1 + internal/derocli/txpool.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 internal/derocli/txpool.go diff --git a/internal/derocli/derocli.go b/internal/derocli/derocli.go index 9c6d7a5..e44f3cc 100644 --- a/internal/derocli/derocli.go +++ b/internal/derocli/derocli.go @@ -56,5 +56,6 @@ func (c *Console) getCmds() []*console.Cmd { c.ConnectionsCmd(), c.HeightCmd(), c.BlockHeaderByTopoHeight(), + c.TxPoolCmd(), } } diff --git a/internal/derocli/txpool.go b/internal/derocli/txpool.go new file mode 100644 index 0000000..7b5a298 --- /dev/null +++ b/internal/derocli/txpool.go @@ -0,0 +1,33 @@ +package derocli + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/jon4hz/console" +) + +func (c *Console) TxPoolCmd() *console.Cmd { + return &console.Cmd{ + Name: "txpool", + Aliases: []string{"get_txpool"}, + Description: "Get the transaction pool", + Handler: c.txPoolCmd, + } +} + +func (c *Console) txPoolCmd(con *console.Console, args []string) error { + ctx, cancel := context.WithTimeout(con.Ctx(), requestTimeout) + defer cancel() + txpool, err := c.deroClient.GetTxPool(ctx) + if err != nil { + return err + } + data, err := json.MarshalIndent(txpool, "", " ") + if err != nil { + return err + } + fmt.Println(string(data)) + return nil +} From c6d1444ece10be009ed47583eae156d316143490 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 02:00:29 +0200 Subject: [PATCH 22/23] feat: implement peers cmd --- cmd/peers.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/peers.go b/cmd/peers.go index c0651b5..b953afb 100644 --- a/cmd/peers.go +++ b/cmd/peers.go @@ -13,10 +13,10 @@ var peersCmd = &cobra.Command{ } func peers(cmd *cobra.Command, args []string) error { - /* info, err := client.GetPeers(context.Background()) + info, err := client.GetPeers(cmd.Context()) if err != nil { return err } - prettyPrint(info) */ + prettyPrint(info) return nil } From 404faf2171e068efcbf6fbbb984504544e497484 Mon Sep 17 00:00:00 2001 From: jon4hz Date: Sun, 5 Jun 2022 02:02:23 +0200 Subject: [PATCH 23/23] refactor: use cmd context, fatal log error instead of return --- cmd/height.go | 6 +++--- cmd/info.go | 6 +++--- cmd/peers.go | 4 +++- cmd/txpool.go | 6 +++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cmd/height.go b/cmd/height.go index 6700c3b..90d74ff 100644 --- a/cmd/height.go +++ b/cmd/height.go @@ -1,7 +1,7 @@ package cmd import ( - "context" + "log" "github.com/spf13/cobra" ) @@ -15,9 +15,9 @@ var heightCmd = &cobra.Command{ } func height(cmd *cobra.Command, args []string) error { - height, err := client.GetHeight(context.Background()) + height, err := client.GetHeight(cmd.Context()) if err != nil { - return err + log.Fatalln(err) } prettyPrint(height) return nil diff --git a/cmd/info.go b/cmd/info.go index ea0a8a2..9821c56 100644 --- a/cmd/info.go +++ b/cmd/info.go @@ -1,7 +1,7 @@ package cmd import ( - "context" + "log" "github.com/spf13/cobra" ) @@ -15,9 +15,9 @@ var infoCmd = &cobra.Command{ } func info(cmd *cobra.Command, args []string) error { - info, err := client.GetInfo(context.Background()) + info, err := client.GetInfo(cmd.Context()) if err != nil { - return err + log.Fatalln(err) } prettyPrint(info) return nil diff --git a/cmd/peers.go b/cmd/peers.go index b953afb..551d3fe 100644 --- a/cmd/peers.go +++ b/cmd/peers.go @@ -1,6 +1,8 @@ package cmd import ( + "log" + "github.com/spf13/cobra" ) @@ -15,7 +17,7 @@ var peersCmd = &cobra.Command{ func peers(cmd *cobra.Command, args []string) error { info, err := client.GetPeers(cmd.Context()) if err != nil { - return err + log.Fatalln(err) } prettyPrint(info) return nil diff --git a/cmd/txpool.go b/cmd/txpool.go index 1974902..b5faa5e 100644 --- a/cmd/txpool.go +++ b/cmd/txpool.go @@ -1,7 +1,7 @@ package cmd import ( - "context" + "log" "github.com/spf13/cobra" ) @@ -15,9 +15,9 @@ var txPoolCmd = &cobra.Command{ } func txPool(cmd *cobra.Command, args []string) error { - txpool, err := client.GetTxPool(context.Background()) + txpool, err := client.GetTxPool(cmd.Context()) if err != nil { - return err + log.Fatalln(err) } prettyPrint(txpool) return nil