mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 10:50:44 +00:00
cmd/geth, internal/flags, go.mod: colorize cli help, support env vars (#28103)
This commit is contained in:
parent
bda88affe6
commit
197551c729
3 changed files with 71 additions and 17 deletions
|
|
@ -193,6 +193,7 @@ func init() {
|
||||||
app.Flags = append(app.Flags, rpcFlags...)
|
app.Flags = append(app.Flags, rpcFlags...)
|
||||||
app.Flags = append(app.Flags, consoleFlags...)
|
app.Flags = append(app.Flags, consoleFlags...)
|
||||||
app.Flags = append(app.Flags, debug.Flags...)
|
app.Flags = append(app.Flags, debug.Flags...)
|
||||||
|
flags.AutoEnvVars(app.Flags, "XDC")
|
||||||
|
|
||||||
app.Before = func(ctx *cli.Context) error {
|
app.Before = func(ctx *cli.Context) error {
|
||||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ type DirectoryFlag struct {
|
||||||
Value DirectoryString
|
Value DirectoryString
|
||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
|
EnvVars []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// For cli.Flag:
|
// For cli.Flag:
|
||||||
|
|
@ -102,7 +103,7 @@ func (f *DirectoryFlag) GetCategory() string { return f.Category }
|
||||||
func (f *DirectoryFlag) TakesValue() bool { return true }
|
func (f *DirectoryFlag) TakesValue() bool { return true }
|
||||||
func (f *DirectoryFlag) GetUsage() string { return f.Usage }
|
func (f *DirectoryFlag) GetUsage() string { return f.Usage }
|
||||||
func (f *DirectoryFlag) GetValue() string { return f.Value.String() }
|
func (f *DirectoryFlag) GetValue() string { return f.Value.String() }
|
||||||
func (f *DirectoryFlag) GetEnvVars() []string { return nil } // env not supported
|
func (f *DirectoryFlag) GetEnvVars() []string { return f.EnvVars }
|
||||||
|
|
||||||
func (f *DirectoryFlag) GetDefaultText() string {
|
func (f *DirectoryFlag) GetDefaultText() string {
|
||||||
if f.DefaultText != "" {
|
if f.DefaultText != "" {
|
||||||
|
|
@ -156,6 +157,7 @@ type TextMarshalerFlag struct {
|
||||||
Value TextMarshaler
|
Value TextMarshaler
|
||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
|
EnvVars []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// For cli.Flag:
|
// For cli.Flag:
|
||||||
|
|
@ -187,7 +189,7 @@ func (f *TextMarshalerFlag) GetCategory() string { return f.Category }
|
||||||
|
|
||||||
func (f *TextMarshalerFlag) TakesValue() bool { return true }
|
func (f *TextMarshalerFlag) TakesValue() bool { return true }
|
||||||
func (f *TextMarshalerFlag) GetUsage() string { return f.Usage }
|
func (f *TextMarshalerFlag) GetUsage() string { return f.Usage }
|
||||||
func (f *TextMarshalerFlag) GetEnvVars() []string { return nil } // env not supported
|
func (f *TextMarshalerFlag) GetEnvVars() []string { return f.EnvVars }
|
||||||
|
|
||||||
func (f *TextMarshalerFlag) GetValue() string {
|
func (f *TextMarshalerFlag) GetValue() string {
|
||||||
t, err := f.Value.MarshalText()
|
t, err := f.Value.MarshalText()
|
||||||
|
|
@ -237,6 +239,7 @@ type BigFlag struct {
|
||||||
Value *big.Int
|
Value *big.Int
|
||||||
|
|
||||||
Aliases []string
|
Aliases []string
|
||||||
|
EnvVars []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// For cli.Flag:
|
// For cli.Flag:
|
||||||
|
|
@ -271,7 +274,7 @@ func (f *BigFlag) GetCategory() string { return f.Category }
|
||||||
func (f *BigFlag) TakesValue() bool { return true }
|
func (f *BigFlag) TakesValue() bool { return true }
|
||||||
func (f *BigFlag) GetUsage() string { return f.Usage }
|
func (f *BigFlag) GetUsage() string { return f.Usage }
|
||||||
func (f *BigFlag) GetValue() string { return f.Value.String() }
|
func (f *BigFlag) GetValue() string { return f.Value.String() }
|
||||||
func (f *BigFlag) GetEnvVars() []string { return nil } // env not supported
|
func (f *BigFlag) GetEnvVars() []string { return f.EnvVars }
|
||||||
|
|
||||||
func (f *BigFlag) GetDefaultText() string {
|
func (f *BigFlag) GetDefaultText() string {
|
||||||
if f.DefaultText != "" {
|
if f.DefaultText != "" {
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,19 @@ package flags
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
|
"github.com/mattn/go-isatty"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// usecolor defines whether the CLI help should use colored output or normal dumb
|
||||||
|
// colorless terminal formatting.
|
||||||
|
var usecolor = (isatty.IsTerminal(os.Stdout.Fd()) || isatty.IsCygwinTerminal(os.Stdout.Fd())) && os.Getenv("TERM") != "dumb"
|
||||||
|
|
||||||
// NewApp creates an app with sane defaults.
|
// NewApp creates an app with sane defaults.
|
||||||
func NewApp(gitCommit, usage string) *cli.App {
|
func NewApp(gitCommit, usage string) *cli.App {
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
|
|
@ -118,6 +125,14 @@ func doMigrateFlags(ctx *cli.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
if usecolor {
|
||||||
|
// Annotate all help categories with colors
|
||||||
|
cli.AppHelpTemplate = regexp.MustCompile("[A-Z ]+:").ReplaceAllString(cli.AppHelpTemplate, "\u001B[33m$0\u001B[0m")
|
||||||
|
|
||||||
|
// Annotate flag categories with colors (private template, so need to
|
||||||
|
// copy-paste the entire thing here...)
|
||||||
|
cli.AppHelpTemplate = strings.ReplaceAll(cli.AppHelpTemplate, "{{template \"visibleFlagCategoryTemplate\" .}}", "{{range .VisibleFlagCategories}}\n {{if .Name}}\u001B[33m{{.Name}}\u001B[0m\n\n {{end}}{{$flglen := len .Flags}}{{range $i, $e := .Flags}}{{if eq (subtract $flglen $i) 1}}{{$e}}\n{{else}}{{$e}}\n {{end}}{{end}}{{end}}")
|
||||||
|
}
|
||||||
cli.FlagStringer = FlagString
|
cli.FlagStringer = FlagString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,37 +142,31 @@ func FlagString(f cli.Flag) string {
|
||||||
if !ok {
|
if !ok {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
needsPlaceholder := df.TakesValue()
|
needsPlaceholder := df.TakesValue()
|
||||||
placeholder := ""
|
placeholder := ""
|
||||||
if needsPlaceholder {
|
if needsPlaceholder {
|
||||||
placeholder = "value"
|
placeholder = "value"
|
||||||
}
|
}
|
||||||
|
|
||||||
namesText := pad(cli.FlagNamePrefixer(df.Names(), placeholder), 30)
|
namesText := cli.FlagNamePrefixer(df.Names(), placeholder)
|
||||||
|
|
||||||
defaultValueString := ""
|
defaultValueString := ""
|
||||||
if s := df.GetDefaultText(); s != "" {
|
if s := df.GetDefaultText(); s != "" {
|
||||||
defaultValueString = " (default: " + s + ")"
|
defaultValueString = " (default: " + s + ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
usage := strings.TrimSpace(df.GetUsage())
|
|
||||||
envHint := strings.TrimSpace(cli.FlagEnvHinter(df.GetEnvVars(), ""))
|
envHint := strings.TrimSpace(cli.FlagEnvHinter(df.GetEnvVars(), ""))
|
||||||
if len(envHint) > 0 {
|
if envHint != "" {
|
||||||
usage += " " + envHint
|
envHint = " (" + envHint[1:len(envHint)-1] + ")"
|
||||||
}
|
}
|
||||||
|
usage := strings.TrimSpace(df.GetUsage())
|
||||||
usage = wordWrap(usage, 80)
|
usage = wordWrap(usage, 80)
|
||||||
usage = indent(usage, 10)
|
usage = indent(usage, 10)
|
||||||
|
|
||||||
return fmt.Sprintf("\n %s%s\n%s", namesText, defaultValueString, usage)
|
if usecolor {
|
||||||
|
return fmt.Sprintf("\n \u001B[32m%-35s%-35s\u001B[0m%s\n%s", namesText, defaultValueString, envHint, usage)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("\n %-35s%-35s%s\n%s", namesText, defaultValueString, envHint, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pad(s string, length int) string {
|
|
||||||
if len(s) < length {
|
|
||||||
s += strings.Repeat(" ", length-len(s))
|
|
||||||
}
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func indent(s string, nspace int) string {
|
func indent(s string, nspace int) string {
|
||||||
|
|
@ -202,3 +211,44 @@ func wordWrap(s string, width int) string {
|
||||||
|
|
||||||
return output.String()
|
return output.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AutoEnvVars extends all the specific CLI flags with automatically generated
|
||||||
|
// env vars by capitalizing the flag, replacing . with _ and prefixing it with
|
||||||
|
// the specified string.
|
||||||
|
//
|
||||||
|
// Note, the prefix should *not* contain the separator underscore, that will be
|
||||||
|
// added automatically.
|
||||||
|
func AutoEnvVars(flags []cli.Flag, prefix string) {
|
||||||
|
for _, flag := range flags {
|
||||||
|
envvar := strings.ToUpper(prefix + "_" + strings.ReplaceAll(strings.ReplaceAll(flag.Names()[0], ".", "_"), "-", "_"))
|
||||||
|
|
||||||
|
switch flag := flag.(type) {
|
||||||
|
case *cli.StringFlag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *cli.BoolFlag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *cli.IntFlag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *cli.Uint64Flag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *cli.DurationFlag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *cli.PathFlag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *BigFlag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *TextMarshalerFlag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
|
||||||
|
case *DirectoryFlag:
|
||||||
|
flag.EnvVars = append(flag.EnvVars, envvar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue