Close #1
All checks were successful
buildbot/tox Build done.

We do things differently now :)
This commit is contained in:
2019-11-14 17:36:23 +01:00
parent 8e86233431
commit c3c0b66ff4
15 changed files with 349 additions and 207 deletions

View File

@@ -1 +1,2 @@
from .config import get_installed_apps, get_urlpatterns
from .main import main

View File

@@ -1 +1,102 @@
try:
from collections.abc import MutableMapping
except ImportError: # pragma: no cover
from collections import MutableMapping
import json
import os
from django.conf.urls import url, include
DJANGO_SETTINGS_DIR = 'main'
class _BaseDict(MutableMapping):
def __init__(self, *args, **kwargs):
super(_BaseDict, self).__init__(*args, **kwargs)
self._store = dict()
self.update(dict(*args, **kwargs))
def __getitem__(self, key):
return self._store[self.__keytransform__(key)]
def __setitem__(self, key, value):
self._store[self.__keytransform__(key)] = value
def __delitem__(self, key):
del self._store[self.__keytransform__(key)]
def __iter__(self):
return iter(self._store)
def __len__(self):
return len(self._store)
@staticmethod
def __keytransform__(key):
return key
class DeployedAppsConfig(_BaseDict): # pylint: disable=too-many-ancestors
def load(self, path=None):
if path is None:
path = self._json_file
if os.path.exists(path):
with open(path, 'r') as f:
self._store = json.load(f)
else:
self._store = dict()
def write(self, path=None):
if path is None:
path = self._json_file
with open(path, 'w') as f:
json.dump(self._store, f, indent=4)
def __init__(self, project_dir=None, settings_dir=None):
assert (project_dir or settings_dir), 'DeployedAppsConfig(): ' \
'Either keyword argument project_dir or settings_dir' \
' must be set.'
assert (not (project_dir and settings_dir)), 'DeployedAppsConfig(): ' \
'Keyword arguments project_dir and settings_dir' \
' are mutually exclusive.'
super(DeployedAppsConfig, self).__init__()
if project_dir is not None:
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
self._json_file = os.path.join(settings_dir, 'django_deploy.json')
self.load()
def get_installed_apps(file_path, installed_apps):
settings_dir = os.path.dirname(os.path.abspath(file_path))
config = DeployedAppsConfig(settings_dir=settings_dir)
app_list = installed_apps[:]
for wanting_app in config:
wanted_apps = config[wanting_app].get('INSTALLED_APPS', [])
for wanted_app in wanted_apps:
if wanted_app not in app_list:
app_list.append(wanted_app)
return app_list
def get_urlpatterns(file_path, urlpatterns):
settings_dir = os.path.dirname(os.path.abspath(file_path))
config = DeployedAppsConfig(settings_dir=settings_dir)
urls_list = urlpatterns[:]
patterns = []
for url_obj in urls_list:
# Django 1 vs Django 2
if url_obj.__class__.__name__.startswith('Regex'): # pragma: no cover
patterns.append(url_obj.regex.pattern)
else: # pragma: no cover
patterns.append(str(url_obj.pattern))
for wanting_app in config:
wanted_urls = config[wanting_app].get('urlpatterns', [])
for wanted_url in wanted_urls:
pattern = wanted_url['pattern']
if pattern in patterns:
continue
if wanted_url['type'] == 'include':
url_obj = url(pattern, include(wanted_url['module']))
urls_list.append(url_obj)
patterns.append(pattern)
return urls_list

View File

@@ -0,0 +1,8 @@
class FatalError(Exception):
def __init__(self, *args, **kwargs):
self._exitval = kwargs.pop('exitval', None)
super(FatalError, self).__init__(*args, **kwargs)
@property
def exitval(self):
return self._exitval

View File

@@ -1,11 +1,10 @@
import argparse
import datetime
import importlib
import os
import sys
from .config import DJANGO_SETTINGS_DIR
from .utils import get_root_urlconf
from .config import DJANGO_SETTINGS_DIR, DeployedAppsConfig
from .exceptions import FatalError
from .version import VERSION
@@ -24,6 +23,10 @@ class Program(object): # pylint: disable=too-few-public-methods
action='store_true', dest='create',
help='Create the django project directory')
parser.add_argument('-e', '--enable',
action='store_true', dest='enable',
help='Enable django_deploy in an existing django project directory')
parser.add_argument('project_dir', metavar='PATH',
help='The directory, where the django project is or will be installed.')
@@ -37,22 +40,6 @@ class Program(object): # pylint: disable=too-few-public-methods
return self._argparser.parse_args(argv)
@staticmethod
def _install_django_files(project_dir, overwrite=False):
if os.path.exists(project_dir):
if not overwrite:
sys.stderr.write('directory already exists: {}\n'.format(project_dir))
return os.EX_NOPERM
else:
os.makedirs(project_dir)
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))
exitval = os.system(cmd)
return exitval
@staticmethod
def _append_to_pythonfile(path, text):
py2_cache = path + 'c'
@@ -75,117 +62,72 @@ class Program(object): # pylint: disable=too-few-public-methods
text = '\n' + comment + '\n' + code + '\n'
return self._append_to_pythonfile(settings_file, text)
def _add_installed_apps_from_app(self, project_dir, app):
settings_from_app = importlib.import_module('{}.django_settings'.format(app))
if hasattr(settings_from_app, 'ADD_INSTALLED_APPS'):
wanted_apps = settings_from_app.ADD_INSTALLED_APPS
else:
wanted_apps = []
if wanted_apps:
sys.stdout.write('{app}: wanted apps: {apps}\n'.format(app=app, apps=', '.join(wanted_apps)))
else:
return os.EX_OK
@staticmethod
def _install_django_files(project_dir, overwrite=False):
if not os.path.exists(project_dir):
os.makedirs(project_dir)
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
sys.path.insert(0, settings_dir)
settings = importlib.import_module('settings')
sys.path.pop(0)
if os.path.exists(settings_dir) and not overwrite:
sys.stderr.write('directory already exists: {}\n'.format(settings_dir))
raise FatalError(exitval=os.EX_NOPERM)
already_apps = []
missing_apps = []
for wanted_app in wanted_apps:
if wanted_app in settings.INSTALLED_APPS:
already_apps.append(wanted_app)
else:
missing_apps.append(wanted_app)
cmd = 'django-admin startproject {name} {path}'.format(name=DJANGO_SETTINGS_DIR,
path=project_dir)
sys.stdout.write('Installing django files to {path}\n'.format(path=project_dir))
exitval = os.system(cmd)
if exitval != os.EX_OK: # pragma: no cover
raise FatalError(exitval=exitval)
if already_apps:
sys.stdout.write('{app}: already in settings.INSTALLED_APPS:'
' {apps}\n'.format(app=app, apps=', '.join(already_apps)))
@staticmethod
def _install_django_deploy_files(project_dir, overwrite=False):
json_file = os.path.join(project_dir, DJANGO_SETTINGS_DIR, 'django_deploy.json')
if os.path.exists(json_file) and not overwrite:
sys.stderr.write('file already exists: {}\n'.format(json_file))
raise FatalError(exitval=os.EX_NOPERM)
if missing_apps:
sys.stdout.write('{app}: adding to settings.INSTALLED_APPS:'
' {apps}\n'.format(app=app, apps=', '.join(missing_apps)))
code = 'INSTALLED_APPS += [\n'
for missing_app in missing_apps:
code += ' \'{}\',\n'.format(missing_app)
code += ']\n'
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
comment = '### {app}: added apps with django-deploy at {timestamp}'.format(app=app,
timestamp=timestamp)
config = DeployedAppsConfig(project_dir=project_dir)
config.write()
self._append_to_settings(project_dir, code, comment)
else:
sys.stdout.write('{app}: all wanted apps are already in settings.INSTALLED_APPS\n'.format(app=app))
def _enable_django_deploy(self, project_dir):
settings_code = ''
settings_code += 'from django_deploy import get_installed_apps\n'
settings_code += 'INSTALLED_APPS = get_installed_apps(__file__, INSTALLED_APPS)\n'
settings_comment = '# django-deploy'
self._append_to_settings(project_dir, settings_code, settings_comment)
urlconf_code = ''
urlconf_code += 'from django_deploy import get_urlpatterns\n'
urlconf_code += 'urlpatterns = get_urlpatterns(__file__, urlpatterns)\n'
urlconf_comment = '# django-deploy'
self._append_to_urlconf(project_dir, urlconf_code, urlconf_comment)
return os.EX_OK
def _add_urlpatterns_from_app(self, project_dir, app): # pylint: disable=too-many-locals,too-many-branches
@staticmethod
def _add_installed_apps_from_app(project_dir, app):
settings_from_app = importlib.import_module('{}.django_settings'.format(app))
if hasattr(settings_from_app, 'ADD_URLPATTERNS'):
wanted_urls = {}
for wanted in settings_from_app.ADD_URLPATTERNS:
wanted_urls[wanted['pattern']] = wanted
wanted_patterns = wanted_urls.keys()
else:
wanted_urls = {}
wanted_patterns = []
wanted_apps = getattr(settings_from_app, 'ADD_INSTALLED_APPS', [])
if wanted_urls:
sys.stdout.write('{app}: wanted urlpatterns: {urls}\n'.format(app=app, urls=', '.join(wanted_patterns)))
else:
return os.EX_OK
config = DeployedAppsConfig(project_dir=project_dir)
if app not in config:
config[app] = {}
root_urlconf = get_root_urlconf(project_dir)
config[app]['INSTALLED_APPS'] = wanted_apps
config.write()
already_patterns = []
for item in root_urlconf.urlpatterns:
if hasattr(item, 'pattern'):
pattern = str(item.pattern)
else:
pattern = item.regex.pattern
if pattern in wanted_patterns:
already_patterns.append(pattern)
@staticmethod
def _add_urlpatterns_from_app(project_dir, app):
settings_from_app = importlib.import_module('{}.django_settings'.format(app))
wanted_urls = getattr(settings_from_app, 'ADD_URLPATTERNS', [])
missing_patterns = [pattern for pattern in wanted_patterns if pattern not in already_patterns]
config = DeployedAppsConfig(project_dir=project_dir)
if app not in config: # pragma: no cover
config[app] = {}
if already_patterns:
sys.stdout.write('{app}: already in urlpatterns:'
' {urls}\n'.format(app=app, urls=', '.join(already_patterns)))
if missing_patterns:
sys.stdout.write('{app}: adding to urlpatterns:'
' {apps}\n'.format(app=app, apps=', '.join(missing_patterns)))
code = ''
if not hasattr(root_urlconf, 'url'):
code += 'from django.conf.urls import url\n'
if not hasattr(root_urlconf, 'include'):
code += 'from django.conf.urls import include\n'
code += 'urlpatterns += [\n'
for pattern in missing_patterns:
url = wanted_urls[pattern]
if url['type'] == 'include':
code += " url(r'{pattern}', include('{module}')),\n".format(pattern=pattern,
module=url['module'])
else:
sys.stderr.write('{app}: not a supported url type: {type}\n'.format(app=app, type=url['type']))
code += ']\n'
timestamp = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
comment = '### {app}: added urlpatterns with django-deploy at {timestamp}'.format(app=app,
timestamp=timestamp)
self._append_to_urlconf(project_dir, code, comment)
else:
sys.stdout.write('{app}: all wanted patterns are already in urlconfig\n'.format(app=app))
return os.EX_OK
config[app]['urlpatterns'] = wanted_urls
config.write()
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
self._add_installed_apps_from_app(project_dir, app)
self._add_urlpatterns_from_app(project_dir, app)
def __init__(self):
self._argparser = argparse.ArgumentParser()
@@ -195,13 +137,15 @@ class Program(object): # pylint: disable=too-few-public-methods
argv = kwargs.get('argv', None)
cmd_args = self._parse_args(argv)
exitval = os.EX_OK
if cmd_args.create:
exitval = self._install_django_files(cmd_args.project_dir)
if exitval != os.EX_OK:
return exitval
if cmd_args.merge_apps:
for app in cmd_args.merge_apps:
exitval = self._merge_app(cmd_args.project_dir, app)
if exitval != os.EX_OK:
return exitval
try:
if cmd_args.create:
self._install_django_files(cmd_args.project_dir)
if cmd_args.create or cmd_args.enable:
self._install_django_deploy_files(cmd_args.project_dir)
self._enable_django_deploy(cmd_args.project_dir)
if cmd_args.merge_apps:
for app in cmd_args.merge_apps:
self._merge_app(cmd_args.project_dir, app)
except FatalError as e:
exitval = e.exitval
return exitval

View File

@@ -1,4 +0,0 @@
ADD_INSTALLED_APPS = ['django_deploy.tests.fake_app']
ADD_URLPATTERNS = [
{'type': 'include', 'pattern': '^fake/', 'module': 'django_deploy.tests.fake_app.urls'},
]

View File

@@ -0,0 +1,5 @@
ADD_INSTALLED_APPS = ['django_deploy.tests.fake_app1']
ADD_URLPATTERNS = [
{'type': 'include', 'pattern': '^fake1/', 'module': 'django_deploy.tests.fake_app1.urls'},
{'type': 'invalid', 'pattern': '^invalid/'},
]

View File

@@ -0,0 +1,5 @@
ADD_INSTALLED_APPS = ['django_deploy.tests.fake_app1', 'django_deploy.tests.fake_app2']
ADD_URLPATTERNS = [
{'type': 'include', 'pattern': '^fake1/', 'module': 'django_deploy.tests.fake_app1.urls'},
{'type': 'include', 'pattern': '^fake2/', 'module': 'django_deploy.tests.fake_app2.urls'},
]

View File

@@ -0,0 +1,3 @@
# pylint: skip-file
app_name = 'fake2'
urlpatterns = []

View File

@@ -0,0 +1,54 @@
import unittest
from django.conf.urls import url, include
from ..config import get_installed_apps, get_urlpatterns, DeployedAppsConfig
class FunctionsTestCase(unittest.TestCase):
def test_get_installed_apps(self):
test_data_sets = [
(__file__, ['fake_app1', 'fake_app2']),
]
for file_path, installed_apps in test_data_sets:
result = get_installed_apps(file_path, installed_apps)
self.assertEqual(installed_apps, result)
def test_get_urlpatterns(self):
test_data_sets = [
(
__file__,
[
url('/app1', include('django_deploy.tests.fake_app1.urls')),
url('/app2', include('django_deploy.tests.fake_app2.urls')),
],
),
]
for file_path, urlpatterns in test_data_sets:
result = get_urlpatterns(file_path, urlpatterns)
self.assertEqual(urlpatterns, result)
class DeployedAppsConfigTestCase(unittest.TestCase):
def test_init_parameters(self):
with self.assertRaises(AssertionError):
DeployedAppsConfig()
with self.assertRaises(AssertionError):
DeployedAppsConfig(project_dir='.', settings_dir='.')
def test_len(self):
c = DeployedAppsConfig(settings_dir='.')
c['a'] = 'a'
c['b'] = 'b'
c['c'] = 'c'
self.assertEqual(3, len(c))
def test_del(self):
c = DeployedAppsConfig(settings_dir='.')
c['a'] = 'a'
c['b'] = 'b'
c['c'] = 'c'
del c['b']
self.assertEqual(2, len(c))

View File

@@ -2,65 +2,96 @@ import importlib
import os
import sys
import unittest
import mock
import pytest
from ..config import DJANGO_SETTINGS_DIR
from ..program import Program
from ..utils import get_root_urlconf
class MainTestCase(unittest.TestCase):
class ProgramTestCase(unittest.TestCase):
@pytest.fixture(autouse=True)
def tmpdir(self, tmpdir): # pylint: disable=method-hidden
self.tmpdir = tmpdir
def _assert_django_project(self, project_dir):
self.assertTrue(os.path.isdir(project_dir), 'no directory: {}'.format(project_dir))
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
self.assertTrue(os.path.isdir(settings_dir), 'no directory: {}'.format(settings_dir))
settings_file = os.path.join(settings_dir, 'settings.py')
self.assertTrue(os.path.isfile(settings_file), 'no file: {}'.format(settings_file))
manage_script = os.path.join(project_dir, 'manage.py')
self.assertTrue(os.path.isfile(manage_script), 'no file: {}'.format(manage_script))
def _assert_django_deploy_project(self, project_dir):
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
settings_file = os.path.join(settings_dir, 'settings.py')
urlconf_file = os.path.join(settings_dir, 'urls.py')
django_deploy_json = os.path.join(settings_dir, 'django_deploy.json')
self.assertTrue(os.path.isfile(django_deploy_json), 'no file: {}'.format(django_deploy_json))
with open(settings_file, 'r') as f:
needle = 'from django_deploy import get_installed_apps'
haystack = f.read()
self.assertIn(needle, haystack)
with open(urlconf_file, 'r') as f:
needle = 'from django_deploy import get_urlpatterns'
haystack = f.read()
self.assertIn(needle, haystack)
def setUp(self):
self._program = Program()
self._project_dir = os.path.join(str(self.tmpdir), 'django')
self._program(argv=['--create', self._project_dir])
def test_create(self):
tmpdir = self.tmpdir
project_dir = os.path.join(str(tmpdir), 'env', 'django')
def test_create_new_dir(self):
project_dir = os.path.join(str(self.tmpdir), 'new_dir')
exitval = self._program(argv=['-c', project_dir])
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_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')
manage_script = os.path.join(project_dir, 'manage.py')
self.assertTrue(os.path.isfile(manage_script), 'manage.py was not created')
self._assert_django_project(project_dir)
self._assert_django_deploy_project(project_dir)
def test_create_dont_overwrite(self):
tmpdir = self.tmpdir
project_dir = os.path.join(str(tmpdir), 'env', 'django')
def test_create_existing_empty_dir(self):
project_dir = os.path.join(str(self.tmpdir), 'empty_dir')
os.makedirs(project_dir)
exitval = self._program(argv=['-c', project_dir])
self._program(argv=['--create', project_dir])
exitval = self._program(argv=['--create', project_dir])
self.assertEqual(os.EX_OK, exitval, 'program() does not return os.EX_OK')
self._assert_django_project(project_dir)
self._assert_django_deploy_project(project_dir)
self.assertEqual(os.EX_NOPERM, exitval, 'second call to program() does not exit with os.EX_NOPERM')
def test_create_existing_project_dir(self):
exitval = self._program(argv=['-c', self._project_dir])
self.assertEqual(os.EX_NOPERM, exitval, 'program() does not return os.EX_NOPERM'
' when project directory is not empty')
def test_enable_django_deploy(self):
project_dir = os.path.join(str(self.tmpdir), 'pure_django')
os.makedirs(project_dir)
cmd = 'django-admin startproject {name} {path}'.format(name=DJANGO_SETTINGS_DIR,
path=project_dir)
os.system(cmd)
self._program(argv=['--enable', project_dir])
self._assert_django_deploy_project(project_dir)
def test_enable_django_deploy_twice(self):
exitval = self._program(argv=['-e', self._project_dir])
self.assertEqual(os.EX_NOPERM, exitval, 'program() does not return os.EX_NOPERM'
' when django_deploy is already enabled')
def test_merge_installed_apps(self):
tmpdir = self.tmpdir
project_dir = os.path.join(str(tmpdir), 'env', 'django')
project_dir = self._project_dir
argv = ['-c', project_dir]
argv = [
'-a', 'django_deploy',
'-a', 'django_deploy.tests.fake_app1',
'-a', 'django_deploy.tests.fake_app2',
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',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_deploy.tests.fake_app',
]
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
sys.path.insert(0, settings_dir)
settings = importlib.import_module('settings')
@@ -70,30 +101,52 @@ class MainTestCase(unittest.TestCase):
importlib.reload(settings) # pylint: disable=no-member
sys.path.pop(0)
expected_installed_apps = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django_deploy.tests.fake_app1',
'django_deploy.tests.fake_app2',
]
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')
project_dir = self._project_dir
argv = ['-c', project_dir]
argv = [
'-a', 'django_deploy',
'-a', 'django_deploy.tests.fake_app1',
'-a', 'django_deploy.tests.fake_app2',
project_dir]
self._program(argv=argv)
argv = ['-a', 'django_deploy', '-a', 'django_deploy.tests.fake_app', project_dir]
self._program(argv=argv)
sys.modules['django.contrib'] = mock.MagicMock(name='django.contrib')
root_urlconf = get_root_urlconf(project_dir)
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 hasattr(root_urlconf, 'path'):
# Django 2 vs Django 1
if hasattr(root_urlconf, 'path'): # pragma: no cover
expected_urlpatterns = [
('URLPattern', 'admin/', 'django.contrib.admin.site.urls'),
]
else:
else: # pragma: no cover
expected_urlpatterns = [
('URLPattern', '^admin/', 'django.contrib.admin.site.urls'),
]
expected_urlpatterns += [
('URLResolver', '^fake/', 'django_deploy.tests.fake_app.urls'),
('URLResolver', '^fake1/', 'django_deploy.tests.fake_app1.urls'),
('URLResolver', '^fake2/', 'django_deploy.tests.fake_app2.urls'),
]
real_urlpatterns = root_urlconf.urlpatterns
@@ -103,17 +156,18 @@ class MainTestCase(unittest.TestCase):
real = real_urlpatterns[i]
real_class_name = real.__class__.__name__
self.assertTrue(real_class_name.endswith(expected[0]))
if real_class_name == 'URLPattern':
# Django 2 vs. Django 1
if real_class_name == 'URLPattern': # pragma: no cover
self.assertEqual(expected[1], str(real.pattern))
self.assertTrue(real.callback.startswith("<Mock name='{}' id=".format(expected[2])))
elif real_class_name == 'RegexURLPattern':
elif real_class_name == 'RegexURLPattern': # pragma: no cover
self.assertEqual(expected[1], real.regex.pattern)
self.assertTrue(real.callback.startswith("<Mock name='{}' id=".format(expected[2])))
elif real_class_name == 'URLResolver':
elif real_class_name == 'URLResolver': # pragma: no cover
self.assertEqual(expected[1], str(real.pattern))
self.assertEqual(expected[2], real.urlconf_name.__name__)
elif real_class_name == 'RegexURLResolver':
elif real_class_name == 'RegexURLResolver': # pragma: no cover
self.assertEqual(expected[1], real.regex.pattern)
self.assertEqual(expected[2], real.urlconf_name.__name__)
else:
else: # pragma: no cover
self.fail('Unknown urlpattern class: {}'.format(real_class_name))

View File

@@ -1,29 +0,0 @@
import importlib
import os
import sys
import mock
from .config import DJANGO_SETTINGS_DIR
def get_root_urlconf(project_dir):
if 'django.contrib' in sys.modules:
original_contrib = sys.modules['django.contrib']
else:
original_contrib = None
mock_contrib = mock.Mock(name='django.contrib')
sys.modules['django.contrib'] = mock_contrib
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_contrib:
sys.modules['django.contrib'] = original_contrib
return root_urlconf

View File

@@ -7,5 +7,5 @@ deps = coverage
py3: pylint-django
pytest
commands = coverage run -m pytest
coverage report --skip-covered --fail-under=90
coverage report --skip-covered --fail-under=98
pylint django_deploy