From 5279ae4acebf5da4cec9ddd63d2c67a36054df28 Mon Sep 17 00:00:00 2001 From: joke2k Date: Thu, 17 Apr 2014 16:23:36 +0200 Subject: [PATCH] add support to load .env file into os.environ --- configurations/base.py | 33 +++++++++++++++++++++++++++++++++ test_project/.env | 1 + tests/settings/main.py | 5 +++++ tests/test_env.py | 10 ++++++++++ 4 files changed, 49 insertions(+) create mode 100644 test_project/.env create mode 100644 tests/test_env.py diff --git a/configurations/base.py b/configurations/base.py index 8601c73..b4ea2ab 100644 --- a/configurations/base.py +++ b/configurations/base.py @@ -41,6 +41,39 @@ 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)): """ diff --git a/test_project/.env b/test_project/.env new file mode 100644 index 0000000..977f829 --- /dev/null +++ b/test_project/.env @@ -0,0 +1 @@ +DJANGO_ENV_LOADED=True \ No newline at end of file diff --git a/tests/settings/main.py b/tests/settings/main.py index dd425fd..9693f5b 100644 --- a/tests/settings/main.py +++ b/tests/settings/main.py @@ -3,9 +3,13 @@ import uuid import django from configurations import Configuration, pristinemethod +from configurations.values import BooleanValue class Test(Configuration): + + ENV_LOADED = BooleanValue(False) + DEBUG = True SITE_ID = 1 @@ -60,6 +64,7 @@ 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 new file mode 100644 index 0000000..637f188 --- /dev/null +++ b/tests/test_env.py @@ -0,0 +1,10 @@ +import os +from django.test import TestCase +from configurations.values import BooleanValue +from mock import patch + +class EnvValueTests(TestCase): + + def test_env_loaded(self): + check_value = BooleanValue(False) + self.assertEqual(check_value.setup('ENV_LOADED'), True) \ No newline at end of file