Skip to content

Commit

Permalink
cmd/geth, internal/flags, go.mod: colorize cli help, support env vars (
Browse files Browse the repository at this point in the history
  • Loading branch information
gzliudan committed Nov 22, 2024
1 parent 849f88b commit 123df02
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 17 deletions.
1 change: 1 addition & 0 deletions cmd/XDC/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ func init() {
app.Flags = append(app.Flags, rpcFlags...)
app.Flags = append(app.Flags, consoleFlags...)
app.Flags = append(app.Flags, debug.Flags...)
flags.AutoEnvVars(app.Flags, "XDC")

app.Before = func(ctx *cli.Context) error {
runtime.GOMAXPROCS(runtime.NumCPU())
Expand Down
9 changes: 6 additions & 3 deletions internal/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type DirectoryFlag struct {
Value DirectoryString

Aliases []string
EnvVars []string
}

// For cli.Flag:
Expand Down Expand Up @@ -102,7 +103,7 @@ func (f *DirectoryFlag) GetCategory() string { return f.Category }
func (f *DirectoryFlag) TakesValue() bool { return true }
func (f *DirectoryFlag) GetUsage() string { return f.Usage }
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 {
if f.DefaultText != "" {
Expand Down Expand Up @@ -156,6 +157,7 @@ type TextMarshalerFlag struct {
Value TextMarshaler

Aliases []string
EnvVars []string
}

// For cli.Flag:
Expand Down Expand Up @@ -187,7 +189,7 @@ func (f *TextMarshalerFlag) GetCategory() string { return f.Category }

func (f *TextMarshalerFlag) TakesValue() bool { return true }
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 {
t, err := f.Value.MarshalText()
Expand Down Expand Up @@ -237,6 +239,7 @@ type BigFlag struct {
Value *big.Int

Aliases []string
EnvVars []string
}

// For cli.Flag:
Expand Down Expand Up @@ -271,7 +274,7 @@ func (f *BigFlag) GetCategory() string { return f.Category }
func (f *BigFlag) TakesValue() bool { return true }
func (f *BigFlag) GetUsage() string { return f.Usage }
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 {
if f.DefaultText != "" {
Expand Down
78 changes: 64 additions & 14 deletions internal/flags/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,19 @@ package flags

import (
"fmt"
"os"
"regexp"
"strings"

"github.com/XinFinOrg/XDPoSChain/params"
"github.com/mattn/go-isatty"
"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.
func NewApp(gitCommit, usage string) *cli.App {
app := cli.NewApp()
Expand Down Expand Up @@ -90,6 +97,14 @@ func doMigrateFlags(ctx *cli.Context) {
}

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
}

Expand All @@ -99,37 +114,31 @@ func FlagString(f cli.Flag) string {
if !ok {
return ""
}

needsPlaceholder := df.TakesValue()
placeholder := ""
if needsPlaceholder {
placeholder = "value"
}

namesText := pad(cli.FlagNamePrefixer(df.Names(), placeholder), 30)
namesText := cli.FlagNamePrefixer(df.Names(), placeholder)

defaultValueString := ""
if s := df.GetDefaultText(); s != "" {
defaultValueString = " (default: " + s + ")"
}

usage := strings.TrimSpace(df.GetUsage())
envHint := strings.TrimSpace(cli.FlagEnvHinter(df.GetEnvVars(), ""))
if len(envHint) > 0 {
usage += " " + envHint
if envHint != "" {
envHint = " (" + envHint[1:len(envHint)-1] + ")"
}

usage := strings.TrimSpace(df.GetUsage())
usage = wordWrap(usage, 80)
usage = indent(usage, 10)

return fmt.Sprintf("\n %s%s\n%s", namesText, defaultValueString, usage)
}

func pad(s string, length int) string {
if len(s) < length {
s += strings.Repeat(" ", length-len(s))
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)
}
return s
}

func indent(s string, nspace int) string {
Expand Down Expand Up @@ -174,3 +183,44 @@ func wordWrap(s string, width int) string {

return output.String()
}

// AutoEnvVars extens 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)
}
}
}

0 comments on commit 123df02

Please sign in to comment.