/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/option.py

  • Committer: John Ferlito
  • Date: 2009-09-02 04:31:45 UTC
  • mto: (4665.7.1 serve-init)
  • mto: This revision was merged to the branch mainline in revision 4913.
  • Revision ID: johnf@inodes.org-20090902043145-gxdsfw03ilcwbyn5
Add a debian init script for bzr --serve

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2006, 2007 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
20
20
import optparse
21
21
import re
22
22
 
23
 
from . import (
 
23
from bzrlib.lazy_import import lazy_import
 
24
lazy_import(globals(), """
 
25
from bzrlib import (
24
26
    errors,
 
27
    revisionspec,
 
28
    )
 
29
""")
 
30
 
 
31
from bzrlib import (
25
32
    registry as _mod_registry,
26
 
    revisionspec,
27
33
    )
28
34
 
29
35
 
30
 
class BadOptionValue(errors.BzrError):
31
 
 
32
 
    _fmt = """Bad value "%(value)s" for option "%(name)s"."""
33
 
 
34
 
    def __init__(self, name, value):
35
 
        errors.BzrError.__init__(self, name=name, value=value)
36
 
 
37
 
 
38
36
def _parse_revision_str(revstr):
39
37
    """This handles a revision string -> revno.
40
38
 
42
40
    each revision specifier supplied.
43
41
 
44
42
    >>> _parse_revision_str('234')
45
 
    [<RevisionSpec_dwim 234>]
 
43
    [<RevisionSpec_revno 234>]
46
44
    >>> _parse_revision_str('234..567')
47
 
    [<RevisionSpec_dwim 234>, <RevisionSpec_dwim 567>]
 
45
    [<RevisionSpec_revno 234>, <RevisionSpec_revno 567>]
48
46
    >>> _parse_revision_str('..')
49
47
    [<RevisionSpec None>, <RevisionSpec None>]
50
48
    >>> _parse_revision_str('..234')
51
 
    [<RevisionSpec None>, <RevisionSpec_dwim 234>]
 
49
    [<RevisionSpec None>, <RevisionSpec_revno 234>]
52
50
    >>> _parse_revision_str('234..')
53
 
    [<RevisionSpec_dwim 234>, <RevisionSpec None>]
 
51
    [<RevisionSpec_revno 234>, <RevisionSpec None>]
54
52
    >>> _parse_revision_str('234..456..789') # Maybe this should be an error
55
 
    [<RevisionSpec_dwim 234>, <RevisionSpec_dwim 456>, <RevisionSpec_dwim 789>]
 
53
    [<RevisionSpec_revno 234>, <RevisionSpec_revno 456>, <RevisionSpec_revno 789>]
56
54
    >>> _parse_revision_str('234....789') #Error ?
57
 
    [<RevisionSpec_dwim 234>, <RevisionSpec None>, <RevisionSpec_dwim 789>]
 
55
    [<RevisionSpec_revno 234>, <RevisionSpec None>, <RevisionSpec_revno 789>]
58
56
    >>> _parse_revision_str('revid:test@other.com-234234')
59
57
    [<RevisionSpec_revid revid:test@other.com-234234>]
60
58
    >>> _parse_revision_str('revid:test@other.com-234234..revid:test@other.com-234235')
61
59
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revid revid:test@other.com-234235>]
62
60
    >>> _parse_revision_str('revid:test@other.com-234234..23')
63
 
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_dwim 23>]
 
61
    [<RevisionSpec_revid revid:test@other.com-234234>, <RevisionSpec_revno 23>]
64
62
    >>> _parse_revision_str('date:2005-04-12')
65
63
    [<RevisionSpec_date date:2005-04-12>]
66
64
    >>> _parse_revision_str('date:2005-04-12 12:24:33')
70
68
    >>> _parse_revision_str('date:2005-04-12,12:24:33')
71
69
    [<RevisionSpec_date date:2005-04-12,12:24:33>]
72
70
    >>> _parse_revision_str('-5..23')
73
 
    [<RevisionSpec_dwim -5>, <RevisionSpec_dwim 23>]
 
71
    [<RevisionSpec_revno -5>, <RevisionSpec_revno 23>]
74
72
    >>> _parse_revision_str('-5')
75
 
    [<RevisionSpec_dwim -5>]
 
73
    [<RevisionSpec_revno -5>]
76
74
    >>> _parse_revision_str('123a')
77
 
    [<RevisionSpec_dwim 123a>]
 
75
    Traceback (most recent call last):
 
76
      ...
 
77
    NoSuchRevisionSpec: No namespace registered for string: '123a'
78
78
    >>> _parse_revision_str('abc')
79
 
    [<RevisionSpec_dwim abc>]
 
79
    Traceback (most recent call last):
 
80
      ...
 
81
    NoSuchRevisionSpec: No namespace registered for string: 'abc'
80
82
    >>> _parse_revision_str('branch:../branch2')
81
83
    [<RevisionSpec_branch branch:../branch2>]
82
84
    >>> _parse_revision_str('branch:../../branch2')
83
85
    [<RevisionSpec_branch branch:../../branch2>]
84
86
    >>> _parse_revision_str('branch:../../branch2..23')
85
 
    [<RevisionSpec_branch branch:../../branch2>, <RevisionSpec_dwim 23>]
 
87
    [<RevisionSpec_branch branch:../../branch2>, <RevisionSpec_revno 23>]
86
88
    >>> _parse_revision_str('branch:..\\\\branch2')
87
89
    [<RevisionSpec_branch branch:..\\branch2>]
88
90
    >>> _parse_revision_str('branch:..\\\\..\\\\branch2..23')
89
 
    [<RevisionSpec_branch branch:..\\..\\branch2>, <RevisionSpec_dwim 23>]
 
91
    [<RevisionSpec_branch branch:..\\..\\branch2>, <RevisionSpec_revno 23>]
90
92
    """
91
93
    # TODO: Maybe move this into revisionspec.py
92
94
    revs = []
102
104
    parent of the revision.
103
105
 
104
106
    >>> _parse_change_str('123')
105
 
    (<RevisionSpec_before before:123>, <RevisionSpec_dwim 123>)
 
107
    (<RevisionSpec_before before:123>, <RevisionSpec_revno 123>)
106
108
    >>> _parse_change_str('123..124')
107
109
    Traceback (most recent call last):
108
110
      ...
109
 
    breezy.errors.RangeInChangeOption: Option --change does not accept revision ranges
 
111
    RangeInChangeOption: Option --change does not accept revision ranges
110
112
    """
111
113
    revs = _parse_revision_str(revstr)
112
114
    if len(revs) > 1:
118
120
def _parse_merge_type(typestring):
119
121
    return get_merge_type(typestring)
120
122
 
121
 
 
122
123
def get_merge_type(typestring):
123
124
    """Attempt to find the merge class/factory associated with a string."""
124
125
    from merge import merge_types
125
126
    try:
126
127
        return merge_types[typestring][0]
127
128
    except KeyError:
128
 
        templ = '%s%%7s: %%s' % (' ' * 12)
129
 
        lines = [templ % (f[0], f[1][1]) for f in merge_types.items()]
 
129
        templ = '%s%%7s: %%s' % (' '*12)
 
130
        lines = [templ % (f[0], f[1][1]) for f in merge_types.iteritems()]
130
131
        type_list = '\n'.join(lines)
131
132
        msg = "No known merge type %s. Supported types are:\n%s" %\
132
133
            (typestring, type_list)
133
 
        raise errors.CommandError(msg)
 
134
        raise errors.BzrCommandError(msg)
134
135
 
135
136
 
136
137
class Option(object):
241
242
            self.custom_callback(option, self._param_name, bool_v, parser)
242
243
 
243
244
    def _optparse_callback(self, option, opt, value, parser):
244
 
        try:
245
 
            v = self.type(value)
246
 
        except ValueError as e:
247
 
            raise optparse.OptionValueError(
248
 
                'invalid value for option %s: %s' % (option, value))
 
245
        v = self.type(value)
249
246
        setattr(parser.values, self._param_name, v)
250
247
        if self.custom_callback is not None:
251
248
            self.custom_callback(option, self.name, v, parser)
255
252
 
256
253
        :return: an iterator of (name, short_name, argname, help)
257
254
        """
258
 
        argname = self.argname
 
255
        argname =  self.argname
259
256
        if argname is not None:
260
257
            argname = argname.upper()
261
258
        yield self.name, self.short_name(), argname, self.help
283
280
        parser.add_option(action='callback',
284
281
                          callback=self._optparse_callback,
285
282
                          type='string', metavar=self.argname.upper(),
286
 
                          help=self.help, dest=self._param_name, default=[],
 
283
                          help=self.help, default=[],
287
284
                          *option_strings)
288
285
 
289
286
    def _optparse_callback(self, option, opt, value, parser):
307
304
    def validate_value(self, value):
308
305
        """Validate a value name"""
309
306
        if value not in self.registry:
310
 
            raise BadOptionValue(self.name, value)
 
307
            raise errors.BadOptionValue(self.name, value)
311
308
 
312
309
    def convert(self, value):
313
310
        """Convert a value name into an output type"""
318
315
            return self.converter(value)
319
316
 
320
317
    def __init__(self, name, help, registry=None, converter=None,
321
 
                 value_switches=False, title=None, enum_switch=True,
322
 
                 lazy_registry=None, short_name=None, short_value_switches=None):
 
318
        value_switches=False, title=None, enum_switch=True,
 
319
        lazy_registry=None):
323
320
        """
324
321
        Constructor.
325
322
 
335
332
            which takes a value.
336
333
        :param lazy_registry: A tuple of (module name, attribute name) for a
337
334
            registry to be lazily loaded.
338
 
        :param short_name: The short name for the enum switch, if any
339
 
        :param short_value_switches: A dict mapping values to short names
340
335
        """
341
 
        Option.__init__(self, name, help, type=self.convert,
342
 
                        short_name=short_name)
 
336
        Option.__init__(self, name, help, type=self.convert)
343
337
        self._registry = registry
344
338
        if registry is None:
345
339
            if lazy_registry is None:
354
348
        self.converter = converter
355
349
        self.value_switches = value_switches
356
350
        self.enum_switch = enum_switch
357
 
        self.short_value_switches = short_value_switches
358
351
        self.title = title
359
352
        if self.title is None:
360
353
            self.title = name
372
365
 
373
366
        name, help, value_switches and enum_switch are passed to the
374
367
        RegistryOption constructor.  Any other keyword arguments are treated
375
 
        as values for the option, and their value is treated as the help.
 
368
        as values for the option, and they value is treated as the help.
376
369
        """
377
370
        reg = _mod_registry.Registry()
378
 
        for name, switch_help in sorted(kwargs.items()):
 
371
        for name, switch_help in kwargs.iteritems():
379
372
            name = name.replace('_', '-')
380
373
            reg.register(name, name, help=switch_help)
381
374
            if not value_switches:
383
376
                if not help.endswith("."):
384
377
                    help = help + "."
385
378
        return RegistryOption(name_, help, reg, title=title,
386
 
                              value_switches=value_switches, enum_switch=enum_switch)
 
379
            value_switches=value_switches, enum_switch=enum_switch)
387
380
 
388
381
    def add_option(self, parser, short_name):
389
382
        """Add this option to an Optparse parser"""
392
385
        if self.enum_switch:
393
386
            Option.add_option(self, parser, short_name)
394
387
        if self.value_switches:
395
 
            alias_map = self.registry.alias_map()
396
388
            for key in self.registry.keys():
397
 
                if key in self.registry.aliases():
398
 
                    continue
399
 
                option_strings = [
400
 
                    ('--%s' % name)
401
 
                    for name in [key] +
402
 
                    [alias for alias in alias_map.get(key, [])
403
 
                        if not self.is_hidden(alias)]]
 
389
                option_strings = ['--%s' % key]
404
390
                if self.is_hidden(key):
405
391
                    help = optparse.SUPPRESS_HELP
406
392
                else:
407
393
                    help = self.registry.get_help(key)
408
 
                if (self.short_value_switches and
409
 
                        key in self.short_value_switches):
410
 
                    option_strings.append('-%s' %
411
 
                                          self.short_value_switches[key])
412
394
                parser.add_option(action='callback',
413
 
                                  callback=self._optparse_value_callback(key),
 
395
                              callback=self._optparse_value_callback(key),
414
396
                                  help=help,
415
397
                                  *option_strings)
416
398
 
433
415
            for key in sorted(self.registry.keys()):
434
416
                yield key, None, None, self.registry.get_help(key)
435
417
 
436
 
    def is_alias(self, name):
437
 
        """Check whether a particular format is an alias."""
438
 
        if name == self.name:
439
 
            return False
440
 
        return name in self.registry.aliases()
441
 
 
442
418
    def is_hidden(self, name):
443
419
        if name == self.name:
444
420
            return Option.is_hidden(self, name)
450
426
 
451
427
    DEFAULT_VALUE = object()
452
428
 
453
 
    def __init__(self):
454
 
        optparse.OptionParser.__init__(self)
455
 
        self.formatter = GettextIndentedHelpFormatter()
456
 
 
457
429
    def error(self, message):
458
 
        raise errors.CommandError(message)
459
 
 
460
 
 
461
 
class GettextIndentedHelpFormatter(optparse.IndentedHelpFormatter):
462
 
    """Adds gettext() call to format_option()"""
463
 
 
464
 
    def __init__(self):
465
 
        optparse.IndentedHelpFormatter.__init__(self)
466
 
 
467
 
    def format_option(self, option):
468
 
        """code taken from Python's optparse.py"""
469
 
        if option.help:
470
 
            from .i18n import gettext
471
 
            option.help = gettext(option.help)
472
 
        return optparse.IndentedHelpFormatter.format_option(self, option)
 
430
        raise errors.BzrCommandError(message)
473
431
 
474
432
 
475
433
def get_optparser(options):
476
 
    """Generate an optparse parser for breezy-style options"""
 
434
    """Generate an optparse parser for bzrlib-style options"""
477
435
 
478
436
    parser = OptionParser()
479
437
    parser.remove_option('--help')
480
 
    for option in options:
 
438
    for option in options.itervalues():
481
439
        option.add_option(parser, option.short_name())
482
440
    return parser
483
441
 
497
455
    Option.OPTIONS[name] = Option.STD_OPTIONS[name]
498
456
 
499
457
 
500
 
def _standard_list_option(name, **kwargs):
501
 
    """Register a standard option."""
502
 
    # All standard options are implicitly 'global' ones
503
 
    Option.STD_OPTIONS[name] = ListOption(name, **kwargs)
504
 
    Option.OPTIONS[name] = Option.STD_OPTIONS[name]
505
 
 
506
 
 
507
458
def _global_option(name, **kwargs):
508
459
    """Register a global option."""
509
460
    Option.OPTIONS[name] = Option(name, **kwargs)
541
492
            _verbosity_level = -1
542
493
 
543
494
 
 
495
class MergeTypeRegistry(_mod_registry.Registry):
 
496
 
 
497
    pass
 
498
 
 
499
 
 
500
_merge_type_registry = MergeTypeRegistry()
 
501
_merge_type_registry.register_lazy('merge3', 'bzrlib.merge', 'Merge3Merger',
 
502
                                   "Native diff3-style merge")
 
503
_merge_type_registry.register_lazy('diff3', 'bzrlib.merge', 'Diff3Merger',
 
504
                                   "Merge using external diff3")
 
505
_merge_type_registry.register_lazy('weave', 'bzrlib.merge', 'WeaveMerger',
 
506
                                   "Weave-based merge")
 
507
_merge_type_registry.register_lazy('lca', 'bzrlib.merge', 'LCAMerger',
 
508
                                   "LCA-newness merge")
 
509
 
544
510
# Declare the standard options
545
511
_standard_option('help', short_name='h',
546
512
                 help='Show help message.')
547
 
_standard_option('quiet', short_name='q',
548
 
                 help="Only display errors and warnings.",
549
 
                 custom_callback=_verbosity_level_callback)
550
513
_standard_option('usage',
551
514
                 help='Show usage message and options.')
552
515
_standard_option('verbose', short_name='v',
553
516
                 help='Display more information.',
554
517
                 custom_callback=_verbosity_level_callback)
 
518
_standard_option('quiet', short_name='q',
 
519
                 help="Only display errors and warnings.",
 
520
                 custom_callback=_verbosity_level_callback)
555
521
 
556
522
# Declare commonly used options
557
 
_global_option('change',
558
 
               type=_parse_change_str,
559
 
               short_name='c',
560
 
               param_name='revision',
561
 
               help='Select changes introduced by the specified revision. See also "help revisionspec".')
562
 
_global_option('directory', short_name='d', type=str,
563
 
               help='Branch to operate on, instead of working directory.')
564
 
_global_option('file', type=str, short_name='F')
565
 
_global_registry_option('log-format', "Use specified log format.",
566
 
                        lazy_registry=('breezy.log', 'log_formatter_registry'),
567
 
                        value_switches=True, title='Log format',
568
 
                        short_value_switches={'short': 'S'})
569
 
_global_registry_option('merge-type', 'Select a particular merge algorithm.',
570
 
                        lazy_registry=('breezy.merge', 'merge_type_registry'),
571
 
                        value_switches=True, title='Merge algorithm')
572
 
_global_option('message', type=str,
 
523
_global_option('all')
 
524
_global_option('overwrite', help='Ignore differences between branches and '
 
525
               'overwrite unconditionally.')
 
526
_global_option('basis', type=str)
 
527
_global_option('bound')
 
528
_global_option('diff-options', type=str)
 
529
_global_option('file', type=unicode, short_name='F')
 
530
_global_option('force')
 
531
_global_option('format', type=unicode)
 
532
_global_option('forward')
 
533
_global_option('message', type=unicode,
573
534
               short_name='m',
574
535
               help='Message string.')
575
 
_global_option('null', short_name='0',
576
 
               help='Use an ASCII NUL (\\0) separator rather than '
577
 
               'a newline.')
578
 
_global_option('overwrite', help='Ignore differences between branches and '
579
 
               'overwrite unconditionally.')
580
 
_global_option('remember', help='Remember the specified location as a'
581
 
               ' default.')
582
 
_global_option('reprocess', help='Reprocess to reduce spurious conflicts.')
 
536
_global_option('no-recurse')
 
537
_global_option('profile',
 
538
               help='Show performance profiling information.')
583
539
_global_option('revision',
584
540
               type=_parse_revision_str,
585
541
               short_name='r',
586
542
               help='See "help revisionspec" for details.')
 
543
_global_option('change',
 
544
               type=_parse_change_str,
 
545
               short_name='c',
 
546
               param_name='revision',
 
547
               help='Select changes introduced by the specified revision. See also "help revisionspec".')
587
548
_global_option('show-ids',
588
549
               help='Show internal object ids.')
589
550
_global_option('timezone',
590
551
               type=str,
591
552
               help='Display timezone as local, original, or utc.')
 
553
_global_option('unbound')
 
554
_global_option('version')
 
555
_global_option('email')
 
556
_global_option('update')
 
557
_global_registry_option('log-format', "Use specified log format.",
 
558
                        lazy_registry=('bzrlib.log', 'log_formatter_registry'),
 
559
                        value_switches=True, title='Log format')
 
560
_global_option('long', help='Use detailed log format. Same as --log-format long',
 
561
               short_name='l')
 
562
_global_option('short', help='Use moderately short log format. Same as --log-format short')
 
563
_global_option('line', help='Use log format with one line per revision. Same as --log-format line')
 
564
_global_option('root', type=str)
 
565
_global_option('no-backup')
 
566
_global_registry_option('merge-type', 'Select a particular merge algorithm.',
 
567
                        _merge_type_registry, value_switches=True,
 
568
                        title='Merge algorithm')
 
569
_global_option('pattern', type=str)
 
570
_global_option('remember', help='Remember the specified location as a'
 
571
               ' default.')
 
572
_global_option('reprocess', help='Reprocess to reduce spurious conflicts.')
 
573
_global_option('kind', type=str)
 
574
_global_option('dry-run',
 
575
               help="Show what would be done, but don't actually do anything.")
 
576
_global_option('name-from-revision', help='The path name in the old tree.')
592
577
 
593
578
diff_writer_registry = _mod_registry.Registry()
594
579
diff_writer_registry.register('plain', lambda x: x, 'Plaintext diff output.')