Explorar o código

Support fig.y(a)ml and show a deprecation warning

Closes #864

Signed-off-by: Aanand Prasad <[email protected]>
Aanand Prasad %!s(int64=10) %!d(string=hai) anos
pai
achega
7c087f1c07
Modificáronse 3 ficheiros con 77 adicións e 18 borrados
  1. 27 9
      compose/cli/command.py
  2. 5 3
      compose/cli/errors.py
  3. 45 6
      tests/unit/cli_test.py

+ 27 - 9
compose/cli/command.py

@@ -1,7 +1,6 @@
 from __future__ import unicode_literals
 from __future__ import absolute_import
 from requests.exceptions import ConnectionError, SSLError
-import errno
 import logging
 import os
 import re
@@ -75,8 +74,6 @@ class Command(DocoptCommand):
             with open(config_path, 'r') as fh:
                 return yaml.safe_load(fh)
         except IOError as e:
-            if e.errno == errno.ENOENT:
-                raise errors.ComposeFileNotFound(os.path.basename(e.filename))
             raise errors.UserError(six.text_type(e))
 
     def get_project(self, config_path, project_name=None, verbose=False):
@@ -110,13 +107,34 @@ class Command(DocoptCommand):
         if file_path:
             return os.path.join(self.base_dir, file_path)
 
-        if os.path.exists(os.path.join(self.base_dir, 'docker-compose.yaml')):
-            log.warning("Compose just read the file 'docker-compose.yaml' on startup, rather "
-                        "than 'docker-compose.yml'")
+        supported_filenames = [
+            'docker-compose.yml',
+            'docker-compose.yaml',
+            'fig.yml',
+            'fig.yaml',
+        ]
+
+        def expand(filename):
+            return os.path.join(self.base_dir, filename)
+
+        candidates = [filename for filename in supported_filenames if os.path.exists(expand(filename))]
+
+        if len(candidates) == 0:
+            raise errors.ComposeFileNotFound(supported_filenames)
+
+        winner = candidates[0]
+
+        if len(candidates) > 1:
+            log.warning("Found multiple config files with supported names: %s", ", ".join(candidates))
+            log.warning("Using %s\n", winner)
+
+        if winner == 'docker-compose.yaml':
             log.warning("Please be aware that .yml is the expected extension "
                         "in most cases, and using .yaml can cause compatibility "
-                        "issues in future")
+                        "issues in future.\n")
 
-            return os.path.join(self.base_dir, 'docker-compose.yaml')
+        if winner.startswith("fig."):
+            log.warning("%s is deprecated and will not be supported in future. "
+                        "Please rename your config file to docker-compose.yml\n" % winner)
 
-        return os.path.join(self.base_dir, 'docker-compose.yml')
+        return expand(winner)

+ 5 - 3
compose/cli/errors.py

@@ -56,7 +56,9 @@ class ConnectionErrorGeneric(UserError):
 
 
 class ComposeFileNotFound(UserError):
-    def __init__(self, filename):
+    def __init__(self, supported_filenames):
         super(ComposeFileNotFound, self).__init__("""
-        Can't find %s. Are you in the right directory?
-        """ % filename)
+        Can't find a suitable configuration file. Are you in the right directory?
+
+        Supported filenames: %s
+        """ % ", ".join(supported_filenames))

+ 45 - 6
tests/unit/cli_test.py

@@ -2,12 +2,15 @@ from __future__ import unicode_literals
 from __future__ import absolute_import
 import logging
 import os
+import tempfile
+import shutil
 from .. import unittest
 
 import mock
 
 from compose.cli import main
 from compose.cli.main import TopLevelCommand
+from compose.cli.errors import ComposeFileNotFound
 from six import StringIO
 
 
@@ -57,12 +60,30 @@ class CLITestCase(unittest.TestCase):
             project_name = command.get_project_name(None)
         self.assertEquals(project_name, name)
 
-    def test_yaml_filename_check(self):
-        command = TopLevelCommand()
-        command.base_dir = 'tests/fixtures/longer-filename-composefile'
-        with mock.patch('compose.cli.command.log', autospec=True) as mock_log:
-            self.assertTrue(command.get_config_path())
-        self.assertEqual(mock_log.warning.call_count, 2)
+    def test_filename_check(self):
+        self.assertEqual('docker-compose.yml', get_config_filename_for_files([
+            'docker-compose.yml',
+            'docker-compose.yaml',
+            'fig.yml',
+            'fig.yaml',
+        ]))
+
+        self.assertEqual('docker-compose.yaml', get_config_filename_for_files([
+            'docker-compose.yaml',
+            'fig.yml',
+            'fig.yaml',
+        ]))
+
+        self.assertEqual('fig.yml', get_config_filename_for_files([
+            'fig.yml',
+            'fig.yaml',
+        ]))
+
+        self.assertEqual('fig.yaml', get_config_filename_for_files([
+            'fig.yaml',
+        ]))
+
+        self.assertRaises(ComposeFileNotFound, lambda: get_config_filename_for_files([]))
 
     def test_get_project(self):
         command = TopLevelCommand()
@@ -81,3 +102,21 @@ class CLITestCase(unittest.TestCase):
         main.setup_logging()
         self.assertEqual(logging.getLogger().level, logging.DEBUG)
         self.assertEqual(logging.getLogger('requests').propagate, False)
+
+
+def get_config_filename_for_files(filenames):
+    project_dir = tempfile.mkdtemp()
+    try:
+        make_files(project_dir, filenames)
+        command = TopLevelCommand()
+        command.base_dir = project_dir
+        return os.path.basename(command.get_config_path())
+    finally:
+        shutil.rmtree(project_dir)
+
+
+def make_files(dirname, filenames):
+    for fname in filenames:
+        with open(os.path.join(dirname, fname), 'w') as f:
+            f.write('')
+