Django

Code

Changeset 5923

Show
Ignore:
Timestamp:
08/17/07 23:51:51 (1 year ago)
Author:
russellm
Message:

Added the ability for end users to register commands with management.py.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/core/management/__init__.py

    r5898 r5923  
    88get_version = django.get_version 
    99 
    10 def load_command_class(name): 
     10def find_commands(path): 
     11    """ 
     12    Given a path to a management directory, return a list of all the command names  
     13    that are available. Returns an empty list if no commands are defined. 
     14    """ 
     15    command_dir = os.path.join(path, 'commands') 
     16    try: 
     17        return [f[:-3] for f in os.listdir(command_dir) if not f.startswith('_') and f.endswith('.py')] 
     18    except OSError: 
     19        return [] 
     20 
     21def load_command_class(module, name): 
    1122    """ 
    1223    Given a command name, returns the Command class instance. Raises 
    13     ImportError if it doesn't exist. 
    14     """ 
    15     # Let the ImportError propogate. 
    16     return getattr(__import__('django.core.management.commands.%s' % name, {}, {}, ['Command']), 'Command')() 
     24    Raises ImportError if a command module doesn't exist, or AttributeError 
     25    if a command module doesn't include . 
     26    """ 
     27    # Let any errors propogate. 
     28    return getattr(__import__('%s.management.commands.%s' % (module, name), {}, {}, ['Command']), 'Command')() 
    1729 
    1830def call_command(name, *args, **options): 
     
    4961        The dictionary is in the format {name: command_instance}. 
    5062        """ 
    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]) 
     63        return dict([(name, load_command_class('django.core',name))  
     64                        for name in find_commands(__path__[0])]) 
    5465 
    5566    def usage(self): 
     
    145156        self.commands['startapp'] = ProjectCommand(project_directory) 
    146157 
     158    def default_commands(self): 
     159        """ 
     160        Returns a dictionary of instances of all available Command classes. 
     161 
     162        This works by looking for and loading all Python modules in the 
     163        django.core.management.commands package. It also looks for a 
     164        management.commands package in each installed application -- if 
     165        a commands package exists, it loads all commands in that application. 
     166 
     167        The dictionary is in the format {name: command_instance}. 
     168        """ 
     169        from django.db import models 
     170 
     171        # Base command set 
     172        commands = super(ProjectManagementUtility, self).default_commands() 
     173         
     174        # Get commands from all installed apps 
     175        for app in models.get_apps(): 
     176            try: 
     177                app_name = '.'.join(app.__name__.split('.')[:-1]) 
     178                path = os.path.join(os.path.dirname(app.__file__),'management') 
     179                commands.update(dict([(name, load_command_class(app_name,name)) for name in find_commands(path)])) 
     180            except AttributeError: 
     181                sys.stderr.write("Management command '%s' in application '%s' doesn't contain a Command instance.\n" % (name, app_name)) 
     182                sys.exit(1) 
     183        return commands 
     184 
    147185def setup_environ(settings_mod): 
    148186    """