/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Martin Pool
  • Date: 2005-08-30 01:35:40 UTC
  • Revision ID: mbp@sourcefrog.net-20050830013540-34e8996a86ba25fb
- rename FunctionalTest to TestCaseInTempDir

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
# TODO: probably should say which arguments are candidates for glob
21
21
# expansion on windows and do that at the command level.
22
22
 
 
23
# TODO: Help messages for options.
 
24
 
 
25
# TODO: Define arguments by objects, rather than just using names.
 
26
# Those objects can specify the expected type of the argument, which
 
27
# would help with validation and shell completion.
 
28
 
 
29
 
 
30
# TODO: Help messages for options.
 
31
 
 
32
# TODO: Define arguments by objects, rather than just using names.
 
33
# Those objects can specify the expected type of the argument, which
 
34
# would help with validation and shell completion.
 
35
 
 
36
 
23
37
import sys
24
38
import os
25
39
 
26
40
import bzrlib
 
41
import bzrlib.trace
27
42
from bzrlib.trace import mutter, note, log_error, warning
28
43
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
29
44
from bzrlib.branch import find_branch
43
58
        k_unsquished = k
44
59
    if not plugin_cmds.has_key(k_unsquished):
45
60
        plugin_cmds[k_unsquished] = cmd
 
61
        mutter('registered plugin command %s', k_unsquished)      
46
62
    else:
47
63
        log_error('Two plugins defined the same command: %r' % k)
48
64
        log_error('Not loading the one in %r' % sys.modules[cmd.__module__])
141
157
        raise BzrCommandError(msg)
142
158
    
143
159
 
 
160
def get_merge_type(typestring):
 
161
    """Attempt to find the merge class/factory associated with a string."""
 
162
    from merge import merge_types
 
163
    try:
 
164
        return merge_types[typestring][0]
 
165
    except KeyError:
 
166
        templ = '%s%%7s: %%s' % (' '*12)
 
167
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
 
168
        type_list = '\n'.join(lines)
 
169
        msg = "No known merge type %s. Supported types are:\n%s" %\
 
170
            (typestring, type_list)
 
171
        raise BzrCommandError(msg)
 
172
    
 
173
 
144
174
 
145
175
def _get_cmd_dict(plugins_override=True):
146
176
    d = {}
170
200
 
171
201
    # first look up this command under the specified name
172
202
    cmds = _get_cmd_dict(plugins_override=plugins_override)
 
203
    mutter("all commands: %r", cmds.keys())
173
204
    try:
174
205
        return cmd, cmds[cmd]
175
206
    except KeyError:
445
476
    takes_options = ['verbose', 'no-recurse']
446
477
    
447
478
    def run(self, file_list, verbose=False, no_recurse=False):
448
 
        from bzrlib.add import smart_add
449
 
        smart_add(file_list, verbose, not no_recurse)
 
479
        from bzrlib.add import smart_add, _PrintAddCallback
 
480
        recurse = not no_recurse
 
481
        smart_add(file_list, verbose, not no_recurse,
 
482
                  callback=_PrintAddCallback)
450
483
 
451
484
 
452
485
 
464
497
            os.mkdir(d)
465
498
            if not b:
466
499
                b = find_branch(d)
467
 
            b.add([d], verbose=True)
 
500
            b.add([d])
 
501
            print 'added', d
468
502
 
469
503
 
470
504
class cmd_relpath(Command):
559
593
        
560
594
        if os.path.isdir(names_list[-1]):
561
595
            # move into existing directory
562
 
            b.move(rel_names[:-1], rel_names[-1])
 
596
            for pair in b.move(rel_names[:-1], rel_names[-1]):
 
597
                print "%s => %s" % pair
563
598
        else:
564
599
            if len(names_list) != 2:
565
600
                raise BzrCommandError('to mv multiple files the destination '
566
601
                                      'must be a versioned directory')
567
 
            b.move(rel_names[0], rel_names[1])
 
602
            for pair in b.move(rel_names[0], rel_names[1]):
 
603
                print "%s => %s" % pair
568
604
            
569
605
    
570
606
 
590
626
        import tempfile
591
627
        from shutil import rmtree
592
628
        import errno
 
629
        from bzrlib.branch import pull_loc
593
630
        
594
631
        br_to = find_branch('.')
595
632
        stored_loc = None
642
679
    aliases = ['get', 'clone']
643
680
 
644
681
    def run(self, from_location, to_location=None, revision=None):
 
682
        from bzrlib.branch import copy_branch, find_cached_branch
 
683
        import tempfile
645
684
        import errno
646
 
        from bzrlib.merge import merge
647
 
        from bzrlib.branch import DivergedBranches, \
648
 
             find_cached_branch, Branch
649
685
        from shutil import rmtree
650
 
        from meta_store import CachedStore
651
 
        import tempfile
652
686
        cache_root = tempfile.mkdtemp()
653
 
 
654
 
        if revision is None:
655
 
            revision = [None]
656
 
        elif len(revision) > 1:
657
 
            raise BzrCommandError('bzr branch --revision takes exactly 1 revision value')
658
 
 
659
687
        try:
 
688
            if revision is None:
 
689
                revision = [None]
 
690
            elif len(revision) > 1:
 
691
                raise BzrCommandError(
 
692
                    'bzr branch --revision takes exactly 1 revision value')
660
693
            try:
661
694
                br_from = find_cached_branch(from_location, cache_root)
662
695
            except OSError, e:
665
698
                                          ' exist.' % to_location)
666
699
                else:
667
700
                    raise
668
 
 
669
701
            if to_location is None:
670
702
                to_location = os.path.basename(from_location.rstrip("/\\"))
671
 
 
672
703
            try:
673
704
                os.mkdir(to_location)
674
705
            except OSError, e:
680
711
                                          to_location)
681
712
                else:
682
713
                    raise
683
 
            br_to = Branch(to_location, init=True)
684
 
 
685
 
            br_to.set_root_id(br_from.get_root_id())
686
 
 
687
 
            if revision:
688
 
                if revision[0] is None:
689
 
                    revno = br_from.revno()
690
 
                else:
691
 
                    revno, rev_id = br_from.get_revision_info(revision[0])
692
 
                try:
693
 
                    br_to.update_revisions(br_from, stop_revision=revno)
694
 
                except bzrlib.errors.NoSuchRevision:
695
 
                    rmtree(to_location)
696
 
                    msg = "The branch %s has no revision %d." % (from_location,
697
 
                                                                 revno)
698
 
                    raise BzrCommandError(msg)
699
 
            
700
 
            merge((to_location, -1), (to_location, 0), this_dir=to_location,
701
 
                  check_clean=False, ignore_zero=True)
702
 
            from_location = pull_loc(br_from)
703
 
            br_to.controlfile("x-pull", "wb").write(from_location + "\n")
 
714
            try:
 
715
                copy_branch(br_from, to_location, revision[0])
 
716
            except bzrlib.errors.NoSuchRevision:
 
717
                rmtree(to_location)
 
718
                msg = "The branch %s has no revision %d." % (from_location, revision[0])
 
719
                raise BzrCommandError(msg)
704
720
        finally:
705
721
            rmtree(cache_root)
706
722
 
707
723
 
708
 
def pull_loc(branch):
709
 
    # TODO: Should perhaps just make attribute be 'base' in
710
 
    # RemoteBranch and Branch?
711
 
    if hasattr(branch, "baseurl"):
712
 
        return branch.baseurl
713
 
    else:
714
 
        return branch.base
715
 
 
716
 
 
717
 
 
718
724
class cmd_renames(Command):
719
725
    """Show list of renamed files.
720
726
 
837
843
    If files are listed, only the changes in those files are listed.
838
844
    Otherwise, all changes for the tree are listed.
839
845
 
840
 
    TODO: Given two revision arguments, show the difference between them.
841
 
 
842
846
    TODO: Allow diff across branches.
843
847
 
844
848
    TODO: Option to use external diff command; could be GNU diff, wdiff,
853
857
          deleted files.
854
858
 
855
859
    TODO: This probably handles non-Unix newlines poorly.
 
860
 
 
861
    examples:
 
862
        bzr diff
 
863
        bzr diff -r1
 
864
        bzr diff -r1:2
856
865
    """
857
866
    
858
867
    takes_args = ['file*']
871
880
        else:
872
881
            b = find_branch('.')
873
882
 
874
 
        # TODO: Make show_diff support taking 2 arguments
875
 
        base_rev = None
876
883
        if revision is not None:
877
 
            if len(revision) != 1:
878
 
                raise BzrCommandError('bzr diff --revision takes exactly one revision identifier')
879
 
            base_rev = revision[0]
880
 
    
881
 
        show_diff(b, base_rev, specific_files=file_list,
882
 
                  external_diff_options=diff_options)
883
 
 
 
884
            if len(revision) == 1:
 
885
                show_diff(b, revision[0], specific_files=file_list,
 
886
                          external_diff_options=diff_options)
 
887
            elif len(revision) == 2:
 
888
                show_diff(b, revision[0], specific_files=file_list,
 
889
                          external_diff_options=diff_options,
 
890
                          revision2=revision[1])
 
891
            else:
 
892
                raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
 
893
        else:
 
894
            show_diff(b, None, specific_files=file_list,
 
895
                      external_diff_options=diff_options)
884
896
 
885
897
        
886
898
 
967
979
    """
968
980
 
969
981
    takes_args = ['filename?']
970
 
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision','long', 'message']
 
982
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision',
 
983
                     'long', 'message', 'short',]
971
984
    
972
985
    def run(self, filename=None, timezone='original',
973
986
            verbose=False,
975
988
            forward=False,
976
989
            revision=None,
977
990
            message=None,
978
 
            long=False):
 
991
            long=False,
 
992
            short=False):
979
993
        from bzrlib.branch import find_branch
980
994
        from bzrlib.log import log_formatter, show_log
981
995
        import codecs
1015
1029
        # in e.g. the default C locale.
1016
1030
        outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
1017
1031
 
1018
 
        if long:
 
1032
        if not short:
1019
1033
            log_format = 'long'
1020
1034
        else:
1021
1035
            log_format = 'short'
1315
1329
 
1316
1330
    def run(self, dir='.'):
1317
1331
        from bzrlib.check import check
 
1332
 
1318
1333
        check(find_branch(dir))
1319
1334
 
1320
1335
 
1321
 
 
1322
1336
class cmd_scan_cache(Command):
1323
1337
    hidden = True
1324
1338
    def run(self):
1343
1357
class cmd_upgrade(Command):
1344
1358
    """Upgrade branch storage to current format.
1345
1359
 
1346
 
    This should normally be used only after the check command tells
1347
 
    you to run it.
 
1360
    The check command or bzr developers may sometimes advise you to run
 
1361
    this command.
1348
1362
    """
1349
1363
    takes_args = ['dir?']
1350
1364
 
1359
1373
    takes_options = ['email']
1360
1374
    
1361
1375
    def run(self, email=False):
 
1376
        try:
 
1377
            b = bzrlib.branch.find_branch('.')
 
1378
        except:
 
1379
            b = None
 
1380
        
1362
1381
        if email:
1363
 
            print bzrlib.osutils.user_email()
 
1382
            print bzrlib.osutils.user_email(b)
1364
1383
        else:
1365
 
            print bzrlib.osutils.username()
 
1384
            print bzrlib.osutils.username(b)
1366
1385
 
1367
1386
 
1368
1387
class cmd_selftest(Command):
1369
1388
    """Run internal test suite"""
1370
1389
    hidden = True
1371
 
    takes_options = ['verbose']
1372
 
    def run(self, verbose=False):
 
1390
    takes_options = ['verbose', 'pattern']
 
1391
    def run(self, verbose=False, pattern=".*"):
 
1392
        import bzrlib.ui
1373
1393
        from bzrlib.selftest import selftest
1374
 
        return int(not selftest(verbose=verbose))
 
1394
        # we don't want progress meters from the tests to go to the
 
1395
        # real output; and we don't want log messages cluttering up
 
1396
        # the real logs.
 
1397
        save_ui = bzrlib.ui.ui_factory
 
1398
        bzrlib.trace.info('running tests...')
 
1399
        try:
 
1400
            bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
 
1401
            result = selftest(verbose=verbose, pattern=pattern)
 
1402
            if result:
 
1403
                bzrlib.trace.info('tests passed')
 
1404
            else:
 
1405
                bzrlib.trace.info('tests failed')
 
1406
            return int(not result)
 
1407
        finally:
 
1408
            bzrlib.ui.ui_factory = save_ui
1375
1409
 
1376
1410
 
1377
1411
class cmd_version(Command):
1432
1466
 
1433
1467
 
1434
1468
 
 
1469
class cmd_find_merge_base(Command):
 
1470
    """Find and print a base revision for merging two branches.
 
1471
 
 
1472
    TODO: Options to specify revisions on either side, as if
 
1473
          merging only part of the history.
 
1474
    """
 
1475
    takes_args = ['branch', 'other']
 
1476
    hidden = True
 
1477
    
 
1478
    def run(self, branch, other):
 
1479
        branch1 = find_branch(branch)
 
1480
        branch2 = find_branch(other)
 
1481
 
 
1482
        base_revno, base_revid = branch1.common_ancestor(branch2)
 
1483
 
 
1484
        if base_revno is None:
 
1485
            raise bzrlib.errors.UnrelatedBranches()
 
1486
 
 
1487
        print 'merge base is revision %s' % base_revid
 
1488
        print ' r%-6d in %s' % (base_revno, branch)
 
1489
 
 
1490
        other_revno = branch2.revision_id_to_revno(base_revid)
 
1491
        
 
1492
        print ' r%-6d in %s' % (other_revno, other)
 
1493
 
 
1494
 
 
1495
 
1435
1496
class cmd_merge(Command):
1436
 
    """Perform a three-way merge of trees.
1437
 
    
1438
 
    The SPEC parameters are working tree or revision specifiers.  Working trees
1439
 
    are specified using standard paths or urls.  No component of a directory
1440
 
    path may begin with '@'.
1441
 
    
1442
 
    Working tree examples: '.', '..', 'foo@', but NOT 'foo/@bar'
1443
 
 
1444
 
    Revisions are specified using a dirname/@revno pair, where dirname is the
1445
 
    branch directory and revno is the revision within that branch.  If no revno
1446
 
    is specified, the latest revision is used.
1447
 
 
1448
 
    Revision examples: './@127', 'foo/@', '../@1'
1449
 
 
1450
 
    The OTHER_SPEC parameter is required.  If the BASE_SPEC parameter is
1451
 
    not supplied, the common ancestor of OTHER_SPEC the current branch is used
1452
 
    as the BASE.
1453
 
 
 
1497
    """Perform a three-way merge.
 
1498
    
 
1499
    The branch is the branch you will merge from.  By default, it will merge
 
1500
    the latest revision.  If you specify a revision, that revision will be
 
1501
    merged.  If you specify two revisions, the first will be used as a BASE, 
 
1502
    and the second one as OTHER.  Revision numbers are always relative to the
 
1503
    specified branch.
 
1504
    
 
1505
    Examples:
 
1506
 
 
1507
    To merge the latest revision from bzr.dev
 
1508
    bzr merge ../bzr.dev
 
1509
 
 
1510
    To merge changes up to and including revision 82 from bzr.dev
 
1511
    bzr merge -r 82 ../bzr.dev
 
1512
 
 
1513
    To merge the changes introduced by 82, without previous changes:
 
1514
    bzr merge -r 81..82 ../bzr.dev
 
1515
    
1454
1516
    merge refuses to run if there are any uncommitted changes, unless
1455
1517
    --force is given.
1456
1518
    """
1457
 
    takes_args = ['other_spec', 'base_spec?']
1458
 
    takes_options = ['force', 'merge-type']
 
1519
    takes_args = ['branch?']
 
1520
    takes_options = ['revision', 'force', 'merge-type']
1459
1521
 
1460
 
    def run(self, other_spec, base_spec=None, force=False, merge_type=None):
 
1522
    def run(self, branch='.', revision=None, force=False, 
 
1523
            merge_type=None):
1461
1524
        from bzrlib.merge import merge
1462
1525
        from bzrlib.merge_core import ApplyMerge3
1463
1526
        if merge_type is None:
1464
1527
            merge_type = ApplyMerge3
1465
 
        merge(parse_spec(other_spec), parse_spec(base_spec),
1466
 
              check_clean=(not force), merge_type=merge_type)
 
1528
 
 
1529
        if revision is None or len(revision) < 1:
 
1530
            base = [None, None]
 
1531
            other = (branch, -1)
 
1532
        else:
 
1533
            if len(revision) == 1:
 
1534
                other = (branch, revision[0])
 
1535
                base = (None, None)
 
1536
            else:
 
1537
                assert len(revision) == 2
 
1538
                if None in revision:
 
1539
                    raise BzrCommandError(
 
1540
                        "Merge doesn't permit that revision specifier.")
 
1541
                base = (branch, revision[0])
 
1542
                other = (branch, revision[1])
 
1543
            
 
1544
        merge(other, base, check_clean=(not force), merge_type=merge_type)
1467
1545
 
1468
1546
 
1469
1547
class cmd_revert(Command):
1479
1557
 
1480
1558
    def run(self, revision=None, no_backup=False, file_list=None):
1481
1559
        from bzrlib.merge import merge
 
1560
        from bzrlib.branch import Branch
1482
1561
        if file_list is not None:
1483
1562
            if len(file_list) == 0:
1484
1563
                raise BzrCommandError("No files specified")
1491
1570
              ignore_zero=True,
1492
1571
              backup_files=not no_backup,
1493
1572
              file_list=file_list)
 
1573
        if not file_list:
 
1574
            Branch('.').set_pending_merges([])
1494
1575
 
1495
1576
 
1496
1577
class cmd_assert_fail(Command):
1504
1585
    """Show help on a command or other topic.
1505
1586
 
1506
1587
    For a list of all available commands, say 'bzr help commands'."""
 
1588
    takes_options = ['long']
1507
1589
    takes_args = ['topic?']
1508
1590
    aliases = ['?']
1509
1591
    
1510
 
    def run(self, topic=None):
 
1592
    def run(self, topic=None, long=False):
1511
1593
        import help
 
1594
        if topic is None and long:
 
1595
            topic = "commands"
1512
1596
        help.help(topic)
1513
1597
 
1514
1598
 
 
1599
class cmd_shell_complete(Command):
 
1600
    """Show appropriate completions for context.
 
1601
 
 
1602
    For a list of all available commands, say 'bzr shell-complete'."""
 
1603
    takes_args = ['context?']
 
1604
    aliases = ['s-c']
 
1605
    hidden = True
 
1606
    
 
1607
    def run(self, context=None):
 
1608
        import shellcomplete
 
1609
        shellcomplete.shellcomplete(context)
 
1610
 
 
1611
 
 
1612
class cmd_missing(Command):
 
1613
    """What is missing in this branch relative to other branch.
 
1614
    """
 
1615
    takes_args = ['remote?']
 
1616
    aliases = ['mis', 'miss']
 
1617
    # We don't have to add quiet to the list, because 
 
1618
    # unknown options are parsed as booleans
 
1619
    takes_options = ['verbose', 'quiet']
 
1620
 
 
1621
    def run(self, remote=None, verbose=False, quiet=False):
 
1622
        from bzrlib.branch import find_branch, DivergedBranches
 
1623
        from bzrlib.errors import BzrCommandError
 
1624
        from bzrlib.missing import get_parent, show_missing
 
1625
 
 
1626
        if verbose and quiet:
 
1627
            raise BzrCommandError('Cannot pass both quiet and verbose')
 
1628
 
 
1629
        b = find_branch('.')
 
1630
        parent = get_parent(b)
 
1631
        if remote is None:
 
1632
            if parent is None:
 
1633
                raise BzrCommandError("No missing location known or specified.")
 
1634
            else:
 
1635
                if not quiet:
 
1636
                    print "Using last location: %s" % parent
 
1637
                remote = parent
 
1638
        elif parent is None:
 
1639
            # We only update x-pull if it did not exist, missing should not change the parent
 
1640
            b.controlfile('x-pull', 'wb').write(remote + '\n')
 
1641
        br_remote = find_branch(remote)
 
1642
 
 
1643
        return show_missing(b, br_remote, verbose=verbose, quiet=quiet)
 
1644
 
1515
1645
 
1516
1646
 
1517
1647
class cmd_plugins(Command):
1522
1652
        from inspect import getdoc
1523
1653
        from pprint import pprint
1524
1654
        for plugin in bzrlib.plugin.all_plugins:
1525
 
            print plugin.__path__[0]
 
1655
            if hasattr(plugin, '__path__'):
 
1656
                print plugin.__path__[0]
 
1657
            else:
 
1658
                print `plugin`
1526
1659
            d = getdoc(plugin)
1527
1660
            if d:
1528
1661
                print '\t', d.split('\n')[0]
1546
1679
    'no-recurse':             None,
1547
1680
    'profile':                None,
1548
1681
    'revision':               _parse_revision_str,
 
1682
    'short':                  None,
1549
1683
    'show-ids':               None,
1550
1684
    'timezone':               str,
1551
1685
    'verbose':                None,
1557
1691
    'root':                   str,
1558
1692
    'no-backup':              None,
1559
1693
    'merge-type':             get_merge_type,
 
1694
    'pattern':                str,
1560
1695
    }
1561
1696
 
1562
1697
SHORT_OPTIONS = {
1776
1911
        return 0
1777
1912
    
1778
1913
    if not args:
1779
 
        print >>sys.stderr, "please try 'bzr help' for help"
1780
 
        return 1
 
1914
        from bzrlib.help import help
 
1915
        help(None)
 
1916
        return 0
1781
1917
    
1782
1918
    cmd = str(args.pop(0))
1783
1919
 
1822
1958
        return cmd_class(cmdopts, cmdargs).status 
1823
1959
 
1824
1960
 
1825
 
def _report_exception(summary, quiet=False):
1826
 
    import traceback
1827
 
    
1828
 
    log_error('bzr: ' + summary)
1829
 
    bzrlib.trace.log_exception()
1830
 
 
1831
 
    if os.environ.get('BZR_DEBUG'):
1832
 
        traceback.print_exc()
1833
 
 
1834
 
    if not quiet:
1835
 
        sys.stderr.write('\n')
1836
 
        tb = sys.exc_info()[2]
1837
 
        exinfo = traceback.extract_tb(tb)
1838
 
        if exinfo:
1839
 
            sys.stderr.write('  at %s:%d in %s()\n' % exinfo[-1][:3])
1840
 
        sys.stderr.write('  see ~/.bzr.log for debug information\n')
1841
 
 
1842
 
 
1843
 
 
1844
1961
def main(argv):
1845
 
    
1846
 
    bzrlib.trace.open_tracefile(argv)
 
1962
    import bzrlib.ui
 
1963
    bzrlib.trace.log_startup(argv)
 
1964
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
1847
1965
 
1848
1966
    try:
1849
1967
        try:
1850
 
            try:
1851
 
                return run_bzr(argv[1:])
1852
 
            finally:
1853
 
                # do this here inside the exception wrappers to catch EPIPE
1854
 
                sys.stdout.flush()
1855
 
        except BzrError, e:
1856
 
            quiet = isinstance(e, (BzrCommandError))
1857
 
            _report_exception('error: ' + str(e), quiet=quiet)
1858
 
            if len(e.args) > 1:
1859
 
                for h in e.args[1]:
1860
 
                    # some explanation or hints
1861
 
                    log_error('  ' + h)
1862
 
            return 1
1863
 
        except AssertionError, e:
1864
 
            msg = 'assertion failed'
1865
 
            if str(e):
1866
 
                msg += ': ' + str(e)
1867
 
            _report_exception(msg)
1868
 
            return 2
1869
 
        except KeyboardInterrupt, e:
1870
 
            _report_exception('interrupted', quiet=True)
1871
 
            return 2
1872
 
        except Exception, e:
1873
 
            import errno
1874
 
            quiet = False
1875
 
            if (isinstance(e, IOError) 
1876
 
                and hasattr(e, 'errno')
1877
 
                and e.errno == errno.EPIPE):
1878
 
                quiet = True
1879
 
                msg = 'broken pipe'
1880
 
            else:
1881
 
                msg = str(e).rstrip('\n')
1882
 
            _report_exception(msg, quiet)
1883
 
            return 2
1884
 
    finally:
1885
 
        bzrlib.trace.close_trace()
 
1968
            return run_bzr(argv[1:])
 
1969
        finally:
 
1970
            # do this here inside the exception wrappers to catch EPIPE
 
1971
            sys.stdout.flush()
 
1972
    except BzrCommandError, e:
 
1973
        # command line syntax error, etc
 
1974
        log_error(str(e))
 
1975
        return 1
 
1976
    except BzrError, e:
 
1977
        bzrlib.trace.log_exception()
 
1978
        return 1
 
1979
    except AssertionError, e:
 
1980
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
 
1981
        return 3
 
1982
    except KeyboardInterrupt, e:
 
1983
        bzrlib.trace.note('interrupted')
 
1984
        return 2
 
1985
    except Exception, e:
 
1986
        import errno
 
1987
        if (isinstance(e, IOError) 
 
1988
            and hasattr(e, 'errno')
 
1989
            and e.errno == errno.EPIPE):
 
1990
            bzrlib.trace.note('broken pipe')
 
1991
            return 2
 
1992
        else:
 
1993
            bzrlib.trace.log_exception()
 
1994
            return 2
1886
1995
 
1887
1996
 
1888
1997
if __name__ == '__main__':