~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/option.py

  • Committer: Ian Clatworthy
  • Date: 2007-08-30 13:40:41 UTC
  • mto: (2779.1.1 ianc-integration)
  • mto: This revision was merged to the branch mainline in revision 2783.
  • Revision ID: ian.clatworthy@internode.on.net-20070830134041-y6wd24dz52fpkthx
Support custom help for commonly used options and standard option definition

Show diffs side-by-side

added added

removed removed

Lines of Context:
124
124
    Otherwise None.
125
125
    """
126
126
 
127
 
    # TODO: Some way to show in help a description of the option argument
 
127
    # The dictionary of standard options. These are always legal.
 
128
    STD_OPTIONS = {}
128
129
 
 
130
    # The dictionary of commonly used options. these are only legal
 
131
    # if a command explicitly references them by name in the list
 
132
    # of supported options.
129
133
    OPTIONS = {}
130
134
 
131
135
    def __init__(self, name, help='', type=None, argname=None,
132
 
                 short_name=None):
 
136
                 short_name=None, custom_callback=None):
133
137
        """Make a new command option.
134
138
 
135
 
        name -- regular name of the command, used in the double-dash
 
139
        :param name: regular name of the command, used in the double-dash
136
140
            form and also as the parameter to the command's run() 
137
141
            method.
138
142
 
139
 
        help -- help message displayed in command help
 
143
        :param help: help message displayed in command help
140
144
 
141
 
        type -- function called to parse the option argument, or 
 
145
        :param type: function called to parse the option argument, or 
142
146
            None (default) if this option doesn't take an argument.
143
147
 
144
 
        argname -- name of option argument, if any
 
148
        :param argname: name of option argument, if any
 
149
 
 
150
        :param short_name: short option code for use with a single -, e.g.
 
151
            short_name="v" to enable parsing of -v.
 
152
 
 
153
        :param custom_callback: a callback routine to be called after normal
 
154
            processing. The signature of the callback routine is the same
 
155
            as that for normal option callbacks. See optparse in the standard
 
156
            Python library for details.
145
157
        """
146
158
        self.name = name
147
159
        self.help = help
152
164
        elif argname is None:
153
165
            argname = 'ARG'
154
166
        self.argname = argname
 
167
        self.custom_callback = custom_callback
155
168
 
156
169
    def short_name(self):
157
170
        if self._short_name:
173
186
            option_strings.append('-%s' % short_name)
174
187
        optargfn = self.type
175
188
        if optargfn is None:
176
 
            parser.add_option(action='store_true', dest=self.name, 
 
189
            parser.add_option(action='callback', 
 
190
                              callback=self._optparse_bool_callback, 
 
191
                              callback_args=(True,),
177
192
                              help=self.help,
178
 
                              default=OptionParser.DEFAULT_VALUE,
179
193
                              *option_strings)
180
194
            negation_strings = ['--%s' % self.get_negation_name()]
181
 
            parser.add_option(action='store_false', dest=self.name, 
 
195
            parser.add_option(action='callback', 
 
196
                              callback=self._optparse_bool_callback, 
 
197
                              callback_args=(False,),
182
198
                              help=optparse.SUPPRESS_HELP, *negation_strings)
183
199
        else:
184
200
            parser.add_option(action='callback', 
188
204
                              default=OptionParser.DEFAULT_VALUE, 
189
205
                              *option_strings)
190
206
 
 
207
    def _optparse_bool_callback(self, option, opt_str, value, parser, bool_v):
 
208
        setattr(parser.values, self.name, bool_v)
 
209
        if self.custom_callback is not None:
 
210
            self.custom_callback(option, self.name, bool_v, parser)
 
211
 
191
212
    def _optparse_callback(self, option, opt, value, parser):
192
213
        setattr(parser.values, self.name, self.type(value))
 
214
        if self.custom_callback is not None:
 
215
            self.custom_callback(option, opt, value, parser)
193
216
 
194
217
    def iter_switches(self):
195
218
        """Iterate through the list of switches provided by the option
233
256
            del values[:]
234
257
        else:
235
258
            values.append(self.type(value))
 
259
        if self.custom_callback is not None:
 
260
            self.custom_callback(option, opt, value, parser)
236
261
 
237
262
 
238
263
class RegistryOption(Option):
319
344
    def _optparse_value_callback(self, cb_value):
320
345
        def cb(option, opt, value, parser):
321
346
            setattr(parser.values, self.name, self.type(cb_value))
 
347
            if self.custom_callback is not None:
 
348
                self.custom_callback(option, opt, value, parser)
322
349
        return cb
323
350
 
324
351
    def iter_switches(self):
357
384
    return parser
358
385
 
359
386
 
 
387
def custom_help(name, help):
 
388
    """Clone a common option overriding the help."""
 
389
    import copy
 
390
    o = copy.copy(Option.OPTIONS[name])
 
391
    o.help = help
 
392
    return o
 
393
 
 
394
 
 
395
def _standard_option(name, **kwargs):
 
396
    """Register a standard option."""
 
397
    # All standard options are implicitly 'global' ones
 
398
    Option.STD_OPTIONS[name] = Option(name, **kwargs)
 
399
    Option.OPTIONS[name] = Option.STD_OPTIONS[name]
 
400
 
 
401
 
360
402
def _global_option(name, **kwargs):
361
 
    """Register o as a global option."""
 
403
    """Register a global option."""
362
404
    Option.OPTIONS[name] = Option(name, **kwargs)
363
405
 
364
406
 
371
413
    pass
372
414
 
373
415
 
 
416
# This is the verbosity level detected during command line parsing.
 
417
# Note that the final value is dependent on the order in which the
 
418
# various flags (verbose, quiet, no-verbose, no-quiet) are given.
 
419
# The final value will be one of the following:
 
420
#
 
421
# * -ve for quiet
 
422
# * 0 for normal
 
423
# * +ve for verbose
 
424
_verbosity_level = 0
 
425
 
 
426
 
 
427
def _verbosity_level_callback(option, opt_str, value, parser):
 
428
    global _verbosity_level
 
429
    if not value:
 
430
        # Either --no-verbose or --no-quiet was specified
 
431
        _verbosity_level = 0
 
432
    elif opt_str == "verbose":
 
433
        if _verbosity_level > 0:
 
434
            _verbosity_level += 1
 
435
        else:
 
436
            _verbosity_level = 1
 
437
    else:
 
438
        if _verbosity_level < 0:
 
439
            _verbosity_level -= 1
 
440
        else:
 
441
            _verbosity_level = -1
 
442
 
 
443
 
374
444
_merge_type_registry = MergeTypeRegistry()
375
445
_merge_type_registry.register_lazy('merge3', 'bzrlib.merge', 'Merge3Merger',
376
446
                                   "Native diff3-style merge")
379
449
_merge_type_registry.register_lazy('weave', 'bzrlib.merge', 'WeaveMerger',
380
450
                                   "Weave-based merge")
381
451
 
 
452
# Declare the standard options
 
453
_standard_option('help', short_name='h',
 
454
                 help='Show help message.')
 
455
_standard_option('verbose', short_name='v',
 
456
                 help='Display more information.',
 
457
                 custom_callback=_verbosity_level_callback)
 
458
_standard_option('quiet', short_name='q',
 
459
                 help="Only display errors and warnings.",
 
460
                 custom_callback=_verbosity_level_callback)
 
461
 
 
462
# Declare commonly used options
382
463
_global_option('all')
383
464
_global_option('overwrite', help='Ignore differences between branches and '
384
465
               'overwrite unconditionally.')
405
486
               type=str,
406
487
               help='display timezone as local, original, or utc')
407
488
_global_option('unbound')
408
 
_global_option('verbose',
409
 
               help='Display more information.',
410
 
               short_name='v')
411
489
_global_option('version')
412
490
_global_option('email')
413
491
_global_option('update')
424
502
                        _merge_type_registry, value_switches=True,
425
503
                        title='Merge algorithm')
426
504
_global_option('pattern', type=str)
427
 
_global_option('quiet', short_name='q')
428
505
_global_option('remember', help='Remember the specified location as a'
429
506
               ' default.')
430
507
_global_option('reprocess', help='Reprocess to reduce spurious conflicts.')
432
509
_global_option('dry-run',
433
510
               help="Show what would be done, but don't actually do anything.")
434
511
_global_option('name-from-revision', help='The path name in the old tree.')
435
 
 
436
 
_help_option = Option('help',
437
 
                      help='Show help message.',
438
 
                      short_name='h')