@@ -328,7 +328,7 @@ func createTransformHook(additionalTransformers ...Transformer) mapstructure.Dec
328328 reflect .TypeOf (types.MappingWithEquals {}): transformMappingOrListFunc ("=" , true ),
329329 reflect .TypeOf (types.Labels {}): transformMappingOrListFunc ("=" , false ),
330330 reflect .TypeOf (types.MappingWithColon {}): transformMappingOrListFunc (":" , false ),
331- reflect .TypeOf (types.HostsList {}): transformListOrMappingFunc ( ":" , false ) ,
331+ reflect .TypeOf (types.HostsList {}): transformHostsList ,
332332 reflect .TypeOf (types.ServiceVolumeConfig {}): transformServiceVolumeConfig ,
333333 reflect .TypeOf (types.BuildConfig {}): transformBuildConfig ,
334334 reflect .TypeOf (types .Duration (0 )): transformStringToDuration ,
@@ -808,28 +808,58 @@ var transformStringList TransformerFunc = func(data any) (any, error) {
808808 }
809809}
810810
811- func transformMappingOrListFunc (sep string , allowNil bool ) TransformerFunc {
812- return func (data any ) (any , error ) {
813- return transformMappingOrList (data , sep , allowNil ), nil
814- }
815- }
811+ var transformHostsList TransformerFunc = func (data any ) (any , error ) {
812+ hl := transformListOrMapping (data , ":" , false , []string {"=" , ":" })
816813
817- func transformListOrMappingFunc (sep string , allowNil bool ) TransformerFunc {
818- return func (data any ) (any , error ) {
819- return transformListOrMapping (data , sep , allowNil ), nil
814+ // Remove brackets from IP addresses if present (for example "[::1]" -> "::1").
815+ result := make ([]string , 0 , len (hl ))
816+ for _ , hip := range hl {
817+ host , ip , _ := strings .Cut (hip , ":" )
818+ if len (ip ) > 2 && ip [0 ] == '[' && ip [len (ip )- 1 ] == ']' {
819+ ip = ip [1 : len (ip )- 1 ]
820+ }
821+ result = append (result , fmt .Sprintf ("%s:%s" , host , ip ))
820822 }
823+ return result , nil
821824}
822825
823- func transformListOrMapping (listOrMapping any , sep string , allowNil bool ) any {
826+ // transformListOrMapping transforms pairs of strings that may be represented as
827+ // a map, or a list of '=' or ':' separated strings, into a list of ':' separated
828+ // strings.
829+ func transformListOrMapping (listOrMapping any , sep string , allowNil bool , allowSeps []string ) []string {
824830 switch value := listOrMapping .(type ) {
825831 case map [string ]any :
826832 return toStringList (value , sep , allowNil )
827833 case []any :
828- return listOrMapping
834+ result := make ([]string , 0 , len (value ))
835+ for _ , entry := range value {
836+ for i , allowSep := range allowSeps {
837+ entry := fmt .Sprint (entry )
838+ k , v , ok := strings .Cut (entry , allowSep )
839+ if ok {
840+ // Entry uses this allowed separator. Add it to the result, using
841+ // sep as a separator.
842+ result = append (result , fmt .Sprintf ("%s%s%s" , k , sep , v ))
843+ break
844+ } else if i == len (allowSeps )- 1 {
845+ // No more separators to try, keep the entry if allowNil.
846+ if allowNil {
847+ result = append (result , k )
848+ }
849+ }
850+ }
851+ }
852+ return result
829853 }
830854 panic (errors .Errorf ("expected a map or a list, got %T: %#v" , listOrMapping , listOrMapping ))
831855}
832856
857+ func transformMappingOrListFunc (sep string , allowNil bool ) TransformerFunc {
858+ return func (data any ) (any , error ) {
859+ return transformMappingOrList (data , sep , allowNil ), nil
860+ }
861+ }
862+
833863func transformMappingOrList (mappingOrList any , sep string , allowNil bool ) any {
834864 switch values := mappingOrList .(type ) {
835865 case map [string ]any :
0 commit comments