Refs #5343 -- Reverted [6047]. Loading custom commands was causing the settings file to get read before the options could be processed to determine if a --settings option was present. Back to the drawing board (again)...
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6050 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
faaf2dad36
commit
e4342b7d28
|
@ -1,5 +1,4 @@
|
||||||
import django
|
import django
|
||||||
from django.core.management.base import CommandError
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -8,61 +7,13 @@ import textwrap
|
||||||
# For backwards compatibility: get_version() used to be in this module.
|
# For backwards compatibility: get_version() used to be in this module.
|
||||||
get_version = django.get_version
|
get_version = django.get_version
|
||||||
|
|
||||||
# A cache of loaded commands, so that call_command
|
def load_command_class(name):
|
||||||
# doesn't have to reload every time it is called
|
|
||||||
_commands = None
|
|
||||||
|
|
||||||
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
|
Given a command name, returns the Command class instance. Raises
|
||||||
Raises ImportError if a command module doesn't exist, or AttributeError
|
ImportError if it doesn't exist.
|
||||||
if a command module doesn't contain a Command instance.
|
|
||||||
"""
|
"""
|
||||||
# Let any errors propogate.
|
# Let the ImportError propogate.
|
||||||
return getattr(__import__('%s.management.commands.%s' % (module, name), {}, {}, ['Command']), 'Command')()
|
return getattr(__import__('django.core.management.commands.%s' % name, {}, {}, ['Command']), 'Command')()
|
||||||
|
|
||||||
def get_commands(load_user_commands=True):
|
|
||||||
"""
|
|
||||||
Returns a dictionary of instances of all available Command classes.
|
|
||||||
Core commands are always included; user-register commands will also
|
|
||||||
be included if ``load_user_commands`` is True.
|
|
||||||
|
|
||||||
This works by looking for a management.commands package in
|
|
||||||
django.core, and 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}.
|
|
||||||
|
|
||||||
The dictionary is cached on the first call, and reused on subsequent
|
|
||||||
calls.
|
|
||||||
"""
|
|
||||||
global _commands
|
|
||||||
if _commands is None:
|
|
||||||
_commands = dict([(name, load_command_class('django.core',name))
|
|
||||||
for name in find_commands(__path__[0])])
|
|
||||||
if load_user_commands:
|
|
||||||
# Get commands from all installed apps
|
|
||||||
from django.db import models
|
|
||||||
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:
|
|
||||||
raise CommandError, "Management command '%s' in application '%s' doesn't contain a Command instance.\n" % (name, app_name)
|
|
||||||
return _commands
|
|
||||||
|
|
||||||
def call_command(name, *args, **options):
|
def call_command(name, *args, **options):
|
||||||
"""
|
"""
|
||||||
|
@ -75,11 +26,8 @@ def call_command(name, *args, **options):
|
||||||
call_command('shell', plain=True)
|
call_command('shell', plain=True)
|
||||||
call_command('sqlall', 'myapp')
|
call_command('sqlall', 'myapp')
|
||||||
"""
|
"""
|
||||||
try:
|
klass = load_command_class(name)
|
||||||
command = get_commands()[name]
|
return klass.execute(*args, **options)
|
||||||
except KeyError:
|
|
||||||
raise CommandError, "Unknown command: %r\n" % name
|
|
||||||
return command.execute(*args, **options)
|
|
||||||
|
|
||||||
class ManagementUtility(object):
|
class ManagementUtility(object):
|
||||||
"""
|
"""
|
||||||
|
@ -89,12 +37,20 @@ class ManagementUtility(object):
|
||||||
by editing the self.commands dictionary.
|
by editing the self.commands dictionary.
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# The base management utility doesn't expose any user-defined commands
|
self.commands = self.default_commands()
|
||||||
try:
|
|
||||||
self.commands = get_commands(load_user_commands=False)
|
def default_commands(self):
|
||||||
except CommandError, e:
|
"""
|
||||||
sys.stderr.write(str(e))
|
Returns a dictionary of instances of all available Command classes.
|
||||||
sys.exit(1)
|
|
||||||
|
This works by looking for and loading all Python modules in the
|
||||||
|
django.core.management.commands package.
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
def usage(self):
|
def usage(self):
|
||||||
"""
|
"""
|
||||||
|
@ -177,11 +133,7 @@ class ProjectManagementUtility(ManagementUtility):
|
||||||
represents django-admin.py.
|
represents django-admin.py.
|
||||||
"""
|
"""
|
||||||
def __init__(self, project_directory):
|
def __init__(self, project_directory):
|
||||||
try:
|
super(ProjectManagementUtility, self).__init__()
|
||||||
self.commands = get_commands()
|
|
||||||
except CommandError, e:
|
|
||||||
sys.stderr.write(str(e))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Remove the "startproject" command from self.commands, because
|
# Remove the "startproject" command from self.commands, because
|
||||||
# that's a django-admin.py command, not a manage.py command.
|
# that's a django-admin.py command, not a manage.py command.
|
||||||
|
|
|
@ -619,32 +619,3 @@ distribution. It enables tab-completion of ``django-admin.py`` and
|
||||||
* Press [TAB] to see all available options.
|
* Press [TAB] to see all available options.
|
||||||
* Type ``sql``, then [TAB], to see all available options whose names start
|
* Type ``sql``, then [TAB], to see all available options whose names start
|
||||||
with ``sql``.
|
with ``sql``.
|
||||||
|
|
||||||
Customized actions
|
|
||||||
==================
|
|
||||||
|
|
||||||
**New in Django development version**
|
|
||||||
|
|
||||||
If you want to add an action of your own to ``manage.py``, you can.
|
|
||||||
Simply add a ``management/commands`` directory to your application.
|
|
||||||
Each python module in that directory will be discovered and registered as
|
|
||||||
a command that can be executed as an action when you run ``manage.py``::
|
|
||||||
|
|
||||||
/fancy_blog
|
|
||||||
__init__.py
|
|
||||||
models.py
|
|
||||||
/management
|
|
||||||
__init__.py
|
|
||||||
/commands
|
|
||||||
__init__.py
|
|
||||||
explode.py
|
|
||||||
views.py
|
|
||||||
|
|
||||||
In this example, ``explode`` command will be made available to any project
|
|
||||||
that includes the ``fancy_blog`` application in ``settings.INSTALLED_APPS``.
|
|
||||||
|
|
||||||
The ``explode.py`` module has only one requirement -- it must define a class
|
|
||||||
called ``Command`` that extends ``django.core.management.base.BaseCommand``.
|
|
||||||
|
|
||||||
For more details on how to define your own commands, look at the code for the
|
|
||||||
existing ``django-admin.py`` commands, in ``/django/core/management/commands``.
|
|
||||||
|
|
Loading…
Reference in New Issue