diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go index 6efdbbf57f..f8a923aac1 100644 --- a/cmd/geth/consolecmd.go +++ b/cmd/geth/consolecmd.go @@ -30,9 +30,7 @@ import ( var ( consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} -) -var ( consoleCommand = cli.Command{ Action: utils.MigrateFlags(localConsole), Name: "console", diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index c719a87b12..403e93a9dc 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -20,6 +20,7 @@ package main import ( "io" + "sort" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/internal/debug" @@ -189,6 +190,39 @@ var AppHelpFlagGroups = []flagGroup{ }, } +// byCategory sorts an array of flagGroup by Name in the order +// defined in AppHelpFlagGroups. +type byCategory []flagGroup + +func (a byCategory) Len() int { return len(a) } +func (a byCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byCategory) Less(i, j int) bool { + iCat, jCat := a[i].Name, a[j].Name + iIdx, jIdx := len(AppHelpFlagGroups), len(AppHelpFlagGroups) // ensure non categorized flags come last + + for i, group := range AppHelpFlagGroups { + if iCat == group.Name { + iIdx = i + } + if jCat == group.Name { + jIdx = i + } + } + + return iIdx < jIdx +} + +func flagCategory(flag cli.Flag) string { + for _, category := range AppHelpFlagGroups { + for _, flg := range category.Flags { + if flg.GetName() == flag.GetName() { + return category.Name + } + } + } + return "MISC" +} + func init() { // Override the default app help template cli.AppHelpTemplate = AppHelpTemplate @@ -198,6 +232,7 @@ func init() { App interface{} FlagGroups []flagGroup } + // Override the default app help printer, but only for the global app help originalHelpPrinter := cli.HelpPrinter cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) { @@ -227,6 +262,27 @@ func init() { } // Render out custom usage screen originalHelpPrinter(w, tmpl, helpData{data, AppHelpFlagGroups}) + } else if tmpl == utils.CommandHelpTemplate { + // Iterate over all command specific flags and categorize them + categorized := make(map[string][]cli.Flag) + for _, flag := range data.(cli.Command).Flags { + if _, ok := categorized[flag.String()]; !ok { + categorized[flagCategory(flag)] = append(categorized[flagCategory(flag)], flag) + } + } + + // sort to get a stable ordering + sorted := make([]flagGroup, 0, len(categorized)) + for cat, flgs := range categorized { + sorted = append(sorted, flagGroup{cat, flgs}) + } + sort.Sort(byCategory(sorted)) + + // add sorted array to data and render with default printer + originalHelpPrinter(w, tmpl, map[string]interface{}{ + "cmd": data, + "categorizedFlags": sorted, + }) } else { originalHelpPrinter(w, tmpl, data) } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index df37d40c96..863761e8c0 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -56,6 +56,19 @@ import ( "gopkg.in/urfave/cli.v1" ) +var ( + CommandHelpTemplate = `{{.cmd.Name}}{{if .cmd.Subcommands}} command{{end}}{{if .cmd.Flags}} [command options]{{end}} [arguments...] +{{if .cmd.Description}}{{.cmd.Description}} +{{end}}{{if .cmd.Subcommands}} +SUBCOMMANDS: + {{range .cmd.Subcommands}}{{.cmd.Name}}{{with .cmd.ShortName}}, {{.cmd}}{{end}}{{ "\t" }}{{.cmd.Usage}} + {{end}}{{end}}{{if .categorizedFlags}} +{{range $idx, $categorized := .categorizedFlags}}{{$categorized.Name}} OPTIONS: +{{range $categorized.Flags}}{{"\t"}}{{.}} +{{end}} +{{end}}{{end}}` +) + func init() { cli.AppHelpTemplate = `{{.Name}} {{if .Flags}}[global options] {{end}}command{{if .Flags}} [command options]{{end}} [arguments...] @@ -70,16 +83,7 @@ GLOBAL OPTIONS: {{end}}{{end}} ` - cli.CommandHelpTemplate = `{{.Name}}{{if .Subcommands}} command{{end}}{{if .Flags}} [command options]{{end}} [arguments...] -{{if .Description}}{{.Description}} -{{end}}{{if .Subcommands}} -SUBCOMMANDS: - {{range .Subcommands}}{{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}} - {{end}}{{end}}{{if .Flags}} -OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{end}} -` + cli.CommandHelpTemplate = CommandHelpTemplate } // NewApp creates an app with sane defaults.