@@ -185,6 +185,7 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
185185 LookupValue : configDetails .LookupEnv ,
186186 TypeCastMapping : interpolateTypeCastMapping ,
187187 },
188+ ResolvePaths : true ,
188189 }
189190
190191 for _ , op := range options {
@@ -248,14 +249,6 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
248249 model = merged
249250 }
250251
251- for _ , s := range model .Services {
252- var newEnvFiles types.StringList
253- for _ , ef := range s .EnvFile {
254- newEnvFiles = append (newEnvFiles , absPath (configDetails .WorkingDir , ef ))
255- }
256- s .EnvFile = newEnvFiles
257- }
258-
259252 project := & types.Project {
260253 Name : projectName ,
261254 WorkingDir : configDetails .WorkingDir ,
@@ -268,8 +261,24 @@ func Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.
268261 Extensions : model .Extensions ,
269262 }
270263
264+ if opts .ResolvePaths {
265+ err = ResolveRelativePaths (project )
266+ if err != nil {
267+ return nil , err
268+ }
269+ }
270+
271+ if opts .ConvertWindowsPaths {
272+ for i , service := range project .Services {
273+ for j , volume := range service .Volumes {
274+ service .Volumes [j ] = convertVolumePath (volume )
275+ }
276+ project .Services [i ] = service
277+ }
278+ }
279+
271280 if ! opts .SkipNormalization {
272- err = Normalize (project , opts . ResolvePaths )
281+ err = Normalize (project )
273282 if err != nil {
274283 return nil , err
275284 }
@@ -428,11 +437,11 @@ func loadSections(filename string, config map[string]interface{}, configDetails
428437 if err != nil {
429438 return nil , err
430439 }
431- cfg .Secrets , err = LoadSecrets (getSection (config , "secrets" ), configDetails , opts . ResolvePaths )
440+ cfg .Secrets , err = LoadSecrets (getSection (config , "secrets" ))
432441 if err != nil {
433442 return nil , err
434443 }
435- cfg .Configs , err = LoadConfigObjs (getSection (config , "configs" ), configDetails , opts . ResolvePaths )
444+ cfg .Configs , err = LoadConfigObjs (getSection (config , "configs" ))
436445 if err != nil {
437446 return nil , err
438447 }
@@ -634,7 +643,7 @@ func loadServiceWithExtends(filename, name string, servicesDict map[string]inter
634643 target = map [string ]interface {}{}
635644 }
636645
637- serviceConfig , err := LoadService (name , target .(map [string ]interface {}), workingDir , lookupEnv , opts . ResolvePaths , opts . ConvertWindowsPaths )
646+ serviceConfig , err := LoadService (name , target .(map [string ]interface {}))
638647 if err != nil {
639648 return nil , err
640649 }
@@ -672,21 +681,9 @@ func loadServiceWithExtends(filename, name string, servicesDict map[string]inter
672681 // make the paths relative to `file` rather than `baseFilePath` so
673682 // that the resulting paths won't be absolute if `file` isn't an
674683 // absolute path.
675- baseFileParent := filepath .Dir (file )
676- if baseService .Build != nil {
677- baseService .Build .Context = resolveBuildContextPath (baseFileParent , baseService .Build .Context )
678- }
679684
680- for i , vol := range baseService .Volumes {
681- if vol .Type != types .VolumeTypeBind {
682- continue
683- }
684- baseService .Volumes [i ].Source = resolveMaybeUnixPath (vol .Source , baseFileParent , lookupEnv )
685- }
686-
687- for i , envFile := range baseService .EnvFile {
688- baseService .EnvFile [i ] = resolveMaybeUnixPath (envFile , baseFileParent , lookupEnv )
689- }
685+ baseFileParent := filepath .Dir (file )
686+ ResolveServiceRelativePaths (baseFileParent , baseService )
690687 }
691688
692689 serviceConfig , err = _merge (baseService , serviceConfig )
@@ -699,22 +696,9 @@ func loadServiceWithExtends(filename, name string, servicesDict map[string]inter
699696 return serviceConfig , nil
700697}
701698
702- func resolveBuildContextPath (baseFileParent string , context string ) string {
703- // Checks if the context is an HTTP(S) URL or a remote git repository URL
704- for _ , prefix := range []string {"https://" , "http://" , "git://" , "github.com/" , "git@" } {
705- if strings .HasPrefix (context , prefix ) {
706- return context
707- }
708- }
709-
710- // Note that the Dockerfile is always defined relative to the
711- // build context, so there's no need to update the Dockerfile field.
712- return absPath (baseFileParent , context )
713- }
714-
715699// LoadService produces a single ServiceConfig from a compose file Dict
716700// the serviceDict is not validated if directly used. Use Load() to enable validation
717- func LoadService (name string , serviceDict map [string ]interface {}, workingDir string , lookupEnv template. Mapping , resolvePaths bool , convertPaths bool ) (* types.ServiceConfig , error ) {
701+ func LoadService (name string , serviceDict map [string ]interface {}) (* types.ServiceConfig , error ) {
718702 serviceConfig := & types.ServiceConfig {
719703 Scale : 1 ,
720704 }
@@ -731,13 +715,6 @@ func LoadService(name string, serviceDict map[string]interface{}, workingDir str
731715 return nil , errors .New (`invalid mount config for type "bind": field Source must not be empty` )
732716 }
733717
734- if resolvePaths || convertPaths {
735- volume = resolveVolumePath (volume , workingDir , lookupEnv )
736- }
737-
738- if convertPaths {
739- volume = convertVolumePath (volume )
740- }
741718 serviceConfig .Volumes [i ] = volume
742719 }
743720
@@ -759,8 +736,8 @@ func convertVolumePath(volume types.ServiceVolumeConfig) types.ServiceVolumeConf
759736 return volume
760737}
761738
762- func resolveMaybeUnixPath (path string , workingDir string , lookupEnv template. Mapping ) string {
763- filePath := expandUser (path , lookupEnv )
739+ func resolveMaybeUnixPath (workingDir string , path string ) string {
740+ filePath := expandUser (path )
764741 // Check if source is an absolute path (either Unix or Windows), to
765742 // handle a Windows client with a Unix daemon or vice-versa.
766743 //
@@ -773,20 +750,15 @@ func resolveMaybeUnixPath(path string, workingDir string, lookupEnv template.Map
773750 return filePath
774751}
775752
776- func resolveVolumePath (volume types.ServiceVolumeConfig , workingDir string , lookupEnv template.Mapping ) types.ServiceVolumeConfig {
777- volume .Source = resolveMaybeUnixPath (volume .Source , workingDir , lookupEnv )
778- return volume
779- }
780-
781753func resolveSecretsPath (secret types.SecretConfig , workingDir string , lookupEnv template.Mapping ) types.SecretConfig {
782754 if ! secret .External .External && secret .File != "" {
783- secret .File = resolveMaybeUnixPath (secret . File , workingDir , lookupEnv )
755+ secret .File = resolveMaybeUnixPath (workingDir , secret . File )
784756 }
785757 return secret
786758}
787759
788760// TODO: make this more robust
789- func expandUser (path string , lookupEnv template. Mapping ) string {
761+ func expandUser (path string ) string {
790762 if strings .HasPrefix (path , "~" ) {
791763 home , err := os .UserHomeDir ()
792764 if err != nil {
@@ -886,44 +858,39 @@ func LoadVolumes(source map[string]interface{}) (map[string]types.VolumeConfig,
886858
887859// LoadSecrets produces a SecretConfig map from a compose file Dict
888860// the source Dict is not validated if directly used. Use Load() to enable validation
889- func LoadSecrets (source map [string ]interface {}, details types. ConfigDetails , resolvePaths bool ) (map [string ]types.SecretConfig , error ) {
861+ func LoadSecrets (source map [string ]interface {}) (map [string ]types.SecretConfig , error ) {
890862 secrets := make (map [string ]types.SecretConfig )
891863 if err := Transform (source , & secrets ); err != nil {
892864 return secrets , err
893865 }
894866 for name , secret := range secrets {
895- obj , err := loadFileObjectConfig (name , "secret" , types .FileObjectConfig (secret ), details , false )
867+ obj , err := loadFileObjectConfig (name , "secret" , types .FileObjectConfig (secret ))
896868 if err != nil {
897869 return nil , err
898870 }
899- secretConfig := types .SecretConfig (obj )
900- if resolvePaths {
901- secretConfig = resolveSecretsPath (secretConfig , details .WorkingDir , details .LookupEnv )
902- }
903- secrets [name ] = secretConfig
871+ secrets [name ] = types .SecretConfig (obj )
904872 }
905873 return secrets , nil
906874}
907875
908876// LoadConfigObjs produces a ConfigObjConfig map from a compose file Dict
909877// the source Dict is not validated if directly used. Use Load() to enable validation
910- func LoadConfigObjs (source map [string ]interface {}, details types. ConfigDetails , resolvePaths bool ) (map [string ]types.ConfigObjConfig , error ) {
878+ func LoadConfigObjs (source map [string ]interface {}) (map [string ]types.ConfigObjConfig , error ) {
911879 configs := make (map [string ]types.ConfigObjConfig )
912880 if err := Transform (source , & configs ); err != nil {
913881 return configs , err
914882 }
915883 for name , config := range configs {
916- obj , err := loadFileObjectConfig (name , "config" , types .FileObjectConfig (config ), details , resolvePaths )
884+ obj , err := loadFileObjectConfig (name , "config" , types .FileObjectConfig (config ))
917885 if err != nil {
918886 return nil , err
919887 }
920- configConfig := types .ConfigObjConfig (obj )
921- configs [name ] = configConfig
888+ configs [name ] = types .ConfigObjConfig (obj )
922889 }
923890 return configs , nil
924891}
925892
926- func loadFileObjectConfig (name string , objType string , obj types.FileObjectConfig , details types. ConfigDetails , resolvePaths bool ) (types.FileObjectConfig , error ) {
893+ func loadFileObjectConfig (name string , objType string , obj types.FileObjectConfig ) (types.FileObjectConfig , error ) {
927894 // if "external: true"
928895 switch {
929896 case obj .External .External :
@@ -943,26 +910,11 @@ func loadFileObjectConfig(name string, objType string, obj types.FileObjectConfi
943910 if obj .File != "" {
944911 return obj , errors .Errorf ("%[1]s %[2]s: %[1]s.driver and %[1]s.file conflict; only use %[1]s.driver" , objType , name )
945912 }
946- default :
947- if obj .File != "" && resolvePaths {
948- obj .File = absPath (details .WorkingDir , obj .File )
949- }
950913 }
951914
952915 return obj , nil
953916}
954917
955- func absPath (workingDir string , filePath string ) string {
956- if strings .HasPrefix (filePath , "~" ) {
957- home , _ := os .UserHomeDir ()
958- return filepath .Join (home , filePath [1 :])
959- }
960- if filepath .IsAbs (filePath ) {
961- return filePath
962- }
963- return filepath .Join (workingDir , filePath )
964- }
965-
966918var transformMapStringString TransformerFunc = func (data interface {}) (interface {}, error ) {
967919 switch value := data .(type ) {
968920 case map [string ]interface {}:
0 commit comments