~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/option.py

  • Committer: wang
  • Date: 2006-10-29 13:41:32 UTC
  • mto: (2104.4.1 wang_65714)
  • mto: This revision was merged to the branch mainline in revision 2109.
  • Revision ID: wang@ubuntu-20061029134132-3d7f4216f20c4aef
Replace python's difflib by patiencediff because the worst case 
performance is cubic for difflib and people commiting large data 
files are often hurt by this. The worst case performance of patience is 
quadratic. Fix bug 65714.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005, 2006 by Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2006 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
19
19
 
20
20
import re
21
21
 
 
22
from bzrlib.lazy_import import lazy_import
 
23
lazy_import(globals(), """
 
24
import optparse
 
25
 
 
26
from bzrlib import (
 
27
    errors,
 
28
    revisionspec,
 
29
    )
 
30
""")
22
31
from bzrlib.trace import warning
23
 
from bzrlib.revisionspec import RevisionSpec
24
 
from bzrlib.errors import BzrCommandError
25
32
 
26
33
 
27
34
def _parse_revision_str(revstr):
31
38
    each revision specifier supplied.
32
39
 
33
40
    >>> _parse_revision_str('234')
34
 
    [<RevisionSpec_int 234>]
 
41
    [<RevisionSpec_revno 234>]
35
42
    >>> _parse_revision_str('234..567')
36
 
    [<RevisionSpec_int 234>, <RevisionSpec_int 567>]
 
43
    [<RevisionSpec_revno 234>, <RevisionSpec_revno 567>]
37
44
    >>> _parse_revision_str('..')
38
45
    [<RevisionSpec None>, <RevisionSpec None>]
39
46
    >>> _parse_revision_str('..234')
40
 
    [<RevisionSpec None>, <RevisionSpec_int 234>]
 
47
    [<RevisionSpec None>, <RevisionSpec_revno 234>]
41
48
    >>> _parse_revision_str('234..')
42
 
    [<RevisionSpec_int 234>, <RevisionSpec None>]
 
49
    [<RevisionSpec_revno 234>, <RevisionSpec None>]
43
50
    >>> _parse_revision_str('234..456..789') # Maybe this should be an error
44
 
    [<RevisionSpec_int 234>, <RevisionSpec_int 456>, <RevisionSpec_int 789>]
 
51
    [<RevisionSpec_revno 234>, <RevisionSpec_revno 456>, <RevisionSpec_revno 789>]
45
52
    >>> _parse_revision_str('234....789') #Error ?
46
 
    [<RevisionSpec_int 234>, <RevisionSpec None>, <RevisionSpec_int 789>]
 
53
    [<RevisionSpec_revno 234>, <RevisionSpec None>, <RevisionSpec_revno 789>]
47
54
    >>> _parse_revision_str('revid:test@other.com-234234')
48
55
    [<RevisionSpec_revid revid:test@other.com-234234>]
49
56
    >>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
50
57
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
51
58
    >>> _parse_revision_str('revid:test@other.com-234234..23')
52
 
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_int 23>]
 
59
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revno 23>]
53
60
    >>> _parse_revision_str('date:2005-04-12')
54
61
    [<RevisionSpec_date date:2005-04-12>]
55
62
    >>> _parse_revision_str('date:2005-04-12 12:24:33')
59
66
    >>> _parse_revision_str('date:2005-04-12,12:24:33')
60
67
    [<RevisionSpec_date date:2005-04-12,12:24:33>]
61
68
    >>> _parse_revision_str('-5..23')
62
 
    [<RevisionSpec_int -5>, <RevisionSpec_int 23>]
 
69
    [<RevisionSpec_revno -5>, <RevisionSpec_revno 23>]
63
70
    >>> _parse_revision_str('-5')
64
 
    [<RevisionSpec_int -5>]
 
71
    [<RevisionSpec_revno -5>]
65
72
    >>> _parse_revision_str('123a')
66
73
    Traceback (most recent call last):
67
74
      ...
68
 
    BzrError: No namespace registered for string: '123a'
 
75
    NoSuchRevisionSpec: No namespace registered for string: '123a'
69
76
    >>> _parse_revision_str('abc')
70
77
    Traceback (most recent call last):
71
78
      ...
72
 
    BzrError: No namespace registered for string: 'abc'
 
79
    NoSuchRevisionSpec: No namespace registered for string: 'abc'
73
80
    >>> _parse_revision_str('branch:../branch2')
74
81
    [<RevisionSpec_branch branch:../branch2>]
75
82
    >>> _parse_revision_str('branch:../../branch2')
76
83
    [<RevisionSpec_branch branch:../../branch2>]
77
84
    >>> _parse_revision_str('branch:../../branch2..23')
78
 
    [<RevisionSpec_branch branch:../../branch2>, <RevisionSpec_int 23>]
 
85
    [<RevisionSpec_branch branch:../../branch2>, <RevisionSpec_revno 23>]
79
86
    """
80
87
    # TODO: Maybe move this into revisionspec.py
81
 
    old_format_re = re.compile('\d*:\d*')
82
 
    m = old_format_re.match(revstr)
83
88
    revs = []
84
 
    if m:
85
 
        warning('Colon separator for revision numbers is deprecated.'
86
 
                ' Use .. instead')
87
 
        for rev in revstr.split(':'):
88
 
            if rev:
89
 
                revs.append(RevisionSpec(int(rev)))
90
 
            else:
91
 
                revs.append(RevisionSpec(None))
92
 
    else:
93
 
        sep = re.compile("\\.\\.(?!/)")
94
 
        for x in sep.split(revstr):
95
 
            revs.append(RevisionSpec(x or None))
 
89
    # split on the first .. that is not followed by a / ?
 
90
    sep = re.compile("\\.\\.(?!/)")
 
91
    for x in sep.split(revstr):
 
92
        revs.append(revisionspec.RevisionSpec.from_string(x or None))
96
93
    return revs
97
94
 
98
95
 
110
107
        type_list = '\n'.join(lines)
111
108
        msg = "No known merge type %s. Supported types are:\n%s" %\
112
109
            (typestring, type_list)
113
 
        raise BzrCommandError(msg)
 
110
        raise errors.BzrCommandError(msg)
114
111
 
115
112
class Option(object):
116
113
    """Description of a command line option"""
153
150
            if option is self:
154
151
                return short
155
152
 
 
153
    def get_negation_name(self):
 
154
        if self.name.startswith('no-'):
 
155
            return self.name[3:]
 
156
        else:
 
157
            return 'no-' + self.name
 
158
 
 
159
    def add_option(self, parser, short_name):
 
160
        """Add this option to an Optparse parser"""
 
161
        option_strings = ['--%s' % self.name]
 
162
        if short_name is not None:
 
163
            option_strings.append('-%s' % short_name)
 
164
        optargfn = self.type
 
165
        if optargfn is None:
 
166
            parser.add_option(action='store_true', dest=self.name, 
 
167
                              help=self.help,
 
168
                              default=OptionParser.DEFAULT_VALUE,
 
169
                              *option_strings)
 
170
            negation_strings = ['--%s' % self.get_negation_name()]
 
171
            parser.add_option(action='store_false', dest=self.name, 
 
172
                              help=optparse.SUPPRESS_HELP, *negation_strings)
 
173
        else:
 
174
            parser.add_option(action='callback', 
 
175
                              callback=self._optparse_callback, 
 
176
                              type='string', metavar=self.argname.upper(),
 
177
                              help=self.help,
 
178
                              default=OptionParser.DEFAULT_VALUE, 
 
179
                              *option_strings)
 
180
 
 
181
    def _optparse_callback(self, option, opt, value, parser):
 
182
        setattr(parser.values, self.name, self.type(value))
 
183
 
 
184
    def iter_switches(self):
 
185
        """Iterate through the list of switches provided by the option
 
186
        
 
187
        :return: an iterator of (name, short_name, argname, help)
 
188
        """
 
189
        argname =  self.argname
 
190
        if argname is not None:
 
191
            argname = argname.upper()
 
192
        yield self.name, self.short_name(), argname, self.help
 
193
 
 
194
 
 
195
class OptionParser(optparse.OptionParser):
 
196
    """OptionParser that raises exceptions instead of exiting"""
 
197
 
 
198
    DEFAULT_VALUE = object()
 
199
 
 
200
    def error(self, message):
 
201
        raise errors.BzrCommandError(message)
 
202
 
 
203
 
 
204
def get_optparser(options):
 
205
    """Generate an optparse parser for bzrlib-style options"""
 
206
 
 
207
    parser = OptionParser()
 
208
    parser.remove_option('--help')
 
209
    short_options = dict((k.name, v) for v, k in 
 
210
                         Option.SHORT_OPTIONS.iteritems())
 
211
    for option in options.itervalues():
 
212
        option.add_option(parser, short_options.get(option.name))
 
213
    return parser
 
214
 
156
215
 
157
216
def _global_option(name, **kwargs):
158
217
    """Register o as a global option."""