@@ -258,7 +258,7 @@ func loadSections(filename string, config map[string]interface{}, configDetails
258258 return nil , err
259259 }
260260
261- cfg .Networks , err = LoadNetworks (getSection (config , "networks" ), configDetails . Version )
261+ cfg .Networks , err = LoadNetworks (getSection (config , "networks" ))
262262 if err != nil {
263263 return nil , err
264264 }
@@ -423,6 +423,14 @@ func formatInvalidKeyError(keyPrefix string, key interface{}) error {
423423func LoadServices (filename string , servicesDict map [string ]interface {}, workingDir string , lookupEnv template.Mapping , opts * Options ) ([]types.ServiceConfig , error ) {
424424 var services []types.ServiceConfig
425425
426+ x , ok := servicesDict ["extensions" ]
427+ if ok {
428+ // as a top-level attribute, "services" doesn't support extensions, and a service can be named `x-foo`
429+ for k , v := range x .(map [string ]interface {}) {
430+ servicesDict [k ] = v
431+ }
432+ }
433+
426434 for name := range servicesDict {
427435 serviceConfig , err := loadServiceWithExtends (filename , name , servicesDict , workingDir , lookupEnv , opts , & cycleTracker {})
428436 if err != nil {
@@ -617,7 +625,7 @@ func transformUlimits(data interface{}) (interface{}, error) {
617625
618626// LoadNetworks produces a NetworkConfig map from a compose file Dict
619627// the source Dict is not validated if directly used. Use Load() to enable validation
620- func LoadNetworks (source map [string ]interface {}, version string ) (map [string ]types.NetworkConfig , error ) {
628+ func LoadNetworks (source map [string ]interface {}) (map [string ]types.NetworkConfig , error ) {
621629 networks := make (map [string ]types.NetworkConfig )
622630 err := Transform (source , & networks )
623631 if err != nil {
0 commit comments