150 # If the command is already loaded, use it directly. |
150 # If the command is already loaded, use it directly. |
151 klass = app_name |
151 klass = app_name |
152 else: |
152 else: |
153 klass = load_command_class(app_name, name) |
153 klass = load_command_class(app_name, name) |
154 except KeyError: |
154 except KeyError: |
155 raise CommandError, "Unknown command: %r" % name |
155 raise CommandError("Unknown command: %r" % name) |
156 |
156 |
157 # Grab out a list of defaults from the options. optparse does this for us |
157 # Grab out a list of defaults from the options. optparse does this for us |
158 # when the script runs from the command line, but since call_command can |
158 # when the script runs from the command line, but since call_command can |
159 # be called programatically, we need to simulate the loading and handling |
159 # be called programatically, we need to simulate the loading and handling |
160 # of defaults (see #10080 for details). |
160 # of defaults (see #10080 for details). |
259 sys.stderr.write("Unknown command: %r\nType '%s help' for usage.\n" % \ |
259 sys.stderr.write("Unknown command: %r\nType '%s help' for usage.\n" % \ |
260 (subcommand, self.prog_name)) |
260 (subcommand, self.prog_name)) |
261 sys.exit(1) |
261 sys.exit(1) |
262 return klass |
262 return klass |
263 |
263 |
|
264 def autocomplete(self): |
|
265 """ |
|
266 Output completion suggestions for BASH. |
|
267 |
|
268 The output of this function is passed to BASH's `COMREPLY` variable and |
|
269 treated as completion suggestions. `COMREPLY` expects a space |
|
270 separated string as the result. |
|
271 |
|
272 The `COMP_WORDS` and `COMP_CWORD` BASH environment variables are used |
|
273 to get information about the cli input. Please refer to the BASH |
|
274 man-page for more information about this variables. |
|
275 |
|
276 Subcommand options are saved as pairs. A pair consists of |
|
277 the long option string (e.g. '--exclude') and a boolean |
|
278 value indicating if the option requires arguments. When printing to |
|
279 stdout, a equal sign is appended to options which require arguments. |
|
280 |
|
281 Note: If debugging this function, it is recommended to write the debug |
|
282 output in a separate file. Otherwise the debug output will be treated |
|
283 and formatted as potential completion suggestions. |
|
284 """ |
|
285 # Don't complete if user hasn't sourced bash_completion file. |
|
286 if not os.environ.has_key('DJANGO_AUTO_COMPLETE'): |
|
287 return |
|
288 |
|
289 cwords = os.environ['COMP_WORDS'].split()[1:] |
|
290 cword = int(os.environ['COMP_CWORD']) |
|
291 |
|
292 try: |
|
293 curr = cwords[cword-1] |
|
294 except IndexError: |
|
295 curr = '' |
|
296 |
|
297 subcommands = get_commands().keys() + ['help'] |
|
298 options = [('--help', None)] |
|
299 |
|
300 # subcommand |
|
301 if cword == 1: |
|
302 print ' '.join(sorted(filter(lambda x: x.startswith(curr), subcommands))) |
|
303 # subcommand options |
|
304 # special case: the 'help' subcommand has no options |
|
305 elif cwords[0] in subcommands and cwords[0] != 'help': |
|
306 subcommand_cls = self.fetch_command(cwords[0]) |
|
307 # special case: 'runfcgi' stores additional options as |
|
308 # 'key=value' pairs |
|
309 if cwords[0] == 'runfcgi': |
|
310 from django.core.servers.fastcgi import FASTCGI_OPTIONS |
|
311 options += [(k, 1) for k in FASTCGI_OPTIONS] |
|
312 # special case: add the names of installed apps to options |
|
313 elif cwords[0] in ('dumpdata', 'reset', 'sql', 'sqlall', |
|
314 'sqlclear', 'sqlcustom', 'sqlindexes', |
|
315 'sqlreset', 'sqlsequencereset', 'test'): |
|
316 try: |
|
317 from django.conf import settings |
|
318 # Get the last part of the dotted path as the app name. |
|
319 options += [(a.split('.')[-1], 0) for a in settings.INSTALLED_APPS] |
|
320 except ImportError: |
|
321 # Fail silently if DJANGO_SETTINGS_MODULE isn't set. The |
|
322 # user will find out once they execute the command. |
|
323 pass |
|
324 options += [(s_opt.get_opt_string(), s_opt.nargs) for s_opt in |
|
325 subcommand_cls.option_list] |
|
326 # filter out previously specified options from available options |
|
327 prev_opts = [x.split('=')[0] for x in cwords[1:cword-1]] |
|
328 options = filter(lambda (x, v): x not in prev_opts, options) |
|
329 |
|
330 # filter options by current input |
|
331 options = sorted([(k, v) for k, v in options if k.startswith(curr)]) |
|
332 for option in options: |
|
333 opt_label = option[0] |
|
334 # append '=' to options which require args |
|
335 if option[1]: |
|
336 opt_label += '=' |
|
337 print opt_label |
|
338 sys.exit(1) |
|
339 |
264 def execute(self): |
340 def execute(self): |
265 """ |
341 """ |
266 Given the command-line arguments, this figures out which subcommand is |
342 Given the command-line arguments, this figures out which subcommand is |
267 being run, creates a parser appropriate to that command, and runs it. |
343 being run, creates a parser appropriate to that command, and runs it. |
268 """ |
344 """ |
270 # These options could affect the commands that are available, so they |
346 # These options could affect the commands that are available, so they |
271 # must be processed early. |
347 # must be processed early. |
272 parser = LaxOptionParser(usage="%prog subcommand [options] [args]", |
348 parser = LaxOptionParser(usage="%prog subcommand [options] [args]", |
273 version=get_version(), |
349 version=get_version(), |
274 option_list=BaseCommand.option_list) |
350 option_list=BaseCommand.option_list) |
|
351 self.autocomplete() |
275 try: |
352 try: |
276 options, args = parser.parse_args(self.argv) |
353 options, args = parser.parse_args(self.argv) |
277 handle_default_options(options) |
354 handle_default_options(options) |
278 except: |
355 except: |
279 pass # Ignore any option errors at this point. |
356 pass # Ignore any option errors at this point. |
280 |
357 |
281 try: |
358 try: |
282 subcommand = self.argv[1] |
359 subcommand = self.argv[1] |
283 except IndexError: |
360 except IndexError: |
284 sys.stderr.write("Type '%s help' for usage.\n" % self.prog_name) |
361 subcommand = 'help' # Display help if no arguments were given. |
285 sys.exit(1) |
|
286 |
362 |
287 if subcommand == 'help': |
363 if subcommand == 'help': |
288 if len(args) > 2: |
364 if len(args) > 2: |
289 self.fetch_command(args[2]).print_help(self.prog_name, args[2]) |
365 self.fetch_command(args[2]).print_help(self.prog_name, args[2]) |
290 else: |
366 else: |