@@ -30,6 +30,7 @@ import (
30
30
"io"
31
31
"os"
32
32
"path/filepath"
33
+ "reflect"
33
34
"strings"
34
35
35
36
"dario.cat/mergo"
@@ -310,12 +311,6 @@ func LoadConfig(ctx context.Context, path string, out *Config) error {
310
311
pending = append (pending , imports ... )
311
312
}
312
313
313
- // Fix up the list of config files loaded
314
- out .Imports = []string {}
315
- for path := range loaded {
316
- out .Imports = append (out .Imports , path )
317
- }
318
-
319
314
err := out .ValidateVersion ()
320
315
if err != nil {
321
316
return fmt .Errorf ("failed to load TOML from %s: %w" , path , err )
@@ -408,9 +403,11 @@ func resolveImports(parent string, imports []string) ([]string, error) {
408
403
// 0 1 1
409
404
// []{"1"} []{"2"} []{"1","2"}
410
405
// []{"1"} []{} []{"1"}
406
+ // []{"1", "2"} []{"1"} []{"1","2"}
407
+ // []{} []{"2"} []{"2"}
411
408
// Maps merged by keys, but values are replaced entirely.
412
409
func mergeConfig (to , from * Config ) error {
413
- err := mergo .Merge (to , from , mergo .WithOverride , mergo .WithAppendSlice )
410
+ err := mergo .Merge (to , from , mergo .WithOverride , mergo .WithTransformers ( sliceTransformer {}) )
414
411
if err != nil {
415
412
return err
416
413
}
@@ -435,6 +432,43 @@ func mergeConfig(to, from *Config) error {
435
432
return nil
436
433
}
437
434
435
+ type sliceTransformer struct {}
436
+
437
+ func (sliceTransformer ) Transformer (t reflect.Type ) func (dst , src reflect.Value ) error {
438
+ if t .Kind () != reflect .Slice {
439
+ return nil
440
+ }
441
+ return func (dst , src reflect.Value ) error {
442
+ if ! dst .CanSet () {
443
+ return nil
444
+ }
445
+ if src .Type () != dst .Type () {
446
+ return fmt .Errorf ("cannot append two slice with different type (%s, %s)" , src .Type (), dst .Type ())
447
+ }
448
+ for i := 0 ; i < src .Len (); i ++ {
449
+ found := false
450
+ for j := 0 ; j < dst .Len (); j ++ {
451
+ srcv := src .Index (i )
452
+ dstv := dst .Index (j )
453
+ if ! srcv .CanInterface () || ! dstv .CanInterface () {
454
+ if srcv .Equal (dstv ) {
455
+ found = true
456
+ break
457
+ }
458
+ } else if reflect .DeepEqual (srcv .Interface (), dstv .Interface ()) {
459
+ found = true
460
+ break
461
+ }
462
+ }
463
+ if ! found {
464
+ dst .Set (reflect .Append (dst , src .Index (i )))
465
+ }
466
+ }
467
+
468
+ return nil
469
+ }
470
+ }
471
+
438
472
// V2DisabledFilter matches based on URI
439
473
func V2DisabledFilter (list []string ) plugin.DisableFilter {
440
474
set := make (map [string ]struct {}, len (list ))
0 commit comments