/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-07-27 20:17:20 UTC
  • Revision ID: mbp@sourcefrog.net-20050727201720-93cd907b349b517f
- update todo list

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
 
# TODO: Split the command framework away from the actual commands.
19
 
 
20
 
# TODO: probably should say which arguments are candidates for glob
21
 
# expansion on windows and do that at the command level.
22
 
 
23
 
import sys
24
 
import os
 
18
 
 
19
import sys, os
25
20
 
26
21
import bzrlib
27
22
from bzrlib.trace import mutter, note, log_error, warning
127
122
    return revs
128
123
 
129
124
 
130
 
def get_merge_type(typestring):
131
 
    """Attempt to find the merge class/factory associated with a string."""
132
 
    from merge import merge_types
133
 
    try:
134
 
        return merge_types[typestring][0]
135
 
    except KeyError:
136
 
        templ = '%s%%7s: %%s' % (' '*12)
137
 
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
138
 
        type_list = '\n'.join(lines)
139
 
        msg = "No known merge type %s. Supported types are:\n%s" %\
140
 
            (typestring, type_list)
141
 
        raise BzrCommandError(msg)
142
 
    
143
 
 
144
125
 
145
126
def _get_cmd_dict(plugins_override=True):
146
127
    d = {}
510
491
    def run(self, source_list, dest):
511
492
        b = find_branch('.')
512
493
 
513
 
        # TODO: glob expansion on windows?
514
494
        b.move([b.relpath(s) for s in source_list], b.relpath(dest))
515
495
 
516
496
 
536
516
 
537
517
 
538
518
 
539
 
class cmd_mv(Command):
540
 
    """Move or rename a file.
541
 
 
542
 
    usage:
543
 
        bzr mv OLDNAME NEWNAME
544
 
        bzr mv SOURCE... DESTINATION
545
 
 
546
 
    If the last argument is a versioned directory, all the other names
547
 
    are moved into it.  Otherwise, there must be exactly two arguments
548
 
    and the file is changed to a new name, which must not already exist.
549
 
 
550
 
    Files cannot be moved between branches.
551
 
    """
552
 
    takes_args = ['names*']
553
 
    def run(self, names_list):
554
 
        if len(names_list) < 2:
555
 
            raise BzrCommandError("missing file argument")
556
 
        b = find_branch(names_list[0])
557
 
 
558
 
        rel_names = [b.relpath(x) for x in names_list]
559
 
        
560
 
        if os.path.isdir(names_list[-1]):
561
 
            # move into existing directory
562
 
            b.move(rel_names[:-1], rel_names[-1])
563
 
        else:
564
 
            if len(names_list) != 2:
565
 
                raise BzrCommandError('to mv multiple files the destination '
566
 
                                      'must be a versioned directory')
567
 
            b.move(rel_names[0], rel_names[1])
568
 
            
569
 
    
570
519
 
571
520
 
572
521
class cmd_pull(Command):
639
588
    """
640
589
    takes_args = ['from_location', 'to_location?']
641
590
    takes_options = ['revision']
642
 
    aliases = ['get', 'clone']
643
591
 
644
592
    def run(self, from_location, to_location=None, revision=None):
645
593
        import errno
646
594
        from bzrlib.merge import merge
647
 
        from bzrlib.branch import DivergedBranches, \
 
595
        from bzrlib.branch import DivergedBranches, NoSuchRevision, \
648
596
             find_cached_branch, Branch
649
597
        from shutil import rmtree
650
598
        from meta_store import CachedStore
691
639
                    revno, rev_id = br_from.get_revision_info(revision[0])
692
640
                try:
693
641
                    br_to.update_revisions(br_from, stop_revision=revno)
694
 
                except bzrlib.errors.NoSuchRevision:
 
642
                except NoSuchRevision:
695
643
                    rmtree(to_location)
696
644
                    msg = "The branch %s has no revision %d." % (from_location,
697
645
                                                                 revno)
912
860
    """List files modified in working tree."""
913
861
    hidden = True
914
862
    def run(self):
915
 
        from bzrlib.delta import compare_trees
 
863
        from bzrlib.diff import compare_trees
916
864
 
917
865
        b = find_branch('.')
918
866
        td = compare_trees(b.basis_tree(), b.working_tree())
1455
1403
    --force is given.
1456
1404
    """
1457
1405
    takes_args = ['other_spec', 'base_spec?']
1458
 
    takes_options = ['force', 'merge-type']
 
1406
    takes_options = ['force']
1459
1407
 
1460
 
    def run(self, other_spec, base_spec=None, force=False, merge_type=None):
 
1408
    def run(self, other_spec, base_spec=None, force=False):
1461
1409
        from bzrlib.merge import merge
1462
 
        from bzrlib.merge_core import ApplyMerge3
1463
 
        if merge_type is None:
1464
 
            merge_type = ApplyMerge3
1465
1410
        merge(parse_spec(other_spec), parse_spec(base_spec),
1466
 
              check_clean=(not force), merge_type=merge_type)
 
1411
              check_clean=(not force))
 
1412
 
1467
1413
 
1468
1414
 
1469
1415
class cmd_revert(Command):
 
1416
    """Restore selected files from a previous revision.
 
1417
    """
 
1418
    takes_args = ['file+']
 
1419
    def run(self, file_list):
 
1420
        from bzrlib.branch import find_branch
 
1421
        
 
1422
        if not file_list:
 
1423
            file_list = ['.']
 
1424
            
 
1425
        b = find_branch(file_list[0])
 
1426
 
 
1427
        b.revert([b.relpath(f) for f in file_list])
 
1428
 
 
1429
 
 
1430
class cmd_merge_revert(Command):
1470
1431
    """Reverse all changes since the last commit.
1471
1432
 
1472
 
    Only versioned files are affected.  Specify filenames to revert only 
1473
 
    those files.  By default, any files that are changed will be backed up
1474
 
    first.  Backup files have a '~' appended to their name.
 
1433
    Only versioned files are affected.
 
1434
 
 
1435
    TODO: Store backups of any files that will be reverted, so
 
1436
          that the revert can be undone.          
1475
1437
    """
1476
 
    takes_options = ['revision', 'no-backup']
1477
 
    takes_args = ['file*']
1478
 
    aliases = ['merge-revert']
 
1438
    takes_options = ['revision']
1479
1439
 
1480
 
    def run(self, revision=None, no_backup=False, file_list=None):
 
1440
    def run(self, revision=None):
1481
1441
        from bzrlib.merge import merge
1482
 
        if file_list is not None:
1483
 
            if len(file_list) == 0:
1484
 
                raise BzrCommandError("No files specified")
1485
1442
        if revision is None:
1486
1443
            revision = [-1]
1487
1444
        elif len(revision) != 1:
1488
 
            raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
 
1445
            raise BzrCommandError('bzr merge-revert --revision takes exactly 1 argument')
1489
1446
        merge(('.', revision[0]), parse_spec('.'),
1490
1447
              check_clean=False,
1491
 
              ignore_zero=True,
1492
 
              backup_files=not no_backup,
1493
 
              file_list=file_list)
 
1448
              ignore_zero=True)
1494
1449
 
1495
1450
 
1496
1451
class cmd_assert_fail(Command):
1555
1510
    'update':                 None,
1556
1511
    'long':                   None,
1557
1512
    'root':                   str,
1558
 
    'no-backup':              None,
1559
 
    'merge-type':             get_merge_type,
1560
1513
    }
1561
1514
 
1562
1515
SHORT_OPTIONS = {
1712
1665
    return argdict
1713
1666
 
1714
1667
 
 
1668
def _parse_master_args(argv):
 
1669
    """Parse the arguments that always go with the original command.
 
1670
    These are things like bzr --no-plugins, etc.
 
1671
 
 
1672
    There are now 2 types of option flags. Ones that come *before* the command,
 
1673
    and ones that come *after* the command.
 
1674
    Ones coming *before* the command are applied against all possible commands.
 
1675
    And are generally applied before plugins are loaded.
 
1676
 
 
1677
    The current list are:
 
1678
        --builtin   Allow plugins to load, but don't let them override builtin commands,
 
1679
                    they will still be allowed if they do not override a builtin.
 
1680
        --no-plugins    Don't load any plugins. This lets you get back to official source
 
1681
                        behavior.
 
1682
        --profile   Enable the hotspot profile before running the command.
 
1683
                    For backwards compatibility, this is also a non-master option.
 
1684
        --version   Spit out the version of bzr that is running and exit.
 
1685
                    This is also a non-master option.
 
1686
        --help      Run help and exit, also a non-master option (I think that should stay, though)
 
1687
 
 
1688
    >>> argv, opts = _parse_master_args(['--test'])
 
1689
    Traceback (most recent call last):
 
1690
    ...
 
1691
    BzrCommandError: Invalid master option: 'test'
 
1692
    >>> argv, opts = _parse_master_args(['--version', 'command'])
 
1693
    >>> print argv
 
1694
    ['command']
 
1695
    >>> print opts['version']
 
1696
    True
 
1697
    >>> argv, opts = _parse_master_args(['--profile', 'command', '--more-options'])
 
1698
    >>> print argv
 
1699
    ['command', '--more-options']
 
1700
    >>> print opts['profile']
 
1701
    True
 
1702
    >>> argv, opts = _parse_master_args(['--no-plugins', 'command'])
 
1703
    >>> print argv
 
1704
    ['command']
 
1705
    >>> print opts['no-plugins']
 
1706
    True
 
1707
    >>> print opts['profile']
 
1708
    False
 
1709
    >>> argv, opts = _parse_master_args(['command', '--profile'])
 
1710
    >>> print argv
 
1711
    ['command', '--profile']
 
1712
    >>> print opts['profile']
 
1713
    False
 
1714
    """
 
1715
    master_opts = {'builtin':False,
 
1716
        'no-plugins':False,
 
1717
        'version':False,
 
1718
        'profile':False,
 
1719
        'help':False
 
1720
    }
 
1721
 
 
1722
    for arg in argv[:]:
 
1723
        if arg[:2] != '--': # at the first non-option, we return the rest
 
1724
            break
 
1725
        arg = arg[2:] # Remove '--'
 
1726
        if arg not in master_opts:
 
1727
            # We could say that this is not an error, that we should
 
1728
            # just let it be handled by the main section instead
 
1729
            raise BzrCommandError('Invalid master option: %r' % arg)
 
1730
        argv.pop(0) # We are consuming this entry
 
1731
        master_opts[arg] = True
 
1732
    return argv, master_opts
 
1733
 
 
1734
 
1715
1735
 
1716
1736
def run_bzr(argv):
1717
1737
    """Execute a command.
1720
1740
    logging and error handling.  
1721
1741
    
1722
1742
    argv
1723
 
       The command-line arguments, without the program name from argv[0]
 
1743
       The command-line arguments, without the program name.
1724
1744
    
1725
1745
    Returns a command status or raises an exception.
1726
 
 
1727
 
    Special master options: these must come before the command because
1728
 
    they control how the command is interpreted.
1729
 
 
1730
 
    --no-plugins
1731
 
        Do not load plugin modules at all
1732
 
 
1733
 
    --builtin
1734
 
        Only use builtin commands.  (Plugins are still allowed to change
1735
 
        other behaviour.)
1736
 
 
1737
 
    --profile
1738
 
        Run under the Python profiler.
1739
1746
    """
1740
 
    
1741
1747
    argv = [a.decode(bzrlib.user_encoding) for a in argv]
1742
1748
 
1743
 
    opt_profile = opt_no_plugins = opt_builtin = False
1744
 
 
1745
 
    # --no-plugins is handled specially at a very early stage. We need
1746
 
    # to load plugins before doing other command parsing so that they
1747
 
    # can override commands, but this needs to happen first.
1748
 
 
1749
 
    for a in argv[:]:
1750
 
        if a == '--profile':
1751
 
            opt_profile = True
1752
 
        elif a == '--no-plugins':
1753
 
            opt_no_plugins = True
1754
 
        elif a == '--builtin':
1755
 
            opt_builtin = True
1756
 
        else:
1757
 
            break
1758
 
        argv.remove(a)
1759
 
 
1760
 
    if not opt_no_plugins:
 
1749
    # some options like --builtin and --no-plugins have special effects
 
1750
    argv, master_opts = _parse_master_args(argv)
 
1751
    if not master_opts['no-plugins']:
1761
1752
        from bzrlib.plugin import load_plugins
1762
1753
        load_plugins()
1763
1754
 
1764
1755
    args, opts = parse_args(argv)
1765
1756
 
1766
 
    if 'help' in opts:
 
1757
    if master_opts.get('help') or 'help' in opts:
1767
1758
        from bzrlib.help import help
1768
 
        if args:
1769
 
            help(args[0])
 
1759
        if argv:
 
1760
            help(argv[0])
1770
1761
        else:
1771
1762
            help()
1772
1763
        return 0            
1775
1766
        show_version()
1776
1767
        return 0
1777
1768
    
1778
 
    if not args:
 
1769
    if args and args[0] == 'builtin':
 
1770
        include_plugins=False
 
1771
        args = args[1:]
 
1772
    
 
1773
    try:
 
1774
        cmd = str(args.pop(0))
 
1775
    except IndexError:
1779
1776
        print >>sys.stderr, "please try 'bzr help' for help"
1780
1777
        return 1
1781
 
    
1782
 
    cmd = str(args.pop(0))
1783
 
 
1784
 
    canonical_cmd, cmd_class = \
1785
 
                   get_cmd_class(cmd, plugins_override=not opt_builtin)
 
1778
 
 
1779
    plugins_override = not (master_opts['builtin'])
 
1780
    canonical_cmd, cmd_class = get_cmd_class(cmd, plugins_override=plugins_override)
 
1781
 
 
1782
    profile = master_opts['profile']
 
1783
    # For backwards compatibility, I would rather stick with --profile being a
 
1784
    # master/global option
 
1785
    if 'profile' in opts:
 
1786
        profile = True
 
1787
        del opts['profile']
1786
1788
 
1787
1789
    # check options are reasonable
1788
1790
    allowed = cmd_class.takes_options
1797
1799
    for k, v in opts.items():
1798
1800
        cmdopts[k.replace('-', '_')] = v
1799
1801
 
1800
 
    if opt_profile:
 
1802
    if profile:
1801
1803
        import hotshot, tempfile
1802
1804
        pffileno, pfname = tempfile.mkstemp()
1803
1805
        try:
1824
1826
 
1825
1827
def _report_exception(summary, quiet=False):
1826
1828
    import traceback
1827
 
    
1828
1829
    log_error('bzr: ' + summary)
1829
1830
    bzrlib.trace.log_exception()
1830
1831
 
1831
 
    if os.environ.get('BZR_DEBUG'):
1832
 
        traceback.print_exc()
1833
 
 
1834
1832
    if not quiet:
1835
 
        sys.stderr.write('\n')
1836
1833
        tb = sys.exc_info()[2]
1837
1834
        exinfo = traceback.extract_tb(tb)
1838
1835
        if exinfo:
1854
1851
                sys.stdout.flush()
1855
1852
        except BzrError, e:
1856
1853
            quiet = isinstance(e, (BzrCommandError))
1857
 
            _report_exception('error: ' + str(e), quiet=quiet)
 
1854
            _report_exception('error: ' + e.args[0], quiet=quiet)
1858
1855
            if len(e.args) > 1:
1859
1856
                for h in e.args[1]:
1860
1857
                    # some explanation or hints