Skip to content

Commit

Permalink
CLI refactor (#410)
Browse files Browse the repository at this point in the history
* Add Cobra

* Start the initial CLI refactor, define base outputs

* Add support for the txpool add command

* Add support for the txpool status command

* Add support for the txpool subscribe command

* Add support for the status command

* Add support for the secrets init command

* Add support for secrets generate

* Minor cleanup

* Add support for the peers status command

* Add support for peers list

* Add support for the peers add command

* Add support for the monitor command

* Minor monitor command code cleanup

* Add support for the loadbot command

* Add support for ibft status command

* Add support for ibft propose command

* Add support for ibft candidates command

* Add support for the backup command

* Register GRPC address for the backup command

* Add support for the genesis command

* Add support for the server command; cleanup pending

* Cleanup & add support for the dev command

* Adios, mitchellh/cli

* Fix minor linting errors in the command package

* Resolve remaining linting errors

* Fix faulty checks

* Resolve failing tests

* Cleanup server command

* Fix rogue GenesisPath renames

* Fix rogue DNSAddr renames

* Refactor the comamnd grouping

* Add additional explanation

* Resolve linting errors

* Add command name to switch helper

* Resolve linting errors

* Set the from field in the ibft switch command

* Add support for backwards compatibility of certain flags

* Fix rogue SecretsConfigPath rename

* Fix rogue SecretsConfigPath rename pt.2

* Rename package import to use camel case

* Fix rogue ShouldSeal comments

* Move out the DNS regex code blocks to the networking package

* Move out the output logic to the command package

* Simplify append in test server

* Drop the protocol name in the default json address
  • Loading branch information
zivkovicmilos committed Mar 4, 2022
1 parent 8a033aa commit b06e562
Show file tree
Hide file tree
Showing 348 changed files with 25,930 additions and 42,765 deletions.
188 changes: 45 additions & 143 deletions command/backup/backup.go
Original file line number Diff line number Diff line change
@@ -1,168 +1,70 @@
package backup

import (
"bytes"
"errors"
"fmt"
"github.com/0xPolygon/polygon-edge/command"
"github.com/spf13/cobra"

"github.com/0xPolygon/polygon-edge/archive"
"github.com/0xPolygon/polygon-edge/command/helper"
"github.com/0xPolygon/polygon-edge/types"
"github.com/hashicorp/go-hclog"
)

type BackupCommand struct {
helper.Base
Formatter *helper.FormatterFlag
GRPC *helper.GRPCFlag
}

// DefineFlags defines the command flags
func (c *BackupCommand) DefineFlags() {
c.Base.DefineFlags(c.Formatter, c.GRPC)

c.FlagMap["out"] = helper.FlagDescriptor{
Description: "The path of backup data to save",
Arguments: []string{
"OUT",
},
ArgumentsOptional: false,
func GetCommand() *cobra.Command {
backupCmd := &cobra.Command{
Use: "backup",
Short: "Create blockchain backup file by fetching blockchain data from the running node",
PreRunE: runPreRun,
Run: runCommand,
}

c.FlagMap["from"] = helper.FlagDescriptor{
Description: "Beginning height of chain in backup",
Arguments: []string{
"FROM",
},
ArgumentsOptional: true,
}

c.FlagMap["to"] = helper.FlagDescriptor{
Description: "End height of the chain in backup",
Arguments: []string{
"TO",
},
ArgumentsOptional: true,
}
}

// GetHelperText returns a simple description of the command
func (c *BackupCommand) GetHelperText() string {
return "Create blockchain backup data by fetching from running node"
}

func (c *BackupCommand) GetBaseCommand() string {
return "backup"
}
helper.RegisterGRPCAddressFlag(backupCmd)

// Help implements the cli.Command interface
func (c *BackupCommand) Help() string {
c.DefineFlags()
setFlags(backupCmd)
setRequiredFlags(backupCmd)

return helper.GenerateHelp(c.Synopsis(), helper.GenerateUsage(c.GetBaseCommand(), c.FlagMap), c.FlagMap)
return backupCmd
}

// Synopsis implements the cli.Command interface
func (c *BackupCommand) Synopsis() string {
return c.GetHelperText()
}

// Run implements the cli.Command interface
func (c *BackupCommand) Run(args []string) int {
flags := c.Base.NewFlagSet(c.GetBaseCommand(), c.Formatter, c.GRPC)

var out, rawFrom, rawTo string

flags.StringVar(&out, "out", "", "")
flags.StringVar(&rawFrom, "from", "0", "")
flags.StringVar(&rawTo, "to", "", "")

if err := flags.Parse(args); err != nil {
c.Formatter.OutputError(err)

return 1
}

var (
from uint64
to *uint64
err error
func setFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(
&params.out,
outFlag,
"",
"the export path for the backup",
)

if out == "" {
c.Formatter.OutputError(errors.New("the path of backup file is required"))

return 1
}

if from, err = types.ParseUint64orHex(&rawFrom); err != nil {
c.Formatter.OutputError(fmt.Errorf("failed to decode from: %w", err))

return 1
}

if rawTo != "" {
var parsedTo uint64

if parsedTo, err = types.ParseUint64orHex(&rawTo); err != nil {
c.Formatter.OutputError(fmt.Errorf("failed to decode to: %w", err))

return 1
} else if from > parsedTo {
c.Formatter.OutputError(errors.New("to must be greater than or equal to from"))

return 1
}

to = &parsedTo
}

conn, err := c.GRPC.Conn()
if err != nil {
c.Formatter.OutputError(err)

return 1
}

logger := hclog.New(&hclog.LoggerOptions{
Name: "backup",
Level: hclog.LevelFromString("INFO"),
})

// resFrom and resTo represents the range of blocks that can be included in the file
resFrom, resTo, err := archive.CreateBackup(conn, logger, from, to, out)
if err != nil {
c.Formatter.OutputError(err)
cmd.Flags().StringVar(
&params.fromRaw,
fromFlag,
"0",
"the beginning height of the chain in backup",
)

return 1
}
cmd.Flags().StringVar(
&params.toRaw,
toFlag,
"",
"the end height of the chain in backup",
)
}

res := &BackupResult{
From: resFrom,
To: resTo,
Out: out,
func setRequiredFlags(cmd *cobra.Command) {
for _, requiredFlag := range params.getRequiredFlags() {
_ = cmd.MarkFlagRequired(requiredFlag)
}
c.Formatter.OutputResult(res)

return 0
}

type BackupResult struct {
From uint64 `json:"from"`
To uint64 `json:"to"`
Out string `json:"out"`
func runPreRun(_ *cobra.Command, _ []string) error {
return params.validateFlags()
}

func (r *BackupResult) Output() string {
var buffer bytes.Buffer
func runCommand(cmd *cobra.Command, _ []string) {
outputter := command.InitializeOutputter(cmd)
defer outputter.WriteOutput()

buffer.WriteString("\n[BACKUP]\n")
buffer.WriteString("Exported backup file successfully:\n")
buffer.WriteString(helper.FormatKV([]string{
fmt.Sprintf("File|%s", r.Out),
fmt.Sprintf("From|%d", r.From),
fmt.Sprintf("To|%d", r.To),
}))
if err := params.createBackup(helper.GetGRPCAddress(cmd)); err != nil {
outputter.SetError(err)

return
}

return buffer.String()
outputter.SetCommandResult(params.getResult())
}
105 changes: 105 additions & 0 deletions command/backup/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package backup

import (
"errors"
"github.com/0xPolygon/polygon-edge/archive"
"github.com/0xPolygon/polygon-edge/command"
"github.com/0xPolygon/polygon-edge/command/helper"
"github.com/0xPolygon/polygon-edge/types"
"github.com/hashicorp/go-hclog"
)

const (
outFlag = "out"
fromFlag = "from"
toFlag = "to"
)

var (
params = &backupParams{}
)

var (
errDecodeRange = errors.New("unable to decode range value")
errInvalidRange = errors.New(`invalid "to" value; must be >= "from"`)
)

type backupParams struct {
out string

fromRaw string
toRaw string

from uint64
to *uint64

resFrom uint64
resTo uint64
}

func (p *backupParams) validateFlags() error {
var parseErr error

if p.from, parseErr = types.ParseUint64orHex(&p.fromRaw); parseErr != nil {
return errDecodeRange
}

if p.toRaw != "" {
var parsedTo uint64

if parsedTo, parseErr = types.ParseUint64orHex(&p.toRaw); parseErr != nil {
return errDecodeRange
}

if p.from > parsedTo {
return errInvalidRange
}

p.to = &parsedTo
}

return nil
}

func (p *backupParams) getRequiredFlags() []string {
return []string{
outFlag,
}
}

func (p *backupParams) createBackup(grpcAddress string) error {
connection, err := helper.GetGRPCConnection(
grpcAddress,
)
if err != nil {
return err
}

// resFrom and resTo represents the range of blocks that can be included in the file
resFrom, resTo, err := archive.CreateBackup(
connection,
hclog.New(&hclog.LoggerOptions{
Name: "backup",
Level: hclog.LevelFromString("INFO"),
}),
p.from,
p.to,
p.out,
)
if err != nil {
return err
}

p.resFrom = resFrom
p.resTo = resTo

return nil
}

func (p *backupParams) getResult() command.CommandResult {
return &BackupResult{
From: p.resFrom,
To: p.resTo,
Out: p.out,
}
}
27 changes: 27 additions & 0 deletions command/backup/result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package backup

import (
"bytes"
"fmt"
"github.com/0xPolygon/polygon-edge/command/helper"
)

type BackupResult struct {
From uint64 `json:"from"`
To uint64 `json:"to"`
Out string `json:"out"`
}

func (r *BackupResult) GetOutput() string {
var buffer bytes.Buffer

buffer.WriteString("\n[BACKUP]\n")
buffer.WriteString("Exported backup file successfully:\n")
buffer.WriteString(helper.FormatKV([]string{
fmt.Sprintf("File|%s", r.Out),
fmt.Sprintf("From|%d", r.From),
fmt.Sprintf("To|%d", r.To),
}))

return buffer.String()
}
32 changes: 32 additions & 0 deletions command/cli_output.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package command

import (
"fmt"
"os"
)

type CLIOutput struct {
commonOutputFormatter
}

func newCLIOutput() *CLIOutput {
return &CLIOutput{}
}

func (cli *CLIOutput) WriteOutput() {
if cli.errorOutput != nil {
_, _ = fmt.Fprintln(os.Stderr, cli.getErrorOutput())

return
}

_, _ = fmt.Fprintln(os.Stdout, cli.getCommandOutput())
}

func (cli *CLIOutput) getErrorOutput() string {
return cli.errorOutput.Error()
}

func (cli *CLIOutput) getCommandOutput() string {
return cli.commandOutput.GetOutput()
}
8 changes: 8 additions & 0 deletions command/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package command

const (
ConsensusFlag = "consensus"
NoDiscoverFlag = "no-discover"
BootnodeFlag = "bootnode"
LogLevelFlag = "log-level"
)

0 comments on commit b06e562

Please sign in to comment.