update commands
All checks were successful
Go Action / goaction (pull_request) Successful in 2m26s

This commit is contained in:
2026-01-06 16:19:45 +03:00
parent 797c938628
commit 1382bea590
20 changed files with 414 additions and 165 deletions

15
app.go
View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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
View 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
}

View 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
}

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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)
}
}

View File

@@ -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)
}

View File

@@ -1,4 +1,4 @@
package errors //nolint:revive
package errs
import (
"errors"

7
go.mod
View File

@@ -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
View File

@@ -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=

View File

@@ -25,6 +25,7 @@ type Command struct {
Bin string
Name string
Description string
Usage func() (string, bool)
Help string
}

View File

@@ -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] ")

View File

@@ -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)
}

View File

@@ -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
View 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)
}

View File

@@ -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,