~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Robert Collins
  • Date: 2005-10-17 11:56:54 UTC
  • mfrom: (1185.16.59)
  • Revision ID: robertc@robertcollins.net-20051017115654-662239e1587524a8
mergeĀ fromĀ martin.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
import os
32
32
from warnings import warn
33
33
from inspect import getdoc
34
 
import errno
35
34
 
36
35
import bzrlib
37
36
import bzrlib.trace
38
 
from bzrlib.trace import mutter, note, log_error, warning, be_quiet
39
 
from bzrlib.errors import (BzrError, 
40
 
                           BzrCheckError,
41
 
                           BzrCommandError,
42
 
                           BzrOptionError,
43
 
                           NotBranchError)
 
37
from bzrlib.trace import mutter, note, log_error, warning
 
38
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
44
39
from bzrlib.revisionspec import RevisionSpec
45
40
from bzrlib import BZRDIR
46
41
from bzrlib.option import Option
48
43
plugin_cmds = {}
49
44
 
50
45
 
51
 
def register_command(cmd, decorate=False):
 
46
def register_command(cmd):
52
47
    "Utility function to help register a command"
53
48
    global plugin_cmds
54
49
    k = cmd.__name__
59
54
    if not plugin_cmds.has_key(k_unsquished):
60
55
        plugin_cmds[k_unsquished] = cmd
61
56
        mutter('registered plugin command %s', k_unsquished)      
62
 
        if decorate and k_unsquished in builtin_command_names():
63
 
            return _builtin_commands()[k_unsquished]
64
 
    elif decorate:
65
 
        result = plugin_cmds[k_unsquished]
66
 
        plugin_cmds[k_unsquished] = cmd
67
 
        return result
68
57
    else:
69
58
        log_error('Two plugins defined the same command: %r' % k)
70
59
        log_error('Not loading the one in %r' % sys.modules[cmd.__module__])
168
157
        List of argument forms, marked with whether they are optional,
169
158
        repeated, etc.
170
159
 
171
 
                Examples:
172
 
 
173
 
                ['to_location', 'from_branch?', 'file*']
174
 
 
175
 
                'to_location' is required
176
 
                'from_branch' is optional
177
 
                'file' can be specified 0 or more times
178
 
 
179
160
    takes_options
180
161
        List of options that may be given for this command.  These can
181
162
        be either strings, referring to globally-defined options,
231
212
        all_cmd_args.update(cmdopts)
232
213
 
233
214
        return self.run(**all_cmd_args)
 
215
 
234
216
    
235
217
    def run(self):
236
218
        """Actually run the command.
314
296
            a = str(a)
315
297
            optarg = None
316
298
            if a[1] == '-':
317
 
                mutter("  got option %r", a)
 
299
                mutter("  got option %r" % a)
318
300
                if '=' in a:
319
301
                    optname, optarg = a[2:].split('=', 1)
320
302
                else:
321
303
                    optname = a[2:]
322
304
                if optname not in cmd_options:
323
 
                    raise BzrOptionError('unknown long option %r for command %s'
324
 
                        % (a, command.name()))
 
305
                    raise BzrCommandError('unknown long option %r for command %s' 
 
306
                            % (a, command.name))
325
307
            else:
326
308
                shortopt = a[1:]
327
309
                if shortopt in Option.SHORT_OPTIONS:
354
336
                            # into the array
355
337
                            optarg = a[2:]
356
338
            
357
 
                if optname not in cmd_options:
358
 
                    raise BzrOptionError('unknown short option %r for command'
359
 
                        ' %s' % (shortopt, command.name()))
360
339
            if optname in opts:
361
340
                # XXX: Do we ever want to support this, e.g. for -r?
362
341
                raise BzrError('repeated option %r' % a)
447
426
        os.remove(pfname)
448
427
 
449
428
 
450
 
def apply_lsprofiled(the_callable, *args, **kwargs):
451
 
    from bzrlib.lsprof import profile
452
 
    ret,stats = profile(the_callable,*args,**kwargs)
453
 
    stats.sort()
454
 
    stats.pprint()
455
 
    return ret
456
 
 
457
429
def run_bzr(argv):
458
430
    """Execute a command.
459
431
 
476
448
        other behaviour.)
477
449
 
478
450
    --profile
479
 
        Run under the Python hotshot profiler.
480
 
 
481
 
    --lsprof
482
 
        Run under the Python lsprof profiler.
 
451
        Run under the Python profiler.
483
452
    """
 
453
    # Load all of the transport methods
 
454
    import bzrlib.transport.local, bzrlib.transport.http
 
455
    
484
456
    argv = [a.decode(bzrlib.user_encoding) for a in argv]
485
457
 
486
 
    opt_lsprof = opt_profile = opt_no_plugins = opt_builtin = False
 
458
    opt_profile = opt_no_plugins = opt_builtin = False
487
459
 
488
460
    # --no-plugins is handled specially at a very early stage. We need
489
461
    # to load plugins before doing other command parsing so that they
492
464
    for a in argv:
493
465
        if a == '--profile':
494
466
            opt_profile = True
495
 
        elif a == '--lsprof':
496
 
            opt_lsprof = True
497
467
        elif a == '--no-plugins':
498
468
            opt_no_plugins = True
499
469
        elif a == '--builtin':
500
470
            opt_builtin = True
501
 
        elif a in ('--quiet', '-q'):
502
 
            be_quiet()
503
471
        else:
504
 
            continue
 
472
            break
505
473
        argv.remove(a)
506
474
 
507
475
    if (not argv) or (argv[0] == '--help'):
525
493
 
526
494
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
527
495
 
528
 
    try:
529
 
        if opt_lsprof:
530
 
            ret = apply_lsprofiled(cmd_obj.run_argv, argv)
531
 
        elif opt_profile:
532
 
            ret = apply_profiled(cmd_obj.run_argv, argv)
533
 
        else:
534
 
            ret = cmd_obj.run_argv(argv)
535
 
        return ret or 0
536
 
    finally:
537
 
        # reset, in case we may do other commands later within the same process
538
 
        be_quiet(False)
539
 
 
540
 
def display_command(func):
541
 
    """Decorator that suppresses pipe/interrupt errors."""
542
 
    def ignore_pipe(*args, **kwargs):
543
 
        try:
544
 
            result = func(*args, **kwargs)
545
 
            sys.stdout.flush()
546
 
            return result
547
 
        except IOError, e:
548
 
            if not hasattr(e, 'errno'):
549
 
                raise
550
 
            if e.errno != errno.EPIPE:
551
 
                raise
552
 
            pass
553
 
        except KeyboardInterrupt:
554
 
            pass
555
 
    return ignore_pipe
 
496
    if opt_profile:
 
497
        ret = apply_profiled(cmd_obj.run_argv, argv)
 
498
    else:
 
499
        ret = cmd_obj.run_argv(argv)
 
500
    return ret or 0
556
501
 
557
502
 
558
503
def main(argv):
559
504
    import bzrlib.ui
560
 
    from bzrlib.ui.text import TextUIFactory
561
 
    ## bzrlib.trace.enable_default_logging()
562
505
    bzrlib.trace.log_startup(argv)
563
 
    bzrlib.ui.ui_factory = TextUIFactory()
564
 
    ret = run_bzr_catch_errors(argv[1:])
565
 
    mutter("return code %d", ret)
566
 
    return ret
 
506
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
 
507
 
 
508
    return run_bzr_catch_errors(argv[1:])
567
509
 
568
510
 
569
511
def run_bzr_catch_errors(argv):
573
515
        finally:
574
516
            # do this here inside the exception wrappers to catch EPIPE
575
517
            sys.stdout.flush()
 
518
    except BzrCommandError, e:
 
519
        # command line syntax error, etc
 
520
        log_error(str(e))
 
521
        return 1
 
522
    except BzrError, e:
 
523
        bzrlib.trace.log_exception()
 
524
        return 1
 
525
    except AssertionError, e:
 
526
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
 
527
        return 3
 
528
    except KeyboardInterrupt, e:
 
529
        bzrlib.trace.log_exception('interrupted')
 
530
        return 2
576
531
    except Exception, e:
577
 
        # used to handle AssertionError and KeyboardInterrupt
578
 
        # specially here, but hopefully they're handled ok by the logger now
579
532
        import errno
580
533
        if (isinstance(e, IOError) 
581
534
            and hasattr(e, 'errno')
582
535
            and e.errno == errno.EPIPE):
583
536
            bzrlib.trace.note('broken pipe')
584
 
            return 3
 
537
            return 2
585
538
        else:
 
539
            ## import pdb
 
540
            ## pdb.pm()
586
541
            bzrlib.trace.log_exception()
587
 
            if os.environ.get('BZR_PDB'):
588
 
                print '**** entering debugger'
589
 
                import pdb
590
 
                pdb.post_mortem(sys.exc_traceback)
591
 
            return 3
 
542
            return 2
592
543
 
593
544
if __name__ == '__main__':
594
545
    sys.exit(main(sys.argv))