This commit is contained in:
15
app.go
15
app.go
@@ -33,7 +33,10 @@ 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.
|
||||
func WithSkipArgs(l int) func(*App) {
|
||||
return WithInput(chain.New(arg.New(arg.WithArgs(os.Args[resolveSkip(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.
|
||||
@@ -53,7 +56,7 @@ func New(opts ...func(*App)) *App {
|
||||
out: output.Stdout(),
|
||||
exit: os.Exit,
|
||||
in: chain.New(
|
||||
arg.New(arg.WithArgs(os.Args[resolveSkip(0):])),
|
||||
arg.New(arg.WithArgs(os.Args[ResolveSkip(0):])),
|
||||
&memory.Default{},
|
||||
),
|
||||
registry: registry.Add,
|
||||
@@ -134,10 +137,14 @@ func (a *App) list(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (a *App) printError(ctx context.Context, err error) {
|
||||
command.Ansi(ctx, a.in, a.out).Println(ctx, "<error>\n\n ", err, "\n</error>")
|
||||
printErr(ctx, a.in, a.out, err)
|
||||
}
|
||||
|
||||
func resolveSkip(in int) int {
|
||||
func printErr(ctx context.Context, in config.Provider, out output.Output, err error) {
|
||||
command.Ansi(ctx, in, out).Printf(ctx, "<error>\n\n %v\n</error>\n", err)
|
||||
}
|
||||
|
||||
func ResolveSkip(in int) int {
|
||||
res := 2
|
||||
|
||||
switch {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/console/command"
|
||||
"gitoa.ru/go-4devs/console/errors"
|
||||
"gitoa.ru/go-4devs/console/errs"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
)
|
||||
|
||||
@@ -115,7 +115,7 @@ func (c *Command) With(opts ...Option) *Command {
|
||||
// Run run command with input and output.
|
||||
func (c *Command) Run(ctx context.Context, in config.Provider, out output.Output) error {
|
||||
if c.Execute == nil {
|
||||
return fmt.Errorf("%w", errors.ErrExecuteNil)
|
||||
return fmt.Errorf("%w", errs.ErrExecuteNil)
|
||||
}
|
||||
|
||||
if c.Handle != nil {
|
||||
|
||||
@@ -3,11 +3,10 @@ package command
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
"gitoa.ru/go-4devs/console/param"
|
||||
"gitoa.ru/go-4devs/console/setting"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -27,17 +26,17 @@ func Configure(fn ConfigureFn) Option {
|
||||
|
||||
func Version(in string) Option {
|
||||
return func(c *Command) {
|
||||
c.Params = param.WithVersion(in)(c.Params)
|
||||
c.Setting = setting.WithVersion(in)(c.Setting)
|
||||
}
|
||||
}
|
||||
|
||||
func Hidden(c *Command) {
|
||||
c.Params = param.Hidden(c.Params)
|
||||
c.Setting = setting.Hidden(c.Setting)
|
||||
}
|
||||
|
||||
func Help(fn param.HelpFn) Option {
|
||||
func Help(fn setting.HelpFn) Option {
|
||||
return func(c *Command) {
|
||||
c.Params = param.WithHelp(fn)(c.Params)
|
||||
c.Setting = setting.WithHelp(fn)(c.Setting)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +60,18 @@ func Prepare(fn PrepareFn) Option {
|
||||
}
|
||||
}
|
||||
|
||||
func Usage(fn setting.UsageFn) Option {
|
||||
return func(c *Command) {
|
||||
c.Setting = setting.WithUsage(fn)(c.Setting)
|
||||
}
|
||||
}
|
||||
|
||||
func EmptyUsage(cmd *Command) {
|
||||
cmd.Setting = setting.WithUsage(func(setting.UData) (string, error) {
|
||||
return "", nil
|
||||
})(cmd.Setting)
|
||||
}
|
||||
|
||||
func New(name, desc string, execute ExecuteFn, opts ...Option) Command {
|
||||
cmd := Command{
|
||||
name: name,
|
||||
@@ -68,7 +79,7 @@ func New(name, desc string, execute ExecuteFn, opts ...Option) Command {
|
||||
configure: emptyConfigure,
|
||||
handle: emptyHandle,
|
||||
prepare: emptyPrepare,
|
||||
Params: param.New(param.WithDescription(desc)),
|
||||
Setting: setting.New(setting.WithDescription(desc)),
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
@@ -79,7 +90,7 @@ func New(name, desc string, execute ExecuteFn, opts ...Option) Command {
|
||||
}
|
||||
|
||||
type Command struct {
|
||||
param.Params
|
||||
setting.Setting
|
||||
|
||||
name string
|
||||
execute ExecuteFn
|
||||
@@ -109,13 +120,12 @@ func (c Command) IsZero() bool {
|
||||
}
|
||||
|
||||
func (c Command) String() string {
|
||||
return fmt.Sprintf("command:%v, version:%v", c.Name(), param.Version(c))
|
||||
return fmt.Sprintf("command:%v, version:%v", c.Name(), setting.Version(c))
|
||||
}
|
||||
|
||||
func With(parent Command, opts ...Option) Command {
|
||||
log.Print(parent.Name())
|
||||
cmd := Command{
|
||||
Params: parent.Params,
|
||||
Setting: parent.Setting,
|
||||
name: parent.Name(),
|
||||
execute: parent.Execute,
|
||||
configure: parent.Configure,
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
cerr "gitoa.ru/go-4devs/console/errors"
|
||||
"gitoa.ru/go-4devs/console/param"
|
||||
"gitoa.ru/go-4devs/console/errs"
|
||||
"gitoa.ru/go-4devs/console/setting"
|
||||
)
|
||||
|
||||
var findCommand = regexp.MustCompile("([^:]+|)")
|
||||
@@ -71,7 +71,7 @@ func (c *Commands) find(name string) (Command, error) {
|
||||
}
|
||||
|
||||
for name, idx := range c.names {
|
||||
if cmdRegexp.MatchString(name) && !param.IsHidden(c.cmds[idx]) {
|
||||
if cmdRegexp.MatchString(name) && !setting.IsHidden(c.cmds[idx]) {
|
||||
findCommands = append(findCommands, c.cmds[idx])
|
||||
}
|
||||
}
|
||||
@@ -86,10 +86,10 @@ func (c *Commands) find(name string) (Command, error) {
|
||||
names[i] = findCommands[i].Name()
|
||||
}
|
||||
|
||||
return Command{}, cerr.AlternativesError{Alt: names, Err: cerr.ErrCommandDplicate}
|
||||
return Command{}, errs.AlternativesError{Alt: names, Err: errs.ErrCommandDplicate}
|
||||
}
|
||||
|
||||
return Command{}, fmt.Errorf("%w", cerr.ErrNotFound)
|
||||
return Command{}, fmt.Errorf("%w", errs.ErrNotFound)
|
||||
}
|
||||
|
||||
func (c *Commands) set(cmds ...Command) error {
|
||||
@@ -99,7 +99,7 @@ func (c *Commands) set(cmds ...Command) error {
|
||||
|
||||
for _, cmd := range cmds {
|
||||
if cmd.IsZero() {
|
||||
return fmt.Errorf("command:%w", cerr.ErrCommandNil)
|
||||
return fmt.Errorf("command:%w", errs.ErrCommandNil)
|
||||
}
|
||||
|
||||
if idx, ok := c.names[cmd.Name()]; ok {
|
||||
@@ -122,11 +122,11 @@ func (c *Commands) add(cmds ...Command) error {
|
||||
|
||||
for _, cmd := range cmds {
|
||||
if cmd.IsZero() {
|
||||
return fmt.Errorf("command:%w", cerr.ErrCommandNil)
|
||||
return fmt.Errorf("command:%w", errs.ErrCommandNil)
|
||||
}
|
||||
|
||||
if _, ok := c.names[cmd.Name()]; ok {
|
||||
return fmt.Errorf("command %s:%w", cmd.Name(), cerr.ErrCommandDplicate)
|
||||
return fmt.Errorf("command %s:%w", cmd.Name(), errs.ErrCommandDplicate)
|
||||
}
|
||||
|
||||
c.names[cmd.Name()] = len(c.cmds)
|
||||
|
||||
67
command/dump/reference.go
Normal file
67
command/dump/reference.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package dump
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/definition"
|
||||
"gitoa.ru/go-4devs/config/definition/option"
|
||||
"gitoa.ru/go-4devs/config/provider/arg"
|
||||
"gitoa.ru/go-4devs/console/command"
|
||||
"gitoa.ru/go-4devs/console/errs"
|
||||
"gitoa.ru/go-4devs/console/internal/registry"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
)
|
||||
|
||||
//go:generate go tool config config:generate
|
||||
|
||||
const NameRefernce = "config:dump-reference"
|
||||
|
||||
func Command() command.Command {
|
||||
return command.New(NameRefernce, "dump reference by command", RExecute, command.Configure(RConfigure))
|
||||
}
|
||||
|
||||
func RExecute(ctx context.Context, in config.Provider, out output.Output) error {
|
||||
provs, ok := in.(config.Providers)
|
||||
if !ok {
|
||||
return fmt.Errorf("%w: expect %T got %T", errs.ErrWrongType, (config.Providers)(nil), in)
|
||||
}
|
||||
|
||||
cfg := NewRConfigureConfig(in)
|
||||
|
||||
cmd, err := registry.Find(cfg.CommandName(ctx))
|
||||
if err != nil {
|
||||
return fmt.Errorf("cmd:%w", err)
|
||||
}
|
||||
|
||||
def := definition.New()
|
||||
if err := cmd.Configure(ctx, def); err != nil {
|
||||
return fmt.Errorf("configure:%w", err)
|
||||
}
|
||||
|
||||
prov, err := provs.Provider(cfg.Format(ctx))
|
||||
if err != nil {
|
||||
return fmt.Errorf("prov:%w", errs.AlternativesError{Alt: provs.Names(), Err: err})
|
||||
}
|
||||
|
||||
bind, ok := prov.(config.DumpProvider)
|
||||
if !ok {
|
||||
return fmt.Errorf("%w: expect config.DunpProvider got %T", errs.ErrWrongType, prov)
|
||||
}
|
||||
|
||||
if err := bind.DumpReference(ctx, out, def); err != nil {
|
||||
return fmt.Errorf("dump:%w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func RConfigure(_ context.Context, def config.Definition) error {
|
||||
def.Add(
|
||||
arg.String("command-name", "command name", option.Required),
|
||||
option.String("format", "format", option.Default(arg.Name)),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
89
command/dump/reference_config.go
Normal file
89
command/dump/reference_config.go
Normal file
@@ -0,0 +1,89 @@
|
||||
// Code generated gitoa.ru/go-4devs/config DO NOT EDIT.
|
||||
package dump
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"gitoa.ru/go-4devs/config"
|
||||
)
|
||||
|
||||
func WithRConfigureConfigHandle(fn func(context.Context, error)) func(*RConfigureConfig) {
|
||||
return func(ci *RConfigureConfig) {
|
||||
ci.handle = fn
|
||||
}
|
||||
}
|
||||
|
||||
func NewRConfigureConfig(prov config.Provider, opts ...func(*RConfigureConfig)) RConfigureConfig {
|
||||
i := RConfigureConfig{
|
||||
Provider: prov,
|
||||
handle: func(_ context.Context, err error) {
|
||||
fmt.Printf("RConfigureConfig:%v", err)
|
||||
},
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(&i)
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
type RConfigureConfig struct {
|
||||
config.Provider
|
||||
handle func(context.Context, error)
|
||||
}
|
||||
|
||||
// readCommandName command name.
|
||||
func (i RConfigureConfig) readCommandName(ctx context.Context) (v string, e error) {
|
||||
val, err := i.Value(ctx, "command-name")
|
||||
if err != nil {
|
||||
return v, fmt.Errorf("read [%v]:%w", []string{"command-name"}, err)
|
||||
|
||||
}
|
||||
|
||||
return val.ParseString()
|
||||
|
||||
}
|
||||
|
||||
// ReadCommandName command name.
|
||||
func (i RConfigureConfig) ReadCommandName(ctx context.Context) (string, error) {
|
||||
return i.readCommandName(ctx)
|
||||
}
|
||||
|
||||
// CommandName command name.
|
||||
func (i RConfigureConfig) CommandName(ctx context.Context) string {
|
||||
val, err := i.readCommandName(ctx)
|
||||
if err != nil {
|
||||
i.handle(ctx, err)
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
// readFormat format.
|
||||
func (i RConfigureConfig) readFormat(ctx context.Context) (v string, e error) {
|
||||
val, err := i.Value(ctx, "format")
|
||||
if err != nil {
|
||||
i.handle(ctx, err)
|
||||
|
||||
return "arg", nil
|
||||
}
|
||||
|
||||
return val.ParseString()
|
||||
|
||||
}
|
||||
|
||||
// ReadFormat format.
|
||||
func (i RConfigureConfig) ReadFormat(ctx context.Context) (string, error) {
|
||||
return i.readFormat(ctx)
|
||||
}
|
||||
|
||||
// Format format.
|
||||
func (i RConfigureConfig) Format(ctx context.Context) string {
|
||||
val, err := i.readFormat(ctx)
|
||||
if err != nil {
|
||||
i.handle(ctx, err)
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package help
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -9,15 +10,16 @@ import (
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/definition"
|
||||
"gitoa.ru/go-4devs/config/definition/option"
|
||||
cparam "gitoa.ru/go-4devs/config/param"
|
||||
"gitoa.ru/go-4devs/config/param"
|
||||
"gitoa.ru/go-4devs/config/provider/arg"
|
||||
"gitoa.ru/go-4devs/config/validator"
|
||||
"gitoa.ru/go-4devs/config/value"
|
||||
"gitoa.ru/go-4devs/console/command"
|
||||
"gitoa.ru/go-4devs/console/errs"
|
||||
"gitoa.ru/go-4devs/console/internal/registry"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
"gitoa.ru/go-4devs/console/output/descriptor"
|
||||
"gitoa.ru/go-4devs/console/param"
|
||||
"gitoa.ru/go-4devs/console/setting"
|
||||
)
|
||||
|
||||
//nolint:gochecknoinits
|
||||
@@ -91,17 +93,31 @@ func Execute(ctx context.Context, in config.Provider, out output.Output) error {
|
||||
bin = os.Args[0]
|
||||
}
|
||||
|
||||
help, err := param.Help(cmd, param.HelpData(bin, cmd.Name()))
|
||||
help, err := setting.Help(cmd, setting.HelpData(bin, cmd.Name()))
|
||||
if err != nil {
|
||||
return fmt.Errorf("create help:%w", err)
|
||||
}
|
||||
|
||||
hasUsage := true
|
||||
|
||||
usage, err := setting.Usage(cmd, setting.UsageData(cmd.Name(), def))
|
||||
if err != nil {
|
||||
if !errors.Is(err, errs.ErrNotFound) {
|
||||
return fmt.Errorf("create usage:%w", err)
|
||||
}
|
||||
|
||||
hasUsage = false
|
||||
}
|
||||
|
||||
derr := des.Command(ctx, out, descriptor.Command{
|
||||
Bin: bin,
|
||||
Name: cmd.Name(),
|
||||
Description: param.Description(cmd),
|
||||
Description: setting.Description(cmd),
|
||||
Help: help,
|
||||
Options: def.With(cparam.New(descriptor.TxtStyle())),
|
||||
Usage: func() (string, bool) {
|
||||
return usage, hasUsage
|
||||
},
|
||||
Options: def.With(param.New(descriptor.TxtStyle())),
|
||||
})
|
||||
if derr != nil {
|
||||
return fmt.Errorf("descriptor help:%w", derr)
|
||||
@@ -118,7 +134,7 @@ You can also output the help in other formats by using the <comment>--format</co
|
||||
To display the list of available commands, please use the <info>list</info> command.
|
||||
`
|
||||
|
||||
func Help(data param.HData) (string, error) {
|
||||
func Help(data setting.HData) (string, error) {
|
||||
return fmt.Sprintf(tpl, data.Bin, data.Name), nil
|
||||
}
|
||||
|
||||
|
||||
@@ -8,16 +8,16 @@ import (
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/definition"
|
||||
"gitoa.ru/go-4devs/config/definition/option"
|
||||
cparam "gitoa.ru/go-4devs/config/param"
|
||||
"gitoa.ru/go-4devs/config/param"
|
||||
"gitoa.ru/go-4devs/config/provider/arg"
|
||||
"gitoa.ru/go-4devs/config/validator"
|
||||
"gitoa.ru/go-4devs/config/value"
|
||||
"gitoa.ru/go-4devs/console/command"
|
||||
cerr "gitoa.ru/go-4devs/console/errors"
|
||||
"gitoa.ru/go-4devs/console/errs"
|
||||
"gitoa.ru/go-4devs/console/internal/registry"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
"gitoa.ru/go-4devs/console/output/descriptor"
|
||||
"gitoa.ru/go-4devs/console/param"
|
||||
"gitoa.ru/go-4devs/console/setting"
|
||||
)
|
||||
|
||||
//nolint:gochecknoinits
|
||||
@@ -80,7 +80,7 @@ func Execite(ctx context.Context, in config.Provider, out output.Output) error {
|
||||
cmds := registry.Commands()
|
||||
commands := descriptor.Commands{
|
||||
Namespace: ns,
|
||||
Options: def.With(cparam.New(descriptor.TxtStyle())),
|
||||
Options: def.With(param.New(descriptor.TxtStyle())),
|
||||
}
|
||||
groups := make(map[string]*descriptor.NSCommand)
|
||||
namespaces := make([]string, 0, len(cmds))
|
||||
@@ -92,13 +92,13 @@ func Execite(ctx context.Context, in config.Provider, out output.Output) error {
|
||||
}
|
||||
|
||||
cmd, _ := registry.Find(name)
|
||||
if param.IsHidden(cmd) {
|
||||
if setting.IsHidden(cmd) {
|
||||
continue
|
||||
}
|
||||
|
||||
gn := strings.SplitN(name, ":", defaultLenNamespace)
|
||||
if len(gn) != defaultLenNamespace {
|
||||
empty.Append(cmd.Name(), param.Description(cmd))
|
||||
empty.Append(cmd.Name(), setting.Description(cmd))
|
||||
|
||||
continue
|
||||
}
|
||||
@@ -111,7 +111,7 @@ func Execite(ctx context.Context, in config.Provider, out output.Output) error {
|
||||
namespaces = append(namespaces, gn[0])
|
||||
}
|
||||
|
||||
groups[gn[0]].Append(name, param.Description(cmd))
|
||||
groups[gn[0]].Append(name, setting.Description(cmd))
|
||||
}
|
||||
|
||||
if len(empty.Commands) > 0 {
|
||||
@@ -123,7 +123,7 @@ func Execite(ctx context.Context, in config.Provider, out output.Output) error {
|
||||
}
|
||||
|
||||
if ns != "" && len(commands.Commands) == 0 {
|
||||
return fmt.Errorf("%w: namespace %s", cerr.ErrNotFound, ns)
|
||||
return fmt.Errorf("%w: namespace %s", errs.ErrNotFound, ns)
|
||||
}
|
||||
|
||||
if err := des.Commands(ctx, out, commands); err != nil {
|
||||
|
||||
@@ -3,7 +3,7 @@ package list
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gitoa.ru/go-4devs/console/param"
|
||||
"gitoa.ru/go-4devs/console/setting"
|
||||
)
|
||||
|
||||
const tpl = `
|
||||
@@ -15,6 +15,6 @@ You can also output the information in other formats by using the <comment>--for
|
||||
<info>%[1]s %[2]s --format=xml</info>
|
||||
`
|
||||
|
||||
func Help(data param.HData) (string, error) {
|
||||
func Help(data setting.HData) (string, error) {
|
||||
return fmt.Sprintf(tpl, data.Bin, data.Name), nil
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
"gitoa.ru/go-4devs/config/value"
|
||||
"gitoa.ru/go-4devs/console"
|
||||
"gitoa.ru/go-4devs/console/command"
|
||||
cerr "gitoa.ru/go-4devs/console/errors"
|
||||
"gitoa.ru/go-4devs/console/errs"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
)
|
||||
|
||||
@@ -82,7 +82,7 @@ func TestRunEmptyExecute(t *testing.T) {
|
||||
out := output.Stdout()
|
||||
|
||||
err := empty.Run(ctx, in, out)
|
||||
if !errors.Is(err, cerr.ErrExecuteNil) {
|
||||
t.Fatalf("expected: %v, got: %v ", cerr.ErrExecuteNil, err)
|
||||
if !errors.Is(err, errs.ErrExecuteNil) {
|
||||
t.Fatalf("expected: %v, got: %v ", errs.ErrExecuteNil, err)
|
||||
}
|
||||
}
|
||||
|
||||
13
console.go
13
console.go
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/definition"
|
||||
@@ -13,16 +12,16 @@ import (
|
||||
"gitoa.ru/go-4devs/config/value"
|
||||
"gitoa.ru/go-4devs/console/command"
|
||||
"gitoa.ru/go-4devs/console/command/help"
|
||||
cerr "gitoa.ru/go-4devs/console/errors"
|
||||
"gitoa.ru/go-4devs/console/errs"
|
||||
"gitoa.ru/go-4devs/console/internal/registry"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
"gitoa.ru/go-4devs/console/param"
|
||||
"gitoa.ru/go-4devs/console/setting"
|
||||
)
|
||||
|
||||
// Execute the current command with option.
|
||||
func Execute(ctx context.Context, cmd command.Command, opts ...func(*App)) {
|
||||
opts = append([]func(*App){WithSkipArgs(1)}, opts...)
|
||||
New(opts...).exec(ctx, cmd)
|
||||
New(opts...).exec(ctx, command.With(cmd, command.EmptyUsage))
|
||||
}
|
||||
|
||||
// Run current command by input and output.
|
||||
@@ -38,7 +37,7 @@ func Run(ctx context.Context, cmd command.Command, in config.BindProvider, out o
|
||||
|
||||
berr := in.Bind(ctx, config.NewVars(def.Options()...))
|
||||
if berr != nil {
|
||||
log.Print(berr)
|
||||
printErr(ctx, in, out, berr)
|
||||
|
||||
return showHelp(ctx, cmd, in, output.Ansi(out))
|
||||
}
|
||||
@@ -46,7 +45,7 @@ func Run(ctx context.Context, cmd command.Command, in config.BindProvider, out o
|
||||
out = command.Verbose(ctx, in, out)
|
||||
|
||||
if command.IsShowVersion(ctx, in) {
|
||||
out.Println(ctx, "command <comment>", cmd.Name(), "</comment> version: <info>", param.Version(cmd), "</info>")
|
||||
out.Println(ctx, "command <comment>", cmd.Name(), "</comment> version: <info>", setting.Version(cmd), "</info>")
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -67,7 +66,7 @@ func showHelp(ctx context.Context, cmd command.Command, in config.Provider, out
|
||||
arr.SetOption(value.New(cmd.Name()), help.ArgumentCommandName)
|
||||
arr.SetOption(value.New(false), command.OptionHelp)
|
||||
|
||||
if _, err := registry.Find(cmd.Name()); errors.Is(err, cerr.ErrNotFound) {
|
||||
if _, err := registry.Find(cmd.Name()); errors.Is(err, errs.ErrNotFound) {
|
||||
_ = registry.Add(cmd)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package errors //nolint:revive
|
||||
package errs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
7
go.mod
7
go.mod
@@ -2,7 +2,7 @@ module gitoa.ru/go-4devs/console
|
||||
|
||||
go 1.24.0
|
||||
|
||||
require gitoa.ru/go-4devs/config v0.0.8
|
||||
require gitoa.ru/go-4devs/config v0.0.10
|
||||
|
||||
require (
|
||||
golang.org/x/mod v0.31.0 // indirect
|
||||
@@ -10,4 +10,7 @@ require (
|
||||
golang.org/x/tools v0.40.0 // indirect
|
||||
)
|
||||
|
||||
tool golang.org/x/tools/cmd/stringer
|
||||
tool (
|
||||
gitoa.ru/go-4devs/config/cmd/config
|
||||
golang.org/x/tools/cmd/stringer
|
||||
)
|
||||
|
||||
6
go.sum
6
go.sum
@@ -1,7 +1,9 @@
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
gitoa.ru/go-4devs/config v0.0.8 h1:o4p8I9jWJMfiFVVKr50IqCGj1fF+8kmSPDkH0deRvn4=
|
||||
gitoa.ru/go-4devs/config v0.0.8/go.mod h1:jHKqVafFVW400LC0M4i1ifPapiI9sqpX/QTh+VMadKw=
|
||||
gitoa.ru/go-4devs/config v0.0.9 h1:Z43kM6k6ocC2YIRQkELq5zWO9LO8fl1l14RyqjLC4I4=
|
||||
gitoa.ru/go-4devs/config v0.0.9/go.mod h1:cLW1+4E4uM4Pw+z4RuKEKbO1Lz6UTs2b2fTPyeEgTx8=
|
||||
gitoa.ru/go-4devs/config v0.0.10 h1:NSagD0voj77/IGqRGsbR0DZmDvFcxbx+oRoWQnLnSy4=
|
||||
gitoa.ru/go-4devs/config v0.0.10/go.mod h1:cLW1+4E4uM4Pw+z4RuKEKbO1Lz6UTs2b2fTPyeEgTx8=
|
||||
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/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
|
||||
@@ -25,6 +25,7 @@ type Command struct {
|
||||
Bin string
|
||||
Name string
|
||||
Description string
|
||||
Usage func() (string, bool)
|
||||
Help string
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"gitoa.ru/go-4devs/config/param"
|
||||
"gitoa.ru/go-4devs/config/provider/arg"
|
||||
"gitoa.ru/go-4devs/console/output"
|
||||
"gitoa.ru/go-4devs/console/setting"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -22,9 +23,9 @@ const (
|
||||
//nolint:gochecknoglobals
|
||||
var (
|
||||
txtFunc = template.FuncMap{
|
||||
"synopsis": txtSynopsis,
|
||||
"definition": txtDefinition,
|
||||
"help": txtHelp,
|
||||
"usage": txtUsage,
|
||||
"commands": txtCommands,
|
||||
}
|
||||
|
||||
@@ -34,11 +35,9 @@ var (
|
||||
{{- if .Description -}}
|
||||
<comment>Description:</comment>
|
||||
{{ .Description }}
|
||||
|
||||
{{ end -}}
|
||||
<comment>Usage:</comment>
|
||||
{{ .Name }} {{ synopsis .Options }}
|
||||
{{ definition .Options }}
|
||||
{{- usage . }}
|
||||
{{- definition .Options }}
|
||||
{{- help . }}
|
||||
`))
|
||||
|
||||
@@ -128,6 +127,23 @@ func txtCommands(cmds []NSCommand) string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func txtUsage(cmd Command) string {
|
||||
if cmd.Usage == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
data, has := cmd.Usage()
|
||||
if has && data == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
if data == "" {
|
||||
data = defaultUsage(setting.UsageData(cmd.Name, cmd.Options))
|
||||
}
|
||||
|
||||
return "\n<comment>Usage:</comment>\n " + data + "\n"
|
||||
}
|
||||
|
||||
func txtHelp(cmd Command) string {
|
||||
if cmd.Help == "" {
|
||||
return ""
|
||||
@@ -152,10 +168,12 @@ func txtDefinition(options config.Options) string {
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func txtSynopsis(options config.Options) string {
|
||||
def := arg.NewViews(options, nil)
|
||||
func defaultUsage(data setting.UData) string {
|
||||
def := arg.NewViews(data.Options, nil)
|
||||
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(data.Name)
|
||||
buf.WriteString(" ")
|
||||
|
||||
if len(def.Options()) > 0 {
|
||||
buf.WriteString("[options] ")
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
package param
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
cerr "gitoa.ru/go-4devs/console/errors"
|
||||
)
|
||||
|
||||
type key uint8
|
||||
|
||||
const (
|
||||
paramHidden key = iota + 1
|
||||
paramDescription
|
||||
paramVerssion
|
||||
paramHelp
|
||||
)
|
||||
|
||||
const (
|
||||
defaultVersion = "undefined"
|
||||
)
|
||||
|
||||
func IsHidden(in Params) bool {
|
||||
data, ok := Bool(in, paramHidden)
|
||||
|
||||
return ok && data
|
||||
}
|
||||
|
||||
func Hidden(in Params) Params {
|
||||
return in.With(paramHidden, true)
|
||||
}
|
||||
|
||||
func Description(in Params) string {
|
||||
data, _ := String(in, paramDescription)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func WithDescription(desc string) Option {
|
||||
return func(p Params) Params {
|
||||
return p.With(paramDescription, desc)
|
||||
}
|
||||
}
|
||||
|
||||
func Version(in Params) string {
|
||||
if data, ok := String(in, paramVerssion); ok {
|
||||
return data
|
||||
}
|
||||
|
||||
return defaultVersion
|
||||
}
|
||||
|
||||
func WithVersion(in string) Option {
|
||||
return func(p Params) Params {
|
||||
return p.With(paramVerssion, in)
|
||||
}
|
||||
}
|
||||
|
||||
func HelpData(bin, name string) HData {
|
||||
return HData{
|
||||
Bin: bin,
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
type HData struct {
|
||||
Bin string
|
||||
Name string
|
||||
}
|
||||
|
||||
type HelpFn func(data HData) (string, error)
|
||||
|
||||
func WithHelp(fn HelpFn) Option {
|
||||
return func(p Params) Params {
|
||||
return p.With(paramHelp, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func Help(in Params, data HData) (string, error) {
|
||||
fn, ok := in.Param(paramHelp)
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
hfn, fok := fn.(HelpFn)
|
||||
if !fok {
|
||||
return "", fmt.Errorf("%w: expect:%T, got:%T", cerr.ErrWrongType, (HelpFn)(nil), fn)
|
||||
}
|
||||
|
||||
return hfn(data)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package param
|
||||
package setting
|
||||
|
||||
func Bool(in Params, key any) (bool, bool) {
|
||||
func Bool(in Setting, key any) (bool, bool) {
|
||||
data, ok := in.Param(key)
|
||||
if !ok {
|
||||
return false, false
|
||||
@@ -11,7 +11,7 @@ func Bool(in Params, key any) (bool, bool) {
|
||||
return res, ok
|
||||
}
|
||||
|
||||
func String(in Params, key any) (string, bool) {
|
||||
func String(in Setting, key any) (string, bool) {
|
||||
data, ok := in.Param(key)
|
||||
if !ok {
|
||||
return "", false
|
||||
127
setting/keys.go
Normal file
127
setting/keys.go
Normal file
@@ -0,0 +1,127 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/console/errs"
|
||||
)
|
||||
|
||||
type key uint8
|
||||
|
||||
const (
|
||||
paramHidden key = iota + 1
|
||||
paramDescription
|
||||
paramVerssion
|
||||
paramHelp
|
||||
paramUsage
|
||||
)
|
||||
|
||||
const (
|
||||
defaultVersion = "undefined"
|
||||
)
|
||||
|
||||
func IsHidden(in Setting) bool {
|
||||
data, ok := Bool(in, paramHidden)
|
||||
|
||||
return ok && data
|
||||
}
|
||||
|
||||
func Hidden(in Setting) Setting {
|
||||
return in.With(paramHidden, true)
|
||||
}
|
||||
|
||||
func Description(in Setting) string {
|
||||
data, _ := String(in, paramDescription)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func WithDescription(desc string) Option {
|
||||
return func(p Setting) Setting {
|
||||
return p.With(paramDescription, desc)
|
||||
}
|
||||
}
|
||||
|
||||
func Version(in Setting) string {
|
||||
if data, ok := String(in, paramVerssion); ok {
|
||||
return data
|
||||
}
|
||||
|
||||
return defaultVersion
|
||||
}
|
||||
|
||||
func WithVersion(in string) Option {
|
||||
return func(p Setting) Setting {
|
||||
return p.With(paramVerssion, in)
|
||||
}
|
||||
}
|
||||
|
||||
func HelpData(bin, name string) HData {
|
||||
return HData{
|
||||
Bin: bin,
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
type HData struct {
|
||||
Bin string
|
||||
Name string
|
||||
}
|
||||
|
||||
type HelpFn func(data HData) (string, error)
|
||||
|
||||
func WithHelp(fn HelpFn) Option {
|
||||
return func(p Setting) Setting {
|
||||
return p.With(paramHelp, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func Help(in Setting, data HData) (string, error) {
|
||||
fn, ok := in.Param(paramHelp)
|
||||
if !ok {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
hfn, fok := fn.(HelpFn)
|
||||
if !fok {
|
||||
return "", fmt.Errorf("%w: expect:func(data HData) (string, error), got:%T", errs.ErrWrongType, fn)
|
||||
}
|
||||
|
||||
return hfn(data)
|
||||
}
|
||||
|
||||
func UsageData(name string, opts config.Options) UData {
|
||||
return UData{
|
||||
Options: opts,
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
|
||||
type UData struct {
|
||||
config.Options
|
||||
|
||||
Name string
|
||||
}
|
||||
|
||||
type UsageFn func(data UData) (string, error)
|
||||
|
||||
func WithUsage(fn UsageFn) Option {
|
||||
return func(p Setting) Setting {
|
||||
return p.With(paramUsage, fn)
|
||||
}
|
||||
}
|
||||
|
||||
func Usage(in Setting, data UData) (string, error) {
|
||||
fn, ok := in.Param(paramUsage)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w", errs.ErrNotFound)
|
||||
}
|
||||
|
||||
ufn, ok := fn.(UsageFn)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("%w: expect: func(data Udata) (string, error), got:%T", errs.ErrWrongType, fn)
|
||||
}
|
||||
|
||||
return ufn(data)
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
package param
|
||||
package setting
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var eparam = empty{}
|
||||
|
||||
func New(opts ...Option) Params {
|
||||
var param Params
|
||||
func New(opts ...Option) Setting {
|
||||
var param Setting
|
||||
|
||||
param = eparam
|
||||
for _, opt := range opts {
|
||||
@@ -14,12 +14,12 @@ func New(opts ...Option) Params {
|
||||
return param
|
||||
}
|
||||
|
||||
type Params interface {
|
||||
type Setting interface {
|
||||
Param(key any) (any, bool)
|
||||
With(key, val any) Params
|
||||
With(key, val any) Setting
|
||||
}
|
||||
|
||||
type Option func(Params) Params
|
||||
type Option func(Setting) Setting
|
||||
|
||||
type empty struct{}
|
||||
|
||||
@@ -27,7 +27,7 @@ func (e empty) Param(any) (any, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (e empty) With(key, val any) Params {
|
||||
func (e empty) With(key, val any) Setting {
|
||||
return data{
|
||||
parent: e,
|
||||
key: key,
|
||||
@@ -36,7 +36,7 @@ func (e empty) With(key, val any) Params {
|
||||
}
|
||||
|
||||
type data struct {
|
||||
parent Params
|
||||
parent Setting
|
||||
key, val any
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func (d data) Param(key any) (any, bool) {
|
||||
return d.parent.Param(key)
|
||||
}
|
||||
|
||||
func (d data) With(key, val any) Params {
|
||||
func (d data) With(key, val any) Setting {
|
||||
return data{
|
||||
parent: d,
|
||||
key: key,
|
||||
Reference in New Issue
Block a user