From 4797615c3a7d3196e3b571c8a4491dbbae545d64 Mon Sep 17 00:00:00 2001 From: urso Date: Tue, 26 Jul 2016 15:15:10 +0200 Subject: [PATCH] Update go-ucfg to version 0.3.1 --- glide.yaml | 2 +- .../github.com/elastic/go-ucfg/CHANGELOG.md | 12 ++- vendor/github.com/elastic/go-ucfg/README.md | 82 ++++++++++++++++++- vendor/github.com/elastic/go-ucfg/getset.go | 6 +- vendor/github.com/elastic/go-ucfg/merge.go | 12 +-- vendor/github.com/elastic/go-ucfg/path.go | 19 ++--- vendor/github.com/elastic/go-ucfg/reify.go | 35 ++++++-- vendor/github.com/elastic/go-ucfg/types.go | 41 ++++++---- vendor/github.com/elastic/go-ucfg/ucfg.go | 54 ++++++++++-- 9 files changed, 213 insertions(+), 50 deletions(-) diff --git a/glide.yaml b/glide.yaml index f7e75d1d4132..e623c0ab16ee 100644 --- a/glide.yaml +++ b/glide.yaml @@ -73,7 +73,7 @@ import: - package: github.com/dustin/go-humanize version: 499693e27ee0d14ffab67c31ad065fdb3d34ea75 - package: github.com/elastic/go-ucfg - version: v0.3.0 + version: v0.3.1 - package: github.com/armon/go-socks5 version: 3a873e99f5400ad7706e464e905ffcc94b3ff247 - package: github.com/pkg/errors diff --git a/vendor/github.com/elastic/go-ucfg/CHANGELOG.md b/vendor/github.com/elastic/go-ucfg/CHANGELOG.md index 74fe0933324e..62101a8aa477 100644 --- a/vendor/github.com/elastic/go-ucfg/CHANGELOG.md +++ b/vendor/github.com/elastic/go-ucfg/CHANGELOG.md @@ -14,6 +14,15 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +## [0.3.1] + +### Added +- Add `(*Config).IsArray` and `(*Config).IsDict`. #44 + +### Fixed +- Fix (*Config).CountField returning 1 for arrays of any size. #43 +- Fix unpacking into slice/array top-level or if `inline`-tag is used. #45 + ## [0.3.0] ### Added @@ -73,7 +82,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Introduced CHANGELOG.md for documenting changes to ucfg. -[Unreleased]: https://github.com/elastic/go-ucfg/compare/v0.3.0...HEAD +[Unreleased]: https://github.com/elastic/go-ucfg/compare/v0.3.1...HEAD +[0.3.1]: https://github.com/elastic/go-ucfg/compare/v0.3.0...v0.3.1 [0.3.0]: https://github.com/elastic/go-ucfg/compare/v0.2.1...v0.3.0 [0.2.1]: https://github.com/elastic/go-ucfg/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/elastic/go-ucfg/compare/v0.1.1...v0.2.0 diff --git a/vendor/github.com/elastic/go-ucfg/README.md b/vendor/github.com/elastic/go-ucfg/README.md index bacae6a2bce0..e73553181130 100644 --- a/vendor/github.com/elastic/go-ucfg/README.md +++ b/vendor/github.com/elastic/go-ucfg/README.md @@ -1,8 +1,84 @@ -# ucfg - [![Build Status](https://travis-ci.org/elastic/go-ucfg.svg?branch=master)](https://travis-ci.org/elastic/go-ucfg) - [![Go Report Card](https://goreportcard.com/badge/github.com/elastic/go-ucfg)](https://goreportcard.com/report/github.com/elastic/go-ucfg) + +# ucfg - Universal Configuration + +`ucfg` is a Golang library to handle yaml and json configuration files in your Golang project. It was developed for the [libbeat framework](https://github.com/elastic/beats/tree/master/libbeat) and used by all [beats](https://github.com/elastic/beats). + + +## API Documentation + +The full API Documentat can be found [here](https://godoc.org/github.com/elastic/go-ucfg). + +## Examples + +A few examples on how ucfg can be used. All examples below assume, that the following packages are imported: + +``` +import ( + "github.com/elastic/go-ucfg" + "github.com/elastic/go-ucfg/yaml" +) +``` + + +### Dot notations + +ufcg allows you to load yaml configuration files using dots instead of indentation. For example instead of having: + +``` +config: + user: name +``` + +with ucfg you can write: + +``` +config.user: name +``` + +This makes configurations easier and simpler. + +To load such a config file in Golang, use the following command: + +``` +config, err := yaml.NewConfigWithFile(path, ucfg.PathSep(".")) +``` + + + +### Validation and Defaults + +ucfg allows to automatically validate fields and set defaults for fields in case they are not defined. + + +``` +// Defines struct to read config from +type ExampleConfig struct { + Counter string `config:"username" validate:"min=0, max=9"` +} + +// Defines default config option +var ( + defaultConfig = ExampleConfig{ + Counter: 4, + } +} + +func main() { + config, err := yaml.NewConfigWithFile(path, ucfg.PathSep(".")) + config.Unpack(defaultConfig) +} +``` + +The above uses `Counter` as the config variable. ucfg assures that the value is between 0 and 9 and will return an error if this is not the case. In addition, if the value is not set, it will default to 4. + + +## Requirements + +ucfg has the following requirements: + +* Golang 1.6 diff --git a/vendor/github.com/elastic/go-ucfg/getset.go b/vendor/github.com/elastic/go-ucfg/getset.go index ce558197befb..e41db69a3ddb 100644 --- a/vendor/github.com/elastic/go-ucfg/getset.go +++ b/vendor/github.com/elastic/go-ucfg/getset.go @@ -14,7 +14,11 @@ func convertErr(opts *options, v value, err error, to string) Error { // number of elements for this field. If config value is a list, returns number // of elements in list func (c *Config) CountField(name string, opts ...Option) (int, error) { - if v, ok := c.fields.fields[name]; ok { + if name == "" { + return len(c.fields.array()) + len(c.fields.dict()), nil + } + + if v, ok := c.fields.get(name); ok { return v.Len(makeOptions(opts)) } return -1, raiseMissing(c, name) diff --git a/vendor/github.com/elastic/go-ucfg/merge.go b/vendor/github.com/elastic/go-ucfg/merge.go index 336f7c72b678..f3085c8a9dcb 100644 --- a/vendor/github.com/elastic/go-ucfg/merge.go +++ b/vendor/github.com/elastic/go-ucfg/merge.go @@ -17,27 +17,27 @@ func (c *Config) Merge(from interface{}, options ...Option) error { } func mergeConfig(opts *options, to, from *Config) Error { - for k, v := range from.fields.fields { + for k, v := range from.fields.dict() { ctx := context{ parent: cfgSub{to}, field: k, } - old, ok := to.fields.fields[k] + old, ok := to.fields.get(k) if !ok { - to.fields.fields[k] = v.cpy(ctx) + to.fields.set(k, v.cpy(ctx)) continue } subOld, err := old.toConfig(opts) if err != nil { - to.fields.fields[k] = v.cpy(ctx) + to.fields.set(k, v.cpy(ctx)) continue } subFrom, err := v.toConfig(opts) if err != nil { - to.fields.fields[k] = v.cpy(ctx) + to.fields.set(k, v.cpy(ctx)) continue } @@ -223,7 +223,7 @@ func normalizeArray( out = append(out, tmp) } - cfg.fields.arr = out + cfg.fields.a = out return val, nil } diff --git a/vendor/github.com/elastic/go-ucfg/path.go b/vendor/github.com/elastic/go-ucfg/path.go index bf01eacc1169..2efc606a85d2 100644 --- a/vendor/github.com/elastic/go-ucfg/path.go +++ b/vendor/github.com/elastic/go-ucfg/path.go @@ -123,7 +123,8 @@ func (n namedField) GetValue(opts *options, elem value) (value, Error) { return nil, raiseExpectedObject(opts, elem) } - return cfg.fields.fields[n.name], nil + v, _ := cfg.fields.get(n.name) + return v, nil } func (i idxField) GetValue(opts *options, elem value) (value, Error) { @@ -136,11 +137,11 @@ func (i idxField) GetValue(opts *options, elem value) (value, Error) { return nil, raiseExpectedObject(opts, elem) } - if i.i >= len(cfg.fields.arr) { + arr := cfg.fields.array() + if i.i >= len(arr) { return nil, raiseMissing(cfg, i.String()) } - - return cfg.fields.arr[i.i], nil + return arr[i.i], nil } func (p cfgPath) SetValue(cfg *Config, opt *options, val value) Error { @@ -188,7 +189,7 @@ func (n namedField) SetValue(opts *options, elem value, v value) Error { return raiseExpectedObject(opts, elem) } - sub.c.fields.fields[n.name] = v + sub.c.fields.set(n.name, v) v.SetContext(context{parent: elem, field: n.name}) return nil } @@ -199,13 +200,7 @@ func (i idxField) SetValue(opts *options, elem value, v value) Error { return raiseExpectedObject(opts, elem) } - if i.i >= len(sub.c.fields.arr) { - tmp := make([]value, i.i+1) - copy(tmp, sub.c.fields.arr) - sub.c.fields.arr = tmp - } - - sub.c.fields.arr[i.i] = v + sub.c.fields.setAt(i.i, v) v.SetContext(context{parent: elem, field: i.String()}) return nil } diff --git a/vendor/github.com/elastic/go-ucfg/reify.go b/vendor/github.com/elastic/go-ucfg/reify.go index 83d87e827707..3ce0390cf764 100644 --- a/vendor/github.com/elastic/go-ucfg/reify.go +++ b/vendor/github.com/elastic/go-ucfg/reify.go @@ -17,7 +17,10 @@ func (c *Config) Unpack(to interface{}, options ...Option) error { } vTo := reflect.ValueOf(to) - if to == nil || (vTo.Kind() != reflect.Ptr && vTo.Kind() != reflect.Map) { + + k := vTo.Kind() + isValid := to != nil && (k == reflect.Ptr || k == reflect.Map) + if !isValid { return raisePointerRequired(vTo) } @@ -32,12 +35,21 @@ func reifyInto(opts *options, to reflect.Value, from *Config) Error { } tTo := chaseTypePointers(to.Type()) + k := tTo.Kind() - switch tTo.Kind() { + switch k { case reflect.Map: return reifyMap(opts, to, from) case reflect.Struct: return reifyStruct(opts, to, from) + case reflect.Slice, reflect.Array: + fopts := fieldOptions{opts: opts, tag: tagOptions{}, validators: nil} + v, err := reifyMergeValue(fopts, to, cfgSub{from}) + if err != nil { + return err + } + to.Set(v) + return nil } return raiseInvalidTopLevelType(to.Interface()) @@ -48,14 +60,15 @@ func reifyMap(opts *options, to reflect.Value, from *Config) Error { return raiseKeyInvalidTypeUnpack(to.Type(), from) } - if len(from.fields.fields) == 0 { + fields := from.fields.dict() + if len(fields) == 0 { return nil } if to.IsNil() { to.Set(reflect.MakeMap(to.Type())) } - for k, value := range from.fields.fields { + for k, value := range fields { key := reflect.ValueOf(k) old := to.MapIndex(key) @@ -88,7 +101,7 @@ func reifyStruct(opts *options, orig reflect.Value, cfg *Config) Error { if v, ok := implementsUnpacker(to); ok { reified, err := cfgSub{cfg}.reify(opts) if err != nil { - raisePathErr(err, cfg.metadata, "", cfg.Path(".")) + return raisePathErr(err, cfg.metadata, "", cfg.Path(".")) } if err := unpackWith(v, reified); err != nil { @@ -113,6 +126,14 @@ func reifyStruct(opts *options, orig reflect.Value, cfg *Config) Error { if err := reifyInto(opts, vField, cfg); err != nil { return err } + case reflect.Slice, reflect.Array: + fopts := fieldOptions{opts: opts, tag: tagOpts, validators: validators} + v, err := reifyMergeValue(fopts, vField, cfgSub{cfg}) + if err != nil { + return err + } + vField.Set(v) + default: return raiseInlineNeedsObject(cfg, stField.Name, vField.Type()) } @@ -378,7 +399,7 @@ func reifyDoArray( func castArr(opts *options, v value) ([]value, Error) { if sub, ok := v.(cfgSub); ok { - return sub.c.fields.arr, nil + return sub.c.fields.array(), nil } if ref, ok := v.(*cfgRef); ok { unrefed, err := ref.resolve(opts) @@ -387,7 +408,7 @@ func castArr(opts *options, v value) ([]value, Error) { } if sub, ok := unrefed.(cfgSub); ok { - return sub.c.fields.arr, nil + return sub.c.fields.array(), nil } } diff --git a/vendor/github.com/elastic/go-ucfg/types.go b/vendor/github.com/elastic/go-ucfg/types.go index b3ea083a837e..230262f4afc8 100644 --- a/vendor/github.com/elastic/go-ucfg/types.go +++ b/vendor/github.com/elastic/go-ucfg/types.go @@ -251,7 +251,6 @@ func (c *cfgString) reflect(*options) (reflect.Value, error) { func (c *cfgString) reify(*options) (interface{}, error) { return c.s, nil } func (c *cfgString) typ(*options) (typeInfo, error) { return typeInfo{"string", tString}, nil } -func (cfgSub) Len(*options) (int, error) { return 1, nil } func (c cfgSub) Context() context { return c.c.ctx } func (cfgSub) toBool(*options) (bool, error) { return false, ErrTypeMismatch } func (cfgSub) toString(*options) (string, error) { return "", ErrTypeMismatch } @@ -260,6 +259,15 @@ func (cfgSub) toUint(*options) (uint64, error) { return 0, ErrTypeMismatch func (cfgSub) toFloat(*options) (float64, error) { return 0, ErrTypeMismatch } func (c cfgSub) toConfig(*options) (*Config, error) { return c.c, nil } +func (c cfgSub) Len(*options) (int, error) { + arr := c.c.fields.array() + if arr != nil { + return len(arr), nil + } + + return 1, nil +} + func (c cfgSub) typ(*options) (typeInfo, error) { return typeInfo{"object", reflect.PtrTo(tConfig)}, nil } @@ -274,18 +282,23 @@ func (c cfgSub) cpy(ctx context) value { c: &Config{ctx: ctx, metadata: c.c.metadata}, } - fields := &fields{ - fields: map[string]value{}, - arr: make([]value, len(c.c.fields.arr)), - } + dict := c.c.fields.dict() + arr := c.c.fields.array() + fields := &fields{} - for name, f := range c.c.fields.fields { + for name, f := range dict { ctx := f.Context() - fields.fields[name] = f.cpy(context{field: ctx.field, parent: newC}) + v := f.cpy(context{field: ctx.field, parent: newC}) + fields.set(name, v) } - for i, f := range c.c.fields.arr { - ctx := f.Context() - fields.arr[i] = f.cpy(context{field: ctx.field, parent: newC}) + + if arr != nil { + fields.a = make([]value, len(arr)) + for i, f := range arr { + ctx := f.Context() + v := f.cpy(context{field: ctx.field, parent: newC}) + fields.setAt(i, v) + } } newC.c.fields = fields @@ -304,15 +317,15 @@ func (c cfgSub) SetContext(ctx context) { } func (c cfgSub) reify(opts *options) (interface{}, error) { - fields := c.c.fields.fields - arr := c.c.fields.arr + fields := c.c.fields.dict() + arr := c.c.fields.array() switch { case len(fields) == 0 && len(arr) == 0: return nil, nil case len(fields) > 0 && len(arr) == 0: m := make(map[string]interface{}) - for k, v := range c.c.fields.fields { + for k, v := range fields { var err error if m[k], err = v.reify(opts); err != nil { return nil, err @@ -330,7 +343,7 @@ func (c cfgSub) reify(opts *options) (interface{}, error) { return m, nil default: m := make(map[string]interface{}) - for k, v := range c.c.fields.fields { + for k, v := range fields { var err error if m[k], err = v.reify(opts); err != nil { return nil, err diff --git a/vendor/github.com/elastic/go-ucfg/ucfg.go b/vendor/github.com/elastic/go-ucfg/ucfg.go index 781fbf40f81a..9e44d4beaf68 100644 --- a/vendor/github.com/elastic/go-ucfg/ucfg.go +++ b/vendor/github.com/elastic/go-ucfg/ucfg.go @@ -19,8 +19,8 @@ type fieldOptions struct { } type fields struct { - fields map[string]value - arr []value + d map[string]value + a []value } // Meta holds additional meta data per config value @@ -54,7 +54,7 @@ var ( func New() *Config { return &Config{ - fields: &fields{map[string]value{}, nil}, + fields: &fields{nil, nil}, } } @@ -66,16 +66,24 @@ func NewFrom(from interface{}, opts ...Option) (*Config, error) { return c, nil } +func (c *Config) IsDict() bool { + return c.fields.dict() != nil +} + +func (c *Config) IsArray() bool { + return c.fields.array() != nil +} + func (c *Config) GetFields() []string { var names []string - for k := range c.fields.fields { + for k := range c.fields.dict() { names = append(names, k) } return names } func (c *Config) HasField(name string) bool { - _, ok := c.fields.fields[name] + _, ok := c.fields.get(name) return ok } @@ -102,3 +110,39 @@ func (c *Config) Parent() *Config { } } } + +func (f *fields) get(name string) (value, bool) { + if f.d == nil { + return nil, false + } + v, found := f.d[name] + return v, found +} + +func (f *fields) dict() map[string]value { + return f.d +} + +func (f *fields) array() []value { + return f.a +} + +func (f *fields) set(name string, v value) { + if f.d == nil { + f.d = map[string]value{} + } + f.d[name] = v +} + +func (f *fields) add(v value) { + f.a = append(f.a, v) +} + +func (f *fields) setAt(idx int, v value) { + if idx >= len(f.a) { + tmp := make([]value, idx+1) + copy(tmp, f.a) + f.a = tmp + } + f.a[idx] = v +}