Generate usage from handler data in btcctl.

Rather than having to keep the usage in sync with the supported commands,
simply include the usage as a field in the command handlers map and
dynamically generate the usage from there.
This commit is contained in:
Dave Collins 2013-10-22 10:56:56 -05:00
parent d4f980c71f
commit 9ded3fa2cf

View file

@ -7,6 +7,7 @@ import (
"github.com/conformal/go-flags" "github.com/conformal/go-flags"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"os" "os"
"sort"
"strconv" "strconv"
) )
@ -33,6 +34,7 @@ type handlerData struct {
optionalArgs int optionalArgs int
displayHandler displayHandler displayHandler displayHandler
conversionHandlers []conversionHandler conversionHandlers []conversionHandler
usage string
} }
var ( var (
@ -41,22 +43,22 @@ var (
ErrUsage = errors.New("btcctl usage") // Real usage is shown. ErrUsage = errors.New("btcctl usage") // Real usage is shown.
) )
// commandHandlers is a map of commands and associate handler data // commandHandlers is a map of commands and associated handler data that is used
// that is used to validate correctness and perform the command. // to validate correctness and perform the command.
var commandHandlers = map[string]*handlerData{ var commandHandlers = map[string]*handlerData{
"addnode": &handlerData{2, 0, displaySpewDump, nil}, "addnode": &handlerData{2, 0, displaySpewDump, nil, "<ip> <add/remove/onetry>"},
"decoderawtransaction": &handlerData{1, 0, displaySpewDump, nil}, "decoderawtransaction": &handlerData{1, 0, displaySpewDump, nil, "<txhash>"},
"getbestblockhash": &handlerData{0, 0, displayGeneric, nil}, "getbestblockhash": &handlerData{0, 0, displayGeneric, nil, ""},
"getblock": &handlerData{1, 0, displaySpewDump, nil}, "getblock": &handlerData{1, 0, displaySpewDump, nil, "<blockhash>"},
"getblockcount": &handlerData{0, 0, displayFloat64, nil}, "getblockcount": &handlerData{0, 0, displayFloat64, nil, ""},
"getblockhash": &handlerData{1, 0, displayGeneric, []conversionHandler{toInt}}, "getblockhash": &handlerData{1, 0, displayGeneric, []conversionHandler{toInt}, "<blocknumber>"},
"getconnectioncount": &handlerData{0, 0, displayFloat64, nil}, "getconnectioncount": &handlerData{0, 0, displayFloat64, nil, ""},
"getdifficulty": &handlerData{0, 0, displayFloat64, nil}, "getdifficulty": &handlerData{0, 0, displayFloat64, nil, ""},
"getgenerate": &handlerData{0, 0, displayGeneric, nil}, "getgenerate": &handlerData{0, 0, displayGeneric, nil, ""},
"getpeerinfo": &handlerData{0, 0, displaySpewDump, nil}, "getpeerinfo": &handlerData{0, 0, displaySpewDump, nil, ""},
"getrawmempool": &handlerData{0, 0, displaySpewDump, nil}, "getrawmempool": &handlerData{0, 0, displaySpewDump, nil, ""},
"getrawtransaction": &handlerData{1, 1, displaySpewDump, []conversionHandler{nil, toInt}}, "getrawtransaction": &handlerData{1, 1, displaySpewDump, []conversionHandler{nil, toInt}, "<txhash> [verbose=0]"},
"stop": &handlerData{0, 0, displayGeneric, nil}, "stop": &handlerData{0, 0, displayGeneric, nil, ""},
} }
// toInt attempts to convert the passed string to an integer. It returns the // toInt attempts to convert the passed string to an integer. It returns the
@ -195,21 +197,22 @@ func commandHandler(cfg *config, command string, data *handlerData, args []strin
// usage displays the command usage. // usage displays the command usage.
func usage(parser *flags.Parser) { func usage(parser *flags.Parser) {
parser.WriteHelp(os.Stderr) parser.WriteHelp(os.Stderr)
fmt.Fprintf(os.Stderr,
"\nCommands:\n"+ // Extract usage information for each command from the command handler
"\taddnode <ip> <add/remove/onetry>\n"+ // data and sort by command name.
"\tdecoderawtransaction <txhash>\n"+ fmt.Fprintf(os.Stderr, "\nCommands:\n")
"\tgetbestblockhash\n"+ usageStrings := make([]string, 0, len(commandHandlers))
"\tgetblock <blockhash>\n"+ for command, data := range commandHandlers {
"\tgetblockcount\n"+ usage := command
"\tgetblockhash <blocknumber>\n"+ if len(data.usage) > 0 {
"\tgetconnectioncount\n"+ usage += " " + data.usage
"\tgetdifficulty\n"+ }
"\tgetgenerate\n"+ usageStrings = append(usageStrings, usage)
"\tgetpeerinfo\n"+ }
"\tgetrawmempool\n"+ sort.Sort(sort.StringSlice(usageStrings))
"\tgetrawtransaction <txhash> [verbose=0]\n"+ for _, usage := range usageStrings {
"\tstop\n") fmt.Fprintf(os.Stderr, "\t%s\n", usage)
}
} }
func main() { func main() {