diff --git a/configurations/__init__.py b/configurations/__init__.py index 1ae1e42..373fa53 100644 --- a/configurations/__init__.py +++ b/configurations/__init__.py @@ -1,9 +1,9 @@ # flake8: noqa -from .base import Settings, Configuration +from .base import Settings, Configuration, DotConfiguration from .decorators import pristinemethod __version__ = '0.8' -__all__ = ['Configuration', 'pristinemethod', 'Settings'] +__all__ = ['Configuration', 'DotConfiguration', 'pristinemethod', 'Settings'] def load_ipython_extension(ipython): diff --git a/configurations/base.py b/configurations/base.py index b4ea2ab..658cf12 100644 --- a/configurations/base.py +++ b/configurations/base.py @@ -41,39 +41,6 @@ class ConfigurationBase(type): return "".format(self.__module__, self.__name__) - @staticmethod - def read_env(env_file='.env', **overrides): - """ - Pulled from Honcho code with minor updates, reads local default - environment variables from a .env file located in the project root - directory. - - http://www.wellfireinteractive.com/blog/easier-12-factor-django/ - https://gist.github.com/bennylope/2999704 - """ - import re - import os - - with open(env_file) as f: - content = f.read() - - for line in content.splitlines(): - m1 = re.match(r'\A([A-Za-z_0-9]+)=(.*)\Z', line) - if not m1: - continue - key, val = m1.group(1), m1.group(2) - m2 = re.match(r"\A'(.*)'\Z", val) - if m2: - val = m2.group(1) - m3 = re.match(r'\A"(.*)"\Z', val) - if m3: - val = re.sub(r'\\(.)', r'\1', m3.group(1)) - os.environ.setdefault(key, val) - - # set defaults - for key, value in overrides.items(): - os.environ.setdefault(key, value) - class Configuration(six.with_metaclass(ConfigurationBase)): """ @@ -114,6 +81,53 @@ class Configuration(six.with_metaclass(ConfigurationBase)): setup_value(cls, name, value) +class DotConfiguration(Configuration): + + DOT_ENV = None + DOT_ENV_LOADED = False + + @classmethod + def pre_setup(cls): + Configuration.pre_setup() + if not cls.DOT_ENV_LOADED and cls.DOT_ENV: + cls.read_env(cls.DOT_ENV) + + @classmethod + def read_env(cls, env_file='.env', **overrides): + """ + Pulled from Honcho code with minor updates, reads local default + environment variables from a .env file located in the project root + or provided directory. + + http://www.wellfireinteractive.com/blog/easier-12-factor-django/ + https://gist.github.com/bennylope/2999704 + """ + import re + import os + + with open(env_file) as f: + content = f.read() + + for line in content.splitlines(): + m1 = re.match(r'\A([A-Za-z_0-9]+)=(.*)\Z', line) + if not m1: + continue + key, val = m1.group(1), m1.group(2) + m2 = re.match(r"\A'(.*)'\Z", val) + if m2: + val = m2.group(1) + m3 = re.match(r'\A"(.*)"\Z', val) + if m3: + val = re.sub(r'\\(.)', r'\1', m3.group(1)) + os.environ.setdefault(key, val) + + # set defaults + for key, value in overrides.items(): + os.environ.setdefault(key, value) + + cls.DOT_ENV_LOADED = True + + class Settings(Configuration): @classmethod diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py index 1ffe526..db6500c 100644 --- a/test_project/test_project/settings.py +++ b/test_project/test_project/settings.py @@ -1,7 +1,7 @@ from configurations import Configuration, values -class Base(Configuration): +class Base(DotConfiguration): # Django settings for test_project project. DEBUG = values.BooleanValue(True, environ=True) diff --git a/tests/settings/dot_env.py b/tests/settings/dot_env.py new file mode 100644 index 0000000..6d7acbb --- /dev/null +++ b/tests/settings/dot_env.py @@ -0,0 +1,6 @@ +from configurations import DotConfiguration + + +class DotEnvConfiguration(DotConfiguration): + + DOT_ENV = 'test_project/.env' diff --git a/tests/settings/main.py b/tests/settings/main.py index 9693f5b..d646271 100644 --- a/tests/settings/main.py +++ b/tests/settings/main.py @@ -64,7 +64,6 @@ class Test(Configuration): @classmethod def pre_setup(cls): cls.PRE_SETUP_TEST_SETTING = 6 - cls.read_env('test_project/.env') @classmethod def post_setup(cls): diff --git a/tests/test_env.py b/tests/test_env.py index 637f188..70e7a53 100644 --- a/tests/test_env.py +++ b/tests/test_env.py @@ -1,10 +1,13 @@ import os from django.test import TestCase -from configurations.values import BooleanValue from mock import patch -class EnvValueTests(TestCase): +class DotEnvLoadingTests(TestCase): + + @patch.dict(os.environ, clear=True, + DJANGO_CONFIGURATION='DotEnvConfiguration', + DJANGO_SETTINGS_MODULE='tests.settings.dot_env') def test_env_loaded(self): - check_value = BooleanValue(False) - self.assertEqual(check_value.setup('ENV_LOADED'), True) \ No newline at end of file + from tests.settings import dot_env + self.assertTrue(dot_env.DOT_ENV_LOADED) \ No newline at end of file