Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Installation checking infrastructure

* Added cms.utils.check.check
* Added 'cms check' command
* Added infrastructure to write installation checks
* Added first simple sekizai check
  • Loading branch information...
commit c72dfc59ccc96476f0771c37a3f0a6bb7f52ceb6 1 parent 6dbe375
@ojii ojii authored
View
2  cms/management/commands/cms.py
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from cms.management.commands.subcommands.base import SubcommandsCommand
+from cms.management.commands.subcommands.check import CheckInstallation
from cms.management.commands.subcommands.list import ListCommand
from cms.management.commands.subcommands.moderator import ModeratorCommand
from cms.management.commands.subcommands.uninstall import UninstallCommand
@@ -27,6 +28,7 @@ class Command(SubcommandsCommand):
'moderator': ModeratorCommand,
'fix-mptt': FixMPTTCommand,
'delete_orphaned_plugins': DeleteOrphanedPluginsCommand,
+ 'check': CheckInstallation,
}
@property
View
11 cms/management/commands/subcommands/check.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+from cms.utils.check import FileOutputWrapper, check
+from django.core.management.base import NoArgsCommand, CommandError
+
+
+class CheckInstallation(NoArgsCommand):
+ help = 'Checks your settings and environment'
+
+ def handle_noargs(self, **options):
+ if not check(FileOutputWrapper(self.stdout, self.stderr)):
+ raise CommandError()
View
141 cms/utils/check.py
@@ -0,0 +1,141 @@
+# -*- coding: utf-8 -*-
+from collections import namedtuple, defaultdict
+from contextlib import contextmanager
+from django.conf import settings
+from django.utils.decorators import method_decorator
+from django.utils.termcolors import colorize
+
+SUCCESS = 1
+WARNING = 2
+ERROR = 3
+SKIPPED = 4
+
+CHECKERS = []
+
+CheckSection = namedtuple('CheckSection', 'title result subchecks')
+CheckResult = namedtuple('CheckResult', 'name result info')
+
+
+class FileOutputWrapper(object):
+ def __init__(self, stdout, stderr):
+ self.stdout = stdout
+ self.stderr = stderr
+ self.section_wrapper = FileSectionWrapper
+ self.errors = 0
+ self.successes = 0
+ self.warnings = 0
+ self.skips = 0
+
+ def colorize(self, msg, opts=(), **kwargs):
+ return colorize(msg, opts=opts, **kwargs)
+
+ def write_line(self, message=''):
+ self.write(u'%s\n' % message)
+
+ def write(self, message):
+ self.stdout.write(message)
+
+ def write_stderr_line(self, message=''):
+ self.stderr.write(u'%s\n' % message)
+
+ def write_stderr(self, message):
+ self.stderr.write(message)
+
+ def success(self, message):
+ self.successes += 1
+ self.write_line(u'%s %s' % (message, self.colorize('[OK]', fg='green', opts=['bold'])))
+
+ def error(self, message):
+ self.errors += 1
+ self.write_stderr_line(u'%s %s' % (message, self.colorize('[ERROR]', fg='red', opts=['bold'])))
+
+ def warning(self, message):
+ self.warnings += 1
+ self.write_stderr_line(u'%s %s' % (message, self.colorize('[WARNING]', fg='yellow', opts=['bold'])))
+
+ def skip(self, message):
+ self.skips += 1
+ self.write_line(u'%s %s' % (message, self.colorize('[SKIP]', fg='blue', opts=['bold'])))
+
+ @method_decorator(contextmanager)
+ def section(self, title):
+ self.write_line(self.colorize(title, opts=['bold']))
+ self.write_line(self.colorize('=' * len(title), opts=['bold']))
+ self.write_line()
+ try:
+ yield self.section_wrapper(self)
+ except:
+ self.error('Checker failed, see traceback')
+ raise
+ self.write_line('')
+
+ @property
+ def successful(self):
+ return not self.errors
+
+
+class FileSectionWrapper(FileOutputWrapper):
+ def __init__(self, wrapper):
+ super(FileSectionWrapper, self).__init__(wrapper.stdout, wrapper.stderr)
+ self.wrapper = wrapper
+
+ def write_line(self, message=''):
+ self.write(u' - %s\n' % message)
+
+ def finish_success(self, message):
+ self.wrapper.write_line()
+ self.wrapper.success(message)
+
+ def finish_error(self, message):
+ self.wrapper.write_line()
+ self.wrapper.error(message)
+
+ def finish_warning(self, message):
+ self.wrapper.write_line()
+ self.wrapper.warning(message)
+
+ def finish_skip(self, message):
+ self.wrapper.write_lin()
+ self.wrapper.skip(message)
+
+
+def define_check(func):
+ CHECKERS.append(func)
+ return func
+
+
+@define_check
+def check_sekizai(output):
+ with output.section("Sekizai") as section:
+ if 'sekizai' in settings.INSTALLED_APPS:
+ section.success("Sekizai is installed")
+ else:
+ section.error("Sekizai is not installed, could not find 'sekizai' in INSTALLED_APPS")
+ section.finish_success("Sekizai configuration okay")
+
+def check(output):
+ title = "Checking django CMS installation"
+ border = '*' * len(title)
+ output.write_line(output.colorize(border, opts=['bold']))
+ output.write_line(output.colorize(title, opts=['bold']))
+ output.write_line(output.colorize(border, opts=['bold']))
+ output.write_line()
+ for checker in CHECKERS:
+ checker(output)
+ output.write_line()
+ with output.section("OVERALL RESULTS") as section:
+ if output.errors:
+ output.write_stderr_line(output.colorize("%s errors!" % output.errors, opts=['bold'], fg='red'))
+ if output.warnings:
+ output.write_stderr_line(output.colorize("%s warnings!" % output.warnings, opts=['bold'], fg='yellow'))
+ if output.skips:
+ output.write_line(output.colorize("%s checks skipped!" % output.skips, opts=['bold'], fg='blue'))
+ output.write_line(output.colorize("%s checks successful!" % output.successes, opts=['bold'], fg='green'))
+ output.write_line()
+ if output.errors:
+ output.write_stderr_line(output.colorize('Please check the errors above', opts=['bold'], fg='red'))
+ elif output.warnings:
+ output.write_stderr_line(output.colorize('Installation okay, but please check warnings above', opts=['bold'], fg='yellow'))
+ else:
+ output.write_line(output.colorize('Installation okay', opts=['bold'], fg='green'))
+ return not output.errors
Please sign in to comment.
Something went wrong with that request. Please try again.