From 247d5c25ff4fc12a3e91da25b3787462c4a98ec2 Mon Sep 17 00:00:00 2001 From: Shreyas S Bhat <35568964+shreyasbhat0@users.noreply.github.com> Date: Thu, 17 Aug 2023 16:34:14 +0530 Subject: [PATCH] fix: validate command args and set log formatter on fatal error (#122) * fix: set proper log formatter when fatal error * fix: validate command when invalid args are given --- cli/commands/bridge/bridge.go | 19 ++++++++++++++++++- cli/commands/bridge/relyas/btp.go | 7 ++++++- cli/commands/bridge/relyas/common.go | 14 ++++++++++++++ cli/commands/bridge/relyas/ibc.go | 2 ++ cli/commands/chain/chains.go | 27 ++++++++++++++++++++++++++- cli/commands/chain/types/archway.go | 2 +- cli/commands/chain/types/eth.go | 2 +- cli/commands/chain/types/hardhat.go | 2 +- cli/commands/chain/types/icon.go | 2 +- cli/commands/clean/clean.go | 2 +- cli/commands/discord/discord.go | 2 +- cli/commands/tutorial/tutorial.go | 2 +- cli/commands/twitter/twitter.go | 2 +- cli/commands/version/version.go | 2 +- cli/common/types.go | 6 ++++-- cli/go.mod | 1 + 16 files changed, 80 insertions(+), 14 deletions(-) diff --git a/cli/commands/bridge/bridge.go b/cli/commands/bridge/bridge.go index f30e0740..5b25a0eb 100644 --- a/cli/commands/bridge/bridge.go +++ b/cli/commands/bridge/bridge.go @@ -4,9 +4,13 @@ Copyright © 2023 Hugobyte AI Labs package bridge import ( + "fmt" + "os" + "github.com/hugobyte/dive/cli/commands/bridge/relyas" "github.com/hugobyte/dive/cli/common" "github.com/spf13/cobra" + "golang.org/x/exp/slices" ) func NewBridgeCmd(diveContext *common.DiveContext) *cobra.Command { @@ -18,7 +22,20 @@ func NewBridgeCmd(diveContext *common.DiveContext) *cobra.Command { This will create an relay to connect two different chains and pass any messages between them.`, Run: func(cmd *cobra.Command, args []string) { - cmd.Help() + validArgs := cmd.ValidArgs + for _, c := range cmd.Commands() { + validArgs = append(validArgs, c.Name()) + } + cmd.ValidArgs = validArgs + + if !slices.Contains(cmd.ValidArgs, args[0]) { + + diveContext.Log.SetOutput(os.Stderr) + diveContext.Error(fmt.Sprintf("Invalid Subcommand: %v", args)) + + cmd.Usage() + os.Exit(1) + } }, } diff --git a/cli/commands/bridge/relyas/btp.go b/cli/commands/bridge/relyas/btp.go index 6aa25245..200d42bb 100644 --- a/cli/commands/bridge/relyas/btp.go +++ b/cli/commands/bridge/relyas/btp.go @@ -50,7 +50,7 @@ func BtpRelayCmd(diveContext *common.DiveContext) *cobra.Command { Short: "Starts BTP Bridge between ChainA and ChainB", Long: ``, Run: func(cmd *cobra.Command, args []string) { - common.ValidateCmdArgs(args, cmd.UsageString()) + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) diveContext.InitKurtosisContext() enclaveCtx, err := diveContext.GetEnclaveContext() @@ -62,6 +62,11 @@ func BtpRelayCmd(diveContext *common.DiveContext) *cobra.Command { bridge, _ := cmd.Flags().GetBool("bmvbridge") // To Specify Which Type of BMV to be used in btp setup(if true BMV bridge is used else BMV-BTP Block is used) chains := initChains(chainA, chainB, serviceA, serviceB, bridge) + + if err := chains.checkForBtpSupportedChains(); err != nil { + diveContext.FatalError(err.Error(), fmt.Sprintf("Supported Chains for BTP: %v", suppottedChainsForBtp)) + } + diveContext.StartSpinner(fmt.Sprintf(" Starting BTP Bridge for %s,%s", chains.chainA, chains.chainB)) if chains.areChainsIcon() { diff --git a/cli/commands/bridge/relyas/common.go b/cli/commands/bridge/relyas/common.go index 2c5adfbf..7ca434df 100644 --- a/cli/commands/bridge/relyas/common.go +++ b/cli/commands/bridge/relyas/common.go @@ -5,9 +5,13 @@ import ( "strconv" "strings" + "slices" + "github.com/hugobyte/dive/cli/common" ) +var suppottedChainsForBtp = []string{"icon", "eth", "hardhat"} + type Chains struct { chainA string chainB string @@ -67,3 +71,13 @@ func (chains *Chains) getServicesResponse() (string, string, error) { return srcChainServiceResponse, dstChainServiceResponse, nil } + +func (chains *Chains) checkForBtpSupportedChains() error { + if !slices.Contains(suppottedChainsForBtp, chains.chainA) { + return fmt.Errorf("Invalid Chain %s", chains.chainA) + } + if !slices.Contains(suppottedChainsForBtp, chains.chainB) { + return fmt.Errorf("Invalid Chain %s", chains.chainB) + } + return nil +} diff --git a/cli/commands/bridge/relyas/ibc.go b/cli/commands/bridge/relyas/ibc.go index e753c723..c0b063e8 100644 --- a/cli/commands/bridge/relyas/ibc.go +++ b/cli/commands/bridge/relyas/ibc.go @@ -16,6 +16,8 @@ func IbcRelayCmd(diveContext *common.DiveContext) *cobra.Command { Short: "Start connection between Cosmos based chainA and ChainB and initiate communication between them", Long: "", Run: func(cmd *cobra.Command, args []string) { + + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) diveContext.InitKurtosisContext() enclaveCtx, err := diveContext.GetEnclaveContext() diff --git a/cli/commands/chain/chains.go b/cli/commands/chain/chains.go index 123a2794..015c70d9 100644 --- a/cli/commands/chain/chains.go +++ b/cli/commands/chain/chains.go @@ -4,6 +4,10 @@ Copyright © 2023 Hugobyte AI Labs package chain import ( + "fmt" + "os" + "slices" + "github.com/hugobyte/dive/cli/commands/chain/types" "github.com/hugobyte/dive/cli/common" "github.com/spf13/cobra" @@ -21,7 +25,20 @@ By executing this command, the node is launched, enabling network participation, maintenance within the specified blockchain ecosystem.`, Run: func(cmd *cobra.Command, args []string) { - cmd.Help() + validArgs := cmd.ValidArgs + for _, c := range cmd.Commands() { + validArgs = append(validArgs, c.Name()) + } + cmd.ValidArgs = validArgs + + if !slices.Contains(cmd.ValidArgs, args[0]) { + + diveContext.Log.SetOutput(os.Stderr) + diveContext.Error(fmt.Sprintf("Invalid Subcommand: %v", args)) + + cmd.Usage() + os.Exit(1) + } }, } @@ -34,3 +51,11 @@ maintenance within the specified blockchain ecosystem.`, return chainCmd } + +func addSubcommandsToValidArgs(cmd *cobra.Command) { + validArgs := cmd.ValidArgs + for _, c := range cmd.Commands() { + validArgs = append(validArgs, c.Name()) + } + cmd.ValidArgs = validArgs +} diff --git a/cli/commands/chain/types/archway.go b/cli/commands/chain/types/archway.go index f9d37840..490cd6f2 100644 --- a/cli/commands/chain/types/archway.go +++ b/cli/commands/chain/types/archway.go @@ -64,7 +64,7 @@ func NewArchwayCmd(diveContext *common.DiveContext) *cobra.Command { Short: "Build, initialize and start a archway node", Long: "The command starts the archway network and allows node in executing contracts", Run: func(cmd *cobra.Command, args []string) { - + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) runResponse := RunArchwayNode(diveContext) common.WriteToServiceFile(runResponse.ServiceName, *runResponse) diff --git a/cli/commands/chain/types/eth.go b/cli/commands/chain/types/eth.go index 962953a8..09adce2c 100644 --- a/cli/commands/chain/types/eth.go +++ b/cli/commands/chain/types/eth.go @@ -18,7 +18,7 @@ func NewEthCmd(diveContext *common.DiveContext) *cobra.Command { It establishes a connection to the Ethereum network and allows the node in executing smart contracts and maintaining the decentralized ledger.`, Run: func(cmd *cobra.Command, args []string) { - common.ValidateCmdArgs(args, cmd.UsageString()) + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) data := RunEthNode(diveContext) diff --git a/cli/commands/chain/types/hardhat.go b/cli/commands/chain/types/hardhat.go index 66492d3a..43e6ce20 100644 --- a/cli/commands/chain/types/hardhat.go +++ b/cli/commands/chain/types/hardhat.go @@ -15,7 +15,7 @@ func NewHardhatCmd(diveContext *common.DiveContext) *cobra.Command { It establishes a connection to the hardhat network and allows the node in executing smart contracts and maintaining the decentralized ledger.`, Run: func(cmd *cobra.Command, args []string) { - common.ValidateCmdArgs(args, cmd.UsageString()) + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) data := RunHardhatNode(diveContext) diff --git a/cli/commands/chain/types/icon.go b/cli/commands/chain/types/icon.go index 75f900f9..050d077c 100644 --- a/cli/commands/chain/types/icon.go +++ b/cli/commands/chain/types/icon.go @@ -58,7 +58,7 @@ func NewIconCmd(diveContext *common.DiveContext) *cobra.Command { It establishes a connection to the Icon network and allows the node in executing smart contracts and maintaining the decentralized ledger.`, Run: func(cmd *cobra.Command, args []string) { - common.ValidateCmdArgs(args, cmd.UsageString()) + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) decentralisation, _ := cmd.Flags().GetBool("decentralisation") diff --git a/cli/commands/clean/clean.go b/cli/commands/clean/clean.go index 2f2c0a64..8644d2a4 100644 --- a/cli/commands/clean/clean.go +++ b/cli/commands/clean/clean.go @@ -18,7 +18,7 @@ func NewCleanCmd(diveContext *common.DiveContext) *cobra.Command { Short: "Cleans up Kurtosis leftover artifacts", Long: `Destroys and removes any running encalves. If no enclaves running to remove it will throw an error`, Run: func(cmd *cobra.Command, args []string) { - common.ValidateCmdArgs(args, cmd.UsageString()) + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) diveContext.InitKurtosisContext() pwd, err := os.Getwd() diff --git a/cli/commands/discord/discord.go b/cli/commands/discord/discord.go index e9698d4f..41885d26 100644 --- a/cli/commands/discord/discord.go +++ b/cli/commands/discord/discord.go @@ -22,7 +22,7 @@ to access the dedicated DIVE community. It allows users to engage in discussions collaborate with other members of the DIVE community within the Discord platform.`, Run: func(cmd *cobra.Command, args []string) { diveContext.Log.SetOutput(os.Stdout) - common.ValidateCmdArgs(args, cmd.UsageString()) + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) diveContext.Log.Info("Redirecting to DIVE discord channel...") if err := common.OpenFile(diveURL); err != nil { diveContext.Log.Errorf("Failed to open Dive discord channel with error %v", err) diff --git a/cli/commands/tutorial/tutorial.go b/cli/commands/tutorial/tutorial.go index f2d710f7..04f463f4 100644 --- a/cli/commands/tutorial/tutorial.go +++ b/cli/commands/tutorial/tutorial.go @@ -23,7 +23,7 @@ directing users to a curated collection of tutorial videos specifically designed offers step-by-step instructions, tips, and demonstrations to help users better understand and utilize the features and functionalities of DIVE.`, Run: func(cmd *cobra.Command, args []string) { diveContext.Log.SetOutput(os.Stdout) - common.ValidateCmdArgs(args, cmd.UsageString()) + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) diveContext.Log.Info("Redirecting to YouTube...") if err := common.OpenFile(tutorialURL); err != nil { diveContext.Log.Errorf("Failed to open Dive YouTube chanel with error %v", err) diff --git a/cli/commands/twitter/twitter.go b/cli/commands/twitter/twitter.go index 43e0e1a1..13d3d7bd 100644 --- a/cli/commands/twitter/twitter.go +++ b/cli/commands/twitter/twitter.go @@ -23,7 +23,7 @@ shared by the official HugoByte Twitter account. Users can stay informed about H community, and follow our social media presence directly from the Twitter homepage.`, Run: func(cmd *cobra.Command, args []string) { diveContext.Log.SetOutput(os.Stdout) - common.ValidateCmdArgs(args, cmd.UsageString()) + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) diveContext.Log.Info("Redirecting to twitter...") if err := common.OpenFile(twitterURL); err != nil { diveContext.Log.Errorf("Failed to open HugoByte twitter with error %v", err) diff --git a/cli/commands/version/version.go b/cli/commands/version/version.go index 974d0d0c..d898fd6e 100644 --- a/cli/commands/version/version.go +++ b/cli/commands/version/version.go @@ -19,7 +19,7 @@ func NewVersionCmd(diveContext *common.DiveContext) *cobra.Command { Short: "Prints the CLI version", Long: `Prints the current DIVE CLI version and warns if you are using an old version.`, Run: func(cmd *cobra.Command, args []string) { - common.ValidateCmdArgs(args, cmd.UsageString()) + common.ValidateCmdArgs(diveContext, args, cmd.UsageString()) diveContext.Log.SetOutput(os.Stdout) // Checks for latest Version latestVersion := common.GetLatestVersion() diff --git a/cli/common/types.go b/cli/common/types.go index b906345c..f296ccc9 100644 --- a/cli/common/types.go +++ b/cli/common/types.go @@ -123,9 +123,10 @@ func WriteToFile(data string) error { return nil } -func ValidateCmdArgs(args []string, cmd string) { +func ValidateCmdArgs(diveContext *DiveContext, args []string, cmd string) { if len(args) != 0 { - logrus.Fatalf("Invalid Usage of command. Find cmd %s", cmd) + + diveContext.FatalError("Invalid Usage of command", cmd) } } @@ -144,6 +145,7 @@ func setupLogger() *logrus.Logger { TimestampFormat: "2006-01-02 15:04:05", FullTimestamp: true, ForceColors: true, + PadLevelText: true, }) ditFilePath := pwd + DiveLogDirectory + DiveDitLogFile diff --git a/cli/go.mod b/cli/go.mod index 5f777aab..08937d2a 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -11,6 +11,7 @@ require ( github.com/natefinch/lumberjack v2.0.0+incompatible github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.7.0 + golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb ) require (