~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

Merged 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())
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 command %s'
 
326
                            % (a, command.name()))
 
327
                else:
 
328
                    shortopt = a[1:]
 
329
                    if shortopt in Option.SHORT_OPTIONS:
 
330
                        # Multi-character options must have a space to delimit
 
331
                        # their value
 
332
                        # ^^^ what does this mean? mbp 20051014
 
333
                        optname = Option.SHORT_OPTIONS[shortopt].name
 
334
                    else:
 
335
                        # Single character short options, can be chained,
 
336
                        # and have their value appended to their name
 
337
                        shortopt = a[1:2]
 
338
                        if shortopt not in Option.SHORT_OPTIONS:
 
339
                            # We didn't find the multi-character name, and we
 
340
                            # didn't find the single char name
 
341
                            raise BzrError('unknown short option %r' % a)
 
342
                        optname = Option.SHORT_OPTIONS[shortopt].name
340
343
 
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:])
 
344
                        if a[2:]:
 
345
                            # There are extra things on this option
 
346
                            # see if it is the value, or if it is another
 
347
                            # short option
 
348
                            optargfn = Option.OPTIONS[optname].type
 
349
                            if optargfn is None:
 
350
                                # This option does not take an argument, so the
 
351
                                # next entry is another short option, pack it back
 
352
                                # into the list
 
353
                                proc_argv.insert(0, '-' + a[2:])
 
354
                            else:
 
355
                                # This option takes an argument, so pack it
 
356
                                # into the array
 
357
                                optarg = a[2:]
 
358
                
 
359
                    if optname not in cmd_options:
 
360
                        raise BzrOptionError('unknown short option %r for command'
 
361
                            ' %s' % (shortopt, command.name()))
 
362
                if optname in opts:
 
363
                    # XXX: Do we ever want to support this, e.g. for -r?
 
364
                    if proc_aliasarg:
 
365
                        raise BzrError('repeated option %r' % a)
 
366
                    elif optname in alias_opts:
 
367
                        # Replace what's in the alias with what's in the real argument
 
368
                        del alias_opts[optname]
 
369
                        del opts[optname]
 
370
                        proc_argv.insert(0, a)
 
371
                        continue
 
372
                    else:
 
373
                        raise BzrError('repeated option %r' % a)
 
374
                    
 
375
                option_obj = cmd_options[optname]
 
376
                optargfn = option_obj.type
 
377
                if optargfn:
 
378
                    if optarg == None:
 
379
                        if not proc_argv:
 
380
                            raise BzrError('option %r needs an argument' % a)
351
381
                        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)
 
382
                            optarg = proc_argv.pop(0)
 
383
                    opts[optname] = optargfn(optarg)
 
384
                    if proc_aliasarg:
 
385
                        alias_opts[optname] = optargfn(optarg)
 
386
                else:
 
387
                    if optarg != None:
 
388
                        raise BzrError('option %r takes no argument' % optname)
 
389
                    opts[optname] = True
 
390
                    if proc_aliasarg:
 
391
                        alias_opts[optname] = True
372
392
            else:
373
 
                if optarg != None:
374
 
                    raise BzrError('option %r takes no argument' % optname)
375
 
                opts[optname] = True
376
 
        else:
377
 
            args.append(a)
 
393
                args.append(a)
 
394
        proc_aliasarg = False # Done with alias argv
378
395
    return args, opts
379
396
 
380
397
 
459
476
        print 'Profile data written to %r.' % filename
460
477
    return ret
461
478
 
 
479
 
 
480
def get_alias(cmd):
 
481
    """if an alias for cmd exists, returns the expanded command
 
482
       else returns None"""
 
483
    import bzrlib.config
 
484
    alias = bzrlib.config.GlobalConfig().get_alias(cmd)
 
485
    if (alias):
 
486
        return alias.split(' ')
 
487
    return None
 
488
 
 
489
 
462
490
def run_bzr(argv):
463
491
    """Execute a command.
464
492
 
476
504
    --no-plugins
477
505
        Do not load plugin modules at all
478
506
 
 
507
    --no-aliases
 
508
        Do not allow aliases
 
509
 
479
510
    --builtin
480
511
        Only use builtin commands.  (Plugins are still allowed to change
481
512
        other behaviour.)
488
519
    """
489
520
    argv = [a.decode(bzrlib.user_encoding) for a in argv]
490
521
 
491
 
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin = False
 
522
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin =  \
 
523
                opt_no_aliases = False
492
524
    opt_lsprof_file = None
493
525
 
494
526
    # --no-plugins is handled specially at a very early stage. We need
508
540
            i += 1
509
541
        elif a == '--no-plugins':
510
542
            opt_no_plugins = True
 
543
        elif a == '--no-aliases':
 
544
            opt_no_aliases = True
511
545
        elif a == '--builtin':
512
546
            opt_builtin = True
513
547
        elif a in ('--quiet', '-q'):
537
571
        from bzrlib.plugin import disable_plugins
538
572
        disable_plugins()
539
573
 
 
574
    if not opt_no_aliases:
 
575
        alias_argv = get_alias(argv[0])
 
576
        if alias_argv:
 
577
            alias_argv = [a.decode(bzrlib.user_encoding) for a in alias_argv]
 
578
            argv[0] = alias_argv.pop(0)
 
579
 
540
580
    cmd = str(argv.pop(0))
541
581
 
542
582
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
543
583
 
544
584
    try:
545
585
        if opt_lsprof:
546
 
            ret = apply_lsprofiled(opt_lsprof_file, cmd_obj.run_argv, argv)
 
586
            ret = apply_lsprofiled(opt_lsprof_file, cmd_obj.run_argv, argv, alias_argv)
547
587
        elif opt_profile:
548
 
            ret = apply_profiled(cmd_obj.run_argv, argv)
 
588
            ret = apply_profiled(cmd_obj.run_argv, argv, alias_argv)
549
589
        else:
550
 
            ret = cmd_obj.run_argv(argv)
 
590
            ret = cmd_obj.run_argv(argv, alias_argv)
551
591
        return ret or 0
552
592
    finally:
553
593
        # reset, in case we may do other commands later within the same process