Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Refs #5343 -- Reverted [6047]. Loading custom commands was causing th…

…e 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
  • Loading branch information...
commit e4342b7d28d3b0c470954f60a02340b472abe7c0 1 parent faaf2da
Russell Keith-Magee authored September 05, 2007
92  django/core/management/__init__.py
... ...
@@ -1,5 +1,4 @@
1 1
 import django
2  
-from django.core.management.base import CommandError
3 2
 from optparse import OptionParser
4 3
 import os
5 4
 import sys
@@ -8,61 +7,13 @@
8 7
 # For backwards compatibility: get_version() used to be in this module.
9 8
 get_version = django.get_version
10 9
 
11  
-# A cache of loaded commands, so that call_command 
12  
-# doesn't have to reload every time it is called
13  
-_commands = None
14  
-    
15  
-def find_commands(path):
16  
-    """
17  
-    Given a path to a management directory, return a list of all the command names 
18  
-    that are available. Returns an empty list if no commands are defined.
19  
-    """
20  
-    command_dir = os.path.join(path, 'commands')
21  
-    try:
22  
-        return [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')]
23  
-    except OSError:
24  
-        return []
25  
-
26  
-def load_command_class(module, name):
  10
+def load_command_class(name):
27 11
     """
28 12
     Given a command name, returns the Command class instance. Raises
29  
-    Raises ImportError if a command module doesn't exist, or AttributeError
30  
-    if a command module doesn't contain a Command instance.
31  
-    """
32  
-    # Let any errors propogate.
33  
-    return getattr(__import__('%s.management.commands.%s' % (module, name), {}, {}, ['Command']), 'Command')()
34  
-
35  
-def get_commands(load_user_commands=True):
  13
+    ImportError if it doesn't exist.
36 14
     """
37  
-    Returns a dictionary of instances of all available Command classes.
38  
-    Core commands are always included; user-register commands will also
39  
-    be included if ``load_user_commands`` is True.
40  
-
41  
-    This works by looking for a management.commands package in 
42  
-    django.core, and in each installed application -- if a commands 
43  
-    package exists, it loads all commands in that application.
44  
-
45  
-    The dictionary is in the format {name: command_instance}.
46  
-    
47  
-    The dictionary is cached on the first call, and reused on subsequent
48  
-    calls.
49  
-    """
50  
-    global _commands
51  
-    if _commands is None:
52  
-        _commands = dict([(name, load_command_class('django.core',name)) 
53  
-                            for name in find_commands(__path__[0])])
54  
-        if load_user_commands:
55  
-            # Get commands from all installed apps
56  
-            from django.db import models
57  
-            for app in models.get_apps():
58  
-                try:
59  
-                    app_name = '.'.join(app.__name__.split('.')[:-1])
60  
-                    path = os.path.join(os.path.dirname(app.__file__),'management')
61  
-                    _commands.update(dict([(name, load_command_class(app_name,name)) 
62  
-                                                    for name in find_commands(path)]))
63  
-                except AttributeError:
64  
-                    raise CommandError, "Management command '%s' in application '%s' doesn't contain a Command instance.\n" % (name, app_name)
65  
-    return _commands
  15
+    # Let the ImportError propogate.
  16
+    return getattr(__import__('django.core.management.commands.%s' % name, {}, {}, ['Command']), 'Command')()
66 17
 
67 18
 def call_command(name, *args, **options):
68 19
     """
@@ -75,12 +26,9 @@ def call_command(name, *args, **options):
75 26
         call_command('shell', plain=True)
76 27
         call_command('sqlall', 'myapp')
77 28
     """
78  
-    try:
79  
-        command = get_commands()[name]
80  
-    except KeyError:
81  
-        raise CommandError, "Unknown command: %r\n" % name
82  
-    return command.execute(*args, **options)
83  
-    
  29
+    klass = load_command_class(name)
  30
+    return klass.execute(*args, **options)
  31
+
84 32
 class ManagementUtility(object):
85 33
     """
86 34
     Encapsulates the logic of the django-admin.py and manage.py utilities.
@@ -89,12 +37,20 @@ class ManagementUtility(object):
89 37
     by editing the self.commands dictionary.
90 38
     """
91 39
     def __init__(self):
92  
-        # The base management utility doesn't expose any user-defined commands
93  
-        try:
94  
-            self.commands = get_commands(load_user_commands=False)
95  
-        except CommandError, e:
96  
-            sys.stderr.write(str(e))
97  
-            sys.exit(1)
  40
+        self.commands = self.default_commands()
  41
+
  42
+    def default_commands(self):
  43
+        """
  44
+        Returns a dictionary of instances of all available Command classes.
  45
+
  46
+        This works by looking for and loading all Python modules in the
  47
+        django.core.management.commands package.
  48
+
  49
+        The dictionary is in the format {name: command_instance}.
  50
+        """
  51
+        command_dir = os.path.join(__path__[0], 'commands')
  52
+        names = [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')]
  53
+        return dict([(name, load_command_class(name)) for name in names])
98 54
 
99 55
     def usage(self):
100 56
         """
@@ -177,11 +133,7 @@ class ProjectManagementUtility(ManagementUtility):
177 133
     represents django-admin.py.
178 134
     """
179 135
     def __init__(self, project_directory):
180  
-        try:
181  
-            self.commands = get_commands()
182  
-        except CommandError, e:
183  
-            sys.stderr.write(str(e))
184  
-            sys.exit(1)
  136
+        super(ProjectManagementUtility, self).__init__()
185 137
 
186 138
         # Remove the "startproject" command from self.commands, because
187 139
         # that's a django-admin.py command, not a manage.py command.
29  docs/django-admin.txt
@@ -619,32 +619,3 @@ distribution. It enables tab-completion of ``django-admin.py`` and
619 619
     * Press [TAB] to see all available options.
620 620
     * Type ``sql``, then [TAB], to see all available options whose names start
621 621
       with ``sql``.
622  
-
623  
-Customized actions
624  
-==================
625  
-
626  
-**New in Django development version**
627  
-
628  
-If you want to add an action of your own to ``manage.py``, you can.
629  
-Simply add a ``management/commands`` directory to your application.
630  
-Each python module in that directory will be discovered and registered as
631  
-a command that can be executed as an action when you run ``manage.py``::
632  
-
633  
-    /fancy_blog
634  
-        __init__.py
635  
-        models.py
636  
-        /management
637  
-            __init__.py
638  
-            /commands
639  
-                __init__.py
640  
-                explode.py
641  
-        views.py
642  
-        
643  
-In this example, ``explode`` command will be made available to any project
644  
-that includes the ``fancy_blog`` application in ``settings.INSTALLED_APPS``.
645  
-
646  
-The ``explode.py`` module has only one requirement -- it must define a class
647  
-called ``Command`` that extends ``django.core.management.base.BaseCommand``.
648  
-
649  
-For more details on how to define your own commands, look at the code for the
650  
-existing ``django-admin.py`` commands, in ``/django/core/management/commands``.

0 notes on commit e4342b7

Please sign in to comment.
Something went wrong with that request. Please try again.