Merge branch 'hirochachacha-feature/reject_environment_variable_that_contains_white_spaces'

This commit is contained in:
Joffrey F 2018-12-14 14:37:36 -08:00
commit 0612d973c7
3 changed files with 33 additions and 7 deletions

View File

@ -5,11 +5,13 @@ import codecs
import contextlib import contextlib
import logging import logging
import os import os
import re
import six import six
from ..const import IS_WINDOWS_PLATFORM from ..const import IS_WINDOWS_PLATFORM
from .errors import ConfigurationError from .errors import ConfigurationError
from .errors import EnvFileNotFound
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -17,10 +19,16 @@ log = logging.getLogger(__name__)
def split_env(env): def split_env(env):
if isinstance(env, six.binary_type): if isinstance(env, six.binary_type):
env = env.decode('utf-8', 'replace') env = env.decode('utf-8', 'replace')
key = value = None
if '=' in env: if '=' in env:
return env.split('=', 1) key, value = env.split('=', 1)
else: else:
return env, None key = env
if re.search(r'\s', key):
raise ConfigurationError(
"environment variable name '{}' may not contains whitespace.".format(key)
)
return key, value
def env_vars_from_file(filename): def env_vars_from_file(filename):
@ -28,16 +36,19 @@ def env_vars_from_file(filename):
Read in a line delimited file of environment variables. Read in a line delimited file of environment variables.
""" """
if not os.path.exists(filename): if not os.path.exists(filename):
raise ConfigurationError("Couldn't find env file: %s" % filename) raise EnvFileNotFound("Couldn't find env file: {}".format(filename))
elif not os.path.isfile(filename): elif not os.path.isfile(filename):
raise ConfigurationError("%s is not a file." % (filename)) raise EnvFileNotFound("{} is not a file.".format(filename))
env = {} env = {}
with contextlib.closing(codecs.open(filename, 'r', 'utf-8-sig')) as fileobj: with contextlib.closing(codecs.open(filename, 'r', 'utf-8-sig')) as fileobj:
for line in fileobj: for line in fileobj:
line = line.strip() line = line.strip()
if line and not line.startswith('#'): if line and not line.startswith('#'):
try:
k, v = split_env(line) k, v = split_env(line)
env[k] = v env[k] = v
except ConfigurationError as e:
raise ConfigurationError('In file {}: {}'.format(filename, e.msg))
return env return env
@ -55,9 +66,10 @@ class Environment(dict):
env_file_path = os.path.join(base_dir, '.env') env_file_path = os.path.join(base_dir, '.env')
try: try:
return cls(env_vars_from_file(env_file_path)) return cls(env_vars_from_file(env_file_path))
except ConfigurationError: except EnvFileNotFound:
pass pass
return result return result
instance = _initialize() instance = _initialize()
instance.update(os.environ) instance.update(os.environ)
return instance return instance

View File

@ -19,6 +19,10 @@ class ConfigurationError(Exception):
return self.msg return self.msg
class EnvFileNotFound(ConfigurationError):
pass
class DependencyError(ConfigurationError): class DependencyError(ConfigurationError):
pass pass

View File

@ -9,6 +9,7 @@ import pytest
from compose.config.environment import env_vars_from_file from compose.config.environment import env_vars_from_file
from compose.config.environment import Environment from compose.config.environment import Environment
from compose.config.errors import ConfigurationError
from tests import unittest from tests import unittest
@ -52,3 +53,12 @@ class EnvironmentTest(unittest.TestCase):
assert env_vars_from_file(str(tmpdir.join('bom.env'))) == { assert env_vars_from_file(str(tmpdir.join('bom.env'))) == {
'PARK_BOM': '박봄' 'PARK_BOM': '박봄'
} }
def test_env_vars_from_file_whitespace(self):
tmpdir = pytest.ensuretemp('env_file')
self.addCleanup(tmpdir.remove)
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(tmpdir.join('whitespace.env')))
assert 'environment variable' in exc.exconly()