Make thinks more useful
Some checks failed
buildbot/tox Build done.

Extract functionality from program.Program to api, so it can be used
from other python code.
And instead of adding predefined urls to root_urlconf, we should
/mount/ apps into a django project.
This commit is contained in:
2019-11-15 17:07:10 +01:00
parent a84c473866
commit 18613d3600
5 changed files with 98 additions and 22 deletions

37
src/django_deploy/api.py Normal file
View File

@@ -0,0 +1,37 @@
import errno
import os
import sys
from .config import DJANGO_SETTINGS_DIR
from .exceptions import DjangoDeployError, FatalError
class DjangoProject(object):
def __init__(self, project_dir):
self._project_dir = project_dir
def create(self):
project_dir = self._project_dir
if not os.path.exists(project_dir):
os.makedirs(project_dir)
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_DIR)
if os.path.exists(settings_dir):
raise DjangoDeployError('directory already exists: {}'.format(settings_dir), code=errno.EEXIST)
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)
def install_hooks(self):
pass
def add_app(self, module):
pass
def mount_app(self, module, route):
pass

View File

@@ -1,7 +1,22 @@
class FatalError(Exception):
def __init__(self, *args, **kwargs):
self._exitval = kwargs.pop('exitval', None)
super(FatalError, self).__init__(*args, **kwargs)
class DjangoDeployError(Exception):
def __init__(self, message=None, code=None):
self._message = message
self._code = code
super(DjangoDeployError, self).__init__(message)
@property
def message(self):
return self._message
@property
def code(self):
return self._code
class FatalError(DjangoDeployError):
def __init__(self, message=None, code=None, exitval=None):
self._exitval = exitval
super(FatalError, self).__init__(message=message, code=code)
@property
def exitval(self):

View File

@@ -3,8 +3,9 @@ import importlib
import os
import sys
from .api import DjangoProject
from .config import DJANGO_SETTINGS_DIR, DeployedAppsConfig
from .exceptions import FatalError
from .exceptions import DjangoDeployError, FatalError
from .version import VERSION
@@ -63,21 +64,9 @@ class Program(object): # pylint: disable=too-few-public-methods
return self._append_to_pythonfile(settings_file, text)
@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)
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)
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)
def _install_django_files(project_dir):
project = DjangoProject(project_dir)
project.create()
@staticmethod
def _install_django_deploy_files(project_dir, overwrite=False):
@@ -147,5 +136,13 @@ class Program(object): # pylint: disable=too-few-public-methods
for app in cmd_args.merge_apps:
self._merge_app(cmd_args.project_dir, app)
except FatalError as e:
if e.message:
sys.stderr.write('{}\n'.format(e.message))
exitval = e.exitval
except DjangoDeployError as e:
if e.message:
sys.stderr.write('{}\n'.format(e.message))
elif e.code:
sys.stderr.write('{}\n'.format(os.strerror(e.code)))
exitval = os.EX_SOFTWARE
return exitval

View File

@@ -0,0 +1,27 @@
import os
import unittest
import pytest
from ..api import DjangoProject
from ..config import DJANGO_SETTINGS_DIR
class DjangoProjectTestCase(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 test_create(self):
project_dir = os.path.join(str(self.tmpdir), 'django')
project = DjangoProject(project_dir)
project.create()
self._assert_django_project(project_dir)

View File

@@ -65,8 +65,8 @@ class ProgramTestCase(unittest.TestCase):
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')
self.assertEqual(os.EX_SOFTWARE, exitval, 'program() does not return os.EX_SOFTWARE'
' when project directory is not empty')
def test_enable_django_deploy(self):
project_dir = os.path.join(str(self.tmpdir), 'pure_django')