From 387756bc34c8cae9f5bc4a48527511a46f9821e5 Mon Sep 17 00:00:00 2001 From: Tom Fleet Date: Fri, 3 Jan 2025 17:03:10 +0000 Subject: [PATCH] `cli.Short` and `cli.Long` now strip leading and trailing whitespace (#120) --- .typos.toml | 2 ++ Taskfile.yml | 8 ++++++++ command_test.go | 12 +++++++++++- internal/flag/flag.go | 4 ++-- option.go | 9 +++++++-- ...default.short.snap.txt => default_short.snap.txt} | 0 .../full_description_strip_whitespace.snap.txt | 9 +++++++++ 7 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 .typos.toml rename testdata/snapshots/TestHelp/{default.short.snap.txt => default_short.snap.txt} (100%) create mode 100644 testdata/snapshots/TestHelp/full_description_strip_whitespace.snap.txt diff --git a/.typos.toml b/.typos.toml new file mode 100644 index 0000000..66269af --- /dev/null +++ b/.typos.toml @@ -0,0 +1,2 @@ +[default.extend-words] +byt = "byt" # Useful name as byte is a keyword in go diff --git a/Taskfile.yml b/Taskfile.yml index d80d3ea..43170de 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -61,8 +61,16 @@ tasks: - sh: command -v nilaway msg: nilaway not installed, see https://github.com/uber-go/nilaway + + - sh: command -v betteralign + msg: requires betteralign, run `go install github.com/dkorunic/betteralign/cmd/betteralign@latest` + + - sh: command -v typos + msg: requires typos-cli, run `brew install typos-cli` cmds: + - betteralign -test_files -apply ./... - golangci-lint run --fix + - typos - nilaway ./... docs: diff --git a/command_test.go b/command_test.go index bc3932d..bd164f4 100644 --- a/command_test.go +++ b/command_test.go @@ -415,7 +415,7 @@ func TestHelp(t *testing.T) { wantErr: false, }, { - name: "default.short", + name: "default short", options: []cli.Option{ cli.OverrideArgs([]string{"-h"}), cli.Run(func(cmd *cli.Command, args []string) error { return nil }), @@ -463,6 +463,16 @@ func TestHelp(t *testing.T) { }, wantErr: false, }, + { + name: "full description strip whitespace", + options: []cli.Option{ + cli.OverrideArgs([]string{"--help"}), + cli.Short(" \t\n A cool CLI to do things \n "), + cli.Long(" \t\n\n A longer, probably multiline description \t\n\n "), + cli.Run(func(cmd *cli.Command, args []string) error { return nil }), + }, + wantErr: false, + }, { name: "with no description", options: []cli.Option{ diff --git a/internal/flag/flag.go b/internal/flag/flag.go index 724f1f1..ea1348f 100644 --- a/internal/flag/flag.go +++ b/internal/flag/flag.go @@ -424,7 +424,7 @@ type signed interface { ~int | ~int8 | ~int16 | ~int32 | ~int64 } -// unsigned is the same as constraints.Unsigned but we don't hve to depend +// unsigned is the same as constraints.Unsigned but we don't have to depend // on golang/x/exp. type unsigned interface { ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr @@ -456,7 +456,7 @@ func cast[T2 any, T1 any](v *T1) *T2 { // validateFlagName ensures a flag name is valid, returning an error if it's not. // -// Flags names must be all lower case ASCII letters, a hypen separator is allowed e.g. "set-default" +// Flags names must be all lower case ASCII letters, a hyphen separator is allowed e.g. "set-default" // but this must be in between letters, not leading or trailing. func validateFlagName(name string) error { if name == "" { diff --git a/option.go b/option.go index 344b03e..92c465c 100644 --- a/option.go +++ b/option.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "slices" + "strings" "github.com/FollowTheProcess/cli/internal/flag" ) @@ -162,6 +163,8 @@ func Stderr(stderr io.Writer) Option { // The one line usage will appear in the help text as well as alongside // subcommands when they are listed. // +// For consistency of formatting, all leading and trailing whitespace is stripped. +// // Successive calls will simply overwrite any previous calls. // // cli.New("rm", cli.Short("Delete files and directories")) @@ -170,7 +173,7 @@ func Short(short string) Option { if short == "" { return errors.New("cannot set command short description to an empty string") } - cfg.short = short + cfg.short = strings.TrimSpace(short) return nil } return option(f) @@ -181,6 +184,8 @@ func Short(short string) Option { // The long description will appear in the help text for a command. Users // are responsible for wrapping the text at a sensible width. // +// For consistency of formatting, all leading and trailing whitespace is stripped. +// // Successive calls will simply overwrite any previous calls. // // cli.New("rm", cli.Long("... lots of text here")) @@ -189,7 +194,7 @@ func Long(long string) Option { if long == "" { return errors.New("cannot set command long description to an empty string") } - cfg.long = long + cfg.long = strings.TrimSpace(long) return nil } return option(f) diff --git a/testdata/snapshots/TestHelp/default.short.snap.txt b/testdata/snapshots/TestHelp/default_short.snap.txt similarity index 100% rename from testdata/snapshots/TestHelp/default.short.snap.txt rename to testdata/snapshots/TestHelp/default_short.snap.txt diff --git a/testdata/snapshots/TestHelp/full_description_strip_whitespace.snap.txt b/testdata/snapshots/TestHelp/full_description_strip_whitespace.snap.txt new file mode 100644 index 0000000..78efc0a --- /dev/null +++ b/testdata/snapshots/TestHelp/full_description_strip_whitespace.snap.txt @@ -0,0 +1,9 @@ +A cool CLI to do things + +A longer, probably multiline description + +Usage: test [OPTIONS] ARGS... + +Options: + -h --help bool Show help for test + -V --version bool Show version info for test