~bzr-pqm/bzr/bzr.dev

1684.1.6 by Martin Pool
(patch) --diff-prefix option (goffredo, alexander)
1
# Copyright (C) 2004, 2005, 2006 by Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
1684.1.6 by Martin Pool
(patch) --diff-prefix option (goffredo, alexander)
17
# TODO: For things like --diff-prefix, we want a way to customize the display
18
# of the option argument.
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
19
1996.3.28 by John Arbash Meinel
lazy import revisionspec and errors for bzrlib.options
20
import re
21
22
from bzrlib.lazy_import import lazy_import
23
lazy_import(globals(), """
1857.1.3 by Aaron Bentley
Make option adding depend on Option type
24
import optparse
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
25
1996.3.28 by John Arbash Meinel
lazy import revisionspec and errors for bzrlib.options
26
from bzrlib import (
27
    errors,
28
    revisionspec,
29
    )
30
""")
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
31
from bzrlib.trace import warning
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
32
33
34
def _parse_revision_str(revstr):
35
    """This handles a revision string -> revno.
36
37
    This always returns a list.  The list will have one element for
38
    each revision specifier supplied.
39
40
    >>> _parse_revision_str('234')
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
41
    [<RevisionSpec_revno 234>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
42
    >>> _parse_revision_str('234..567')
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
43
    [<RevisionSpec_revno 234>, <RevisionSpec_revno 567>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
44
    >>> _parse_revision_str('..')
45
    [<RevisionSpec None>, <RevisionSpec None>]
46
    >>> _parse_revision_str('..234')
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
47
    [<RevisionSpec None>, <RevisionSpec_revno 234>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
48
    >>> _parse_revision_str('234..')
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
49
    [<RevisionSpec_revno 234>, <RevisionSpec None>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
50
    >>> _parse_revision_str('234..456..789') # Maybe this should be an error
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
51
    [<RevisionSpec_revno 234>, <RevisionSpec_revno 456>, <RevisionSpec_revno 789>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
52
    >>> _parse_revision_str('234....789') #Error ?
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
53
    [<RevisionSpec_revno 234>, <RevisionSpec None>, <RevisionSpec_revno 789>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
54
    >>> _parse_revision_str('revid:test@other.com-234234')
55
    [<RevisionSpec_revid revid:test@other.com-234234>]
56
    >>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
57
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
58
    >>> _parse_revision_str('revid:test@other.com-234234..23')
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
59
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revno 23>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
60
    >>> _parse_revision_str('date:2005-04-12')
61
    [<RevisionSpec_date date:2005-04-12>]
62
    >>> _parse_revision_str('date:2005-04-12 12:24:33')
63
    [<RevisionSpec_date date:2005-04-12 12:24:33>]
64
    >>> _parse_revision_str('date:2005-04-12T12:24:33')
65
    [<RevisionSpec_date date:2005-04-12T12:24:33>]
66
    >>> _parse_revision_str('date:2005-04-12,12:24:33')
67
    [<RevisionSpec_date date:2005-04-12,12:24:33>]
68
    >>> _parse_revision_str('-5..23')
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
69
    [<RevisionSpec_revno -5>, <RevisionSpec_revno 23>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
70
    >>> _parse_revision_str('-5')
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
71
    [<RevisionSpec_revno -5>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
72
    >>> _parse_revision_str('123a')
73
    Traceback (most recent call last):
74
      ...
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
75
    NoSuchRevisionSpec: No namespace registered for string: '123a'
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
76
    >>> _parse_revision_str('abc')
77
    Traceback (most recent call last):
78
      ...
1948.4.32 by John Arbash Meinel
Clean up __repr__, as well as add tests that we can handle -r12:branch/
79
    NoSuchRevisionSpec: No namespace registered for string: 'abc'
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
80
    >>> _parse_revision_str('branch:../branch2')
81
    [<RevisionSpec_branch branch:../branch2>]
1545.1.1 by Denys Duchier
distinguish ../ as path to branch and .. as revspec separator
82
    >>> _parse_revision_str('branch:../../branch2')
83
    [<RevisionSpec_branch branch:../../branch2>]
84
    >>> _parse_revision_str('branch:../../branch2..23')
1948.4.31 by John Arbash Meinel
fix bugs in the test_annonate.py suite, which was passing '-r 3' as n argument not '-r3' or '-r', '3'
85
    [<RevisionSpec_branch branch:../../branch2>, <RevisionSpec_revno 23>]
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
86
    """
87
    # TODO: Maybe move this into revisionspec.py
88
    revs = []
1948.4.28 by John Arbash Meinel
Remove some places that were directly instantiating a RevisionSpec object. Also get rid of support for --revision 1:2, it has been deprecated for a long time
89
    sep = re.compile("\\.\\.(?!/)")
90
    for x in sep.split(revstr):
1996.3.28 by John Arbash Meinel
lazy import revisionspec and errors for bzrlib.options
91
        revs.append(revisionspec.RevisionSpec.from_string(x or None))
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
92
    return revs
93
94
95
def _parse_merge_type(typestring):
1185.12.62 by Aaron Bentley
Restored merge-type selection
96
    return get_merge_type(typestring)
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
97
1185.12.62 by Aaron Bentley
Restored merge-type selection
98
def get_merge_type(typestring):
99
    """Attempt to find the merge class/factory associated with a string."""
100
    from merge import merge_types
101
    try:
102
        return merge_types[typestring][0]
103
    except KeyError:
104
        templ = '%s%%7s: %%s' % (' '*12)
105
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
106
        type_list = '\n'.join(lines)
107
        msg = "No known merge type %s. Supported types are:\n%s" %\
108
            (typestring, type_list)
1996.3.28 by John Arbash Meinel
lazy import revisionspec and errors for bzrlib.options
109
        raise errors.BzrCommandError(msg)
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
110
111
class Option(object):
1185.16.45 by Martin Pool
- refactor handling of short option names
112
    """Description of a command line option"""
113
    # TODO: Some way to show in help a description of the option argument
114
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
115
    OPTIONS = {}
116
    SHORT_OPTIONS = {}
117
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
118
    def __init__(self, name, help='', type=None, argname=None):
1185.16.45 by Martin Pool
- refactor handling of short option names
119
        """Make a new command option.
120
121
        name -- regular name of the command, used in the double-dash
122
            form and also as the parameter to the command's run() 
123
            method.
124
125
        help -- help message displayed in command help
126
127
        type -- function called to parse the option argument, or 
128
            None (default) if this option doesn't take an argument.
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
129
130
        argname -- name of option argument, if any
1185.16.45 by Martin Pool
- refactor handling of short option names
131
        """
132
        # TODO: perhaps a subclass that automatically does 
1759.2.1 by Jelmer Vernooij
Fix some types (found using aspell).
133
        # --option, --no-option for reversible booleans
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
134
        self.name = name
135
        self.help = help
136
        self.type = type
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
137
        if type is None:
138
            assert argname is None
139
        elif argname is None:
140
            argname = 'ARG'
141
        self.argname = argname
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
142
1185.16.45 by Martin Pool
- refactor handling of short option names
143
    def short_name(self):
144
        """Return the single character option for this command, if any.
145
146
        Short options are globally registered.
147
        """
1185.25.3 by Aaron Bentley
Restored short options in help
148
        for short, option in Option.SHORT_OPTIONS.iteritems():
149
            if option is self:
150
                return short
1185.16.45 by Martin Pool
- refactor handling of short option names
151
1857.1.9 by Aaron Bentley
Add hidden negation options
152
    def get_negation_name(self):
153
        if self.name.startswith('no-'):
154
            return self.name[3:]
155
        else:
156
            return 'no-' + self.name
157
1857.1.3 by Aaron Bentley
Make option adding depend on Option type
158
    def add_option(self, parser, short_name):
159
        """Add this option to an Optparse parser"""
160
        option_strings = ['--%s' % self.name]
161
        if short_name is not None:
162
            option_strings.append('-%s' % short_name)
163
        optargfn = self.type
164
        if optargfn is None:
165
            parser.add_option(action='store_true', dest=self.name, 
166
                              help=self.help,
167
                              default=OptionParser.DEFAULT_VALUE,
168
                              *option_strings)
1857.1.9 by Aaron Bentley
Add hidden negation options
169
            negation_strings = ['--%s' % self.get_negation_name()]
1857.1.22 by Aaron Bentley
Negations set value to False, instead of Optparser.DEFAULT_VALUE
170
            parser.add_option(action='store_false', dest=self.name, 
171
                              help=optparse.SUPPRESS_HELP, *negation_strings)
1857.1.3 by Aaron Bentley
Make option adding depend on Option type
172
        else:
173
            parser.add_option(action='callback', 
174
                              callback=self._optparse_callback, 
1857.1.12 by Aaron Bentley
Fix a bunch of test cases that assumed --merge-type or log-format
175
                              type='string', metavar=self.argname.upper(),
1857.1.4 by Aaron Bentley
Set metavar according to option
176
                              help=self.help,
1857.1.3 by Aaron Bentley
Make option adding depend on Option type
177
                              default=OptionParser.DEFAULT_VALUE, 
178
                              *option_strings)
179
180
    def _optparse_callback(self, option, opt, value, parser):
181
        setattr(parser.values, self.name, self.type(value))
182
1857.1.14 by Aaron Bentley
Fix man page generation
183
    def iter_switches(self):
184
        """Iterate through the list of switches provided by the option
185
        
186
        :return: an iterator of (name, short_name, argname, help)
187
        """
188
        argname =  self.argname
189
        if argname is not None:
190
            argname = argname.upper()
191
        yield self.name, self.short_name(), argname, self.help
1857.1.3 by Aaron Bentley
Make option adding depend on Option type
192
1857.1.15 by Aaron Bentley
Add tests for generating an option parser
193
1857.1.3 by Aaron Bentley
Make option adding depend on Option type
194
class OptionParser(optparse.OptionParser):
195
    """OptionParser that raises exceptions instead of exiting"""
196
1857.1.6 by Aaron Bentley
Make the DEFAULT_VALUE an object instance
197
    DEFAULT_VALUE = object()
1857.1.3 by Aaron Bentley
Make option adding depend on Option type
198
199
    def error(self, message):
1996.3.28 by John Arbash Meinel
lazy import revisionspec and errors for bzrlib.options
200
        raise errors.BzrCommandError(message)
1857.1.3 by Aaron Bentley
Make option adding depend on Option type
201
202
203
def get_optparser(options):
204
    """Generate an optparse parser for bzrlib-style options"""
205
206
    parser = OptionParser()
207
    parser.remove_option('--help')
208
    short_options = dict((k.name, v) for v, k in 
209
                         Option.SHORT_OPTIONS.iteritems())
210
    for option in options.itervalues():
211
        option.add_option(parser, short_options.get(option.name))
212
    return parser
213
1185.16.45 by Martin Pool
- refactor handling of short option names
214
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
215
def _global_option(name, **kwargs):
216
    """Register o as a global option."""
217
    Option.OPTIONS[name] = Option(name, **kwargs)
218
1185.16.45 by Martin Pool
- refactor handling of short option names
219
_global_option('all')
1185.12.92 by Aaron Bentley
Fixed pull help, renamed clobber to overwrite
220
_global_option('overwrite', help='Ignore differences between branches and '
221
               'overwrite unconditionally')
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
222
_global_option('basis', type=str)
1505.1.2 by John Arbash Meinel
(broken) working on implementing bound branches.
223
_global_option('bound')
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
224
_global_option('diff-options', type=str)
1185.16.55 by mbp at sourcefrog
- more option help
225
_global_option('help',
226
               help='show help message')
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
227
_global_option('file', type=unicode)
1185.16.45 by Martin Pool
- refactor handling of short option names
228
_global_option('force')
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
229
_global_option('format', type=unicode)
1185.16.45 by Martin Pool
- refactor handling of short option names
230
_global_option('forward')
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
231
_global_option('message', type=unicode)
1185.16.45 by Martin Pool
- refactor handling of short option names
232
_global_option('no-recurse')
1694.2.3 by Martin Pool
Add -p0, -p1 options for diff.
233
_global_option('prefix', type=str, 
234
               help='Set prefixes to added to old and new filenames, as '
235
                    'two values separated by a colon.')
1185.16.55 by mbp at sourcefrog
- more option help
236
_global_option('profile',
237
               help='show performance profiling information')
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
238
_global_option('revision', type=_parse_revision_str)
1185.16.47 by Martin Pool
- help for global options
239
_global_option('show-ids', 
240
               help='show internal object ids')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
241
_global_option('timezone', 
242
               type=str,
243
               help='display timezone as local, original, or utc')
1505.1.2 by John Arbash Meinel
(broken) working on implementing bound branches.
244
_global_option('unbound')
1185.16.48 by mbp at sourcefrog
- more refactoring of and tests for option parsing
245
_global_option('verbose',
246
               help='display more information')
1185.16.45 by Martin Pool
- refactor handling of short option names
247
_global_option('version')
248
_global_option('email')
249
_global_option('update')
1857.1.20 by Aaron Bentley
Strip out all the EnumOption stuff
250
_global_option('log-format', type=str, help="Use this log format")
251
_global_option('long', help='Use detailed log format. Same as --log-format long')
252
_global_option('short', help='Use moderately short log format. Same as --log-format short')
253
_global_option('line', help='Use log format with one line per revision. Same as --log-format line')
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
254
_global_option('root', type=str)
1185.16.45 by Martin Pool
- refactor handling of short option names
255
_global_option('no-backup')
1857.1.20 by Aaron Bentley
Strip out all the EnumOption stuff
256
_global_option('merge-type', type=_parse_merge_type, 
257
               help='Select a particular merge algorithm')
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
258
_global_option('pattern', type=str)
1185.16.45 by Martin Pool
- refactor handling of short option names
259
_global_option('quiet')
1185.12.92 by Aaron Bentley
Fixed pull help, renamed clobber to overwrite
260
_global_option('remember', help='Remember the specified location as a'
261
               ' default.')
1185.24.3 by Aaron Bentley
Integrated reprocessing into the rest of the merge stuff
262
_global_option('reprocess', help='Reprocess to reduce spurious conflicts')
1185.33.33 by Martin Pool
[patch] add 'bzr inventory --kind directory'; remove 'bzr directories'
263
_global_option('kind', type=str)
1185.33.90 by Martin Pool
[merge] add --dry-run option (mpe)
264
_global_option('dry-run',
265
               help="show what would be done, but don't actually do anything")
1185.16.45 by Martin Pool
- refactor handling of short option names
266
267
268
def _global_short(short_name, long_name):
269
    assert short_name not in Option.SHORT_OPTIONS
270
    Option.SHORT_OPTIONS[short_name] = Option.OPTIONS[long_name]
271
    
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
272
273
Option.SHORT_OPTIONS['F'] = Option.OPTIONS['file']
274
Option.SHORT_OPTIONS['h'] = Option.OPTIONS['help']
275
Option.SHORT_OPTIONS['m'] = Option.OPTIONS['message']
276
Option.SHORT_OPTIONS['r'] = Option.OPTIONS['revision']
277
Option.SHORT_OPTIONS['v'] = Option.OPTIONS['verbose']
1857.1.20 by Aaron Bentley
Strip out all the EnumOption stuff
278
Option.SHORT_OPTIONS['l'] = Option.OPTIONS['long']
1185.16.41 by Martin Pool
[patch] define cli options as objects, not strings
279
Option.SHORT_OPTIONS['q'] = Option.OPTIONS['quiet']
1694.2.3 by Martin Pool
Add -p0, -p1 options for diff.
280
Option.SHORT_OPTIONS['p'] = Option.OPTIONS['prefix']