diff --git a/compose/config/config.py b/compose/config/config.py index 84933e9c9..3bd49a0f7 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -408,7 +408,7 @@ def load(config_details, compatibility=False, interpolate=True): configs = load_mapping( config_details.config_files, 'get_configs', 'Config', config_details.working_dir ) - service_dicts = load_services(config_details, main_file, compatibility) + service_dicts = load_services(config_details, main_file, compatibility, interpolate=interpolate) if main_file.version != V1: for service_dict in service_dicts: @@ -460,7 +460,7 @@ def validate_external(entity_type, name, config, version): entity_type, name, ', '.join(k for k in config if k != 'external'))) -def load_services(config_details, config_file, compatibility=False): +def load_services(config_details, config_file, compatibility=False, interpolate=True): def build_service(service_name, service_dict, service_names): service_config = ServiceConfig.with_abs_paths( config_details.working_dir, @@ -479,7 +479,8 @@ def load_services(config_details, config_file, compatibility=False): service_names, config_file.version, config_details.environment, - compatibility + compatibility, + interpolate ) return service_dict @@ -679,13 +680,13 @@ class ServiceExtendsResolver(object): return filename -def resolve_environment(service_dict, environment=None): +def resolve_environment(service_dict, environment=None, interpolate=True): """Unpack any environment variables from an env_file, if set. Interpolate environment values if set. """ env = {} for env_file in service_dict.get('env_file', []): - env.update(env_vars_from_file(env_file)) + env.update(env_vars_from_file(env_file, interpolate)) env.update(parse_environment(service_dict.get('environment'))) return dict(resolve_env_var(k, v, environment) for k, v in six.iteritems(env)) @@ -881,11 +882,12 @@ def finalize_service_volumes(service_dict, environment): return service_dict -def finalize_service(service_config, service_names, version, environment, compatibility): +def finalize_service(service_config, service_names, version, environment, compatibility, + interpolate=True): service_dict = dict(service_config.config) if 'environment' in service_dict or 'env_file' in service_dict: - service_dict['environment'] = resolve_environment(service_dict, environment) + service_dict['environment'] = resolve_environment(service_dict, environment, interpolate) service_dict.pop('env_file', None) if 'volumes_from' in service_dict: diff --git a/compose/config/environment.py b/compose/config/environment.py index 6afbfc972..292029eb5 100644 --- a/compose/config/environment.py +++ b/compose/config/environment.py @@ -30,7 +30,7 @@ def split_env(env): return key, value -def env_vars_from_file(filename): +def env_vars_from_file(filename, interpolate=True): """ Read in a line delimited file of environment variables. """ @@ -39,6 +39,7 @@ def env_vars_from_file(filename): elif not os.path.isfile(filename): raise EnvFileNotFound("{} is not a file.".format(filename)) + # TODO: now we should do something with interpolate here, but what? return dotenv.dotenv_values(dotenv_path=filename, encoding='utf-8-sig') diff --git a/tests/fixtures/env/three.env b/tests/fixtures/env/three.env new file mode 100644 index 000000000..c2da74f19 --- /dev/null +++ b/tests/fixtures/env/three.env @@ -0,0 +1,2 @@ +FOO=NO $ENV VAR +DOO=NO ${ENV} VAR diff --git a/tests/unit/config/config_test.py b/tests/unit/config/config_test.py index dc346df95..933f659f8 100644 --- a/tests/unit/config/config_test.py +++ b/tests/unit/config/config_test.py @@ -5420,15 +5420,19 @@ class SerializeTest(unittest.TestCase): 'environment': { 'CURRENCY': '$' }, + 'env_file': ['tests/fixtures/env/three.env'], 'entrypoint': ['$SHELL', '-c'], } } } - config_dict = config.load(build_config_details(cfg), interpolate=False) + config_dict = config.load(build_config_details(cfg, working_dir='.'), interpolate=False) serialized_config = yaml.safe_load(serialize_config(config_dict, escape_dollar=False)) serialized_service = serialized_config['services']['web'] assert serialized_service['environment']['CURRENCY'] == '$' + # Values coming from env_files are not allowed to have variables + assert serialized_service['environment']['FOO'] == 'NO $$ENV VAR' + assert serialized_service['environment']['DOO'] == 'NO $${ENV} VAR' assert serialized_service['command'] == 'echo $FOO' assert serialized_service['entrypoint'][0] == '$SHELL'