Skip to content

Commit 10a3c04

Browse files
authored
Merge branch 'v0.11' into dependabot/npm_and_yarn/webui/v0.11/rushstack/eslint-patch-1.10.5
2 parents 91e2470 + 728e321 commit 10a3c04

File tree

22 files changed

+1170
-368
lines changed

22 files changed

+1170
-368
lines changed

config/dynamic/config.go

Lines changed: 4 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package dynamic
22

33
import (
44
"bytes"
5-
"fmt"
65
"github.com/Masterminds/sprig"
76
"mokapi/sortedmap"
87
"strings"
@@ -22,7 +21,7 @@ type Config struct {
2221
Data interface{}
2322
Refs Refs
2423
Listeners Listeners
25-
Scope *Scope
24+
Scope Scope
2625
}
2726

2827
type Refs struct {
@@ -48,13 +47,6 @@ func AddRef(parent, ref *Config) {
4847
parent.Info.Time = ref.Info.Time
4948
parent.Listeners.Invoke(parent)
5049
})
51-
52-
if ref.Scope == nil {
53-
ref.OpenScope("")
54-
}
55-
if parent.Scope != nil {
56-
ref.Scope.dynamic = parent.Scope.dynamic
57-
}
5850
}
5951

6052
func (l *Listeners) Add(key string, fn ConfigListener) {
@@ -156,81 +148,10 @@ func extractUsername(s string) string {
156148
return slice[len(slice)-1]
157149
}
158150

159-
type Scope struct {
160-
Name string
161-
162-
stack []map[string]interface{}
163-
dynamic *Scope
164-
}
165-
166-
func NewScope(name string) *Scope {
167-
return &Scope{Name: name, stack: []map[string]interface{}{
168-
{},
169-
}}
170-
}
171-
172-
func (s *Scope) Get(name string) (interface{}, error) {
173-
if s == nil {
174-
return nil, fmt.Errorf("anchor '%s' not found: no scope present", name)
175-
}
176-
177-
if len(s.stack) != 0 {
178-
lexical := s.stack[len(s.stack)-1]
179-
if v, ok := lexical[name]; ok {
180-
return v, nil
181-
}
182-
}
183-
184-
return nil, fmt.Errorf("anchor '%s' not found in scope '%s", name, s.Name)
185-
}
186-
187-
func (s *Scope) Set(name string, value interface{}) error {
188-
if s == nil || len(s.stack) == 0 {
189-
return fmt.Errorf("set anchor '%s' failed: no scope present", name)
190-
}
191-
192-
lexical := s.stack[len(s.stack)-1]
193-
if _, ok := lexical[name]; ok {
194-
return fmt.Errorf("anchor '%s' already defined in scope '%s'", name, s.Name)
195-
}
196-
lexical[name] = value
197-
return nil
198-
}
199-
200-
func (s *Scope) GetDynamic(name string) (interface{}, error) {
201-
return s.dynamic.Get(name)
202-
}
203-
204-
func (s *Scope) SetDynamic(name string, value interface{}) error {
205-
return s.dynamic.Set(name, value)
206-
}
207-
208-
func (s *Scope) openScope(name string) {
209-
s.stack = append(s.stack, map[string]interface{}{})
210-
}
211-
212-
func (s *Scope) close() {
213-
s.stack = s.stack[:len(s.stack)-1]
214-
}
215-
216-
func (s *Scope) IsEmpty() bool {
217-
return len(s.stack) == 0
218-
}
219-
220151
func (c *Config) OpenScope(name string) {
221-
if c.Scope == nil {
222-
c.Scope = NewScope(name)
223-
} else {
224-
c.Scope.openScope(name)
225-
}
152+
c.Scope.Open(name)
226153
}
227154

228-
func (c *Config) Close() {
229-
if c.Scope != nil {
230-
if c.Scope.IsEmpty() {
231-
c.Scope = nil
232-
} else {
233-
c.Scope.close()
234-
}
235-
}
155+
func (c *Config) CloseScope() {
156+
c.Scope.Close()
236157
}

config/dynamic/dynamictest/reader.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,34 @@ var NotFound = errors.New("TestReader: config not found")
1010

1111
type Reader struct {
1212
Data map[string]*dynamic.Config
13+
14+
parsed map[string]bool
1315
}
1416

1517
func (r *Reader) Read(u *url.URL, v any) (*dynamic.Config, error) {
1618
if r.Data == nil {
1719
return nil, NotFound
1820
}
1921
if c, ok := r.Data[u.String()]; ok {
22+
if c.Data == nil {
23+
c.Data = v
24+
err := dynamic.Parse(c, r)
25+
return c, err
26+
}
27+
2028
if p, isParser := c.Data.(dynamic.Parser); isParser {
29+
if _, alreadyParsed := r.parsed[u.String()]; alreadyParsed {
30+
return c, nil
31+
}
2132
if err := p.Parse(c, r); err != nil {
2233
return nil, err
2334
}
24-
return c, nil
35+
36+
if r.parsed == nil {
37+
r.parsed = make(map[string]bool)
38+
}
39+
40+
r.parsed[u.String()] = true
2541
}
2642

2743
return c, nil

config/dynamic/json.go

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,17 @@ type decoder struct {
1717
}
1818

1919
func UnmarshalJSON(b []byte, v interface{}) error {
20+
rv := reflect.ValueOf(v)
21+
if rv.Kind() != reflect.Pointer || rv.IsNil() {
22+
return &json.InvalidUnmarshalError{Type: reflect.TypeOf(v)}
23+
}
24+
2025
d := &decoder{
2126
d: json.NewDecoder(bytes.NewReader(b)),
2227
b: b,
2328
}
2429

25-
err := unmarshalJSON(d, reflect.ValueOf(v))
30+
err := unmarshalJSON(d, rv)
2631
if errors.Is(err, io.ErrUnexpectedEOF) {
2732
return fmt.Errorf("unexpected end of JSON input")
2833
}
@@ -41,15 +46,19 @@ func NextTokenIndex(b []byte) int64 {
4146
}
4247

4348
func unmarshalJSON(d *decoder, v reflect.Value) error {
44-
if unmarshaler(v) {
45-
v = indirect(v, false)
49+
i2 := v.Interface()
50+
_ = i2
51+
52+
if u, _ := indirect(v); u != nil {
4653
p := reflect.New(v.Type())
4754
p.Elem().Set(v)
4855
err := d.d.Decode(p.Interface())
4956
if err != nil {
5057
return err
5158
}
52-
v.Set(p.Elem())
59+
if v.CanSet() {
60+
v.Set(p.Elem())
61+
}
5362
return nil
5463
}
5564

@@ -70,7 +79,7 @@ func value(token json.Token, d *decoder, v reflect.Value) error {
7079
return array(d, v)
7180
}
7281
case string:
73-
v = indirect(v, false)
82+
_, v = indirect(v)
7483
switch v.Kind() {
7584
case reflect.String:
7685
v.SetString(t)
@@ -84,7 +93,7 @@ func value(token json.Token, d *decoder, v reflect.Value) error {
8493
case float64:
8594
return number(t, v)
8695
case bool:
87-
v = indirect(v, false)
96+
_, v = indirect(v)
8897
if v.Type().AssignableTo(reflect.TypeOf(t)) {
8998
v.Set(reflect.ValueOf(t))
9099
} else {
@@ -94,7 +103,6 @@ func value(token json.Token, d *decoder, v reflect.Value) error {
94103
case nil:
95104
switch v.Kind() {
96105
case reflect.Interface, reflect.Pointer, reflect.Map, reflect.Slice:
97-
v = indirect(v, true)
98106
v.Set(reflect.Zero(v.Type()))
99107
return nil
100108
default:
@@ -107,7 +115,7 @@ func value(token json.Token, d *decoder, v reflect.Value) error {
107115
}
108116

109117
func object(d *decoder, v reflect.Value) error {
110-
v = indirect(v, false)
118+
_, v = indirect(v)
111119
// check type
112120
switch v.Kind() {
113121
case reflect.Struct, reflect.Map:
@@ -157,7 +165,7 @@ func object(d *decoder, v reflect.Value) error {
157165
}
158166

159167
func array(d *decoder, v reflect.Value) error {
160-
v = indirect(v, false)
168+
_, v = indirect(v)
161169
isAny := false
162170
// check type
163171
switch v.Kind() {
@@ -198,7 +206,7 @@ func array(d *decoder, v reflect.Value) error {
198206
v.Set(reflect.Append(v.Elem(), p.Elem()))
199207
} else {
200208
p := reflect.New(v.Type().Elem())
201-
if unmarshaler(p) {
209+
if u, _ := indirect(p); u != nil {
202210
err = d.d.Decode(p.Interface())
203211
if err != nil {
204212
return err
@@ -222,7 +230,7 @@ func array(d *decoder, v reflect.Value) error {
222230
}
223231

224232
func number(f float64, v reflect.Value) error {
225-
v = indirect(v, false)
233+
_, v = indirect(v)
226234
switch v.Kind() {
227235
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
228236
n := int64(f)
@@ -257,47 +265,49 @@ func number(f float64, v reflect.Value) error {
257265
return nil
258266
}
259267

260-
func unmarshaler(v reflect.Value) bool {
268+
func indirect(v reflect.Value) (json.Unmarshaler, reflect.Value) {
269+
v0 := v
270+
haveAddr := false
271+
261272
// If v is a named type and is addressable,
262273
// start with its address, so that if the type has pointer methods,
263274
// we find them.
264275
if v.Kind() != reflect.Pointer && v.Type().Name() != "" && v.CanAddr() {
265276
v = v.Addr()
277+
haveAddr = true
266278
}
267279

268280
for {
269-
if v.Kind() != reflect.Pointer {
270-
break
271-
}
272-
273-
if _, ok := v.Interface().(json.Unmarshaler); ok {
274-
return true
275-
}
276-
277-
if v.IsNil() {
278-
v.Set(reflect.New(v.Type().Elem()))
281+
// Load value from interface, but only if the result will be
282+
// usefully addressable.
283+
if v.Kind() == reflect.Interface && !v.IsNil() {
284+
e := v.Elem()
285+
if e.Kind() == reflect.Pointer && !e.IsNil() {
286+
v = e
287+
continue
288+
}
279289
}
280-
v = v.Elem()
281-
}
282-
return false
283-
}
284290

285-
func indirect(v reflect.Value, isNil bool) reflect.Value {
286-
for {
287291
if v.Kind() != reflect.Pointer {
288292
break
289293
}
290294

291-
if isNil && v.CanSet() {
292-
break
295+
if u, ok := v.Interface().(json.Unmarshaler); ok {
296+
return u, v
293297
}
294298

295299
if v.IsNil() {
296300
v.Set(reflect.New(v.Type().Elem()))
297301
}
298-
v = v.Elem()
302+
303+
if haveAddr {
304+
v = v0 // restore original value after round-trip Value.Addr().Elem()
305+
haveAddr = false
306+
} else {
307+
v = v.Elem()
308+
}
299309
}
300-
return v
310+
return nil, v
301311
}
302312

303313
func getField(v reflect.Value, name string) (reflect.Value, error) {

0 commit comments

Comments
 (0)