diff --git a/compose/config/config.py b/compose/config/config.py index 39c815a98..cd708bae3 100644 --- a/compose/config/config.py +++ b/compose/config/config.py @@ -304,7 +304,16 @@ def find(base_dir, filenames, environment, override_dir=None): if filenames: filenames = [os.path.join(base_dir, f) for f in filenames] else: + # search for compose files in the base dir and its parents filenames = get_default_config_files(base_dir) + if not filenames and not override_dir: + # none found in base_dir and no override_dir defined + raise ComposeFileNotFound(SUPPORTED_FILENAMES) + if not filenames: + # search for compose files in the project directory and its parents + filenames = get_default_config_files(override_dir) + if not filenames: + raise ComposeFileNotFound(SUPPORTED_FILENAMES) log.debug("Using configuration files: {}".format(",".join(filenames))) return ConfigDetails( @@ -335,7 +344,7 @@ def get_default_config_files(base_dir): (candidates, path) = find_candidates_in_parent_dirs(SUPPORTED_FILENAMES, base_dir) if not candidates: - raise ComposeFileNotFound(SUPPORTED_FILENAMES) + return None winner = candidates[0] @@ -556,8 +565,7 @@ def process_config_section(config_file, config, section, environment, interpolat config_file.version, config, section, - environment - ) + environment) else: return config diff --git a/compose/config/environment.py b/compose/config/environment.py index 8769df9f8..5045a730b 100644 --- a/compose/config/environment.py +++ b/compose/config/environment.py @@ -54,9 +54,10 @@ class Environment(dict): if base_dir is None: return result if env_file: - env_file_path = os.path.join(base_dir, env_file) - else: - env_file_path = os.path.join(base_dir, '.env') + env_file_path = os.path.join(os.getcwd(), env_file) + return cls(env_vars_from_file(env_file_path)) + + env_file_path = os.path.join(base_dir, '.env') try: return cls(env_vars_from_file(env_file_path)) except EnvFileNotFound: diff --git a/tests/fixtures/env-file-override/.env b/tests/fixtures/env-file-override/.env new file mode 100644 index 000000000..467f2c1d2 --- /dev/null +++ b/tests/fixtures/env-file-override/.env @@ -0,0 +1 @@ +WHEREAMI=default diff --git a/tests/integration/environment_test.py b/tests/integration/environment_test.py index 12a969c94..92e12e0d4 100644 --- a/tests/integration/environment_test.py +++ b/tests/integration/environment_test.py @@ -3,11 +3,14 @@ import tempfile from ddt import data from ddt import ddt +import pytest + from .. import mock from ..acceptance.cli_test import dispatch from compose.cli.command import get_project from compose.cli.command import project_from_options from compose.config.environment import Environment +from compose.config.errors import EnvFileNotFound from tests.integration.testcases import DockerClientTestCase @@ -55,13 +58,36 @@ services: class EnvironmentOverrideFileTest(DockerClientTestCase): def test_env_file_override(self): base_dir = 'tests/fixtures/env-file-override' + # '--env-file' are relative to the current working dir + env = Environment.from_env_file(base_dir, base_dir+'/.env.override') dispatch(base_dir, ['--env-file', '.env.override', 'up']) project = get_project(project_dir=base_dir, config_path=['docker-compose.yml'], - environment=Environment.from_env_file(base_dir, '.env.override'), + environment=env, override_dir=base_dir) containers = project.containers(stopped=True) assert len(containers) == 1 assert "WHEREAMI=override" in containers[0].get('Config.Env') assert "DEFAULT_CONF_LOADED=true" in containers[0].get('Config.Env') dispatch(base_dir, ['--env-file', '.env.override', 'down'], None) + + def test_env_file_not_found_error(self): + base_dir = 'tests/fixtures/env-file-override' + with pytest.raises(EnvFileNotFound) as excinfo: + Environment.from_env_file(base_dir, '.env.override') + + assert "Couldn't find env file" in excinfo.exconly() + + def test_dot_env_file(self): + base_dir = 'tests/fixtures/env-file-override' + # '.env' is relative to the project_dir (base_dir) + env = Environment.from_env_file(base_dir, None) + dispatch(base_dir, ['up']) + project = get_project(project_dir=base_dir, + config_path=['docker-compose.yml'], + environment=env, + override_dir=base_dir) + containers = project.containers(stopped=True) + assert len(containers) == 1 + assert "WHEREAMI=default" in containers[0].get('Config.Env') + dispatch(base_dir, ['down'], None) diff --git a/tests/unit/config/config_test.py b/tests/unit/config/config_test.py index ffc16e085..13a30e7bd 100644 --- a/tests/unit/config/config_test.py +++ b/tests/unit/config/config_test.py @@ -3567,9 +3567,11 @@ class InterpolationTest(unittest.TestCase): @mock.patch.dict(os.environ) def test_config_file_with_options_environment_file(self): project_dir = 'tests/fixtures/default-env-file' + # env-file is relative to current working dir + env = Environment.from_env_file(project_dir, project_dir + '/.env2') service_dicts = config.load( config.find( - project_dir, None, Environment.from_env_file(project_dir, '.env2') + project_dir, None, env ) ).services @@ -5266,8 +5268,10 @@ def get_config_filename_for_files(filenames, subdir=None): base_dir = tempfile.mkdtemp(dir=project_dir) else: base_dir = project_dir - filename, = config.get_default_config_files(base_dir) - return os.path.basename(filename) + filenames = config.get_default_config_files(base_dir) + if not filenames: + raise config.ComposeFileNotFound(config.SUPPORTED_FILENAMES) + return os.path.basename(filenames[0]) finally: shutil.rmtree(project_dir)