~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Michael Ellerman
  • Date: 2005-12-10 22:11:13 UTC
  • mto: This revision was merged to the branch mainline in revision 1528.
  • Revision ID: michael@ellerman.id.au-20051210221113-99ca561aaab4661e
Simplify handling of DivergedBranches in cmd_pull()

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
34
35
 
35
36
import bzrlib
36
37
import bzrlib.trace
37
 
from bzrlib.trace import mutter, note, log_error, warning
38
 
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
 
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)
39
44
from bzrlib.revisionspec import RevisionSpec
40
45
from bzrlib import BZRDIR
41
46
from bzrlib.option import Option
43
48
plugin_cmds = {}
44
49
 
45
50
 
46
 
def register_command(cmd):
 
51
def register_command(cmd, decorate=False):
47
52
    "Utility function to help register a command"
48
53
    global plugin_cmds
49
54
    k = cmd.__name__
54
59
    if not plugin_cmds.has_key(k_unsquished):
55
60
        plugin_cmds[k_unsquished] = cmd
56
61
        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
57
68
    else:
58
69
        log_error('Two plugins defined the same command: %r' % k)
59
70
        log_error('Not loading the one in %r' % sys.modules[cmd.__module__])
157
168
        List of argument forms, marked with whether they are optional,
158
169
        repeated, etc.
159
170
 
 
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
 
160
179
    takes_options
161
180
        List of options that may be given for this command.  These can
162
181
        be either strings, referring to globally-defined options,
212
231
        all_cmd_args.update(cmdopts)
213
232
 
214
233
        return self.run(**all_cmd_args)
215
 
 
216
234
    
217
235
    def run(self):
218
236
        """Actually run the command.
296
314
            a = str(a)
297
315
            optarg = None
298
316
            if a[1] == '-':
299
 
                mutter("  got option %r" % a)
 
317
                mutter("  got option %r", a)
300
318
                if '=' in a:
301
319
                    optname, optarg = a[2:].split('=', 1)
302
320
                else:
303
321
                    optname = a[2:]
304
322
                if optname not in cmd_options:
305
 
                    raise BzrCommandError('unknown long option %r for command %s' 
306
 
                            % (a, command.name))
 
323
                    raise BzrOptionError('unknown long option %r for command %s'
 
324
                        % (a, command.name()))
307
325
            else:
308
326
                shortopt = a[1:]
309
327
                if shortopt in Option.SHORT_OPTIONS:
336
354
                            # into the array
337
355
                            optarg = a[2:]
338
356
            
 
357
                if optname not in cmd_options:
 
358
                    raise BzrOptionError('unknown short option %r for command'
 
359
                        ' %s' % (shortopt, command.name()))
339
360
            if optname in opts:
340
361
                # XXX: Do we ever want to support this, e.g. for -r?
341
362
                raise BzrError('repeated option %r' % a)
465
486
            opt_no_plugins = True
466
487
        elif a == '--builtin':
467
488
            opt_builtin = True
 
489
        elif a in ('--quiet', '-q'):
 
490
            be_quiet()
468
491
        else:
469
 
            break
 
492
            continue
470
493
        argv.remove(a)
471
494
 
472
495
    if (not argv) or (argv[0] == '--help'):
490
513
 
491
514
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
492
515
 
493
 
    if opt_profile:
494
 
        ret = apply_profiled(cmd_obj.run_argv, argv)
495
 
    else:
496
 
        ret = cmd_obj.run_argv(argv)
497
 
    return ret or 0
 
516
    try:
 
517
        if opt_profile:
 
518
            ret = apply_profiled(cmd_obj.run_argv, argv)
 
519
        else:
 
520
            ret = cmd_obj.run_argv(argv)
 
521
        return ret or 0
 
522
    finally:
 
523
        # reset, in case we may do other commands later within the same process
 
524
        be_quiet(False)
 
525
 
 
526
def display_command(func):
 
527
    """Decorator that suppresses pipe/interrupt errors."""
 
528
    def ignore_pipe(*args, **kwargs):
 
529
        try:
 
530
            result = func(*args, **kwargs)
 
531
            sys.stdout.flush()
 
532
            return result
 
533
        except IOError, e:
 
534
            if not hasattr(e, 'errno'):
 
535
                raise
 
536
            if e.errno != errno.EPIPE:
 
537
                raise
 
538
            pass
 
539
        except KeyboardInterrupt:
 
540
            pass
 
541
    return ignore_pipe
498
542
 
499
543
 
500
544
def main(argv):
501
545
    import bzrlib.ui
 
546
    from bzrlib.ui.text import TextUIFactory
 
547
    ## bzrlib.trace.enable_default_logging()
502
548
    bzrlib.trace.log_startup(argv)
503
 
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
504
 
 
505
 
    return run_bzr_catch_errors(argv[1:])
 
549
    bzrlib.ui.ui_factory = TextUIFactory()
 
550
    ret = run_bzr_catch_errors(argv[1:])
 
551
    mutter("return code %d", ret)
 
552
    return ret
506
553
 
507
554
 
508
555
def run_bzr_catch_errors(argv):
512
559
        finally:
513
560
            # do this here inside the exception wrappers to catch EPIPE
514
561
            sys.stdout.flush()
515
 
    except BzrCommandError, e:
516
 
        # command line syntax error, etc
517
 
        log_error(str(e))
518
 
        return 1
519
 
    except BzrError, e:
520
 
        bzrlib.trace.log_exception()
521
 
        return 1
522
 
    except AssertionError, e:
523
 
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
524
 
        return 3
525
 
    except KeyboardInterrupt, e:
526
 
        bzrlib.trace.log_exception('interrupted')
527
 
        return 2
528
562
    except Exception, e:
 
563
        # used to handle AssertionError and KeyboardInterrupt
 
564
        # specially here, but hopefully they're handled ok by the logger now
529
565
        import errno
530
566
        if (isinstance(e, IOError) 
531
567
            and hasattr(e, 'errno')
532
568
            and e.errno == errno.EPIPE):
533
569
            bzrlib.trace.note('broken pipe')
534
 
            return 2
 
570
            return 3
535
571
        else:
536
 
            ## import pdb
537
 
            ## pdb.pm()
538
572
            bzrlib.trace.log_exception()
539
 
            return 2
 
573
            if os.environ.get('BZR_PDB'):
 
574
                print '**** entering debugger'
 
575
                import pdb
 
576
                pdb.post_mortem(sys.exc_traceback)
 
577
            return 3
540
578
 
541
579
if __name__ == '__main__':
542
580
    sys.exit(main(sys.argv))