Merge pull request 'dump-reference' (#36) from dump-reference into master
All checks were successful
Go Action / goaction (push) Successful in 56s
All checks were successful
Go Action / goaction (push) Successful in 56s
Reviewed-on: #36
This commit was merged in pull request #36.
This commit is contained in:
@@ -231,7 +231,7 @@ func (v View) ParentStruct() string {
|
||||
}
|
||||
|
||||
func (v View) Description() string {
|
||||
return option.DataDescription(v.Option)
|
||||
return param.Description(v.Option)
|
||||
}
|
||||
|
||||
func (v View) Default() any {
|
||||
|
||||
@@ -2,7 +2,6 @@ package group
|
||||
|
||||
import (
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/definition/option"
|
||||
"gitoa.ru/go-4devs/config/param"
|
||||
)
|
||||
|
||||
@@ -12,7 +11,7 @@ func New(name, desc string, opts ...config.Option) *Group {
|
||||
group := Group{
|
||||
name: name,
|
||||
opts: opts,
|
||||
Params: param.New(option.Description(desc)),
|
||||
Params: param.New(param.WithDescription(desc)),
|
||||
}
|
||||
|
||||
return &group
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"gitoa.ru/go-4devs/config/definition/group"
|
||||
"gitoa.ru/go-4devs/config/definition/option"
|
||||
"gitoa.ru/go-4devs/config/param"
|
||||
"gitoa.ru/go-4devs/config/test/require"
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ func TestGroupWith(t *testing.T) {
|
||||
const descrition = "group description"
|
||||
|
||||
gr := group.New("test", "test desc")
|
||||
gr = gr.With(option.Description(descrition))
|
||||
gr = gr.With(param.WithDescription(descrition))
|
||||
|
||||
require.Equal(t, descrition, option.DataDescription(gr))
|
||||
require.Equal(t, descrition, param.Description(gr))
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
var _ config.Option = New("", "", nil)
|
||||
|
||||
func New(name, desc string, vtype any, opts ...param.Option) Option {
|
||||
opts = append(opts, Description(desc), WithType(vtype))
|
||||
opts = append(opts, param.WithDescription(desc), WithType(vtype))
|
||||
res := Option{
|
||||
name: name,
|
||||
Params: param.New(opts...),
|
||||
|
||||
@@ -9,7 +9,6 @@ type key int
|
||||
const (
|
||||
paramHidden key = iota + 1
|
||||
paramDefault
|
||||
paramDesc
|
||||
paramRequired
|
||||
paramSlice
|
||||
paramBool
|
||||
@@ -72,10 +71,9 @@ func Default(in any) param.Option {
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated: use param.WithDescription.
|
||||
func Description(in string) param.Option {
|
||||
return func(v param.Params) param.Params {
|
||||
return param.With(v, paramDesc, in)
|
||||
}
|
||||
return param.WithDescription(in)
|
||||
}
|
||||
|
||||
func HasDefaut(fn param.Params) bool {
|
||||
@@ -118,8 +116,7 @@ func IsRequired(fn param.Params) bool {
|
||||
return ok && data
|
||||
}
|
||||
|
||||
// Deprecated: use param.Description.
|
||||
func DataDescription(fn param.Params) string {
|
||||
data, _ := param.String(fn, paramDesc)
|
||||
|
||||
return data
|
||||
return param.Description(fn)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package proto
|
||||
|
||||
import (
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/definition/option"
|
||||
"gitoa.ru/go-4devs/config/key"
|
||||
"gitoa.ru/go-4devs/config/param"
|
||||
)
|
||||
@@ -13,7 +12,7 @@ func New(name string, desc string, opts ...config.Option) Proto {
|
||||
return Proto{
|
||||
name: key.Wild(name),
|
||||
opts: opts,
|
||||
Params: param.New(option.Description(desc)),
|
||||
Params: param.New(param.WithDescription(desc)),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
16
key/wild.go
16
key/wild.go
@@ -1,15 +1,21 @@
|
||||
package key
|
||||
|
||||
import "slices"
|
||||
|
||||
const minWildCount = 3
|
||||
|
||||
func IsWild(name string) bool {
|
||||
func IsWild(keys ...string) bool {
|
||||
return slices.ContainsFunc(keys, isWild)
|
||||
}
|
||||
|
||||
func Wild(name string) string {
|
||||
return "{" + name + "}"
|
||||
}
|
||||
|
||||
func isWild(name string) bool {
|
||||
if len(name) < minWildCount {
|
||||
return false
|
||||
}
|
||||
|
||||
return name[0] == '{' && name[len(name)-1] == '}'
|
||||
}
|
||||
|
||||
func Wild(name string) string {
|
||||
return "{" + name + "}"
|
||||
}
|
||||
|
||||
16
key/wild_test.go
Normal file
16
key/wild_test.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package key_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitoa.ru/go-4devs/config/key"
|
||||
"gitoa.ru/go-4devs/config/test/require"
|
||||
)
|
||||
|
||||
func TestWild(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.True(t, key.IsWild(key.Wild("test")))
|
||||
require.True(t, !key.IsWild("test"))
|
||||
require.True(t, key.IsWild("test", key.Wild("test"), "key"))
|
||||
}
|
||||
@@ -5,6 +5,7 @@ type key int
|
||||
const (
|
||||
paramTimeFormat key = iota + 1
|
||||
paramType
|
||||
paramDescription
|
||||
)
|
||||
|
||||
func WithTimeFormat(format string) Option {
|
||||
@@ -28,3 +29,15 @@ func Type(fn Params) any {
|
||||
|
||||
return param
|
||||
}
|
||||
|
||||
func WithDescription(in string) Option {
|
||||
return func(p Params) Params {
|
||||
return With(p, paramDescription, in)
|
||||
}
|
||||
}
|
||||
|
||||
func Description(fn Params) string {
|
||||
data, _ := String(fn, paramDescription)
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
61
provider/env/provider.go
vendored
61
provider/env/provider.go
vendored
@@ -3,10 +3,14 @@ package env
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/definition/option"
|
||||
"gitoa.ru/go-4devs/config/key"
|
||||
"gitoa.ru/go-4devs/config/param"
|
||||
"gitoa.ru/go-4devs/config/value"
|
||||
)
|
||||
|
||||
@@ -42,15 +46,68 @@ type Provider struct {
|
||||
prefix string
|
||||
}
|
||||
|
||||
func (p *Provider) Key(path ...string) string {
|
||||
return p.prefix + p.key(path...)
|
||||
}
|
||||
|
||||
func (p *Provider) Name() string {
|
||||
return p.name
|
||||
}
|
||||
|
||||
func (p *Provider) Value(_ context.Context, path ...string) (config.Value, error) {
|
||||
name := p.prefix + p.key(path...)
|
||||
if val, ok := os.LookupEnv(name); ok {
|
||||
if val, ok := os.LookupEnv(p.Key(path...)); ok {
|
||||
return value.JString(val), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%v:%w", p.Name(), config.ErrNotFound)
|
||||
}
|
||||
|
||||
func (p *Provider) DumpReference(_ context.Context, w io.Writer, opt config.Options) error {
|
||||
return p.writeOptions(w, opt)
|
||||
}
|
||||
|
||||
func (p *Provider) writeOptions(w io.Writer, opt config.Options, key ...string) error {
|
||||
for idx, option := range opt.Options() {
|
||||
if err := p.writeOption(w, option, key...); err != nil {
|
||||
return fmt.Errorf("option[%d]:%w", idx, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) writeOption(w io.Writer, opt config.Option, keys ...string) error {
|
||||
if desc := param.Description(opt); desc != "" {
|
||||
if _, derr := fmt.Fprintf(w, "# %v.\n", desc); derr != nil {
|
||||
return fmt.Errorf("write description:%w", derr)
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
switch one := opt.(type) {
|
||||
case config.Group:
|
||||
err = p.writeOptions(w, one, append(keys, one.Name())...)
|
||||
case config.Options:
|
||||
err = p.writeOptions(w, one, keys...)
|
||||
default:
|
||||
def, dok := option.DataDefaut(opt)
|
||||
|
||||
prefix := ""
|
||||
if !dok || key.IsWild(keys...) {
|
||||
prefix = "#"
|
||||
}
|
||||
|
||||
if !dok {
|
||||
def = ""
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(w, "%s%s=%v\n", prefix, p.Key(append(keys, one.Name())...), def)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("%w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
39
provider/env/provider_test.go
vendored
39
provider/env/provider_test.go
vendored
@@ -1,10 +1,17 @@
|
||||
package env_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"gitoa.ru/go-4devs/config"
|
||||
"gitoa.ru/go-4devs/config/definition/group"
|
||||
"gitoa.ru/go-4devs/config/definition/option"
|
||||
"gitoa.ru/go-4devs/config/definition/proto"
|
||||
"gitoa.ru/go-4devs/config/provider/env"
|
||||
"gitoa.ru/go-4devs/config/test"
|
||||
"gitoa.ru/go-4devs/config/test/require"
|
||||
)
|
||||
|
||||
func TestProvider(t *testing.T) {
|
||||
@@ -19,3 +26,35 @@ func TestProvider(t *testing.T) {
|
||||
}
|
||||
test.Run(t, provider, read)
|
||||
}
|
||||
|
||||
func TestProvider_DumpReference(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const expect = `# configure log.
|
||||
# level.
|
||||
FDEVS_CONFIG_LOG_LEVEL=info
|
||||
# configure log service.
|
||||
# level.
|
||||
#FDEVS_CONFIG_LOG_{SERVICE}_LEVEL=
|
||||
`
|
||||
|
||||
ctx := context.Background()
|
||||
prov := env.New("fdevs", "config")
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
require.NoError(t, prov.DumpReference(ctx, buf, testOptions(t)))
|
||||
require.Equal(t, buf.String(), expect)
|
||||
}
|
||||
|
||||
func testOptions(t *testing.T) config.Options {
|
||||
t.Helper()
|
||||
|
||||
return group.New("test", "test",
|
||||
group.New("log", "configure log",
|
||||
option.String("level", "level", option.Default("info")),
|
||||
proto.New("service", "configure log service",
|
||||
option.String("level", "level"),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,3 +12,13 @@ func Truef(t *testing.T, value bool, msg string, args ...any) {
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
func True(t *testing.T, value bool, args ...any) {
|
||||
t.Helper()
|
||||
|
||||
if !value {
|
||||
t.Errorf("require:true got:%v", value)
|
||||
t.Error(args...)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user