summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2007-08-18 04:51:51 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2007-08-18 04:51:51 +0000
commit6ad0a0188741f80c6dafef3aec62c3b2c46b7812 (patch)
tree45520757908a4deb8410e0c9a2b6ffef500a9486
parent7969c1ba05ef342725083d060b038a8a874e69e6 (diff)
Added the ability for end users to register commands with management.py.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5923 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/core/management/__init__.py52
1 files changed, 45 insertions, 7 deletions
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index 7a3f9ca7a5..8fa583707e 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -7,13 +7,25 @@ import textwrap
# For backwards compatibility: get_version() used to be in this module.
get_version = django.get_version
-def load_command_class(name):
+def find_commands(path):
+ """
+ Given a path to a management directory, return a list of all the command names
+ that are available. Returns an empty list if no commands are defined.
+ """
+ command_dir = os.path.join(path, 'commands')
+ try:
+ return [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')]
+ except OSError:
+ return []
+
+def load_command_class(module, name):
"""
Given a command name, returns the Command class instance. Raises
- ImportError if it doesn't exist.
+ Raises ImportError if a command module doesn't exist, or AttributeError
+ if a command module doesn't include .
"""
- # Let the ImportError propogate.
- return getattr(__import__('django.core.management.commands.%s' % name, {}, {}, ['Command']), 'Command')()
+ # Let any errors propogate.
+ return getattr(__import__('%s.management.commands.%s' % (module, name), {}, {}, ['Command']), 'Command')()
def call_command(name, *args, **options):
"""
@@ -48,9 +60,8 @@ class ManagementUtility(object):
The dictionary is in the format {name: command_instance}.
"""
- command_dir = os.path.join(__path__[0], 'commands')
- names = [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')]
- return dict([(name, load_command_class(name)) for name in names])
+ return dict([(name, load_command_class('django.core',name))
+ for name in find_commands(__path__[0])])
def usage(self):
"""
@@ -144,6 +155,33 @@ class ProjectManagementUtility(ManagementUtility):
from django.core.management.commands.startapp import ProjectCommand
self.commands['startapp'] = ProjectCommand(project_directory)
+ def default_commands(self):
+ """
+ Returns a dictionary of instances of all available Command classes.
+
+ This works by looking for and loading all Python modules in the
+ django.core.management.commands package. It also looks for a
+ management.commands package in each installed application -- if
+ a commands package exists, it loads all commands in that application.
+
+ The dictionary is in the format {name: command_instance}.
+ """
+ from django.db import models
+
+ # Base command set
+ commands = super(ProjectManagementUtility, self).default_commands()
+
+ # Get commands from all installed apps
+ for app in models.get_apps():
+ try:
+ app_name = '.'.join(app.__name__.split('.')[:-1])
+ path = os.path.join(os.path.dirname(app.__file__),'management')
+ commands.update(dict([(name, load_command_class(app_name,name)) for name in find_commands(path)]))
+ except AttributeError:
+ sys.stderr.write("Management command '%s' in application '%s' doesn't contain a Command instance.\n" % (name, app_name))
+ sys.exit(1)
+ return commands
+
def setup_environ(settings_mod):
"""
Configure the runtime environment. This can also be used by external