This commit is contained in:
21
app.go
21
app.go
@@ -28,7 +28,7 @@ func WithInput(in config.BindProvider) func(*App) {
|
|||||||
|
|
||||||
// WithSkipArgs sets how many arguments are passed. For example, you don't need to pass the name of a single command.
|
// WithSkipArgs sets how many arguments are passed. For example, you don't need to pass the name of a single command.
|
||||||
func WithSkipArgs(l int) func(*App) {
|
func WithSkipArgs(l int) func(*App) {
|
||||||
return WithInput(chain.New(arg.New(arg.WithSkip(l)), &memory.Default{}))
|
return WithInput(chain.New(arg.New(arg.WithArgs(os.Args[resolveSkip(l):])), &memory.Default{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithExit sets exit callback by default os.Exit.
|
// WithExit sets exit callback by default os.Exit.
|
||||||
@@ -43,7 +43,7 @@ func New(opts ...func(*App)) *App {
|
|||||||
app := &App{
|
app := &App{
|
||||||
out: output.Stdout(),
|
out: output.Stdout(),
|
||||||
exit: os.Exit,
|
exit: os.Exit,
|
||||||
in: chain.New(arg.New(arg.WithSkip(0)), &memory.Default{}),
|
in: chain.New(arg.New(arg.WithArgs(os.Args[resolveSkip(0):])), &memory.Default{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
@@ -125,3 +125,20 @@ func (a *App) list(ctx context.Context) error {
|
|||||||
func (a *App) printError(ctx context.Context, err error) {
|
func (a *App) printError(ctx context.Context, err error) {
|
||||||
ansi(ctx, a.in, a.out).Println(ctx, "<error>\n\n ", err, "\n</error>")
|
ansi(ctx, a.in, a.out).Println(ctx, "<error>\n\n ", err, "\n</error>")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resolveSkip(in int) int {
|
||||||
|
res := 2
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case in > 0 && len(os.Args) > in:
|
||||||
|
res = in
|
||||||
|
case in > 0:
|
||||||
|
res = len(os.Args)
|
||||||
|
case len(os.Args) == 1:
|
||||||
|
res = 1
|
||||||
|
case len(os.Args) > 1 && os.Args[1][0] == '-':
|
||||||
|
res = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|||||||
28
app_test.go
28
app_test.go
@@ -30,21 +30,21 @@ func ExampleNew_help() {
|
|||||||
// test:command [options] [--] [<test_argument>]
|
// test:command [options] [--] [<test_argument>]
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// test_argument test argument
|
// test_argument test argument
|
||||||
//
|
//
|
||||||
// Options:
|
// Options:
|
||||||
// --string[=STRING] array string (multiple values allowed)
|
// --string[=STRING] array string (multiple values allowed)
|
||||||
// --group-bool bool
|
// --group-bool bool
|
||||||
// --group-test-string[=GROUP-TEST-STRING] test group string [default: group string default value]
|
// --group-test-string[=GROUP-TEST-STRING] test group string [default:group string default value]
|
||||||
// --log-{service}-level[=LOG-{SERVICE}-LEVEL] service level [default: debug]
|
// --log-{service}-level[=LOG-{SERVICE}-LEVEL] service level [default:debug]
|
||||||
// --bool test bool option
|
// --bool test bool option
|
||||||
// --duration[=DURATION] test duration with default [default: 1s]
|
// --duration[=DURATION] test duration with default
|
||||||
// --ansi Do not ask any interactive question
|
// --ansi Do not ask any interactive question
|
||||||
// -V, --version Display this application version
|
// -V, --version Display this application version
|
||||||
// -h, --help Display this help message
|
// -h, --help Display this help message
|
||||||
// -v, --verbose Increase the verbosity of messages: -v for info output, -vv for debug and -vvv for trace (multiple values allowed)
|
// -v, --verbose Increase the verbosity of messages: -v for info output, -vv for debug and -vvv for trace (multiple values allowed)
|
||||||
// -q, --quiet Do not output any message
|
// -q, --quiet Do not output any message
|
||||||
// --no-ansi Disable ANSI output
|
// --no-ansi Disable ANSI output
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExampleNew_list() {
|
func ExampleNew_list() {
|
||||||
@@ -81,7 +81,7 @@ func ExampleNew_list() {
|
|||||||
// --ansi Do not ask any interactive question
|
// --ansi Do not ask any interactive question
|
||||||
// -V, --version Display this application version
|
// -V, --version Display this application version
|
||||||
// -h, --help Display this help message
|
// -h, --help Display this help message
|
||||||
// -v, --verbose Increase the verbosity of messages: -v for info output, -vv for debug and -vvv for trace (multiple values allowed)
|
// -v, --verbose Increase the verbosity of messages: -v for info output, -vv for debug and -vvv for trace (multiple values allowed)
|
||||||
// -q, --quiet Do not output any message
|
// -q, --quiet Do not output any message
|
||||||
//
|
//
|
||||||
// Available commands:
|
// Available commands:
|
||||||
|
|||||||
4
go.mod
4
go.mod
@@ -2,7 +2,9 @@ module gitoa.ru/go-4devs/console
|
|||||||
|
|
||||||
go 1.24.0
|
go 1.24.0
|
||||||
|
|
||||||
require gitoa.ru/go-4devs/config v0.0.7
|
require gitoa.ru/go-4devs/config v0.0.8
|
||||||
|
|
||||||
|
replace gitoa.ru/go-4devs/config => ../config
|
||||||
|
|
||||||
require (
|
require (
|
||||||
golang.org/x/mod v0.31.0 // indirect
|
golang.org/x/mod v0.31.0 // indirect
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -1,12 +1,8 @@
|
|||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
gitoa.ru/go-4devs/config v0.0.7 h1:8q6axRNLgXE5dYQd8Jbh9j+STqevbibVyvwrtsuHpZk=
|
|
||||||
gitoa.ru/go-4devs/config v0.0.7/go.mod h1:UINWnObZA0nLiJro+TtavUBBvN0cSt17aRHOk20pP74=
|
|
||||||
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
|
golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
|
||||||
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
|
golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
|
||||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
|
||||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
|
||||||
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
|
golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA=
|
||||||
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
|
golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc=
|
||||||
|
|||||||
3
help.go
3
help.go
@@ -9,6 +9,7 @@ import (
|
|||||||
"gitoa.ru/go-4devs/config"
|
"gitoa.ru/go-4devs/config"
|
||||||
"gitoa.ru/go-4devs/config/definition"
|
"gitoa.ru/go-4devs/config/definition"
|
||||||
"gitoa.ru/go-4devs/config/definition/option"
|
"gitoa.ru/go-4devs/config/definition/option"
|
||||||
|
"gitoa.ru/go-4devs/config/param"
|
||||||
"gitoa.ru/go-4devs/config/provider/arg"
|
"gitoa.ru/go-4devs/config/provider/arg"
|
||||||
"gitoa.ru/go-4devs/config/validator"
|
"gitoa.ru/go-4devs/config/validator"
|
||||||
"gitoa.ru/go-4devs/config/value"
|
"gitoa.ru/go-4devs/config/value"
|
||||||
@@ -70,7 +71,7 @@ To display the list of available commands, please use the <info>list</info> comm
|
|||||||
Name: cmd.Name,
|
Name: cmd.Name,
|
||||||
Description: cmd.Description,
|
Description: cmd.Description,
|
||||||
Help: cmd.Help,
|
Help: cmd.Help,
|
||||||
Definition: descriptor.NewDefinition(config.NewVars(def.Options()...).Variables()),
|
Options: def.With(param.New(descriptor.TxtStyle())),
|
||||||
})
|
})
|
||||||
if derr != nil {
|
if derr != nil {
|
||||||
return fmt.Errorf("descriptor help:%w", derr)
|
return fmt.Errorf("descriptor help:%w", derr)
|
||||||
|
|||||||
5
list.go
5
list.go
@@ -8,6 +8,7 @@ import (
|
|||||||
"gitoa.ru/go-4devs/config"
|
"gitoa.ru/go-4devs/config"
|
||||||
"gitoa.ru/go-4devs/config/definition"
|
"gitoa.ru/go-4devs/config/definition"
|
||||||
"gitoa.ru/go-4devs/config/definition/option"
|
"gitoa.ru/go-4devs/config/definition/option"
|
||||||
|
"gitoa.ru/go-4devs/config/param"
|
||||||
"gitoa.ru/go-4devs/config/provider/arg"
|
"gitoa.ru/go-4devs/config/provider/arg"
|
||||||
"gitoa.ru/go-4devs/config/validator"
|
"gitoa.ru/go-4devs/config/validator"
|
||||||
"gitoa.ru/go-4devs/config/value"
|
"gitoa.ru/go-4devs/config/value"
|
||||||
@@ -71,8 +72,8 @@ func executeList(ctx context.Context, in config.Provider, out output.Output) err
|
|||||||
|
|
||||||
cmds := Commands()
|
cmds := Commands()
|
||||||
commands := descriptor.Commands{
|
commands := descriptor.Commands{
|
||||||
Namespace: ns,
|
Namespace: ns,
|
||||||
Definition: descriptor.NewDefinition(config.NewVars(definition.New(Default()...).Options()...).Variables()),
|
Options: definition.New(Default()...).With(param.New(descriptor.TxtStyle())),
|
||||||
}
|
}
|
||||||
groups := make(map[string]*descriptor.NSCommand)
|
groups := make(map[string]*descriptor.NSCommand)
|
||||||
namespaces := make([]string, 0, len(cmds))
|
namespaces := make([]string, 0, len(cmds))
|
||||||
|
|||||||
@@ -3,13 +3,9 @@ package descriptor
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"gitoa.ru/go-4devs/config"
|
"gitoa.ru/go-4devs/config"
|
||||||
"gitoa.ru/go-4devs/config/definition/option"
|
|
||||||
"gitoa.ru/go-4devs/config/provider/arg"
|
|
||||||
"gitoa.ru/go-4devs/console/output"
|
"gitoa.ru/go-4devs/console/output"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -24,17 +20,19 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Command struct {
|
type Command struct {
|
||||||
|
config.Options
|
||||||
|
|
||||||
Bin string
|
Bin string
|
||||||
Name string
|
Name string
|
||||||
Description string
|
Description string
|
||||||
Help string
|
Help string
|
||||||
Definition Definition
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Commands struct {
|
type Commands struct {
|
||||||
Namespace string
|
config.Options
|
||||||
Definition Definition
|
|
||||||
Commands []NSCommand
|
Namespace string
|
||||||
|
Commands []NSCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
type NSCommand struct {
|
type NSCommand struct {
|
||||||
@@ -46,65 +44,6 @@ func (n *NSCommand) Append(name, desc string) {
|
|||||||
n.Commands = append(n.Commands, ShortCommand{Name: name, Description: desc})
|
n.Commands = append(n.Commands, ShortCommand{Name: name, Description: desc})
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefinition(opts []config.Variable) Definition {
|
|
||||||
type data struct {
|
|
||||||
name string
|
|
||||||
pos uint64
|
|
||||||
opt config.Variable
|
|
||||||
}
|
|
||||||
|
|
||||||
posArgs := make([]data, 0, len(opts))
|
|
||||||
|
|
||||||
posOpt := make([]data, 0, len(opts))
|
|
||||||
for _, opt := range opts {
|
|
||||||
pos, ok := arg.ParamArgument(opt)
|
|
||||||
if !ok {
|
|
||||||
pos, _ = option.DataPosition(opt)
|
|
||||||
posOpt = append(posOpt, data{pos: pos, opt: opt})
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
posArgs = append(posArgs, data{name: strings.Join(opt.Key(), "."), pos: pos, opt: opt})
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Slice(posArgs, func(i, j int) bool {
|
|
||||||
return posArgs[i].pos > posArgs[j].pos && posArgs[i].name > posArgs[j].name
|
|
||||||
})
|
|
||||||
|
|
||||||
sort.Slice(posOpt, func(i, j int) bool {
|
|
||||||
return posOpt[i].pos < posOpt[j].pos
|
|
||||||
})
|
|
||||||
|
|
||||||
args := make([]config.Variable, len(posArgs))
|
|
||||||
for idx := range posArgs {
|
|
||||||
args[idx] = posArgs[idx].opt
|
|
||||||
}
|
|
||||||
|
|
||||||
options := make([]config.Variable, len(posOpt))
|
|
||||||
for idx := range posOpt {
|
|
||||||
options[idx] = posOpt[idx].opt
|
|
||||||
}
|
|
||||||
|
|
||||||
return Definition{
|
|
||||||
options: options,
|
|
||||||
args: args,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Definition struct {
|
|
||||||
args []config.Variable
|
|
||||||
options []config.Variable
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d Definition) Arguments() []config.Variable {
|
|
||||||
return d.args
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d Definition) Options() []config.Variable {
|
|
||||||
return d.options
|
|
||||||
}
|
|
||||||
|
|
||||||
type ShortCommand struct {
|
type ShortCommand struct {
|
||||||
Name string
|
Name string
|
||||||
Description string
|
Description string
|
||||||
|
|||||||
@@ -4,21 +4,18 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
|
||||||
|
|
||||||
"gitoa.ru/go-4devs/config"
|
"gitoa.ru/go-4devs/config"
|
||||||
"gitoa.ru/go-4devs/config/definition/option"
|
"gitoa.ru/go-4devs/config/definition/option"
|
||||||
"gitoa.ru/go-4devs/config/param"
|
"gitoa.ru/go-4devs/config/param"
|
||||||
"gitoa.ru/go-4devs/config/value"
|
"gitoa.ru/go-4devs/config/provider/arg"
|
||||||
"gitoa.ru/go-4devs/console/output"
|
"gitoa.ru/go-4devs/console/output"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultSpace = 2
|
defaultSpace = 2
|
||||||
infoLen = 13
|
|
||||||
dashDelimiter = "-"
|
dashDelimiter = "-"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,8 +37,8 @@ var (
|
|||||||
|
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
<comment>Usage:</comment>
|
<comment>Usage:</comment>
|
||||||
{{ .Name }} {{ synopsis .Definition }}
|
{{ .Name }} {{ synopsis .Options }}
|
||||||
{{- definition .Definition }}
|
{{ definition .Options }}
|
||||||
{{- help . }}
|
{{- help . }}
|
||||||
`))
|
`))
|
||||||
|
|
||||||
@@ -49,11 +46,24 @@ var (
|
|||||||
Funcs(txtFunc).
|
Funcs(txtFunc).
|
||||||
Parse(`<comment>Usage:</comment>
|
Parse(`<comment>Usage:</comment>
|
||||||
command [options] [arguments]
|
command [options] [arguments]
|
||||||
{{- definition .Definition }}
|
{{ definition .Options }}
|
||||||
{{- commands .Commands -}}
|
{{- commands .Commands -}}
|
||||||
`))
|
`))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TxtStyle() param.Option {
|
||||||
|
return arg.WithStyle(
|
||||||
|
arg.Style{
|
||||||
|
Start: "<comment>",
|
||||||
|
End: "</comment>",
|
||||||
|
},
|
||||||
|
arg.Style{
|
||||||
|
Start: "<info>",
|
||||||
|
End: "</info>",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
type txt struct{}
|
type txt struct{}
|
||||||
|
|
||||||
func (t *txt) Command(ctx context.Context, out output.Output, cmd Command) error {
|
func (t *txt) Command(ctx context.Context, out output.Output, cmd Command) error {
|
||||||
@@ -82,54 +92,6 @@ func (t *txt) Commands(ctx context.Context, out output.Output, cmds Commands) er
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func txtDefaultArray(val config.Value) string {
|
|
||||||
var st any
|
|
||||||
|
|
||||||
err := val.Unmarshal(&st)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%v", st)
|
|
||||||
}
|
|
||||||
|
|
||||||
//nolint:cyclop
|
|
||||||
func txtDefault(val config.Value, vr config.Variable) []byte {
|
|
||||||
var buf bytes.Buffer
|
|
||||||
|
|
||||||
buf.WriteString("<comment> [default: ")
|
|
||||||
|
|
||||||
dataType := param.Type(vr)
|
|
||||||
if option.IsSlice(vr) {
|
|
||||||
buf.WriteString(txtDefaultArray(val))
|
|
||||||
} else {
|
|
||||||
switch dataType.(type) {
|
|
||||||
case int:
|
|
||||||
buf.WriteString(strconv.Itoa(val.Int()))
|
|
||||||
case int64:
|
|
||||||
buf.WriteString(strconv.FormatInt(val.Int64(), 10))
|
|
||||||
case uint:
|
|
||||||
buf.WriteString(strconv.FormatUint(uint64(val.Uint()), 10))
|
|
||||||
case uint64:
|
|
||||||
buf.WriteString(strconv.FormatUint(val.Uint64(), 10))
|
|
||||||
case float64:
|
|
||||||
buf.WriteString(strconv.FormatFloat(val.Float64(), 'g', -1, 64))
|
|
||||||
case time.Duration:
|
|
||||||
buf.WriteString(val.Duration().String())
|
|
||||||
case time.Time:
|
|
||||||
buf.WriteString(val.Time().Format(time.RFC3339))
|
|
||||||
case string:
|
|
||||||
buf.WriteString(val.String())
|
|
||||||
default:
|
|
||||||
buf.WriteString(fmt.Sprint(val.Any()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("]</comment>")
|
|
||||||
|
|
||||||
return buf.Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
func txtCommands(cmds []NSCommand) string {
|
func txtCommands(cmds []NSCommand) string {
|
||||||
width := commandsTotalWidth(cmds)
|
width := commandsTotalWidth(cmds)
|
||||||
showNS := len(cmds) > 1
|
showNS := len(cmds) > 1
|
||||||
@@ -181,95 +143,20 @@ func txtHelp(cmd Command) string {
|
|||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func txtDefinitionOption(maxLen int, opts ...config.Variable) string {
|
func txtDefinition(options config.Options) string {
|
||||||
buf := bytes.Buffer{}
|
|
||||||
buf.WriteString("\n\n<comment>Options:</comment>\n")
|
|
||||||
|
|
||||||
for _, opt := range opts {
|
|
||||||
if option.IsHidden(opt) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var op bytes.Buffer
|
|
||||||
|
|
||||||
op.WriteString(" <info>")
|
|
||||||
|
|
||||||
if short, ok := option.ParamShort(opt); ok {
|
|
||||||
op.WriteString("-")
|
|
||||||
op.WriteString(short)
|
|
||||||
op.WriteString(", ")
|
|
||||||
} else {
|
|
||||||
op.WriteString(" ")
|
|
||||||
}
|
|
||||||
|
|
||||||
op.WriteString("--")
|
|
||||||
op.WriteString(strings.Join(opt.Key(), dashDelimiter))
|
|
||||||
|
|
||||||
if !option.IsBool(opt) {
|
|
||||||
if !option.IsRequired(opt) {
|
|
||||||
op.WriteString("[")
|
|
||||||
}
|
|
||||||
|
|
||||||
op.WriteString("=")
|
|
||||||
op.WriteString(strings.ToUpper(strings.Join(opt.Key(), dashDelimiter)))
|
|
||||||
|
|
||||||
if !option.IsRequired(opt) {
|
|
||||||
op.WriteString("]")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
op.WriteString("</info>")
|
|
||||||
buf.Write(op.Bytes())
|
|
||||||
buf.WriteString(strings.Repeat(" ", maxLen+17-op.Len()))
|
|
||||||
buf.WriteString(option.DataDescription(opt))
|
|
||||||
|
|
||||||
if data, ok := option.DataDefaut(opt); ok {
|
|
||||||
buf.Write(txtDefault(value.New(data), opt))
|
|
||||||
}
|
|
||||||
|
|
||||||
if option.IsSlice(opt) {
|
|
||||||
buf.WriteString("<comment> (multiple values allowed)</comment>")
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.WriteString("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func txtDefinition(def Definition) string {
|
|
||||||
width := totalWidth(def)
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
if args := def.Arguments(); len(args) > 0 {
|
err := arg.NewDump().Reference(&buf, options)
|
||||||
buf.WriteString("\n\n<comment>Arguments:</comment>\n")
|
if err != nil {
|
||||||
|
return err.Error()
|
||||||
for _, arg := range args {
|
|
||||||
var ab bytes.Buffer
|
|
||||||
|
|
||||||
ab.WriteString(" <info>")
|
|
||||||
ab.WriteString(strings.Join(arg.Key(), dashDelimiter))
|
|
||||||
ab.WriteString("</info>")
|
|
||||||
ab.WriteString(strings.Repeat(" ", width+infoLen+defaultSpace-ab.Len()))
|
|
||||||
|
|
||||||
buf.Write(ab.Bytes())
|
|
||||||
buf.WriteString(option.DataDescription(arg))
|
|
||||||
|
|
||||||
if data, ok := option.DataDefaut(arg); ok {
|
|
||||||
buf.Write(txtDefault(value.New(data), arg))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts := def.Options(); len(opts) > 0 {
|
|
||||||
buf.WriteString(txtDefinitionOption(width, opts...))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func txtSynopsis(def Definition) string {
|
func txtSynopsis(options config.Options) string {
|
||||||
|
def := arg.NewViews(options, nil)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
if len(def.Options()) > 0 {
|
if len(def.Options()) > 0 {
|
||||||
@@ -294,7 +181,7 @@ func txtSynopsis(def Definition) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf.WriteString("<")
|
buf.WriteString("<")
|
||||||
buf.WriteString(strings.Join(arg.Key(), dashDelimiter))
|
buf.WriteString(arg.Name(dashDelimiter))
|
||||||
buf.WriteString(">")
|
buf.WriteString(">")
|
||||||
|
|
||||||
if option.IsSlice(arg) {
|
if option.IsSlice(arg) {
|
||||||
@@ -320,32 +207,3 @@ func commandsTotalWidth(cmds []NSCommand) int {
|
|||||||
|
|
||||||
return width
|
return width
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:mnd
|
|
||||||
func totalWidth(def Definition) int {
|
|
||||||
var width int
|
|
||||||
|
|
||||||
for _, arg := range def.Arguments() {
|
|
||||||
if l := len(strings.Join(arg.Key(), dashDelimiter)); l > width {
|
|
||||||
width = l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, opt := range def.Options() {
|
|
||||||
current := len(strings.Join(opt.Key(), dashDelimiter)) + 6
|
|
||||||
|
|
||||||
if !option.IsBool(opt) {
|
|
||||||
current = current*2 + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := option.DataDefaut(opt); ok {
|
|
||||||
current += 2
|
|
||||||
}
|
|
||||||
|
|
||||||
if current > width {
|
|
||||||
width = current
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return width
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user