command: hard wrap help message flags
Test / Create distribution (push) Successful in 53s
Test / Sandbox (push) Successful in 2m51s
Test / Hakurei (push) Successful in 4m29s
Test / Sandbox (race detector) (push) Successful in 5m53s
Test / Hakurei (race detector) (push) Successful in 7m2s
Test / ShareFS (push) Successful in 7m19s
Test / Flake checks (push) Successful in 1m8s
Test / Create distribution (push) Successful in 53s
Test / Sandbox (push) Successful in 2m51s
Test / Hakurei (push) Successful in 4m29s
Test / Sandbox (race detector) (push) Successful in 5m53s
Test / Hakurei (race detector) (push) Successful in 7m2s
Test / ShareFS (push) Successful in 7m19s
Test / Flake checks (push) Successful in 1m8s
This greatly improves readability when lots of flags are registered. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -19,10 +19,9 @@ func TestHelp(t *testing.T) {
|
|||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"main", []string{}, `
|
"main", []string{}, `usage: hakurei [-h | --help] [-v] [--insecure] [--json] <command> [<args>]
|
||||||
Usage: hakurei [-h | --help] [-v] [--insecure] [--json] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
run Load and start container from configuration file
|
run Load and start container from configuration file
|
||||||
exec Configure and start a permissive container
|
exec Configure and start a permissive container
|
||||||
show Show live or local instance configuration
|
show Show live or local instance configuration
|
||||||
@@ -35,10 +34,14 @@ Commands:
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"exec", []string{"exec", "-h"}, `
|
"exec", []string{"exec", "-h"}, `usage: hakurei exec [-h | --help] [--dbus-config <value>]
|
||||||
Usage: hakurei exec [-h | --help] [--dbus-config <value>] [--dbus-system <value>] [--mpris] [--dbus-log] [--id <value>] [-a <int>] [-g <value>] [-d <value>] [-u <value>] [--policy <value>] [--priority <int>] [--private-runtime] [--private-tmpdir] [--wayland] [-X] [--dbus] [--pipewire] [--pulse] COMMAND [OPTIONS]
|
[--dbus-system <value>] [--mpris] [--dbus-log]
|
||||||
|
[--id <value>] [-a <int>] [-g <value>] [-d <value>]
|
||||||
|
[-u <value>] [--policy <value>] [--priority <int>]
|
||||||
|
[--private-runtime] [--private-tmpdir] [--wayland] [-X]
|
||||||
|
[--dbus] [--pipewire] [--pulse] <command> [<args>]
|
||||||
|
|
||||||
Flags:
|
flags:
|
||||||
-X Enable direct connection to X11
|
-X Enable direct connection to X11
|
||||||
-a int
|
-a int
|
||||||
Application identity
|
Application identity
|
||||||
|
|||||||
+2
-2
@@ -23,8 +23,8 @@ func newNode(output io.Writer, logf LogFunc, name, usage string) *node {
|
|||||||
n.set.SetOutput(output)
|
n.set.SetOutput(output)
|
||||||
n.set.Usage = func() {
|
n.set.Usage = func() {
|
||||||
_ = n.writeHelp()
|
_ = n.writeHelp()
|
||||||
if n.suffix.Len() > 0 {
|
if len(n.suffix) > 0 {
|
||||||
_, _ = fmt.Fprintln(output, "Flags:")
|
_, _ = fmt.Fprintln(output, "flags:")
|
||||||
n.set.PrintDefaults()
|
n.set.PrintDefaults()
|
||||||
_, _ = fmt.Fprintln(output)
|
_, _ = fmt.Fprintln(output)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -16,7 +16,13 @@ func (e FlagError) Is(target error) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) Flag(p any, name string, value FlagDefiner, usage string) Node {
|
func (n *node) Flag(p any, name string, value FlagDefiner, usage string) Node {
|
||||||
value.Define(&n.suffix, n.set, p, name, usage)
|
var buf strings.Builder
|
||||||
|
value.Define(&buf, n.set, p, name, usage)
|
||||||
|
s := buf.String()
|
||||||
|
if len(s) > 0 && s[0] == ' ' {
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
|
n.suffix = append(n.suffix, s)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+21
-3
@@ -1,6 +1,7 @@
|
|||||||
package command
|
package command
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -13,14 +14,31 @@ var ErrHelp = errors.New("help requested")
|
|||||||
func (n *node) PrintHelp() { _ = n.writeHelp() }
|
func (n *node) PrintHelp() { _ = n.writeHelp() }
|
||||||
|
|
||||||
func (n *node) writeHelp() error {
|
func (n *node) writeHelp() error {
|
||||||
|
prefix := strings.Join(append(n.prefix, n.name), " ")
|
||||||
|
var buf strings.Builder
|
||||||
|
offset := 7 + len(prefix)
|
||||||
|
line := offset + 14
|
||||||
|
w := bytes.Repeat([]byte{' '}, offset+1)
|
||||||
|
w[0] = '\n'
|
||||||
|
|
||||||
|
for _, flag := range n.suffix {
|
||||||
|
line += len(flag) + 1
|
||||||
|
if line >= 80 {
|
||||||
|
line = offset + len(flag) + 1
|
||||||
|
buf.Write(w)
|
||||||
|
}
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
buf.WriteString(flag)
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := fmt.Fprintf(n.out,
|
if _, err := fmt.Fprintf(n.out,
|
||||||
"\nUsage:\t%s [-h | --help]%s COMMAND [OPTIONS]\n",
|
"usage: %s [-h | --help]%s <command> [<args>]\n",
|
||||||
strings.Join(append(n.prefix, n.name), " "), &n.suffix,
|
prefix, &buf,
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if n.child != nil {
|
if n.child != nil {
|
||||||
if _, err := fmt.Fprint(n.out, "\nCommands:\n"); err != nil {
|
if _, err := fmt.Fprint(n.out, "\ncommands:\n"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -3,7 +3,6 @@ package command
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// A node represents a command.
|
// A node represents a command.
|
||||||
@@ -17,7 +16,7 @@ type node struct {
|
|||||||
// Names of commands preceding node.
|
// Names of commands preceding node.
|
||||||
prefix []string
|
prefix []string
|
||||||
// Short user-facing representations of flags received by node.
|
// Short user-facing representations of flags received by node.
|
||||||
suffix strings.Builder
|
suffix []string
|
||||||
|
|
||||||
f HandlerFunc
|
f HandlerFunc
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
|
|||||||
+18
-22
@@ -70,7 +70,7 @@ func TestParse(t *testing.T) {
|
|||||||
"d=0 out of order string flag",
|
"d=0 out of order string flag",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"string", "--string", "64d3b4b7b21788585845060e2199a78f"},
|
[]string{"string", "--string", "64d3b4b7b21788585845060e2199a78f"},
|
||||||
"flag provided but not defined: -string\n\nUsage:\ttest string [-h | --help] COMMAND [OPTIONS]\n\n", "",
|
"flag provided but not defined: -string\nusage: test string [-h | --help] <command> [<args>]\n\n", "",
|
||||||
errors.New("flag provided but not defined: -string"),
|
errors.New("flag provided but not defined: -string"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -120,7 +120,7 @@ func TestParse(t *testing.T) {
|
|||||||
"d=1 empty sub help",
|
"d=1 empty sub help",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"empty", "-h"},
|
[]string{"empty", "-h"},
|
||||||
"\nUsage:\ttest empty [-h | --help] COMMAND [OPTIONS]\n\n", "", flag.ErrHelp,
|
"usage: test empty [-h | --help] <command> [<args>]\n\n", "", flag.ErrHelp,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"d=1 no match",
|
"d=1 no match",
|
||||||
@@ -151,10 +151,10 @@ func TestParse(t *testing.T) {
|
|||||||
"d=0 help",
|
"d=0 help",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{},
|
[]string{},
|
||||||
`
|
`usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>]
|
||||||
Usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>] [--repeat <value>] COMMAND [OPTIONS]
|
[--repeat <value>] <command> [<args>]
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
error return an error
|
error return an error
|
||||||
print wraps Fprint
|
print wraps Fprint
|
||||||
string print string passed by flag
|
string print string passed by flag
|
||||||
@@ -171,10 +171,10 @@ Commands:
|
|||||||
"d=0 help flag",
|
"d=0 help flag",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"-h"},
|
[]string{"-h"},
|
||||||
`
|
`usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>]
|
||||||
Usage: test [-h | --help] [-v] [--fail] [--string <value>] [--int <int>] [--repeat <value>] COMMAND [OPTIONS]
|
[--repeat <value>] <command> [<args>]
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
error return an error
|
error return an error
|
||||||
print wraps Fprint
|
print wraps Fprint
|
||||||
string print string passed by flag
|
string print string passed by flag
|
||||||
@@ -185,7 +185,7 @@ Commands:
|
|||||||
succeed this command succeeds
|
succeed this command succeeds
|
||||||
deep top level of command tree with various levels
|
deep top level of command tree with various levels
|
||||||
|
|
||||||
Flags:
|
flags:
|
||||||
-fail
|
-fail
|
||||||
fail early
|
fail early
|
||||||
-int int
|
-int int
|
||||||
@@ -203,10 +203,9 @@ Flags:
|
|||||||
"d=1 help",
|
"d=1 help",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"join"},
|
[]string{"join"},
|
||||||
`
|
`usage: test join [-h | --help] <command> [<args>]
|
||||||
Usage: test join [-h | --help] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
out write result to wout
|
out write result to wout
|
||||||
log log result to wlog
|
log log result to wlog
|
||||||
|
|
||||||
@@ -216,10 +215,9 @@ Commands:
|
|||||||
"d=1 help flag",
|
"d=1 help flag",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"join", "-h"},
|
[]string{"join", "-h"},
|
||||||
`
|
`usage: test join [-h | --help] <command> [<args>]
|
||||||
Usage: test join [-h | --help] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
out write result to wout
|
out write result to wout
|
||||||
log log result to wlog
|
log log result to wlog
|
||||||
|
|
||||||
@@ -230,10 +228,9 @@ Commands:
|
|||||||
"d=2 help",
|
"d=2 help",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"deep", "d=2"},
|
[]string{"deep", "d=2"},
|
||||||
`
|
`usage: test deep d=2 [-h | --help] <command> [<args>]
|
||||||
Usage: test deep d=2 [-h | --help] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
d=3 relative third level
|
d=3 relative third level
|
||||||
|
|
||||||
`, "", command.ErrHelp,
|
`, "", command.ErrHelp,
|
||||||
@@ -242,10 +239,9 @@ Commands:
|
|||||||
"d=2 help flag",
|
"d=2 help flag",
|
||||||
buildTestCommand,
|
buildTestCommand,
|
||||||
[]string{"deep", "d=2", "-h"},
|
[]string{"deep", "d=2", "-h"},
|
||||||
`
|
`usage: test deep d=2 [-h | --help] <command> [<args>]
|
||||||
Usage: test deep d=2 [-h | --help] COMMAND [OPTIONS]
|
|
||||||
|
|
||||||
Commands:
|
commands:
|
||||||
d=3 relative third level
|
d=3 relative third level
|
||||||
|
|
||||||
`, "", flag.ErrHelp,
|
`, "", flag.ErrHelp,
|
||||||
@@ -261,7 +257,7 @@ Commands:
|
|||||||
t.Errorf("Parse: error = %v; wantErr %v", err, tc.wantErr)
|
t.Errorf("Parse: error = %v; wantErr %v", err, tc.wantErr)
|
||||||
}
|
}
|
||||||
if got := wout.String(); got != tc.want {
|
if got := wout.String(); got != tc.want {
|
||||||
t.Errorf("Parse: %s want %s", got, tc.want)
|
t.Errorf("Parse:\n%s\nwant\n%s", got, tc.want)
|
||||||
}
|
}
|
||||||
if gotLog := wlog.String(); gotLog != tc.wantLog {
|
if gotLog := wlog.String(); gotLog != tc.wantLog {
|
||||||
t.Errorf("Parse: log = %s wantLog %s", gotLog, tc.wantLog)
|
t.Errorf("Parse: log = %s wantLog %s", gotLog, tc.wantLog)
|
||||||
|
|||||||
Reference in New Issue
Block a user