浏览代码

Add python-dotenv

Signed-off-by: Ulysses Souza <[email protected]>
Ulysses Souza 5 年之前
父节点
当前提交
6d2658ea65
共有 3 个文件被更改,包括 24 次插入30 次删除
  1. 3 13
      compose/config/environment.py
  2. 1 0
      requirements.txt
  3. 20 17
      tests/unit/config/environment_test.py

+ 3 - 13
compose/config/environment.py

@@ -1,12 +1,11 @@
 from __future__ import absolute_import
 from __future__ import unicode_literals
 
-import codecs
-import contextlib
 import logging
 import os
 import re
 
+import dotenv
 import six
 
 from ..const import IS_WINDOWS_PLATFORM
@@ -39,17 +38,8 @@ def env_vars_from_file(filename):
         raise EnvFileNotFound("Couldn't find env file: {}".format(filename))
     elif not os.path.isfile(filename):
         raise EnvFileNotFound("{} is not a file.".format(filename))
-    env = {}
-    with contextlib.closing(codecs.open(filename, 'r', 'utf-8-sig')) as fileobj:
-        for line in fileobj:
-            line = line.strip()
-            if line and not line.startswith('#'):
-                try:
-                    k, v = split_env(line)
-                    env[k] = v
-                except ConfigurationError as e:
-                    raise ConfigurationError('In file {}: {}'.format(filename, e.msg))
-    return env
+
+    return dotenv.dotenv_values(dotenv_path=filename, encoding='utf-8-sig')
 
 
 class Environment(dict):

+ 1 - 0
requirements.txt

@@ -17,6 +17,7 @@ paramiko==2.7.1
 pypiwin32==219; sys_platform == 'win32' and python_version < '3.6'
 pypiwin32==223; sys_platform == 'win32' and python_version >= '3.6'
 PySocks==1.7.1
+python-dotenv==0.10.5
 PyYAML==5.3
 requests==2.22.0
 six==1.12.0

+ 20 - 17
tests/unit/config/environment_test.py

@@ -8,15 +8,18 @@ import os
 import shutil
 import tempfile
 
-import pytest
+from ddt import data
+from ddt import ddt
+from ddt import unpack
 
 from compose.config.environment import env_vars_from_file
 from compose.config.environment import Environment
-from compose.config.errors import ConfigurationError
 from tests import unittest
 
 
+@ddt
 class EnvironmentTest(unittest.TestCase):
+    @classmethod
     def test_get_simple(self):
         env = Environment({
             'FOO': 'bar',
@@ -28,12 +31,14 @@ class EnvironmentTest(unittest.TestCase):
         assert env.get('BAR') == '1'
         assert env.get('BAZ') == ''
 
+    @classmethod
     def test_get_undefined(self):
         env = Environment({
             'FOO': 'bar'
         })
         assert env.get('FOOBAR') is None
 
+    @classmethod
     def test_get_boolean(self):
         env = Environment({
             'FOO': '',
@@ -48,20 +53,18 @@ class EnvironmentTest(unittest.TestCase):
         assert env.get_boolean('FOOBAR') is True
         assert env.get_boolean('UNDEFINED') is False
 
-    def test_env_vars_from_file_bom(self):
+    @data(
+        ('unicode exclude test', '\ufeffPARK_BOM=박봄\n', {'PARK_BOM': '박봄'}),
+        ('export prefixed test', 'export PREFIXED_VARS=yes\n', {"PREFIXED_VARS": "yes"}),
+        ('quoted vars test', "QUOTED_VARS='yes'\n", {"QUOTED_VARS": "yes"}),
+        ('double quoted vars test', 'DOUBLE_QUOTED_VARS="yes"\n', {"DOUBLE_QUOTED_VARS": "yes"}),
+        ('extra spaces test', 'SPACES_VARS = "yes"\n', {"SPACES_VARS": "yes"}),
+    )
+    @unpack
+    def test_env_vars(self, test_name, content, expected):
         tmpdir = tempfile.mkdtemp('env_file')
         self.addCleanup(shutil.rmtree, tmpdir)
-        with codecs.open('{}/bom.env'.format(str(tmpdir)), 'w', encoding='utf-8') as f:
-            f.write('\ufeffPARK_BOM=박봄\n')
-        assert env_vars_from_file(str(os.path.join(tmpdir, 'bom.env'))) == {
-            'PARK_BOM': '박봄'
-        }
-
-    def test_env_vars_from_file_whitespace(self):
-        tmpdir = tempfile.mkdtemp('env_file')
-        self.addCleanup(shutil.rmtree, tmpdir)
-        with codecs.open('{}/whitespace.env'.format(str(tmpdir)), 'w', encoding='utf-8') as f:
-            f.write('WHITESPACE =yes\n')
-        with pytest.raises(ConfigurationError) as exc:
-            env_vars_from_file(str(os.path.join(tmpdir, 'whitespace.env')))
-        assert 'environment variable' in exc.exconly()
+        file_abs_path = str(os.path.join(tmpdir, ".env"))
+        with codecs.open(file_abs_path, 'w', encoding='utf-8') as f:
+            f.write(content)
+        assert env_vars_from_file(file_abs_path) == expected, '"{}" Failed'.format(test_name)