Files
django-deploy/src/django_deploy/program.py
2019-10-29 18:34:25 +01:00

115 lines
4.2 KiB
Python

import argparse
import datetime
import importlib
import os
import sys
from .config import DJANGO_SETTINGS_MODULE_NAME
from .version import VERSION
class Program(object): # pylint: disable=too-few-public-methods
@staticmethod
def _setup_argparser(parser):
parser.add_argument('-V', '--version', action='version',
version='%(prog)s ' + VERSION)
parser.add_argument('-a', '--app',
action='append', dest='merge_apps', metavar='MODULE',
help='Merge settings from the django app MODULE\n'
'Can be used multiple times')
parser.add_argument('-c', '--create',
action='store_true', dest='create',
help='Create the django project directory')
parser.add_argument('project_dir', metavar='PATH',
help='The directory, where the django project is or will be installed.')
return parser
def _parse_args(self, argv=None):
if argv is None:
argv = sys.argv[1:]
if not argv:
argv = ()
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_MODULE_NAME
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 _add_installed_apps_from_app(project_dir, app):
settings_dir = os.path.join(project_dir, DJANGO_SETTINGS_MODULE_NAME)
settings_from_app = importlib.import_module('{}.django_settings'.format(app))
if hasattr(settings_from_app, 'ADD_INSTALLED_APPS'):
add_apps = settings_from_app.ADD_INSTALLED_APPS
else:
add_apps = []
if not add_apps:
sys.stdout.write('{}: do not care about INSTALLED_APPS\n'.format(app))
return os.EX_OK
sys.path.insert(0, settings_dir)
settings = importlib.import_module('settings')
sys.path.pop(0)
missing_apps = []
for app in add_apps:
if app not in settings.INSTALLED_APPS:
missing_apps.append(app)
if missing_apps:
sys.stdout.write('{app}: adding {apps} to INSTALLED_APPS\n'.format(app=app, apps=missing_apps))
comment = '### {app}: added apps with django-deploy at {timestamp}'
code = 'INSTALLED_APPS += [\n'
for app in missing_apps:
code += ' \'{}\',\n'.format(app)
code += ']\n'
append_text = '\n' + comment + '\n' + code + '\n'
settings_file = os.path.join(settings_dir, 'settings.py')
with open(settings_file, 'a') as f:
now = datetime.datetime.now()
timestamp = now.strftime('%Y-%m-%d %H:%M:%S')
f.write(append_text.format(app=app, timestamp=timestamp))
else:
sys.stdout.write('{app}: INSTALLED_APPS is fine\n'.format(app=app))
return os.EX_OK
def __init__(self):
self._argparser = argparse.ArgumentParser()
self._setup_argparser(self._argparser)
def __call__(self, *args, **kwargs):
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._add_installed_apps_from_app(cmd_args.project_dir, app)
if exitval != os.EX_OK:
return exitval
return exitval