@@ -53,6 +53,8 @@ type Options struct {
5353 SkipNormalization bool
5454 // Resolve paths
5555 ResolvePaths bool
56+ // Convert Windows paths
57+ ConvertWindowsPaths bool
5658 // Skip consistency check
5759 SkipConsistencyCheck bool
5860 // Skip extends
@@ -489,7 +491,7 @@ func loadServiceWithExtends(filename, name string, servicesDict map[string]inter
489491 return nil , fmt .Errorf ("cannot extend service %q in %s: service not found" , name , filename )
490492 }
491493
492- serviceConfig , err := LoadService (name , target .(map [string ]interface {}), workingDir , lookupEnv , opts .ResolvePaths )
494+ serviceConfig , err := LoadService (name , target .(map [string ]interface {}), workingDir , lookupEnv , opts .ResolvePaths , opts . ConvertWindowsPaths )
493495 if err != nil {
494496 return nil , err
495497 }
@@ -552,7 +554,7 @@ func loadServiceWithExtends(filename, name string, servicesDict map[string]inter
552554
553555// LoadService produces a single ServiceConfig from a compose file Dict
554556// the serviceDict is not validated if directly used. Use Load() to enable validation
555- func LoadService (name string , serviceDict map [string ]interface {}, workingDir string , lookupEnv template.Mapping , resolvePaths bool ) (* types.ServiceConfig , error ) {
557+ func LoadService (name string , serviceDict map [string ]interface {}, workingDir string , lookupEnv template.Mapping , resolvePaths bool , convertPaths bool ) (* types.ServiceConfig , error ) {
556558 serviceConfig := & types.ServiceConfig {
557559 Scale : 1 ,
558560 }
@@ -577,11 +579,30 @@ func LoadService(name string, serviceDict map[string]interface{}, workingDir str
577579 if resolvePaths {
578580 serviceConfig .Volumes [i ] = resolveVolumePath (volume , workingDir , lookupEnv )
579581 }
582+
583+ if convertPaths {
584+ serviceConfig .Volumes [i ] = convertVolumePath (volume )
585+ }
580586 }
581587
582588 return serviceConfig , nil
583589}
584590
591+ // Windows paths, c:\\my\\path\\shiny, need to be changed to be compatible with
592+ // the Engine. Volume paths are expected to be linux style /c/my/path/shiny/
593+ func convertVolumePath (volume types.ServiceVolumeConfig ) types.ServiceVolumeConfig {
594+ volumeName := strings .ToLower (filepath .VolumeName (volume .Source ))
595+ if len (volumeName ) != 2 {
596+ return volume
597+ }
598+
599+ convertedSource := fmt .Sprintf ("/%c%s" , volumeName [0 ], volume .Source [len (volumeName ):])
600+ convertedSource = strings .ReplaceAll (convertedSource , "\\ " , "/" )
601+
602+ volume .Source = convertedSource
603+ return volume
604+ }
605+
585606func resolveEnvironment (serviceConfig * types.ServiceConfig , workingDir string , lookupEnv template.Mapping ) error {
586607 environment := types.MappingWithEquals {}
587608
0 commit comments