This commit is contained in:
@@ -1 +1 @@
|
||||
DJANGO_SETTINGS_MODULE_NAME = 'main'
|
||||
DJANGO_SETTINGS_DIR = 'main'
|
||||
|
||||
@@ -1 +1,4 @@
|
||||
# ADD_INSTALLED_APPS = ['django_deploy']
|
||||
# ADD_URLPATTERNS = [
|
||||
# {'type': 'include', 'pattern': '', 'module': 'django_deploy.urls'},
|
||||
# ]
|
||||
|
||||
@@ -4,7 +4,7 @@ import importlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
from .config import DJANGO_SETTINGS_MODULE_NAME
|
||||
from .config import DJANGO_SETTINGS_DIR
|
||||
from .version import VERSION
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ class Program(object): # pylint: disable=too-few-public-methods
|
||||
|
||||
@staticmethod
|
||||
def _append_to_settings(project_dir, code, comment):
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_MODULE_NAME)
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
settings_file = os.path.join(settings_dir, 'settings.py')
|
||||
settings_file_py2cache = settings_file + 'c'
|
||||
|
||||
@@ -57,7 +57,7 @@ class Program(object): # pylint: disable=too-few-public-methods
|
||||
else:
|
||||
os.makedirs(project_dir)
|
||||
|
||||
settings_module = DJANGO_SETTINGS_MODULE_NAME
|
||||
settings_module = DJANGO_SETTINGS_DIR
|
||||
cmd = 'django-admin startproject {name} {path}'.format(name=settings_module,
|
||||
path=project_dir)
|
||||
sys.stdout.write('Installing django files to {path}\n'.format(path=project_dir))
|
||||
@@ -65,7 +65,7 @@ class Program(object): # pylint: disable=too-few-public-methods
|
||||
return exitval
|
||||
|
||||
def _add_installed_apps_from_app(self, project_dir, app):
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_MODULE_NAME)
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
|
||||
settings_from_app = importlib.import_module('{}.django_settings'.format(app))
|
||||
if hasattr(settings_from_app, 'ADD_INSTALLED_APPS'):
|
||||
@@ -102,6 +102,29 @@ class Program(object): # pylint: disable=too-few-public-methods
|
||||
|
||||
return os.EX_OK
|
||||
|
||||
def _add_urlpatterns_from_app(self, project_dir, app):
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
|
||||
settings_from_app = importlib.import_module('{}.django_settings'.format(app))
|
||||
if hasattr(settings_from_app, 'ADD_URLPATTERNS'):
|
||||
add_urls = settings_from_app.ADD_URLPATTERNS
|
||||
else:
|
||||
add_urls = []
|
||||
|
||||
if not add_urls:
|
||||
sys.stdout.write('{}: do not care about ROOT_URLCONF\n'.format(app))
|
||||
return os.EX_OK
|
||||
|
||||
raise NotImplementedError()
|
||||
self._append_to_settings(project_dir, code, comment)
|
||||
|
||||
def _merge_app(self, project_dir, app):
|
||||
exitval = self._add_installed_apps_from_app(project_dir, app)
|
||||
if exitval != os.EX_OK:
|
||||
return exitval
|
||||
exitval = self._add_urlpatterns_from_app(project_dir, app)
|
||||
return exitval
|
||||
|
||||
def __init__(self):
|
||||
self._argparser = argparse.ArgumentParser()
|
||||
self._setup_argparser(self._argparser)
|
||||
@@ -116,7 +139,7 @@ class Program(object): # pylint: disable=too-few-public-methods
|
||||
return exitval
|
||||
if cmd_args.merge_apps:
|
||||
for app in cmd_args.merge_apps:
|
||||
exitval = self._add_installed_apps_from_app(cmd_args.project_dir, app)
|
||||
exitval = self._merge_app(cmd_args.project_dir, app)
|
||||
if exitval != os.EX_OK:
|
||||
return exitval
|
||||
return exitval
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
ADD_INSTALLED_APPS = ['fake_app1', 'fake_app2']
|
||||
0
src/django_deploy/tests/fake_app/__init__.py
Normal file
0
src/django_deploy/tests/fake_app/__init__.py
Normal file
4
src/django_deploy/tests/fake_app/django_settings.py
Normal file
4
src/django_deploy/tests/fake_app/django_settings.py
Normal file
@@ -0,0 +1,4 @@
|
||||
ADD_INSTALLED_APPS = ['django_deploy.tests.fake_app']
|
||||
ADD_URLPATTERNS = [
|
||||
{'type': 'include', 'pattern': 'fake/', 'module': 'django_deploy.tests.fake_app.urls'},
|
||||
]
|
||||
2
src/django_deploy/tests/fake_app/urls.py
Normal file
2
src/django_deploy/tests/fake_app/urls.py
Normal file
@@ -0,0 +1,2 @@
|
||||
app_name = 'fake1'
|
||||
urlpatterns = []
|
||||
@@ -4,7 +4,9 @@ import sys
|
||||
import unittest
|
||||
import pytest
|
||||
|
||||
from ..config import DJANGO_SETTINGS_MODULE_NAME
|
||||
from unittest import mock
|
||||
|
||||
from ..config import DJANGO_SETTINGS_DIR
|
||||
from ..program import Program
|
||||
|
||||
|
||||
@@ -24,7 +26,7 @@ class MainTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEqual(os.EX_OK, exitval, 'program() does not return os.EX_OK')
|
||||
self.assertTrue(os.path.isdir(project_dir), 'project directory was not created')
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_MODULE_NAME)
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
self.assertTrue(os.path.isdir(settings_dir), 'settings directory was not created')
|
||||
settings_file = os.path.join(settings_dir, 'settings.py')
|
||||
self.assertTrue(os.path.isfile(settings_file), 'settings.py was not created')
|
||||
@@ -44,6 +46,12 @@ class MainTestCase(unittest.TestCase):
|
||||
tmpdir = self.tmpdir
|
||||
project_dir = os.path.join(str(tmpdir), 'env', 'django')
|
||||
|
||||
argv = ['-c', project_dir]
|
||||
self._program(argv=argv)
|
||||
|
||||
argv = ['-a', 'django_deploy', '-a', 'django_deploy.tests.fake_app', project_dir]
|
||||
self._program(argv=argv)
|
||||
|
||||
expected_installed_apps = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
@@ -51,17 +59,10 @@ class MainTestCase(unittest.TestCase):
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'fake_app1',
|
||||
'fake_app2',
|
||||
'django_deploy.tests.fake_app',
|
||||
]
|
||||
|
||||
argv = ['-c', project_dir]
|
||||
self._program(argv=argv)
|
||||
|
||||
argv = ['-a', 'django_deploy', '-a', 'django_deploy.tests', project_dir]
|
||||
self._program(argv=argv)
|
||||
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_MODULE_NAME)
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
sys.path.insert(0, settings_dir)
|
||||
settings = importlib.import_module('settings')
|
||||
if sys.version_info.major == 2: # pragma: no cover
|
||||
@@ -69,4 +70,54 @@ class MainTestCase(unittest.TestCase):
|
||||
else: # pragma: no cover
|
||||
importlib.reload(settings) # pylint: disable=no-member
|
||||
sys.path.pop(0)
|
||||
|
||||
self.assertListEqual(expected_installed_apps, settings.INSTALLED_APPS)
|
||||
|
||||
def test_merge_root_urlconf(self):
|
||||
tmpdir = self.tmpdir
|
||||
project_dir = os.path.join(str(tmpdir), 'env', 'django')
|
||||
|
||||
argv = ['-c', project_dir]
|
||||
self._program(argv=argv)
|
||||
|
||||
argv = ['-a', 'django_deploy', '-a', 'django_deploy.tests.fake_app', project_dir]
|
||||
self._program(argv=argv)
|
||||
|
||||
if 'django.contrib.admin' in sys.modules:
|
||||
original_admin = sys.modules['django.contrib.admin']
|
||||
else:
|
||||
original_admin = None
|
||||
mock_admin = mock.Mock()
|
||||
sys.modules['django.contrib.admin'] = mock_admin
|
||||
|
||||
from django.urls import path
|
||||
|
||||
expected_urlpatterns = [
|
||||
('URLPattern', 'admin/', mock_admin.site.urls),
|
||||
('URLResolver', 'fake/'),
|
||||
]
|
||||
|
||||
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
|
||||
sys.path.insert(0, settings_dir)
|
||||
root_urlconf = importlib.import_module('urls')
|
||||
if sys.version_info.major == 2: # pragma: no cover
|
||||
reload(root_urlconf) # pylint: disable=undefined-variable
|
||||
else: # pragma: no cover
|
||||
importlib.reload(root_urlconf) # pylint: disable=no-member
|
||||
sys.path.pop(0)
|
||||
|
||||
if original_admin:
|
||||
sys.modules['django.contrib.admin'] = original_admin
|
||||
|
||||
real_urlpatterns = root_urlconf.urlpatterns
|
||||
self.assertEqual(len(expected_urlpatterns), len(real_urlpatterns))
|
||||
|
||||
for i in range(0, len(expected_urlpatterns)):
|
||||
expected = expected_urlpatterns[i]
|
||||
real = real_urlpatterns[i]
|
||||
self.assertEqual(expected[0], real.__class__.__name__)
|
||||
if expected[0] == 'URLPattern':
|
||||
self.assertIsNotNone(real.pattern.match(expected[1]))
|
||||
self.assertEqual(expected[2], real.callback)
|
||||
else:
|
||||
raise Exception(dir(real))
|
||||
|
||||
4
src/django_deploy/tests/test_settings.py
Normal file
4
src/django_deploy/tests/test_settings.py
Normal file
@@ -0,0 +1,4 @@
|
||||
SECRET_KEY = 'test_settings'
|
||||
INSTALLED_APPS = [
|
||||
'django_deploy.tests.fake_app',
|
||||
]
|
||||
16
src/django_deploy/tests/test_utils.py
Normal file
16
src/django_deploy/tests/test_utils.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import unittest
|
||||
|
||||
from ..utils import DjangoEnvironment
|
||||
|
||||
|
||||
class DjangoEnvironmentTestCase(unittest.TestCase):
|
||||
def test_django_environment(self):
|
||||
settings_module_name = 'django_deploy.tests.test_settings'
|
||||
|
||||
with DjangoEnvironment(settings_module_name=settings_module_name) as env:
|
||||
check_attrs = [
|
||||
('SECRET_KEY', 'test_settings'),
|
||||
('INSTALLED_APPS', ['django_deploy.tests.fake_app']),
|
||||
]
|
||||
for key, value in check_attrs:
|
||||
self.assertEqual(value, getattr(env.settings, key))
|
||||
41
src/django_deploy/utils.py
Normal file
41
src/django_deploy/utils.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
import django
|
||||
|
||||
from .config import DJANGO_SETTINGS_DIR
|
||||
|
||||
|
||||
class DjangoEnvironment(object):
|
||||
def __init__(self, project_dir=None, settings_module_name=None):
|
||||
self.project_dir = project_dir
|
||||
|
||||
if settings_module_name is not None:
|
||||
self.settings_module_name = settings_module_name
|
||||
else:
|
||||
self.settings_module_name = '{}.settings'.format(DJANGO_SETTINGS_DIR)
|
||||
|
||||
self._original_sys_path = None
|
||||
self._modified_sys_path = None
|
||||
|
||||
def __enter__(self):
|
||||
if self.project_dir:
|
||||
self._original_sys_path = sys.path
|
||||
sys.path.insert(0, self.project_dir)
|
||||
self._modified_sys_path = sys.path
|
||||
|
||||
print('Debug: %s' % self.settings_module_name)
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = self.settings_module_name
|
||||
django.setup()
|
||||
|
||||
from django.conf import settings
|
||||
self.settings = settings
|
||||
if hasattr(settings, 'ROOT_URLCONF'):
|
||||
self.root_urlconf = importlib.import_module(settings.ROOT_URLCONF)
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
if self._modified_sys_path is not None and self._original_sys_path is not None:
|
||||
if sys.path == self._modified_sys_path:
|
||||
sys.path = self._original_sys_path
|
||||
Reference in New Issue
Block a user