From 904e03926794663089b73d52a02def065d819200 Mon Sep 17 00:00:00 2001 From: Andrew Morozko Date: Fri, 29 Nov 2019 22:33:16 +0300 Subject: [PATCH] Added the "dataname" tag --- example_test.go | 36 ++++++++++++++++++++++++++++++++++++ parse.go | 7 +++++++ usage.go | 9 ++++----- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/example_test.go b/example_test.go index f71fbeb..3f7f2ab 100644 --- a/example_test.go +++ b/example_test.go @@ -135,6 +135,42 @@ func Example_helpText() { // --help, -h display this help and exit } +// This example shows the usage string generated by go-arg with custom datanames +func Example_helpDataname() { + // These are the args you would pass in on the command line + os.Args = split("./example --help") + + var args struct { + Input string `arg:"positional,dataname:DATAFILE"` + Output []string `arg:"positional"` + Verbose bool `arg:"-v" help:"verbosity level"` + Dataset string `help:"dataset to use"` + Optimize int `arg:"-O,help:optimization level,dataname:LEVEL"` + MaxJobs int `arg:"-j,help:maximum number of simultaneous jobs,dataname:N"` + } + + // This is only necessary when running inside golang's runnable example harness + osExit = func(int) {} + + MustParse(&args) + + // output: + + // Usage: example [--verbose] [--dataset DATASET] [--optimize LEVEL] [--maxjobs N] DATAFILE [OUTPUT [OUTPUT ...]] + + // Positional arguments: + // DATAFILE + // OUTPUT + + // Options: + // --verbose, -v verbosity level + // --dataset DATASET dataset to use + // --optimize LEVEL, -O LEVEL + // optimization level + // --maxjobs N, -j N maximum number of simultanious jobs + // --help, -h display this help and exit +} + // This example shows the usage string generated by go-arg when using subcommands func Example_helpTextWithSubcommand() { // These are the args you would pass in on the command line diff --git a/parse.go b/parse.go index bc156df..3e1d719 100644 --- a/parse.go +++ b/parse.go @@ -56,6 +56,7 @@ type spec struct { env string boolean bool defaultVal string // default value for this option + dataname string // name of the data in help } // command represents a named subcommand, or the top-level command @@ -305,6 +306,8 @@ func cmdFromStruct(name string, dest path, t reflect.Type) (*command, error) { spec.required = true case key == "positional": spec.positional = true + case key == "dataname": + spec.dataname = value case key == "separate": spec.separate = true case key == "help": // deprecated @@ -342,6 +345,10 @@ func cmdFromStruct(name string, dest path, t reflect.Type) (*command, error) { } } + if spec.dataname == "" { + spec.dataname = strings.ToUpper(spec.long) + } + // Check whether this field is supported. It's good to do this here rather than // wait until ParseValue because it means that a program with invalid argument // fields will always fail regardless of whether the arguments it received diff --git a/usage.go b/usage.go index 43db703..372b77d 100644 --- a/usage.go +++ b/usage.go @@ -76,17 +76,16 @@ func (p *Parser) writeUsageForCommand(w io.Writer, cmd *command) { for _, spec := range positionals { // prefix with a space fmt.Fprint(w, " ") - up := strings.ToUpper(spec.long) if spec.multiple { if !spec.required { fmt.Fprint(w, "[") } - fmt.Fprintf(w, "%s [%s ...]", up, up) + fmt.Fprintf(w, "%s [%s ...]", spec.dataname, spec.dataname) if !spec.required { fmt.Fprint(w, "]") } } else { - fmt.Fprint(w, up) + fmt.Fprint(w, spec.dataname) } } fmt.Fprint(w, "\n") @@ -134,7 +133,7 @@ func (p *Parser) writeHelpForCommand(w io.Writer, cmd *command) { if len(positionals) > 0 { fmt.Fprint(w, "\nPositional arguments:\n") for _, spec := range positionals { - printTwoCols(w, strings.ToUpper(spec.long), spec.help, "") + printTwoCols(w, spec.dataname, spec.help, "") } } @@ -180,7 +179,7 @@ func synopsis(spec *spec, form string) string { if spec.boolean { return form } - return form + " " + strings.ToUpper(spec.long) + return form + " " + spec.dataname } func ptrTo(s string) *string {