diff --git a/cmd/tendermint/commands/gen_validator.go b/cmd/tendermint/commands/gen_validator.go new file mode 100644 index 000000000..a1217e1f0 --- /dev/null +++ b/cmd/tendermint/commands/gen_validator.go @@ -0,0 +1,27 @@ +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/tendermint/go-wire" + "github.com/tendermint/tendermint/types" +) + +var genValidatorCmd = &cobra.Command{ + Use: "gen_validator", + Short: "Generate new validator keypair", + Run: genValidator, +} + +func init() { + RootCmd.AddCommand(genValidatorCmd) +} + +func genValidator(cmd *cobra.Command, args []string) { + privValidator := types.GenPrivValidator() + privValidatorJSONBytes := wire.JSONBytesPretty(privValidator) + fmt.Printf(`%v +`, string(privValidatorJSONBytes)) +} diff --git a/cmd/tendermint/init.go b/cmd/tendermint/commands/init.go similarity index 78% rename from cmd/tendermint/init.go rename to cmd/tendermint/commands/init.go index 5ec1efefb..366ca4e84 100644 --- a/cmd/tendermint/init.go +++ b/cmd/tendermint/commands/init.go @@ -1,13 +1,25 @@ -package main +package commands import ( "os" + "github.com/spf13/cobra" + cmn "github.com/tendermint/go-common" "github.com/tendermint/tendermint/types" ) -func init_files() { +var initFilesCmd = &cobra.Command{ + Use: "init", + Short: "Initialize Tendermint", + Run: initFiles, +} + +func init() { + RootCmd.AddCommand(initFilesCmd) +} + +func initFiles(cmd *cobra.Command, args []string) { privValFile := config.GetString("priv_validator_file") if _, err := os.Stat(privValFile); os.IsNotExist(err) { privValidator := types.GenPrivValidator() diff --git a/cmd/tendermint/probe_upnp.go b/cmd/tendermint/commands/probe_upnp.go similarity index 55% rename from cmd/tendermint/probe_upnp.go rename to cmd/tendermint/commands/probe_upnp.go index 5dcadddcd..bff433bc9 100644 --- a/cmd/tendermint/probe_upnp.go +++ b/cmd/tendermint/commands/probe_upnp.go @@ -1,13 +1,25 @@ -package main +package commands import ( "encoding/json" "fmt" + "github.com/spf13/cobra" + "github.com/tendermint/go-p2p/upnp" ) -func probe_upnp() { +var probeUpnpCmd = &cobra.Command{ + Use: "probe_upnp", + Short: "Test UPnP functionality", + Run: probeUpnp, +} + +func init() { + RootCmd.AddCommand(probeUpnpCmd) +} + +func probeUpnp(cmd *cobra.Command, args []string) { capabilities, err := upnp.Probe() if err != nil { diff --git a/cmd/tendermint/commands/replay.go b/cmd/tendermint/commands/replay.go new file mode 100644 index 000000000..2f0e3266e --- /dev/null +++ b/cmd/tendermint/commands/replay.go @@ -0,0 +1,40 @@ +package commands + +import ( + "fmt" + + "github.com/tendermint/tendermint/consensus" + + "github.com/spf13/cobra" +) + +var replayCmd = &cobra.Command{ + Use: "replay [walfile]", + Short: "Replay messages from WAL", + Run: func(cmd *cobra.Command, args []string) { + + if len(args) > 1 { + consensus.RunReplayFile(config, args[1], false) + } else { + fmt.Println("replay requires an argument (walfile)") + } + }, +} + +var replayConsoleCmd = &cobra.Command{ + Use: "replay_console [walfile]", + Short: "Replay messages from WAL in a console", + Run: func(cmd *cobra.Command, args []string) { + + if len(args) > 1 { + consensus.RunReplayFile(config, args[1], true) + } else { + fmt.Println("replay_console requires an argument (walfile)") + } + }, +} + +func init() { + RootCmd.AddCommand(replayCmd) + RootCmd.AddCommand(replayConsoleCmd) +} diff --git a/cmd/tendermint/reset_priv_validator.go b/cmd/tendermint/commands/reset_priv_validator.go similarity index 57% rename from cmd/tendermint/reset_priv_validator.go rename to cmd/tendermint/commands/reset_priv_validator.go index 5bf3ba69b..217c387a5 100644 --- a/cmd/tendermint/reset_priv_validator.go +++ b/cmd/tendermint/commands/reset_priv_validator.go @@ -1,22 +1,41 @@ -package main +package commands import ( "os" + "github.com/spf13/cobra" + "github.com/tendermint/tendermint/types" ) +var resetAllCmd = &cobra.Command{ + Use: "unsafe_reset_all", + Short: "(unsafe) Remove all the data and WAL, reset this node's validator", + Run: resetAll, +} + +var resetPrivValidatorCmd = &cobra.Command{ + Use: "unsafe_reset_priv_validator", + Short: "(unsafe) Reset this node's validator", + Run: resetPrivValidator, +} + +func init() { + RootCmd.AddCommand(resetAllCmd) + RootCmd.AddCommand(resetPrivValidatorCmd) +} + // XXX: this is totally unsafe. // it's only suitable for testnets. -func reset_all() { - reset_priv_validator() +func resetAll(cmd *cobra.Command, args []string) { + resetPrivValidator(cmd, args) os.RemoveAll(config.GetString("db_dir")) os.Remove(config.GetString("cs_wal_file")) } // XXX: this is totally unsafe. // it's only suitable for testnets. -func reset_priv_validator() { +func resetPrivValidator(cmd *cobra.Command, args []string) { // Get PrivValidator var privValidator *types.PrivValidator privValidatorFile := config.GetString("priv_validator_file") diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go new file mode 100644 index 000000000..cee5b6604 --- /dev/null +++ b/cmd/tendermint/commands/root.go @@ -0,0 +1,35 @@ +package commands + +import ( + "github.com/spf13/cobra" + + cfg "github.com/tendermint/go-config" + "github.com/tendermint/go-logger" + tmcfg "github.com/tendermint/tendermint/config/tendermint" +) + +var config cfg.Config +var log = logger.New("module", "main") + +//global flag +var logLevel string + +var RootCmd = &cobra.Command{ + Use: "tendermint", + Short: "Tendermint Core (BFT Consensus) in Go", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + config.Set("log_level", logLevel) + }, +} + +func init() { + + // Get configuration + config = tmcfg.GetConfig("") + + //parse flag and set config + RootCmd.PersistentFlags().StringVar(&logLevel, "log_level", config.GetString("log_level"), "Log level") + + // set the log level + logger.SetLogLevel(config.GetString("log_level")) +} diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go new file mode 100644 index 000000000..a04b52d09 --- /dev/null +++ b/cmd/tendermint/commands/run_node.go @@ -0,0 +1,124 @@ +package commands + +import ( + "io/ioutil" + "time" + + "github.com/spf13/cobra" + + . "github.com/tendermint/go-common" + "github.com/tendermint/tendermint/node" + "github.com/tendermint/tendermint/types" +) + +var runNodeCmd = &cobra.Command{ + Use: "node", + Short: "Run the tendermint node", + PreRun: setConfigFlags, + Run: runNode, +} + +//flags +var ( + moniker string + nodeLaddr string + seeds string + fastSync bool + skipUPNP bool + rpcLaddr string + grpcLaddr string + proxyApp string + abciTransport string + pex bool +) + +func init() { + + // configuration options + runNodeCmd.Flags().StringVar(&moniker, "moniker", config.GetString("moniker"), + "Node Name") + runNodeCmd.Flags().StringVar(&nodeLaddr, "node_laddr", config.GetString("node_laddr"), + "Node listen address. (0.0.0.0:0 means any interface, any port)") + runNodeCmd.Flags().StringVar(&seeds, "seeds", config.GetString("seeds"), + "Comma delimited host:port seed nodes") + runNodeCmd.Flags().BoolVar(&fastSync, "fast_sync", config.GetBool("fast_sync"), + "Fast blockchain syncing") + runNodeCmd.Flags().BoolVar(&skipUPNP, "skip_upnp", config.GetBool("skip_upnp"), + "Skip UPNP configuration") + runNodeCmd.Flags().StringVar(&rpcLaddr, "rpc_laddr", config.GetString("rpc_laddr"), + "RPC listen address. Port required") + runNodeCmd.Flags().StringVar(&grpcLaddr, "grpc_laddr", config.GetString("grpc_laddr"), + "GRPC listen address (BroadcastTx only). Port required") + runNodeCmd.Flags().StringVar(&proxyApp, "proxy_app", config.GetString("proxy_app"), + "Proxy app address, or 'nilapp' or 'dummy' for local testing.") + runNodeCmd.Flags().StringVar(&abciTransport, "abci", config.GetString("abci"), + "Specify abci transport (socket | grpc)") + + // feature flags + runNodeCmd.Flags().BoolVar(&pex, "pex", config.GetBool("pex_reactor"), + "Enable Peer-Exchange (dev feature)") + + RootCmd.AddCommand(runNodeCmd) +} + +func setConfigFlags(cmd *cobra.Command, args []string) { + + // Merge parsed flag values onto config + config.Set("moniker", moniker) + config.Set("node_laddr", nodeLaddr) + config.Set("seeds", seeds) + config.Set("fast_sync", fastSync) + config.Set("skip_upnp", skipUPNP) + config.Set("rpc_laddr", rpcLaddr) + config.Set("grpc_laddr", grpcLaddr) + config.Set("proxy_app", proxyApp) + config.Set("abci", abciTransport) + config.Set("pex_reactor", pex) +} + +// Users wishing to: +// * Use an external signer for their validators +// * Supply an in-proc abci app +// should import github.com/tendermint/tendermint/node and implement +// their own run_node to call node.NewNode (instead of node.NewNodeDefault) +// with their custom priv validator and/or custom proxy.ClientCreator +func runNode(cmd *cobra.Command, args []string) { + + // Wait until the genesis doc becomes available + // This is for Mintnet compatibility. + // TODO: If Mintnet gets deprecated or genesis_file is + // always available, remove. + genDocFile := config.GetString("genesis_file") + if !FileExists(genDocFile) { + log.Notice(Fmt("Waiting for genesis file %v...", genDocFile)) + for { + time.Sleep(time.Second) + if !FileExists(genDocFile) { + continue + } + jsonBlob, err := ioutil.ReadFile(genDocFile) + if err != nil { + Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) + } + genDoc, err := types.GenesisDocFromJSON(jsonBlob) + if err != nil { + Exit(Fmt("Error reading GenesisDoc: %v", err)) + } + if genDoc.ChainID == "" { + Exit(Fmt("Genesis doc %v must include non-empty chain_id", genDocFile)) + } + config.Set("chain_id", genDoc.ChainID) + } + } + + // Create & start node + n := node.NewNodeDefault(config) + if _, err := n.Start(); err != nil { + Exit(Fmt("Failed to start node: %v", err)) + } else { + log.Notice("Started node", "nodeInfo", n.Switch().NodeInfo()) + } + + // Trap signal, run forever. + n.RunForever() +} diff --git a/cmd/tendermint/show_validator.go b/cmd/tendermint/commands/show_validator.go similarity index 50% rename from cmd/tendermint/show_validator.go rename to cmd/tendermint/commands/show_validator.go index e6c68e31f..4aa80ae14 100644 --- a/cmd/tendermint/show_validator.go +++ b/cmd/tendermint/commands/show_validator.go @@ -1,13 +1,25 @@ -package main +package commands import ( "fmt" + "github.com/spf13/cobra" + "github.com/tendermint/go-wire" "github.com/tendermint/tendermint/types" ) -func show_validator() { +var showValidatorCmd = &cobra.Command{ + Use: "show_validator", + Short: "Show this node's validator info", + Run: showValidator, +} + +func init() { + RootCmd.AddCommand(showValidatorCmd) +} + +func showValidator(cmd *cobra.Command, args []string) { privValidatorFile := config.GetString("priv_validator_file") privValidator := types.LoadOrGenPrivValidator(privValidatorFile) fmt.Println(string(wire.JSONBytesPretty(privValidator.PubKey))) diff --git a/cmd/tendermint/commands/version.go b/cmd/tendermint/commands/version.go new file mode 100644 index 000000000..5c92160ea --- /dev/null +++ b/cmd/tendermint/commands/version.go @@ -0,0 +1,21 @@ +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/tendermint/tendermint/version" +) + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "Show version info", + Run: func(cmd *cobra.Command, args []string) { + fmt.Println(version.Version) + }, +} + +func init() { + RootCmd.AddCommand(versionCmd) +} diff --git a/cmd/tendermint/flags.go b/cmd/tendermint/flags.go deleted file mode 100644 index fdf43b657..000000000 --- a/cmd/tendermint/flags.go +++ /dev/null @@ -1,66 +0,0 @@ -package main - -import ( - flag "github.com/spf13/pflag" - "os" - - cfg "github.com/tendermint/go-config" -) - -func parseFlags(config cfg.Config, args []string) { - var ( - printHelp bool - moniker string - nodeLaddr string - seeds string - fastSync bool - skipUPNP bool - rpcLaddr string - grpcLaddr string - logLevel string - proxyApp string - abciTransport string - - pex bool - ) - - // Declare flags - var flags = flag.NewFlagSet("main", flag.ExitOnError) - flags.BoolVar(&printHelp, "help", false, "Print this help message.") - - // configuration options - flags.StringVar(&moniker, "moniker", config.GetString("moniker"), "Node Name") - flags.StringVar(&nodeLaddr, "node_laddr", config.GetString("node_laddr"), "Node listen address. (0.0.0.0:0 means any interface, any port)") - flags.StringVar(&seeds, "seeds", config.GetString("seeds"), "Comma delimited host:port seed nodes") - flags.BoolVar(&fastSync, "fast_sync", config.GetBool("fast_sync"), "Fast blockchain syncing") - flags.BoolVar(&skipUPNP, "skip_upnp", config.GetBool("skip_upnp"), "Skip UPNP configuration") - flags.StringVar(&rpcLaddr, "rpc_laddr", config.GetString("rpc_laddr"), "RPC listen address. Port required") - flags.StringVar(&grpcLaddr, "grpc_laddr", config.GetString("grpc_laddr"), "GRPC listen address (BroadcastTx only). Port required") - flags.StringVar(&logLevel, "log_level", config.GetString("log_level"), "Log level") - flags.StringVar(&proxyApp, "proxy_app", config.GetString("proxy_app"), - "Proxy app address, or 'nilapp' or 'dummy' for local testing.") - flags.StringVar(&abciTransport, "abci", config.GetString("abci"), "Specify abci transport (socket | grpc)") - - // feature flags - flags.BoolVar(&pex, "pex", config.GetBool("pex_reactor"), "Enable Peer-Exchange (dev feature)") - - flags.Parse(args) - if printHelp { - flags.PrintDefaults() - os.Exit(0) - } - - // Merge parsed flag values onto app. - config.Set("moniker", moniker) - config.Set("node_laddr", nodeLaddr) - config.Set("seeds", seeds) - config.Set("fast_sync", fastSync) - config.Set("skip_upnp", skipUPNP) - config.Set("rpc_laddr", rpcLaddr) - config.Set("grpc_laddr", grpcLaddr) - config.Set("log_level", logLevel) - config.Set("proxy_app", proxyApp) - config.Set("abci", abciTransport) - - config.Set("pex_reactor", pex) -} diff --git a/cmd/tendermint/gen_validator.go b/cmd/tendermint/gen_validator.go deleted file mode 100644 index 0fc0e1661..000000000 --- a/cmd/tendermint/gen_validator.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "fmt" - - "github.com/tendermint/go-wire" - "github.com/tendermint/tendermint/types" -) - -func gen_validator() { - privValidator := types.GenPrivValidator() - privValidatorJSONBytes := wire.JSONBytesPretty(privValidator) - fmt.Printf(`%v -`, string(privValidatorJSONBytes)) -} diff --git a/cmd/tendermint/log.go b/cmd/tendermint/log.go deleted file mode 100644 index ce626d2e9..000000000 --- a/cmd/tendermint/log.go +++ /dev/null @@ -1,7 +0,0 @@ -package main - -import ( - "github.com/tendermint/go-logger" -) - -var log = logger.New("module", "main") diff --git a/cmd/tendermint/main.go b/cmd/tendermint/main.go index 640f2c275..cddae985b 100644 --- a/cmd/tendermint/main.go +++ b/cmd/tendermint/main.go @@ -4,76 +4,12 @@ import ( "fmt" "os" - cfg "github.com/tendermint/go-config" - "github.com/tendermint/go-logger" - tmcfg "github.com/tendermint/tendermint/config/tendermint" - "github.com/tendermint/tendermint/consensus" - "github.com/tendermint/tendermint/version" + "github.com/tendermint/tendermint/cmd/tendermint/commands" ) -var config cfg.Config - func main() { - - args := os.Args[1:] - if len(args) == 0 { - fmt.Println(`Tendermint - -Commands: - init Initialize tendermint - node Run the tendermint node - show_validator Show this node's validator info - gen_validator Generate new validator keypair - probe_upnp Test UPnP functionality - replay Replay messages from WAL - replay_console Replay messages from WAL in a console - unsafe_reset_all (unsafe) Remove all the data and WAL, reset this node's validator - unsafe_reset_priv_validator (unsafe) Reset this node's validator - version Show version info -`) - return - } - - // Get configuration - config = tmcfg.GetConfig("") - parseFlags(config, args[1:]) // Command line overrides - - // set the log level - logger.SetLogLevel(config.GetString("log_level")) - - switch args[0] { - case "node": - run_node(config) - case "replay": - if len(args) > 1 { - consensus.RunReplayFile(config, args[1], false) - } else { - fmt.Println("replay requires an argument (walfile)") - os.Exit(1) - } - case "replay_console": - if len(args) > 1 { - consensus.RunReplayFile(config, args[1], true) - } else { - fmt.Println("replay_console requires an argument (walfile)") - os.Exit(1) - } - case "init": - init_files() - case "show_validator": - show_validator() - case "gen_validator": - gen_validator() - case "probe_upnp": - probe_upnp() - case "unsafe_reset_all": - reset_all() - case "unsafe_reset_priv_validator": - reset_priv_validator() - case "version": - fmt.Println(version.Version) - default: - fmt.Printf("Unknown command %v\n", args[0]) + if err := commands.RootCmd.Execute(); err != nil { + fmt.Println(err) os.Exit(1) } } diff --git a/cmd/tendermint/run_node.go b/cmd/tendermint/run_node.go deleted file mode 100644 index 1940a6056..000000000 --- a/cmd/tendermint/run_node.go +++ /dev/null @@ -1,59 +0,0 @@ -package main - -import ( - "io/ioutil" - "time" - - . "github.com/tendermint/go-common" - cfg "github.com/tendermint/go-config" - "github.com/tendermint/tendermint/node" - "github.com/tendermint/tendermint/types" -) - -// Users wishing to: -// * Use an external signer for their validators -// * Supply an in-proc abci app -// should import github.com/tendermint/tendermint/node and implement -// their own run_node to call node.NewNode (instead of node.NewNodeDefault) -// with their custom priv validator and/or custom proxy.ClientCreator -func run_node(config cfg.Config) { - - // Wait until the genesis doc becomes available - // This is for Mintnet compatibility. - // TODO: If Mintnet gets deprecated or genesis_file is - // always available, remove. - genDocFile := config.GetString("genesis_file") - if !FileExists(genDocFile) { - log.Notice(Fmt("Waiting for genesis file %v...", genDocFile)) - for { - time.Sleep(time.Second) - if !FileExists(genDocFile) { - continue - } - jsonBlob, err := ioutil.ReadFile(genDocFile) - if err != nil { - Exit(Fmt("Couldn't read GenesisDoc file: %v", err)) - } - genDoc, err := types.GenesisDocFromJSON(jsonBlob) - if err != nil { - Exit(Fmt("Error reading GenesisDoc: %v", err)) - } - if genDoc.ChainID == "" { - Exit(Fmt("Genesis doc %v must include non-empty chain_id", genDocFile)) - } - config.Set("chain_id", genDoc.ChainID) - } - } - - // Create & start node - n := node.NewNodeDefault(config) - if _, err := n.Start(); err != nil { - Exit(Fmt("Failed to start node: %v", err)) - } else { - log.Notice("Started node", "nodeInfo", n.Switch().NodeInfo()) - } - - // Trap signal, run forever. - n.RunForever() - -} diff --git a/glide.lock b/glide.lock index c39121639..e79888029 100644 --- a/glide.lock +++ b/glide.lock @@ -1,8 +1,8 @@ -hash: 41f8fec708e98b7f8c4804be46008493199fa45e89b2d5dc237fd65fe431c62f -updated: 2017-03-06T04:01:33.319604992-05:00 +hash: 81cd41d28f9a747a71e6a47e8bc7d855846df29f359ffdcc8d1645c451112b31 +updated: 2017-03-06T17:34:23.99160606-05:00 imports: - name: github.com/btcsuite/btcd - version: d06c0bb181529331be8f8d9350288c420d9e60e4 + version: 583684b21bfbde9b5fc4403916fd7c807feb0289 subpackages: - btcec - name: github.com/BurntSushi/toml @@ -12,7 +12,7 @@ imports: subpackages: - spew - name: github.com/ebuchman/fail-test - version: 13f91f14c826314205cdbed1ec8ac8bf08e03381 + version: 95f809107225be108efcf10a3509e4ea6ceef3c4 - name: github.com/go-stack/stack version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 - name: github.com/gogo/protobuf @@ -20,25 +20,29 @@ imports: subpackages: - proto - name: github.com/golang/protobuf - version: 8ee79997227bf9b34611aee7946ae64735e6fd93 + version: 69b215d01a5606c843240eab4937eab3acee6530 subpackages: - proto - name: github.com/golang/snappy - version: d9eb7a3d35ec988b8585d4a0068e462c27d28380 + version: 553a641470496b2327abcac10b36396bd98e45c9 - name: github.com/gorilla/websocket version: 3ab3a8b8831546bd18fd182c20687ca853b2bb13 +- name: github.com/inconshreveable/mousetrap + version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 - name: github.com/jmhodges/levigo version: c42d9e0ca023e2198120196f842701bb4c55d7b9 - name: github.com/mattn/go-colorable - version: d228849504861217f796da67fae4f6e347643f15 + version: acb9493f2794fd0f820de7a27a217dafbb1b65ea - name: github.com/mattn/go-isatty - version: 30a891c33c7cde7b02a981314b4228ec99380cca + version: 9622e0cc9d8f9be434ca605520ff9a16808fee47 - name: github.com/pkg/errors version: 645ef00459ed84a119197bfb8d8205042c6df63d - name: github.com/pmezard/go-difflib version: d8ed2627bdf02c080bf22230dbb337003b7aba2d subpackages: - difflib +- name: github.com/spf13/cobra + version: fcd0c5a1df88f5d6784cb4feead962c3f3d0b66c - name: github.com/spf13/pflag version: 9ff6c6923cfffbcd502984b8e0c80539a94968b7 - name: github.com/stretchr/testify @@ -47,7 +51,7 @@ imports: - assert - require - name: github.com/syndtr/goleveldb - version: 23851d93a2292dcc56e71a18ec9e0624d84a0f65 + version: 3c5717caf1475fd25964109a0fc640bd150fce43 subpackages: - leveldb - leveldb/cache @@ -123,7 +127,7 @@ imports: - client - testutil - name: golang.org/x/crypto - version: 7c6cc321c680f03b9ef0764448e780704f486b51 + version: 40541ccb1c6e64c947ed6f606b8a6cb4b67d7436 subpackages: - curve25519 - nacl/box @@ -134,7 +138,7 @@ imports: - ripemd160 - salsa20/salsa - name: golang.org/x/net - version: 61557ac0112b576429a0df080e1c2cef5dfbb642 + version: d379faa25cbdc04d653984913a2ceb43b0bc46d7 subpackages: - context - http2 @@ -144,11 +148,11 @@ imports: - lex/httplex - trace - name: golang.org/x/sys - version: d75a52659825e75fff6158388dddc6a5b04f9ba5 + version: e48874b42435b4347fc52bdee0424a52abc974d7 subpackages: - unix - name: google.golang.org/grpc - version: cbcceb2942a489498cf22b2f918536e819d33f0a + version: 7b399ed358736bc5522021cdc7d79a8ee9ac6f98 subpackages: - codes - credentials diff --git a/glide.yaml b/glide.yaml index e40293802..53d308233 100644 --- a/glide.yaml +++ b/glide.yaml @@ -39,6 +39,7 @@ import: - proto - package: github.com/gorilla/websocket version: ^1.1.0 +- package: github.com/spf13/cobra - package: github.com/spf13/pflag - package: github.com/pkg/errors version: ^0.8.0