~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/commands.py

  • Committer: Martin Pool
  • Date: 2005-09-30 00:58:02 UTC
  • mto: (1185.14.2)
  • mto: This revision was merged to the branch mainline in revision 1396.
  • Revision ID: mbp@sourcefrog.net-20050930005802-721cfc318e393817
- copy_branch creates destination if it doesn't exist

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
# would help with validation and shell completion.
26
26
 
27
27
 
 
28
# TODO: Help messages for options.
 
29
 
 
30
# TODO: Define arguments by objects, rather than just using names.
 
31
# Those objects can specify the expected type of the argument, which
 
32
# would help with validation and shell completion.
 
33
 
 
34
 
28
35
 
29
36
import sys
30
37
import os
34
41
import bzrlib
35
42
import bzrlib.trace
36
43
from bzrlib.trace import mutter, note, log_error, warning
37
 
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
38
 
from bzrlib.branch import find_branch
 
44
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError, NotBranchError
 
45
from bzrlib.revisionspec import RevisionSpec
39
46
from bzrlib import BZRDIR
40
47
 
41
48
plugin_cmds = {}
69
76
def _parse_revision_str(revstr):
70
77
    """This handles a revision string -> revno.
71
78
 
72
 
    This always returns a list.  The list will have one element for 
73
 
 
74
 
    It supports integers directly, but everything else it
75
 
    defers for passing to Branch.get_revision_info()
 
79
    This always returns a list.  The list will have one element for
 
80
    each revision.
76
81
 
77
82
    >>> _parse_revision_str('234')
78
 
    [234]
 
83
    [<RevisionSpec_int 234>]
79
84
    >>> _parse_revision_str('234..567')
80
 
    [234, 567]
 
85
    [<RevisionSpec_int 234>, <RevisionSpec_int 567>]
81
86
    >>> _parse_revision_str('..')
82
 
    [None, None]
 
87
    [<RevisionSpec None>, <RevisionSpec None>]
83
88
    >>> _parse_revision_str('..234')
84
 
    [None, 234]
 
89
    [<RevisionSpec None>, <RevisionSpec_int 234>]
85
90
    >>> _parse_revision_str('234..')
86
 
    [234, None]
 
91
    [<RevisionSpec_int 234>, <RevisionSpec None>]
87
92
    >>> _parse_revision_str('234..456..789') # Maybe this should be an error
88
 
    [234, 456, 789]
 
93
    [<RevisionSpec_int 234>, <RevisionSpec_int 456>, <RevisionSpec_int 789>]
89
94
    >>> _parse_revision_str('234....789') # Error?
90
 
    [234, None, 789]
 
95
    [<RevisionSpec_int 234>, <RevisionSpec None>, <RevisionSpec_int 789>]
91
96
    >>> _parse_revision_str('revid:test@other.com-234234')
92
 
    ['revid:test@other.com-234234']
 
97
    [<RevisionSpec_revid revid:test@other.com-234234>]
93
98
    >>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
94
 
    ['revid:test@other.com-234234', 'revid:test@other.com-234235']
 
99
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
95
100
    >>> _parse_revision_str('revid:test@other.com-234234..23')
96
 
    ['revid:test@other.com-234234', 23]
 
101
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_int 23>]
97
102
    >>> _parse_revision_str('date:2005-04-12')
98
 
    ['date:2005-04-12']
 
103
    [<RevisionSpec_date date:2005-04-12>]
99
104
    >>> _parse_revision_str('date:2005-04-12 12:24:33')
100
 
    ['date:2005-04-12 12:24:33']
 
105
    [<RevisionSpec_date date:2005-04-12 12:24:33>]
101
106
    >>> _parse_revision_str('date:2005-04-12T12:24:33')
102
 
    ['date:2005-04-12T12:24:33']
 
107
    [<RevisionSpec_date date:2005-04-12T12:24:33>]
103
108
    >>> _parse_revision_str('date:2005-04-12,12:24:33')
104
 
    ['date:2005-04-12,12:24:33']
 
109
    [<RevisionSpec_date date:2005-04-12,12:24:33>]
105
110
    >>> _parse_revision_str('-5..23')
106
 
    [-5, 23]
 
111
    [<RevisionSpec_int -5>, <RevisionSpec_int 23>]
107
112
    >>> _parse_revision_str('-5')
108
 
    [-5]
 
113
    [<RevisionSpec_int -5>]
109
114
    >>> _parse_revision_str('123a')
110
 
    ['123a']
 
115
    Traceback (most recent call last):
 
116
      ...
 
117
    BzrError: No namespace registered for string: '123a'
111
118
    >>> _parse_revision_str('abc')
112
 
    ['abc']
 
119
    Traceback (most recent call last):
 
120
      ...
 
121
    BzrError: No namespace registered for string: 'abc'
113
122
    """
114
123
    import re
115
124
    old_format_re = re.compile('\d*:\d*')
116
125
    m = old_format_re.match(revstr)
 
126
    revs = []
117
127
    if m:
118
128
        warning('Colon separator for revision numbers is deprecated.'
119
129
                ' Use .. instead')
120
 
        revs = []
121
130
        for rev in revstr.split(':'):
122
131
            if rev:
123
 
                revs.append(int(rev))
124
 
            else:
125
 
                revs.append(None)
126
 
        return revs
127
 
    revs = []
128
 
    for x in revstr.split('..'):
129
 
        if not x:
130
 
            revs.append(None)
131
 
        else:
132
 
            try:
133
 
                revs.append(int(x))
134
 
            except ValueError:
135
 
                revs.append(x)
 
132
                revs.append(RevisionSpec(int(rev)))
 
133
            else:
 
134
                revs.append(RevisionSpec(None))
 
135
    else:
 
136
        for x in revstr.split('..'):
 
137
            if not x:
 
138
                revs.append(RevisionSpec(None))
 
139
            else:
 
140
                revs.append(RevisionSpec(x))
136
141
    return revs
137
142
 
138
143
 
139
 
def get_merge_type(typestring):
140
 
    """Attempt to find the merge class/factory associated with a string."""
141
 
    from merge import merge_types
142
 
    try:
143
 
        return merge_types[typestring][0]
144
 
    except KeyError:
145
 
        templ = '%s%%7s: %%s' % (' '*12)
146
 
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
147
 
        type_list = '\n'.join(lines)
148
 
        msg = "No known merge type %s. Supported types are:\n%s" %\
149
 
            (typestring, type_list)
150
 
        raise BzrCommandError(msg)
151
 
    
152
 
 
153
 
def get_merge_type(typestring):
154
 
    """Attempt to find the merge class/factory associated with a string."""
155
 
    from merge import merge_types
156
 
    try:
157
 
        return merge_types[typestring][0]
158
 
    except KeyError:
159
 
        templ = '%s%%7s: %%s' % (' '*12)
160
 
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
161
 
        type_list = '\n'.join(lines)
162
 
        msg = "No known merge type %s. Supported types are:\n%s" %\
163
 
            (typestring, type_list)
164
 
        raise BzrCommandError(msg)
165
 
 
166
 
 
167
144
def _builtin_commands():
168
145
    import bzrlib.builtins
169
146
    r = {}
356
333
    return parsed
357
334
 
358
335
 
359
 
 
360
 
 
361
336
# list of all available options; the rhs can be either None for an
362
337
# option that takes no argument, or a constructor function that checks
363
338
# the type.
364
339
OPTIONS = {
365
340
    'all':                    None,
 
341
    'basis':                  str,
366
342
    'diff-options':           str,
367
343
    'help':                   None,
368
344
    'file':                   unicode,
384
360
    'long':                   None,
385
361
    'root':                   str,
386
362
    'no-backup':              None,
387
 
    'merge-type':             get_merge_type,
388
363
    'pattern':                str,
389
364
    }
390
365
 
417
392
    >>> parse_args('commit --message=biter'.split())
418
393
    (['commit'], {'message': u'biter'})
419
394
    >>> parse_args('log -r 500'.split())
420
 
    (['log'], {'revision': [500]})
 
395
    (['log'], {'revision': [<RevisionSpec_int 500>]})
421
396
    >>> parse_args('log -r500..600'.split())
422
 
    (['log'], {'revision': [500, 600]})
 
397
    (['log'], {'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
423
398
    >>> parse_args('log -vr500..600'.split())
424
 
    (['log'], {'verbose': True, 'revision': [500, 600]})
425
 
    >>> parse_args('log -rv500..600'.split()) #the r takes an argument
426
 
    (['log'], {'revision': ['v500', 600]})
 
399
    (['log'], {'verbose': True, 'revision': [<RevisionSpec_int 500>, <RevisionSpec_int 600>]})
 
400
    >>> parse_args('log -rrevno:500..600'.split()) #the r takes an argument
 
401
    (['log'], {'revision': [<RevisionSpec_revno revno:500>, <RevisionSpec_int 600>]})
427
402
    """
428
403
    args = []
429
404
    opts = {}
649
624
    bzrlib.trace.log_startup(argv)
650
625
    bzrlib.ui.ui_factory = bzrlib.ui.TextUIFactory()
651
626
 
 
627
    return run_bzr_catch_errors(argv[1:])
 
628
 
 
629
 
 
630
def run_bzr_catch_errors(argv):
652
631
    try:
653
632
        try:
654
 
            return run_bzr(argv[1:])
655
 
        finally:
656
 
            # do this here inside the exception wrappers to catch EPIPE
657
 
            sys.stdout.flush()
 
633
            try:
 
634
                return run_bzr(argv)
 
635
            finally:
 
636
                # do this here inside the exception wrappers to catch EPIPE
 
637
                sys.stdout.flush()
 
638
        #wrap common errors as CommandErrors.
 
639
        except (NotBranchError,), e:
 
640
            raise BzrCommandError(str(e))
658
641
    except BzrCommandError, e:
659
642
        # command line syntax error, etc
660
643
        log_error(str(e))
666
649
        bzrlib.trace.log_exception('assertion failed: ' + str(e))
667
650
        return 3
668
651
    except KeyboardInterrupt, e:
669
 
        bzrlib.trace.note('interrupted')
 
652
        bzrlib.trace.log_exception('interrupted')
670
653
        return 2
671
654
    except Exception, e:
672
655
        import errno