~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

Update news and readme

- better explanation of dependencies

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)
486
465
            opt_no_plugins = True
487
466
        elif a == '--builtin':
488
467
            opt_builtin = True
489
 
        elif a in ('--quiet', '-q'):
490
 
            be_quiet()
491
468
        else:
492
 
            continue
 
469
            break
493
470
        argv.remove(a)
494
471
 
495
472
    if (not argv) or (argv[0] == '--help'):
513
490
 
514
491
    cmd_obj = get_cmd_object(cmd, plugins_override=not opt_builtin)
515
492
 
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
 
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
542
498
 
543
499
 
544
500
def main(argv):
545
501
    import bzrlib.ui
546
 
    from bzrlib.ui.text import TextUIFactory
547
 
    ## bzrlib.trace.enable_default_logging()
548
502
    bzrlib.trace.log_startup(argv)
549
 
    bzrlib.ui.ui_factory = TextUIFactory()
550
 
    ret = run_bzr_catch_errors(argv[1:])
551
 
    mutter("return code %d", ret)
552
 
    return ret
 
503
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
 
504
 
 
505
    return run_bzr_catch_errors(argv[1:])
553
506
 
554
507
 
555
508
def run_bzr_catch_errors(argv):
559
512
        finally:
560
513
            # do this here inside the exception wrappers to catch EPIPE
561
514
            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
562
528
    except Exception, e:
563
 
        # used to handle AssertionError and KeyboardInterrupt
564
 
        # specially here, but hopefully they're handled ok by the logger now
565
529
        import errno
566
530
        if (isinstance(e, IOError) 
567
531
            and hasattr(e, 'errno')
568
532
            and e.errno == errno.EPIPE):
569
533
            bzrlib.trace.note('broken pipe')
570
 
            return 3
 
534
            return 2
571
535
        else:
 
536
            ## import pdb
 
537
            ## pdb.pm()
572
538
            bzrlib.trace.log_exception()
573
 
            if os.environ.get('BZR_PDB'):
574
 
                print '**** entering debugger'
575
 
                import pdb
576
 
                pdb.post_mortem(sys.exc_traceback)
577
 
            return 3
 
539
            return 2
578
540
 
579
541
if __name__ == '__main__':
580
542
    sys.exit(main(sys.argv))