瀏覽代碼

Make `--env-file` paths relative to current working directory
Look up compose files in project dir as fallback to no compose file in current working directory
Update config and env-file tests
- get_default_config does not raise error anymore, returns None if no compose file is found

Signed-off-by: Anca Iordache <[email protected]>

Anca Iordache 4 年之前
父節點
當前提交
4a26d95de4

+ 11 - 3
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
 

+ 4 - 3
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:

+ 1 - 0
tests/fixtures/env-file-override/.env

@@ -0,0 +1 @@
+WHEREAMI=default

+ 27 - 1
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)

+ 7 - 3
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)