~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-02-23 17:03:04 UTC
  • mfrom: (1558.1.10 Aaron's integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060223170304-293223b3e089d67f
Merge user command aliases

Show diffs side-by-side

added added

removed removed

Lines of Context:
207
207
            r[o.name] = o
208
208
        return r
209
209
 
210
 
    def run_argv(self, argv):
 
210
    def run_argv(self, argv, alias_argv=None):
211
211
        """Parse command line and run."""
212
 
        args, opts = parse_args(self, argv)
 
212
        args, opts = parse_args(self, argv, alias_argv)
213
213
        if 'help' in opts:  # e.g. bzr add --help
214
214
            from bzrlib.help import help_on_command
215
215
            help_on_command(self.name())
218
218
        allowed_names = self.options().keys()
219
219
        for oname in opts:
220
220
            if oname not in allowed_names:
221
 
                raise BzrCommandError("option '--%s' is not allowed for command %r"
222
 
                                      % (oname, self.name()))
 
221
                raise BzrCommandError("option '--%s' is not allowed for"
 
222
                                      " command %r" % (oname, self.name()))
223
223
        # mix arguments and options into one dictionary
224
224
        cmdargs = _match_argform(self.name(), self.takes_args, args)
225
225
        cmdopts = {}
285
285
        parsed = [spec, None]
286
286
    return parsed
287
287
 
288
 
def parse_args(command, argv):
 
288
def parse_args(command, argv, alias_argv=None):
289
289
    """Parse command line.
290
290
    
291
291
    Arguments and options are parsed at this level before being passed
296
296
    # TODO: chop up this beast; make it a method of the Command
297
297
    args = []
298
298
    opts = {}
 
299
    alias_opts = {}
299
300
 
300
301
    cmd_options = command.options()
301
302
    argsover = False
302
 
    while argv:
303
 
        a = argv.pop(0)
304
 
        if argsover:
305
 
            args.append(a)
306
 
            continue
307
 
        elif a == '--':
308
 
            # We've received a standalone -- No more flags
309
 
            argsover = True
310
 
            continue
311
 
        if a[0] == '-':
312
 
            # option names must not be unicode
313
 
            a = str(a)
314
 
            optarg = None
315
 
            if a[1] == '-':
316
 
                mutter("  got option %r", a)
317
 
                if '=' in a:
318
 
                    optname, optarg = a[2:].split('=', 1)
319
 
                else:
320
 
                    optname = a[2:]
321
 
                if optname not in cmd_options:
322
 
                    raise BzrOptionError('unknown long option %r for command %s'
323
 
                        % (a, command.name()))
324
 
            else:
325
 
                shortopt = a[1:]
326
 
                if shortopt in Option.SHORT_OPTIONS:
327
 
                    # Multi-character options must have a space to delimit
328
 
                    # their value
329
 
                    # ^^^ what does this mean? mbp 20051014
330
 
                    optname = Option.SHORT_OPTIONS[shortopt].name
331
 
                else:
332
 
                    # Single character short options, can be chained,
333
 
                    # and have their value appended to their name
334
 
                    shortopt = a[1:2]
335
 
                    if shortopt not in Option.SHORT_OPTIONS:
336
 
                        # We didn't find the multi-character name, and we
337
 
                        # didn't find the single char name
338
 
                        raise BzrError('unknown short option %r' % a)
339
 
                    optname = Option.SHORT_OPTIONS[shortopt].name
 
303
    proc_aliasarg = True # Are we processing alias_argv now?
 
304
    for proc_argv in alias_argv, argv:
 
305
        while proc_argv:
 
306
            a = proc_argv.pop(0)
 
307
            if argsover:
 
308
                args.append(a)
 
309
                continue
 
310
            elif a == '--':
 
311
                # We've received a standalone -- No more flags
 
312
                argsover = True
 
313
                continue
 
314
            if a[0] == '-':
 
315
                # option names must not be unicode
 
316
                a = str(a)
 
317
                optarg = None
 
318
                if a[1] == '-':
 
319
                    mutter("  got option %r", a)
 
320
                    if '=' in a:
 
321
                        optname, optarg = a[2:].split('=', 1)
 
322
                    else:
 
323
                        optname = a[2:]
 
324
                    if optname not in cmd_options:
 
325
                        raise BzrOptionError('unknown long option %r for'
 
326
                                             ' command %s' % 
 
327
                                             (a, command.name()))
 
328
                else:
 
329
                    shortopt = a[1:]
 
330
                    if shortopt in Option.SHORT_OPTIONS:
 
331
                        # Multi-character options must have a space to delimit
 
332
                        # their value
 
333
                        # ^^^ what does this mean? mbp 20051014
 
334
                        optname = Option.SHORT_OPTIONS[shortopt].name
 
335
                    else:
 
336
                        # Single character short options, can be chained,
 
337
                        # and have their value appended to their name
 
338
                        shortopt = a[1:2]
 
339
                        if shortopt not in Option.SHORT_OPTIONS:
 
340
                            # We didn't find the multi-character name, and we
 
341
                            # didn't find the single char name
 
342
                            raise BzrError('unknown short option %r' % a)
 
343
                        optname = Option.SHORT_OPTIONS[shortopt].name
340
344
 
341
 
                    if a[2:]:
342
 
                        # There are extra things on this option
343
 
                        # see if it is the value, or if it is another
344
 
                        # short option
345
 
                        optargfn = Option.OPTIONS[optname].type
346
 
                        if optargfn is None:
347
 
                            # This option does not take an argument, so the
348
 
                            # next entry is another short option, pack it back
349
 
                            # into the list
350
 
                            argv.insert(0, '-' + a[2:])
 
345
                        if a[2:]:
 
346
                            # There are extra things on this option
 
347
                            # see if it is the value, or if it is another
 
348
                            # short option
 
349
                            optargfn = Option.OPTIONS[optname].type
 
350
                            if optargfn is None:
 
351
                                # This option does not take an argument, so the
 
352
                                # next entry is another short option, pack it
 
353
                                # back into the list
 
354
                                proc_argv.insert(0, '-' + a[2:])
 
355
                            else:
 
356
                                # This option takes an argument, so pack it
 
357
                                # into the array
 
358
                                optarg = a[2:]
 
359
                
 
360
                    if optname not in cmd_options:
 
361
                        raise BzrOptionError('unknown short option %r for'
 
362
                                             ' command %s' % 
 
363
                                             (shortopt, command.name()))
 
364
                if optname in opts:
 
365
                    # XXX: Do we ever want to support this, e.g. for -r?
 
366
                    if proc_aliasarg:
 
367
                        raise BzrError('repeated option %r' % a)
 
368
                    elif optname in alias_opts:
 
369
                        # Replace what's in the alias with what's in the real
 
370
                        # argument
 
371
                        del alias_opts[optname]
 
372
                        del opts[optname]
 
373
                        proc_argv.insert(0, a)
 
374
                        continue
 
375
                    else:
 
376
                        raise BzrError('repeated option %r' % a)
 
377
                    
 
378
                option_obj = cmd_options[optname]
 
379
                optargfn = option_obj.type
 
380
                if optargfn:
 
381
                    if optarg == None:
 
382
                        if not proc_argv:
 
383
                            raise BzrError('option %r needs an argument' % a)
351
384
                        else:
352
 
                            # This option takes an argument, so pack it
353
 
                            # into the array
354
 
                            optarg = a[2:]
355
 
            
356
 
                if optname not in cmd_options:
357
 
                    raise BzrOptionError('unknown short option %r for command'
358
 
                        ' %s' % (shortopt, command.name()))
359
 
            if optname in opts:
360
 
                # XXX: Do we ever want to support this, e.g. for -r?
361
 
                raise BzrError('repeated option %r' % a)
362
 
                
363
 
            option_obj = cmd_options[optname]
364
 
            optargfn = option_obj.type
365
 
            if optargfn:
366
 
                if optarg == None:
367
 
                    if not argv:
368
 
                        raise BzrError('option %r needs an argument' % a)
369
 
                    else:
370
 
                        optarg = argv.pop(0)
371
 
                opts[optname] = optargfn(optarg)
 
385
                            optarg = proc_argv.pop(0)
 
386
                    opts[optname] = optargfn(optarg)
 
387
                    if proc_aliasarg:
 
388
                        alias_opts[optname] = optargfn(optarg)
 
389
                else:
 
390
                    if optarg != None:
 
391
                        raise BzrError('option %r takes no argument' % optname)
 
392
                    opts[optname] = True
 
393
                    if proc_aliasarg:
 
394
                        alias_opts[optname] = True
372
395
            else:
373
 
                if optarg != None:
374
 
                    raise BzrError('option %r takes no argument' % optname)
375
 
                opts[optname] = True
376
 
        else:
377
 
            args.append(a)
 
396
                args.append(a)
 
397
        proc_aliasarg = False # Done with alias argv
378
398
    return args, opts
379
399
 
380
400
 
459
479
        print 'Profile data written to %r.' % filename
460
480
    return ret
461
481
 
 
482
 
 
483
def get_alias(cmd):
 
484
    """if an alias for cmd exists, returns the expanded command
 
485
       else returns None"""
 
486
    import bzrlib.config
 
487
    alias = bzrlib.config.GlobalConfig().get_alias(cmd)
 
488
    if (alias):
 
489
        return alias.split(' ')
 
490
    return None
 
491
 
 
492
 
462
493
def run_bzr(argv):
463
494
    """Execute a command.
464
495
 
476
507
    --no-plugins
477
508
        Do not load plugin modules at all
478
509
 
 
510
    --no-aliases
 
511
        Do not allow aliases
 
512
 
479
513
    --builtin
480
514
        Only use builtin commands.  (Plugins are still allowed to change
481
515
        other behaviour.)
488
522
    """
489
523
    argv = [a.decode(bzrlib.user_encoding) for a in argv]
490
524
 
491
 
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin = False
 
525
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin =  \
 
526
                opt_no_aliases = False
492
527
    opt_lsprof_file = None
493
528
 
494
529
    # --no-plugins is handled specially at a very early stage. We need
508
543
            i += 1
509
544
        elif a == '--no-plugins':
510
545
            opt_no_plugins = True
 
546
        elif a == '--no-aliases':
 
547
            opt_no_aliases = True
511
548
        elif a == '--builtin':
512
549
            opt_builtin = True
513
550
        elif a in ('--quiet', '-q'):
537
574
        from bzrlib.plugin import disable_plugins
538
575
        disable_plugins()
539
576
 
 
577
    if not opt_no_aliases:
 
578
        alias_argv = get_alias(argv[0])
 
579
        if alias_argv:
 
580
            alias_argv = [a.decode(bzrlib.user_encoding) for a in alias_argv]
 
581
            argv[0] = alias_argv.pop(0)
 
582
 
540
583
    cmd = str(argv.pop(0))
541
584
 
542
585
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
543
586
 
544
587
    try:
545
588
        if opt_lsprof:
546
 
            ret = apply_lsprofiled(opt_lsprof_file, cmd_obj.run_argv, argv)
 
589
            ret = apply_lsprofiled(opt_lsprof_file, cmd_obj.run_argv, argv, 
 
590
                                   alias_argv)
547
591
        elif opt_profile:
548
 
            ret = apply_profiled(cmd_obj.run_argv, argv)
 
592
            ret = apply_profiled(cmd_obj.run_argv, argv, alias_argv)
549
593
        else:
550
 
            ret = cmd_obj.run_argv(argv)
 
594
            ret = cmd_obj.run_argv(argv, alias_argv)
551
595
        return ret or 0
552
596
    finally:
553
597
        # reset, in case we may do other commands later within the same process