|
|
|
@ -18,13 +18,20 @@ package flags |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"fmt" |
|
|
|
|
"os" |
|
|
|
|
"regexp" |
|
|
|
|
"strings" |
|
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/internal/version" |
|
|
|
|
"github.com/ethereum/go-ethereum/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(usage string) *cli.App { |
|
|
|
|
git, _ := version.VCS() |
|
|
|
@ -129,6 +136,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 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -138,30 +153,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) |
|
|
|
|
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 { |
|
|
|
@ -213,3 +229,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) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|