~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/option.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-04-07 07:52:50 UTC
  • mfrom: (3340.1.1 208418-1.4)
  • Revision ID: pqm@pqm.ubuntu.com-20080407075250-phs53xnslo8boaeo
Return the correct knit serialisation method in _StreamAccess.
        (Andrew Bennetts, Martin Pool, Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
# TODO: For things like --diff-prefix, we want a way to customize the display
18
18
# of the option argument.
29
29
""")
30
30
 
31
31
from bzrlib import (
32
 
    registry as _mod_registry,
 
32
    log,
 
33
    registry,
33
34
    )
34
35
 
35
 
 
36
36
def _parse_revision_str(revstr):
37
37
    """This handles a revision string -> revno.
38
38
 
40
40
    each revision specifier supplied.
41
41
 
42
42
    >>> _parse_revision_str('234')
43
 
    [<RevisionSpec_dwim 234>]
 
43
    [<RevisionSpec_revno 234>]
44
44
    >>> _parse_revision_str('234..567')
45
 
    [<RevisionSpec_dwim 234>, <RevisionSpec_dwim 567>]
 
45
    [<RevisionSpec_revno 234>, <RevisionSpec_revno 567>]
46
46
    >>> _parse_revision_str('..')
47
47
    [<RevisionSpec None>, <RevisionSpec None>]
48
48
    >>> _parse_revision_str('..234')
49
 
    [<RevisionSpec None>, <RevisionSpec_dwim 234>]
 
49
    [<RevisionSpec None>, <RevisionSpec_revno 234>]
50
50
    >>> _parse_revision_str('234..')
51
 
    [<RevisionSpec_dwim 234>, <RevisionSpec None>]
 
51
    [<RevisionSpec_revno 234>, <RevisionSpec None>]
52
52
    >>> _parse_revision_str('234..456..789') # Maybe this should be an error
53
 
    [<RevisionSpec_dwim 234>, <RevisionSpec_dwim 456>, <RevisionSpec_dwim 789>]
 
53
    [<RevisionSpec_revno 234>, <RevisionSpec_revno 456>, <RevisionSpec_revno 789>]
54
54
    >>> _parse_revision_str('234....789') #Error ?
55
 
    [<RevisionSpec_dwim 234>, <RevisionSpec None>, <RevisionSpec_dwim 789>]
 
55
    [<RevisionSpec_revno 234>, <RevisionSpec None>, <RevisionSpec_revno 789>]
56
56
    >>> _parse_revision_str('revid:test@other.com-234234')
57
57
    [<RevisionSpec_revid revid:test@other.com-234234>]
58
58
    >>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
59
59
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
60
60
    >>> _parse_revision_str('revid:test@other.com-234234..23')
61
 
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_dwim 23>]
 
61
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revno 23>]
62
62
    >>> _parse_revision_str('date:2005-04-12')
63
63
    [<RevisionSpec_date date:2005-04-12>]
64
64
    >>> _parse_revision_str('date:2005-04-12 12:24:33')
68
68
    >>> _parse_revision_str('date:2005-04-12,12:24:33')
69
69
    [<RevisionSpec_date date:2005-04-12,12:24:33>]
70
70
    >>> _parse_revision_str('-5..23')
71
 
    [<RevisionSpec_dwim -5>, <RevisionSpec_dwim 23>]
 
71
    [<RevisionSpec_revno -5>, <RevisionSpec_revno 23>]
72
72
    >>> _parse_revision_str('-5')
73
 
    [<RevisionSpec_dwim -5>]
 
73
    [<RevisionSpec_revno -5>]
74
74
    >>> _parse_revision_str('123a')
75
 
    [<RevisionSpec_dwim 123a>]
 
75
    Traceback (most recent call last):
 
76
      ...
 
77
    NoSuchRevisionSpec: No namespace registered for string: '123a'
76
78
    >>> _parse_revision_str('abc')
77
 
    [<RevisionSpec_dwim abc>]
 
79
    Traceback (most recent call last):
 
80
      ...
 
81
    NoSuchRevisionSpec: No namespace registered for string: 'abc'
78
82
    >>> _parse_revision_str('branch:../branch2')
79
83
    [<RevisionSpec_branch branch:../branch2>]
80
84
    >>> _parse_revision_str('branch:../../branch2')
81
85
    [<RevisionSpec_branch branch:../../branch2>]
82
86
    >>> _parse_revision_str('branch:../../branch2..23')
83
 
    [<RevisionSpec_branch branch:../../branch2>, <RevisionSpec_dwim 23>]
 
87
    [<RevisionSpec_branch branch:../../branch2>, <RevisionSpec_revno 23>]
84
88
    >>> _parse_revision_str('branch:..\\\\branch2')
85
89
    [<RevisionSpec_branch branch:..\\branch2>]
86
90
    >>> _parse_revision_str('branch:..\\\\..\\\\branch2..23')
87
 
    [<RevisionSpec_branch branch:..\\..\\branch2>, <RevisionSpec_dwim 23>]
 
91
    [<RevisionSpec_branch branch:..\\..\\branch2>, <RevisionSpec_revno 23>]
88
92
    """
89
93
    # TODO: Maybe move this into revisionspec.py
90
94
    revs = []
100
104
    parent of the revision.
101
105
 
102
106
    >>> _parse_change_str('123')
103
 
    (<RevisionSpec_before before:123>, <RevisionSpec_dwim 123>)
 
107
    (<RevisionSpec_before before:123>, <RevisionSpec_revno 123>)
104
108
    >>> _parse_change_str('123..124')
105
109
    Traceback (most recent call last):
106
110
      ...
132
136
 
133
137
class Option(object):
134
138
    """Description of a command line option
135
 
 
 
139
    
136
140
    :ivar _short_name: If this option has a single-letter name, this is it.
137
141
    Otherwise None.
138
142
    """
146
150
    OPTIONS = {}
147
151
 
148
152
    def __init__(self, name, help='', type=None, argname=None,
149
 
                 short_name=None, param_name=None, custom_callback=None,
150
 
                 hidden=False):
 
153
                 short_name=None, param_name=None, custom_callback=None):
151
154
        """Make a new command option.
152
155
 
153
156
        :param name: regular name of the command, used in the double-dash
154
 
            form and also as the parameter to the command's run()
 
157
            form and also as the parameter to the command's run() 
155
158
            method (unless param_name is specified).
156
159
 
157
160
        :param help: help message displayed in command help
158
161
 
159
 
        :param type: function called to parse the option argument, or
 
162
        :param type: function called to parse the option argument, or 
160
163
            None (default) if this option doesn't take an argument.
161
164
 
162
165
        :param argname: name of option argument, if any
170
173
        :param custom_callback: a callback routine to be called after normal
171
174
            processing. The signature of the callback routine is
172
175
            (option, name, new_value, parser).
173
 
        :param hidden: If True, the option should be hidden in help and
174
 
            documentation.
175
176
        """
176
177
        self.name = name
177
178
        self.help = help
178
179
        self.type = type
179
180
        self._short_name = short_name
180
181
        if type is None:
181
 
            if argname:
182
 
                raise ValueError('argname not valid for booleans')
 
182
            assert argname is None
183
183
        elif argname is None:
184
184
            argname = 'ARG'
185
185
        self.argname = argname
186
186
        if param_name is None:
187
 
            self._param_name = self.name.replace('-', '_')
 
187
            self._param_name = self.name
188
188
        else:
189
189
            self._param_name = param_name
190
190
        self.custom_callback = custom_callback
191
 
        self.hidden = hidden
192
191
 
193
192
    def short_name(self):
194
193
        if self._short_name:
208
207
        option_strings = ['--%s' % self.name]
209
208
        if short_name is not None:
210
209
            option_strings.append('-%s' % short_name)
211
 
        if self.hidden:
212
 
            help = optparse.SUPPRESS_HELP
213
 
        else:
214
 
            help = self.help
215
210
        optargfn = self.type
216
211
        if optargfn is None:
217
 
            parser.add_option(action='callback',
218
 
                              callback=self._optparse_bool_callback,
 
212
            parser.add_option(action='callback', 
 
213
                              callback=self._optparse_bool_callback, 
219
214
                              callback_args=(True,),
220
 
                              help=help,
 
215
                              help=self.help,
221
216
                              *option_strings)
222
217
            negation_strings = ['--%s' % self.get_negation_name()]
223
 
            parser.add_option(action='callback',
224
 
                              callback=self._optparse_bool_callback,
 
218
            parser.add_option(action='callback', 
 
219
                              callback=self._optparse_bool_callback, 
225
220
                              callback_args=(False,),
226
221
                              help=optparse.SUPPRESS_HELP, *negation_strings)
227
222
        else:
228
 
            parser.add_option(action='callback',
229
 
                              callback=self._optparse_callback,
 
223
            parser.add_option(action='callback', 
 
224
                              callback=self._optparse_callback, 
230
225
                              type='string', metavar=self.argname.upper(),
231
 
                              help=help,
232
 
                              default=OptionParser.DEFAULT_VALUE,
 
226
                              help=self.help,
 
227
                              default=OptionParser.DEFAULT_VALUE, 
233
228
                              *option_strings)
234
229
 
235
230
    def _optparse_bool_callback(self, option, opt_str, value, parser, bool_v):
245
240
 
246
241
    def iter_switches(self):
247
242
        """Iterate through the list of switches provided by the option
248
 
 
 
243
        
249
244
        :return: an iterator of (name, short_name, argname, help)
250
245
        """
251
246
        argname =  self.argname
254
249
        yield self.name, self.short_name(), argname, self.help
255
250
 
256
251
    def is_hidden(self, name):
257
 
        return self.hidden
 
252
        return False
258
253
 
259
254
 
260
255
class ListOption(Option):
310
305
        else:
311
306
            return self.converter(value)
312
307
 
313
 
    def __init__(self, name, help, registry=None, converter=None,
314
 
        value_switches=False, title=None, enum_switch=True,
315
 
        lazy_registry=None):
 
308
    def __init__(self, name, help, registry, converter=None,
 
309
        value_switches=False, title=None, enum_switch=True):
316
310
        """
317
311
        Constructor.
318
312
 
326
320
            '--knit' can be used interchangeably.
327
321
        :param enum_switch: If true, a switch is provided with the option name,
328
322
            which takes a value.
329
 
        :param lazy_registry: A tuple of (module name, attribute name) for a
330
 
            registry to be lazily loaded.
331
323
        """
332
324
        Option.__init__(self, name, help, type=self.convert)
333
 
        self._registry = registry
334
 
        if registry is None:
335
 
            if lazy_registry is None:
336
 
                raise AssertionError(
337
 
                    'One of registry or lazy_registry must be given.')
338
 
            self._lazy_registry = _mod_registry._LazyObjectGetter(
339
 
                *lazy_registry)
340
 
        if registry is not None and lazy_registry is not None:
341
 
            raise AssertionError(
342
 
                'registry and lazy_registry are mutually exclusive')
 
325
        self.registry = registry
343
326
        self.name = name
344
327
        self.converter = converter
345
328
        self.value_switches = value_switches
348
331
        if self.title is None:
349
332
            self.title = name
350
333
 
351
 
    @property
352
 
    def registry(self):
353
 
        if self._registry is None:
354
 
            self._registry = self._lazy_registry.get_obj()
355
 
        return self._registry
356
 
 
357
334
    @staticmethod
358
335
    def from_kwargs(name_, help=None, title=None, value_switches=False,
359
336
                    enum_switch=True, **kwargs):
363
340
        RegistryOption constructor.  Any other keyword arguments are treated
364
341
        as values for the option, and they value is treated as the help.
365
342
        """
366
 
        reg = _mod_registry.Registry()
 
343
        reg = registry.Registry()
367
344
        for name, switch_help in kwargs.iteritems():
368
345
            name = name.replace('_', '-')
369
346
            reg.register(name, name, help=switch_help)
370
 
            if not value_switches:
371
 
                help = help + '  "' + name + '": ' + switch_help
372
 
                if not help.endswith("."):
373
 
                    help = help + "."
374
347
        return RegistryOption(name_, help, reg, title=title,
375
348
            value_switches=value_switches, enum_switch=enum_switch)
376
349
 
456
429
    Option.OPTIONS[name] = Option(name, **kwargs)
457
430
 
458
431
 
459
 
def _global_registry_option(name, help, registry=None, **kwargs):
 
432
def _global_registry_option(name, help, registry, **kwargs):
460
433
    Option.OPTIONS[name] = RegistryOption(name, help, registry, **kwargs)
461
434
 
462
435
 
 
436
class MergeTypeRegistry(registry.Registry):
 
437
 
 
438
    pass
 
439
 
 
440
 
463
441
# This is the verbosity level detected during command line parsing.
464
442
# Note that the final value is dependent on the order in which the
465
443
# various flags (verbose, quiet, no-verbose, no-quiet) are given.
488
466
            _verbosity_level = -1
489
467
 
490
468
 
491
 
class MergeTypeRegistry(_mod_registry.Registry):
492
 
 
493
 
    pass
494
 
 
495
 
 
496
469
_merge_type_registry = MergeTypeRegistry()
497
470
_merge_type_registry.register_lazy('merge3', 'bzrlib.merge', 'Merge3Merger',
498
471
                                   "Native diff3-style merge")
506
479
# Declare the standard options
507
480
_standard_option('help', short_name='h',
508
481
                 help='Show help message.')
509
 
_standard_option('usage',
510
 
                 help='Show usage message and options.')
511
482
_standard_option('verbose', short_name='v',
512
483
                 help='Display more information.',
513
484
                 custom_callback=_verbosity_level_callback)
543
514
               help='Select changes introduced by the specified revision. See also "help revisionspec".')
544
515
_global_option('show-ids',
545
516
               help='Show internal object ids.')
546
 
_global_option('timezone',
 
517
_global_option('timezone', 
547
518
               type=str,
548
 
               help='Display timezone as local, original, or utc.')
 
519
               help='display timezone as local, original, or utc')
549
520
_global_option('unbound')
550
521
_global_option('version')
551
522
_global_option('email')
552
523
_global_option('update')
553
524
_global_registry_option('log-format', "Use specified log format.",
554
 
                        lazy_registry=('bzrlib.log', 'log_formatter_registry'),
555
 
                        value_switches=True, title='Log format')
 
525
                        log.log_formatter_registry, value_switches=True,
 
526
                        title='Log format')
556
527
_global_option('long', help='Use detailed log format. Same as --log-format long',
557
528
               short_name='l')
558
529
_global_option('short', help='Use moderately short log format. Same as --log-format short')
570
541
_global_option('dry-run',
571
542
               help="Show what would be done, but don't actually do anything.")
572
543
_global_option('name-from-revision', help='The path name in the old tree.')
573
 
 
574
 
diff_writer_registry = _mod_registry.Registry()
575
 
diff_writer_registry.register('plain', lambda x: x, 'Plaintext diff output.')
576
 
diff_writer_registry.default_key = 'plain'