~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

(jameinel) Fix bug #397739,
 resolve 'lp:foo' locally as long as we have a launchpad-login to use
 bzr+ssh. (John A Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
3
#            and others
4
4
#
65
65
import os
66
66
import sys
67
67
 
 
68
from bzrlib import commands
 
69
from bzrlib.decorators import needs_write_lock
68
70
from bzrlib.lazy_import import lazy_import
69
71
lazy_import(globals(), """
70
72
import errno
71
 
from fnmatch import fnmatch
 
73
import fnmatch
72
74
import re
73
75
from cStringIO import StringIO
74
76
 
75
77
import bzrlib
76
78
from bzrlib import (
 
79
    atomicfile,
 
80
    bzrdir,
77
81
    debug,
78
82
    errors,
 
83
    lockdir,
79
84
    mail_client,
 
85
    mergetools,
80
86
    osutils,
81
87
    registry,
82
88
    symbol_versioning,
83
89
    trace,
 
90
    transport,
84
91
    ui,
85
92
    urlutils,
86
93
    win32utils,
122
129
STORE_BRANCH = 3
123
130
STORE_GLOBAL = 4
124
131
 
125
 
_ConfigObj = None
126
 
def ConfigObj(*args, **kwargs):
127
 
    global _ConfigObj
128
 
    if _ConfigObj is None:
129
 
        class ConfigObj(configobj.ConfigObj):
130
 
 
131
 
            def get_bool(self, section, key):
132
 
                return self[section].as_bool(key)
133
 
 
134
 
            def get_value(self, section, name):
135
 
                # Try [] for the old DEFAULT section.
136
 
                if section == "DEFAULT":
137
 
                    try:
138
 
                        return self[name]
139
 
                    except KeyError:
140
 
                        pass
141
 
                return self[section][name]
142
 
        _ConfigObj = ConfigObj
143
 
    return _ConfigObj(*args, **kwargs)
 
132
 
 
133
class ConfigObj(configobj.ConfigObj):
 
134
 
 
135
    def __init__(self, infile=None, **kwargs):
 
136
        # We define our own interpolation mechanism calling it option expansion
 
137
        super(ConfigObj, self).__init__(infile=infile,
 
138
                                        interpolation=False,
 
139
                                        **kwargs)
 
140
 
 
141
 
 
142
    def get_bool(self, section, key):
 
143
        return self[section].as_bool(key)
 
144
 
 
145
    def get_value(self, section, name):
 
146
        # Try [] for the old DEFAULT section.
 
147
        if section == "DEFAULT":
 
148
            try:
 
149
                return self[name]
 
150
            except KeyError:
 
151
                pass
 
152
        return self[section][name]
 
153
 
 
154
 
 
155
# FIXME: Until we can guarantee that each config file is loaded once and and
 
156
# only once for a given bzrlib session, we don't want to re-read the file every
 
157
# time we query for an option so we cache the value (bad ! watch out for tests
 
158
# needing to restore the proper value).This shouldn't be part of 2.4.0 final,
 
159
# yell at mgz^W vila and the RM if this is still present at that time
 
160
# -- vila 20110219
 
161
_expand_default_value = None
 
162
def _get_expand_default_value():
 
163
    global _expand_default_value
 
164
    if _expand_default_value is not None:
 
165
        return _expand_default_value
 
166
    conf = GlobalConfig()
 
167
    # Note that we must not use None for the expand value below or we'll run
 
168
    # into infinite recursion. Using False really would be quite silly ;)
 
169
    expand = conf.get_user_option_as_bool('bzr.config.expand', expand=True)
 
170
    if expand is None:
 
171
        # This is an opt-in feature, you *really* need to clearly say you want
 
172
        # to activate it !
 
173
        expand = False
 
174
    _expand_default_value = expand
 
175
    return expand
144
176
 
145
177
 
146
178
class Config(object):
149
181
    def __init__(self):
150
182
        super(Config, self).__init__()
151
183
 
 
184
    def config_id(self):
 
185
        """Returns a unique ID for the config."""
 
186
        raise NotImplementedError(self.config_id)
 
187
 
152
188
    def get_editor(self):
153
189
        """Get the users pop up editor."""
154
190
        raise NotImplementedError
178
214
    def _get_signing_policy(self):
179
215
        """Template method to override signature creation policy."""
180
216
 
 
217
    option_ref_re = None
 
218
 
 
219
    def expand_options(self, string, env=None):
 
220
        """Expand option references in the string in the configuration context.
 
221
 
 
222
        :param string: The string containing option to expand.
 
223
 
 
224
        :param env: An option dict defining additional configuration options or
 
225
            overriding existing ones.
 
226
 
 
227
        :returns: The expanded string.
 
228
        """
 
229
        return self._expand_options_in_string(string, env)
 
230
 
 
231
    def _expand_options_in_list(self, slist, env=None, _ref_stack=None):
 
232
        """Expand options in  a list of strings in the configuration context.
 
233
 
 
234
        :param slist: A list of strings.
 
235
 
 
236
        :param env: An option dict defining additional configuration options or
 
237
            overriding existing ones.
 
238
 
 
239
        :param _ref_stack: Private list containing the options being
 
240
            expanded to detect loops.
 
241
 
 
242
        :returns: The flatten list of expanded strings.
 
243
        """
 
244
        # expand options in each value separately flattening lists
 
245
        result = []
 
246
        for s in slist:
 
247
            value = self._expand_options_in_string(s, env, _ref_stack)
 
248
            if isinstance(value, list):
 
249
                result.extend(value)
 
250
            else:
 
251
                result.append(value)
 
252
        return result
 
253
 
 
254
    def _expand_options_in_string(self, string, env=None, _ref_stack=None):
 
255
        """Expand options in the string in the configuration context.
 
256
 
 
257
        :param string: The string to be expanded.
 
258
 
 
259
        :param env: An option dict defining additional configuration options or
 
260
            overriding existing ones.
 
261
 
 
262
        :param _ref_stack: Private list containing the options being
 
263
            expanded to detect loops.
 
264
 
 
265
        :returns: The expanded string.
 
266
        """
 
267
        if string is None:
 
268
            # Not much to expand there
 
269
            return None
 
270
        if _ref_stack is None:
 
271
            # What references are currently resolved (to detect loops)
 
272
            _ref_stack = []
 
273
        if self.option_ref_re is None:
 
274
            # We want to match the most embedded reference first (i.e. for
 
275
            # '{{foo}}' we will get '{foo}',
 
276
            # for '{bar{baz}}' we will get '{baz}'
 
277
            self.option_ref_re = re.compile('({[^{}]+})')
 
278
        result = string
 
279
        # We need to iterate until no more refs appear ({{foo}} will need two
 
280
        # iterations for example).
 
281
        while True:
 
282
            try:
 
283
                raw_chunks = self.option_ref_re.split(result)
 
284
            except TypeError:
 
285
                import pdb; pdb.set_trace()
 
286
            if len(raw_chunks) == 1:
 
287
                # Shorcut the trivial case: no refs
 
288
                return result
 
289
            chunks = []
 
290
            list_value = False
 
291
            # Split will isolate refs so that every other chunk is a ref
 
292
            chunk_is_ref = False
 
293
            for chunk in raw_chunks:
 
294
                if not chunk_is_ref:
 
295
                    if chunk:
 
296
                        # Keep only non-empty strings (or we get bogus empty
 
297
                        # slots when a list value is involved).
 
298
                        chunks.append(chunk)
 
299
                    chunk_is_ref = True
 
300
                else:
 
301
                    name = chunk[1:-1]
 
302
                    if name in _ref_stack:
 
303
                        raise errors.OptionExpansionLoop(string, _ref_stack)
 
304
                    _ref_stack.append(name)
 
305
                    value = self._expand_option(name, env, _ref_stack)
 
306
                    if value is None:
 
307
                        raise errors.ExpandingUnknownOption(name, string)
 
308
                    if isinstance(value, list):
 
309
                        list_value = True
 
310
                        chunks.extend(value)
 
311
                    else:
 
312
                        chunks.append(value)
 
313
                    _ref_stack.pop()
 
314
                    chunk_is_ref = False
 
315
            if list_value:
 
316
                # Once a list appears as the result of an expansion, all
 
317
                # callers will get a list result. This allows a consistent
 
318
                # behavior even when some options in the expansion chain
 
319
                # defined as strings (no comma in their value) but their
 
320
                # expanded value is a list.
 
321
                return self._expand_options_in_list(chunks, env, _ref_stack)
 
322
            else:
 
323
                result = ''.join(chunks)
 
324
        return result
 
325
 
 
326
    def _expand_option(self, name, env, _ref_stack):
 
327
        if env is not None and name in env:
 
328
            # Special case, values provided in env takes precedence over
 
329
            # anything else
 
330
            value = env[name]
 
331
        else:
 
332
            # FIXME: This is a limited implementation, what we really need is a
 
333
            # way to query the bzr config for the value of an option,
 
334
            # respecting the scope rules (That is, once we implement fallback
 
335
            # configs, getting the option value should restart from the top
 
336
            # config, not the current one) -- vila 20101222
 
337
            value = self.get_user_option(name, expand=False)
 
338
            if isinstance(value, list):
 
339
                value = self._expand_options_in_list(value, env, _ref_stack)
 
340
            else:
 
341
                value = self._expand_options_in_string(value, env, _ref_stack)
 
342
        return value
 
343
 
181
344
    def _get_user_option(self, option_name):
182
345
        """Template method to provide a user option."""
183
346
        return None
184
347
 
185
 
    def get_user_option(self, option_name):
186
 
        """Get a generic option - no special process, no default."""
187
 
        return self._get_user_option(option_name)
188
 
 
189
 
    def get_user_option_as_bool(self, option_name):
 
348
    def get_user_option(self, option_name, expand=None):
 
349
        """Get a generic option - no special process, no default.
 
350
 
 
351
        :param option_name: The queried option.
 
352
 
 
353
        :param expand: Whether options references should be expanded.
 
354
 
 
355
        :returns: The value of the option.
 
356
        """
 
357
        if expand is None:
 
358
            expand = _get_expand_default_value()
 
359
        value = self._get_user_option(option_name)
 
360
        if expand:
 
361
            if isinstance(value, list):
 
362
                value = self._expand_options_in_list(value)
 
363
            elif isinstance(value, dict):
 
364
                trace.warning('Cannot expand "%s":'
 
365
                              ' Dicts do not support option expansion'
 
366
                              % (option_name,))
 
367
            else:
 
368
                value = self._expand_options_in_string(value)
 
369
        return value
 
370
 
 
371
    def get_user_option_as_bool(self, option_name, expand=None):
190
372
        """Get a generic option as a boolean - no special process, no default.
191
373
 
192
374
        :return None if the option doesn't exist or its value can't be
193
375
            interpreted as a boolean. Returns True or False otherwise.
194
376
        """
195
 
        s = self._get_user_option(option_name)
 
377
        s = self.get_user_option(option_name, expand=expand)
196
378
        if s is None:
197
379
            # The option doesn't exist
198
380
            return None
203
385
                          s, option_name)
204
386
        return val
205
387
 
206
 
    def get_user_option_as_list(self, option_name):
 
388
    def get_user_option_as_list(self, option_name, expand=None):
207
389
        """Get a generic option as a list - no special process, no default.
208
390
 
209
391
        :return None if the option doesn't exist. Returns the value as a list
210
392
            otherwise.
211
393
        """
212
 
        l = self._get_user_option(option_name)
 
394
        l = self.get_user_option(option_name, expand=expand)
213
395
        if isinstance(l, (str, unicode)):
214
 
            # A single value, most probably the user forgot the final ','
 
396
            # A single value, most probably the user forgot (or didn't care to
 
397
            # add) the final ','
215
398
            l = [l]
216
399
        return l
217
400
 
257
440
 
258
441
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
259
442
 
260
 
        $BZR_EMAIL can be set to override this (as well as the
261
 
        deprecated $BZREMAIL), then
 
443
        $BZR_EMAIL can be set to override this, then
262
444
        the concrete policy type is checked, and finally
263
445
        $EMAIL is examined.
264
 
        If none is found, a reasonable default is (hopefully)
265
 
        created.
 
446
        If no username can be found, errors.NoWhoami exception is raised.
266
447
 
267
448
        TODO: Check it's reasonably well-formed.
268
449
        """
278
459
        if v:
279
460
            return v.decode(osutils.get_user_encoding())
280
461
 
281
 
        name, email = _auto_user_id()
282
 
        if name:
283
 
            return '%s <%s>' % (name, email)
284
 
        else:
285
 
            return email
 
462
        raise errors.NoWhoami()
 
463
 
 
464
    def ensure_username(self):
 
465
        """Raise errors.NoWhoami if username is not set.
 
466
 
 
467
        This method relies on the username() function raising the error.
 
468
        """
 
469
        self.username()
286
470
 
287
471
    def signature_checking(self):
288
472
        """What is the current policy for signature checking?."""
346
530
        else:
347
531
            return True
348
532
 
 
533
    def get_merge_tools(self):
 
534
        tools = {}
 
535
        for (oname, value, section, conf_id, parser) in self._get_options():
 
536
            if oname.startswith('bzr.mergetool.'):
 
537
                tool_name = oname[len('bzr.mergetool.'):]
 
538
                tools[tool_name] = value
 
539
        trace.mutter('loaded merge tools: %r' % tools)
 
540
        return tools
 
541
 
 
542
    def find_merge_tool(self, name):
 
543
        # We fake a defaults mechanism here by checking if the given name can 
 
544
        # be found in the known_merge_tools if it's not found in the config.
 
545
        # This should be done through the proposed config defaults mechanism
 
546
        # when it becomes available in the future.
 
547
        command_line = (self.get_user_option('bzr.mergetool.%s' % name,
 
548
                                             expand=False)
 
549
                        or mergetools.known_merge_tools.get(name, None))
 
550
        return command_line
 
551
 
349
552
 
350
553
class IniBasedConfig(Config):
351
554
    """A configuration policy that draws from ini files."""
352
555
 
353
 
    def __init__(self, get_filename):
 
556
    def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
 
557
                 file_name=None):
 
558
        """Base class for configuration files using an ini-like syntax.
 
559
 
 
560
        :param file_name: The configuration file path.
 
561
        """
354
562
        super(IniBasedConfig, self).__init__()
355
 
        self._get_filename = get_filename
 
563
        self.file_name = file_name
 
564
        if symbol_versioning.deprecated_passed(get_filename):
 
565
            symbol_versioning.warn(
 
566
                'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
 
567
                ' Use file_name instead.',
 
568
                DeprecationWarning,
 
569
                stacklevel=2)
 
570
            if get_filename is not None:
 
571
                self.file_name = get_filename()
 
572
        else:
 
573
            self.file_name = file_name
 
574
        self._content = None
356
575
        self._parser = None
357
576
 
358
 
    def _get_parser(self, file=None):
 
577
    @classmethod
 
578
    def from_string(cls, str_or_unicode, file_name=None, save=False):
 
579
        """Create a config object from a string.
 
580
 
 
581
        :param str_or_unicode: A string representing the file content. This will
 
582
            be utf-8 encoded.
 
583
 
 
584
        :param file_name: The configuration file path.
 
585
 
 
586
        :param _save: Whether the file should be saved upon creation.
 
587
        """
 
588
        conf = cls(file_name=file_name)
 
589
        conf._create_from_string(str_or_unicode, save)
 
590
        return conf
 
591
 
 
592
    def _create_from_string(self, str_or_unicode, save):
 
593
        self._content = StringIO(str_or_unicode.encode('utf-8'))
 
594
        # Some tests use in-memory configs, some other always need the config
 
595
        # file to exist on disk.
 
596
        if save:
 
597
            self._write_config_file()
 
598
 
 
599
    def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
359
600
        if self._parser is not None:
360
601
            return self._parser
361
 
        if file is None:
362
 
            input = self._get_filename()
 
602
        if symbol_versioning.deprecated_passed(file):
 
603
            symbol_versioning.warn(
 
604
                'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
 
605
                ' Use IniBasedConfig(_content=xxx) instead.',
 
606
                DeprecationWarning,
 
607
                stacklevel=2)
 
608
        if self._content is not None:
 
609
            co_input = self._content
 
610
        elif self.file_name is None:
 
611
            raise AssertionError('We have no content to create the config')
363
612
        else:
364
 
            input = file
 
613
            co_input = self.file_name
365
614
        try:
366
 
            self._parser = ConfigObj(input, encoding='utf-8')
 
615
            self._parser = ConfigObj(co_input, encoding='utf-8')
367
616
        except configobj.ConfigObjError, e:
368
617
            raise errors.ParseConfigError(e.errors, e.config.filename)
 
618
        # Make sure self.reload() will use the right file name
 
619
        self._parser.filename = self.file_name
369
620
        return self._parser
370
621
 
 
622
    def reload(self):
 
623
        """Reload the config file from disk."""
 
624
        if self.file_name is None:
 
625
            raise AssertionError('We need a file name to reload the config')
 
626
        if self._parser is not None:
 
627
            self._parser.reload()
 
628
 
371
629
    def _get_matching_sections(self):
372
630
        """Return an ordered list of (section_name, extra_path) pairs.
373
631
 
384
642
        """Override this to define the section used by the config."""
385
643
        return "DEFAULT"
386
644
 
 
645
    def _get_sections(self, name=None):
 
646
        """Returns an iterator of the sections specified by ``name``.
 
647
 
 
648
        :param name: The section name. If None is supplied, the default
 
649
            configurations are yielded.
 
650
 
 
651
        :return: A tuple (name, section, config_id) for all sections that will
 
652
            be walked by user_get_option() in the 'right' order. The first one
 
653
            is where set_user_option() will update the value.
 
654
        """
 
655
        parser = self._get_parser()
 
656
        if name is not None:
 
657
            yield (name, parser[name], self.config_id())
 
658
        else:
 
659
            # No section name has been given so we fallback to the configobj
 
660
            # itself which holds the variables defined outside of any section.
 
661
            yield (None, parser, self.config_id())
 
662
 
 
663
    def _get_options(self, sections=None):
 
664
        """Return an ordered list of (name, value, section, config_id) tuples.
 
665
 
 
666
        All options are returned with their associated value and the section
 
667
        they appeared in. ``config_id`` is a unique identifier for the
 
668
        configuration file the option is defined in.
 
669
 
 
670
        :param sections: Default to ``_get_matching_sections`` if not
 
671
            specified. This gives a better control to daughter classes about
 
672
            which sections should be searched. This is a list of (name,
 
673
            configobj) tuples.
 
674
        """
 
675
        opts = []
 
676
        if sections is None:
 
677
            parser = self._get_parser()
 
678
            sections = []
 
679
            for (section_name, _) in self._get_matching_sections():
 
680
                try:
 
681
                    section = parser[section_name]
 
682
                except KeyError:
 
683
                    # This could happen for an empty file for which we define a
 
684
                    # DEFAULT section. FIXME: Force callers to provide sections
 
685
                    # instead ? -- vila 20100930
 
686
                    continue
 
687
                sections.append((section_name, section))
 
688
        config_id = self.config_id()
 
689
        for (section_name, section) in sections:
 
690
            for (name, value) in section.iteritems():
 
691
                yield (name, parser._quote(value), section_name,
 
692
                       config_id, parser)
 
693
 
387
694
    def _get_option_policy(self, section, option_name):
388
695
        """Return the policy for the given (section, option_name) pair."""
389
696
        return POLICY_NONE
476
783
    def _get_nickname(self):
477
784
        return self.get_user_option('nickname')
478
785
 
479
 
 
480
 
class GlobalConfig(IniBasedConfig):
 
786
    def remove_user_option(self, option_name, section_name=None):
 
787
        """Remove a user option and save the configuration file.
 
788
 
 
789
        :param option_name: The option to be removed.
 
790
 
 
791
        :param section_name: The section the option is defined in, default to
 
792
            the default section.
 
793
        """
 
794
        self.reload()
 
795
        parser = self._get_parser()
 
796
        if section_name is None:
 
797
            section = parser
 
798
        else:
 
799
            section = parser[section_name]
 
800
        try:
 
801
            del section[option_name]
 
802
        except KeyError:
 
803
            raise errors.NoSuchConfigOption(option_name)
 
804
        self._write_config_file()
 
805
 
 
806
    def _write_config_file(self):
 
807
        if self.file_name is None:
 
808
            raise AssertionError('We cannot save, self.file_name is None')
 
809
        conf_dir = os.path.dirname(self.file_name)
 
810
        ensure_config_dir_exists(conf_dir)
 
811
        atomic_file = atomicfile.AtomicFile(self.file_name)
 
812
        self._get_parser().write(atomic_file)
 
813
        atomic_file.commit()
 
814
        atomic_file.close()
 
815
        osutils.copy_ownership_from_path(self.file_name)
 
816
 
 
817
 
 
818
class LockableConfig(IniBasedConfig):
 
819
    """A configuration needing explicit locking for access.
 
820
 
 
821
    If several processes try to write the config file, the accesses need to be
 
822
    serialized.
 
823
 
 
824
    Daughter classes should decorate all methods that update a config with the
 
825
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
 
826
    ``_write_config_file()`` method. These methods (typically ``set_option()``
 
827
    and variants must reload the config file from disk before calling
 
828
    ``_write_config_file()``), this can be achieved by calling the
 
829
    ``self.reload()`` method. Note that the lock scope should cover both the
 
830
    reading and the writing of the config file which is why the decorator can't
 
831
    be applied to ``_write_config_file()`` only.
 
832
 
 
833
    This should be enough to implement the following logic:
 
834
    - lock for exclusive write access,
 
835
    - reload the config file from disk,
 
836
    - set the new value
 
837
    - unlock
 
838
 
 
839
    This logic guarantees that a writer can update a value without erasing an
 
840
    update made by another writer.
 
841
    """
 
842
 
 
843
    lock_name = 'lock'
 
844
 
 
845
    def __init__(self, file_name):
 
846
        super(LockableConfig, self).__init__(file_name=file_name)
 
847
        self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
 
848
        # FIXME: It doesn't matter that we don't provide possible_transports
 
849
        # below since this is currently used only for local config files ;
 
850
        # local transports are not shared. But if/when we start using
 
851
        # LockableConfig for other kind of transports, we will need to reuse
 
852
        # whatever connection is already established -- vila 20100929
 
853
        self.transport = transport.get_transport(self.dir)
 
854
        self._lock = lockdir.LockDir(self.transport, 'lock')
 
855
 
 
856
    def _create_from_string(self, unicode_bytes, save):
 
857
        super(LockableConfig, self)._create_from_string(unicode_bytes, False)
 
858
        if save:
 
859
            # We need to handle the saving here (as opposed to IniBasedConfig)
 
860
            # to be able to lock
 
861
            self.lock_write()
 
862
            self._write_config_file()
 
863
            self.unlock()
 
864
 
 
865
    def lock_write(self, token=None):
 
866
        """Takes a write lock in the directory containing the config file.
 
867
 
 
868
        If the directory doesn't exist it is created.
 
869
        """
 
870
        ensure_config_dir_exists(self.dir)
 
871
        return self._lock.lock_write(token)
 
872
 
 
873
    def unlock(self):
 
874
        self._lock.unlock()
 
875
 
 
876
    def break_lock(self):
 
877
        self._lock.break_lock()
 
878
 
 
879
    @needs_write_lock
 
880
    def remove_user_option(self, option_name, section_name=None):
 
881
        super(LockableConfig, self).remove_user_option(option_name,
 
882
                                                       section_name)
 
883
 
 
884
    def _write_config_file(self):
 
885
        if self._lock is None or not self._lock.is_held:
 
886
            # NB: if the following exception is raised it probably means a
 
887
            # missing @needs_write_lock decorator on one of the callers.
 
888
            raise errors.ObjectNotLocked(self)
 
889
        super(LockableConfig, self)._write_config_file()
 
890
 
 
891
 
 
892
class GlobalConfig(LockableConfig):
481
893
    """The configuration that should be used for a specific location."""
482
894
 
 
895
    def __init__(self):
 
896
        super(GlobalConfig, self).__init__(file_name=config_filename())
 
897
 
 
898
    def config_id(self):
 
899
        return 'bazaar'
 
900
 
 
901
    @classmethod
 
902
    def from_string(cls, str_or_unicode, save=False):
 
903
        """Create a config object from a string.
 
904
 
 
905
        :param str_or_unicode: A string representing the file content. This
 
906
            will be utf-8 encoded.
 
907
 
 
908
        :param save: Whether the file should be saved upon creation.
 
909
        """
 
910
        conf = cls()
 
911
        conf._create_from_string(str_or_unicode, save)
 
912
        return conf
 
913
 
483
914
    def get_editor(self):
484
915
        return self._get_user_option('editor')
485
916
 
486
 
    def __init__(self):
487
 
        super(GlobalConfig, self).__init__(config_filename)
488
 
 
 
917
    @needs_write_lock
489
918
    def set_user_option(self, option, value):
490
919
        """Save option and its value in the configuration."""
491
920
        self._set_option(option, value, 'DEFAULT')
497
926
        else:
498
927
            return {}
499
928
 
 
929
    @needs_write_lock
500
930
    def set_alias(self, alias_name, alias_command):
501
931
        """Save the alias in the configuration."""
502
932
        self._set_option(alias_name, alias_command, 'ALIASES')
503
933
 
 
934
    @needs_write_lock
504
935
    def unset_alias(self, alias_name):
505
936
        """Unset an existing alias."""
 
937
        self.reload()
506
938
        aliases = self._get_parser().get('ALIASES')
507
939
        if not aliases or alias_name not in aliases:
508
940
            raise errors.NoSuchAlias(alias_name)
510
942
        self._write_config_file()
511
943
 
512
944
    def _set_option(self, option, value, section):
513
 
        # FIXME: RBC 20051029 This should refresh the parser and also take a
514
 
        # file lock on bazaar.conf.
515
 
        conf_dir = os.path.dirname(self._get_filename())
516
 
        ensure_config_dir_exists(conf_dir)
 
945
        self.reload()
517
946
        self._get_parser().setdefault(section, {})[option] = value
518
947
        self._write_config_file()
519
948
 
520
 
    def _write_config_file(self):
521
 
        path = self._get_filename()
522
 
        f = open(path, 'wb')
523
 
        osutils.copy_ownership_from_path(path)
524
 
        self._get_parser().write(f)
525
 
        f.close()
526
 
 
527
 
 
528
 
class LocationConfig(IniBasedConfig):
 
949
 
 
950
    def _get_sections(self, name=None):
 
951
        """See IniBasedConfig._get_sections()."""
 
952
        parser = self._get_parser()
 
953
        # We don't give access to options defined outside of any section, we
 
954
        # used the DEFAULT section by... default.
 
955
        if name in (None, 'DEFAULT'):
 
956
            # This could happen for an empty file where the DEFAULT section
 
957
            # doesn't exist yet. So we force DEFAULT when yielding
 
958
            name = 'DEFAULT'
 
959
            if 'DEFAULT' not in parser:
 
960
               parser['DEFAULT']= {}
 
961
        yield (name, parser[name], self.config_id())
 
962
 
 
963
    @needs_write_lock
 
964
    def remove_user_option(self, option_name, section_name=None):
 
965
        if section_name is None:
 
966
            # We need to force the default section.
 
967
            section_name = 'DEFAULT'
 
968
        # We need to avoid the LockableConfig implementation or we'll lock
 
969
        # twice
 
970
        super(LockableConfig, self).remove_user_option(option_name,
 
971
                                                       section_name)
 
972
 
 
973
 
 
974
class LocationConfig(LockableConfig):
529
975
    """A configuration object that gives the policy for a location."""
530
976
 
531
977
    def __init__(self, location):
532
 
        name_generator = locations_config_filename
533
 
        if (not os.path.exists(name_generator()) and
534
 
                os.path.exists(branches_config_filename())):
535
 
            if sys.platform == 'win32':
536
 
                trace.warning('Please rename %s to %s'
537
 
                              % (branches_config_filename(),
538
 
                                 locations_config_filename()))
539
 
            else:
540
 
                trace.warning('Please rename ~/.bazaar/branches.conf'
541
 
                              ' to ~/.bazaar/locations.conf')
542
 
            name_generator = branches_config_filename
543
 
        super(LocationConfig, self).__init__(name_generator)
 
978
        super(LocationConfig, self).__init__(
 
979
            file_name=locations_config_filename())
544
980
        # local file locations are looked up by local path, rather than
545
981
        # by file url. This is because the config file is a user
546
982
        # file, and we would rather not expose the user to file urls.
548
984
            location = urlutils.local_path_from_url(location)
549
985
        self.location = location
550
986
 
 
987
    def config_id(self):
 
988
        return 'locations'
 
989
 
 
990
    @classmethod
 
991
    def from_string(cls, str_or_unicode, location, save=False):
 
992
        """Create a config object from a string.
 
993
 
 
994
        :param str_or_unicode: A string representing the file content. This will
 
995
            be utf-8 encoded.
 
996
 
 
997
        :param location: The location url to filter the configuration.
 
998
 
 
999
        :param save: Whether the file should be saved upon creation.
 
1000
        """
 
1001
        conf = cls(location)
 
1002
        conf._create_from_string(str_or_unicode, save)
 
1003
        return conf
 
1004
 
551
1005
    def _get_matching_sections(self):
552
1006
        """Return an ordered list of section names matching this location."""
553
1007
        sections = self._get_parser()
570
1024
            names = zip(location_names, section_names)
571
1025
            matched = True
572
1026
            for name in names:
573
 
                if not fnmatch(name[0], name[1]):
 
1027
                if not fnmatch.fnmatch(name[0], name[1]):
574
1028
                    matched = False
575
1029
                    break
576
1030
            if not matched:
581
1035
                continue
582
1036
            matches.append((len(section_names), section,
583
1037
                            '/'.join(location_names[len(section_names):])))
 
1038
        # put the longest (aka more specific) locations first
584
1039
        matches.sort(reverse=True)
585
1040
        sections = []
586
1041
        for (length, section, extra_path) in matches:
593
1048
                pass
594
1049
        return sections
595
1050
 
 
1051
    def _get_sections(self, name=None):
 
1052
        """See IniBasedConfig._get_sections()."""
 
1053
        # We ignore the name here as the only sections handled are named with
 
1054
        # the location path and we don't expose embedded sections either.
 
1055
        parser = self._get_parser()
 
1056
        for name, extra_path in self._get_matching_sections():
 
1057
            yield (name, parser[name], self.config_id())
 
1058
 
596
1059
    def _get_option_policy(self, section, option_name):
597
1060
        """Return the policy for the given (section, option_name) pair."""
598
1061
        # check for the old 'recurse=False' flag
641
1104
            if policy_key in self._get_parser()[section]:
642
1105
                del self._get_parser()[section][policy_key]
643
1106
 
 
1107
    @needs_write_lock
644
1108
    def set_user_option(self, option, value, store=STORE_LOCATION):
645
1109
        """Save option and its value in the configuration."""
646
1110
        if store not in [STORE_LOCATION,
648
1112
                         STORE_LOCATION_APPENDPATH]:
649
1113
            raise ValueError('bad storage policy %r for %r' %
650
1114
                (store, option))
651
 
        # FIXME: RBC 20051029 This should refresh the parser and also take a
652
 
        # file lock on locations.conf.
653
 
        conf_dir = os.path.dirname(self._get_filename())
654
 
        ensure_config_dir_exists(conf_dir)
 
1115
        self.reload()
655
1116
        location = self.location
656
1117
        if location.endswith('/'):
657
1118
            location = location[:-1]
658
 
        if (not location in self._get_parser() and
659
 
            not location + '/' in self._get_parser()):
660
 
            self._get_parser()[location]={}
661
 
        elif location + '/' in self._get_parser():
 
1119
        parser = self._get_parser()
 
1120
        if not location in parser and not location + '/' in parser:
 
1121
            parser[location] = {}
 
1122
        elif location + '/' in parser:
662
1123
            location = location + '/'
663
 
        self._get_parser()[location][option]=value
 
1124
        parser[location][option]=value
664
1125
        # the allowed values of store match the config policies
665
1126
        self._set_option_policy(location, option, store)
666
 
        self._get_parser().write(file(self._get_filename(), 'wb'))
 
1127
        self._write_config_file()
667
1128
 
668
1129
 
669
1130
class BranchConfig(Config):
670
1131
    """A configuration object giving the policy for a branch."""
671
1132
 
 
1133
    def __init__(self, branch):
 
1134
        super(BranchConfig, self).__init__()
 
1135
        self._location_config = None
 
1136
        self._branch_data_config = None
 
1137
        self._global_config = None
 
1138
        self.branch = branch
 
1139
        self.option_sources = (self._get_location_config,
 
1140
                               self._get_branch_data_config,
 
1141
                               self._get_global_config)
 
1142
 
 
1143
    def config_id(self):
 
1144
        return 'branch'
 
1145
 
672
1146
    def _get_branch_data_config(self):
673
1147
        if self._branch_data_config is None:
674
1148
            self._branch_data_config = TreeConfig(self.branch)
 
1149
            self._branch_data_config.config_id = self.config_id
675
1150
        return self._branch_data_config
676
1151
 
677
1152
    def _get_location_config(self):
745
1220
                return value
746
1221
        return None
747
1222
 
 
1223
    def _get_sections(self, name=None):
 
1224
        """See IniBasedConfig.get_sections()."""
 
1225
        for source in self.option_sources:
 
1226
            for section in source()._get_sections(name):
 
1227
                yield section
 
1228
 
 
1229
    def _get_options(self, sections=None):
 
1230
        opts = []
 
1231
        # First the locations options
 
1232
        for option in self._get_location_config()._get_options():
 
1233
            yield option
 
1234
        # Then the branch options
 
1235
        branch_config = self._get_branch_data_config()
 
1236
        if sections is None:
 
1237
            sections = [('DEFAULT', branch_config._get_parser())]
 
1238
        # FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
 
1239
        # Config itself has no notion of sections :( -- vila 20101001
 
1240
        config_id = self.config_id()
 
1241
        for (section_name, section) in sections:
 
1242
            for (name, value) in section.iteritems():
 
1243
                yield (name, value, section_name,
 
1244
                       config_id, branch_config._get_parser())
 
1245
        # Then the global options
 
1246
        for option in self._get_global_config()._get_options():
 
1247
            yield option
 
1248
 
748
1249
    def set_user_option(self, name, value, store=STORE_BRANCH,
749
1250
        warn_masked=False):
750
1251
        if store == STORE_BRANCH:
768
1269
                        trace.warning('Value "%s" is masked by "%s" from'
769
1270
                                      ' branch.conf', value, mask_value)
770
1271
 
 
1272
    def remove_user_option(self, option_name, section_name=None):
 
1273
        self._get_branch_data_config().remove_option(option_name, section_name)
 
1274
 
771
1275
    def _gpg_signing_command(self):
772
1276
        """See Config.gpg_signing_command."""
773
1277
        return self._get_safe_value('_gpg_signing_command')
774
1278
 
775
 
    def __init__(self, branch):
776
 
        super(BranchConfig, self).__init__()
777
 
        self._location_config = None
778
 
        self._branch_data_config = None
779
 
        self._global_config = None
780
 
        self.branch = branch
781
 
        self.option_sources = (self._get_location_config,
782
 
                               self._get_branch_data_config,
783
 
                               self._get_global_config)
784
 
 
785
1279
    def _post_commit(self):
786
1280
        """See Config.post_commit."""
787
1281
        return self._get_safe_value('_post_commit')
817
1311
            parent_dir = os.path.dirname(path)
818
1312
            if not os.path.isdir(parent_dir):
819
1313
                trace.mutter('creating config parent directory: %r', parent_dir)
820
 
            os.mkdir(parent_dir)
 
1314
                os.mkdir(parent_dir)
821
1315
        trace.mutter('creating config directory: %r', path)
822
1316
        os.mkdir(path)
823
1317
        osutils.copy_ownership_from_path(path)
826
1320
def config_dir():
827
1321
    """Return per-user configuration directory.
828
1322
 
829
 
    By default this is ~/.bazaar/
 
1323
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
 
1324
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
 
1325
    that will be used instead.
830
1326
 
831
1327
    TODO: Global option --config-dir to override this.
832
1328
    """
833
1329
    base = os.environ.get('BZR_HOME', None)
834
1330
    if sys.platform == 'win32':
 
1331
        # environ variables on Windows are in user encoding/mbcs. So decode
 
1332
        # before using one
 
1333
        if base is not None:
 
1334
            base = base.decode('mbcs')
835
1335
        if base is None:
836
1336
            base = win32utils.get_appdata_location_unicode()
837
1337
        if base is None:
838
1338
            base = os.environ.get('HOME', None)
 
1339
            if base is not None:
 
1340
                base = base.decode('mbcs')
839
1341
        if base is None:
840
1342
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
841
1343
                                  ' or HOME set')
842
1344
        return osutils.pathjoin(base, 'bazaar', '2.0')
 
1345
    elif sys.platform == 'darwin':
 
1346
        if base is None:
 
1347
            # this takes into account $HOME
 
1348
            base = os.path.expanduser("~")
 
1349
        return osutils.pathjoin(base, '.bazaar')
843
1350
    else:
844
 
        # cygwin, linux, and darwin all have a $HOME directory
845
1351
        if base is None:
 
1352
 
 
1353
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
 
1354
            if xdg_dir is None:
 
1355
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
 
1356
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
 
1357
            if osutils.isdir(xdg_dir):
 
1358
                trace.mutter(
 
1359
                    "Using configuration in XDG directory %s." % xdg_dir)
 
1360
                return xdg_dir
 
1361
 
846
1362
            base = os.path.expanduser("~")
847
1363
        return osutils.pathjoin(base, ".bazaar")
848
1364
 
852
1368
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
853
1369
 
854
1370
 
855
 
def branches_config_filename():
856
 
    """Return per-user configuration ini file filename."""
857
 
    return osutils.pathjoin(config_dir(), 'branches.conf')
858
 
 
859
 
 
860
1371
def locations_config_filename():
861
1372
    """Return per-user configuration ini file filename."""
862
1373
    return osutils.pathjoin(config_dir(), 'locations.conf')
899
1410
        return os.path.expanduser('~/.cache')
900
1411
 
901
1412
 
902
 
def _auto_user_id():
903
 
    """Calculate automatic user identification.
904
 
 
905
 
    Returns (realname, email).
906
 
 
907
 
    Only used when none is set in the environment or the id file.
908
 
 
909
 
    This previously used the FQDN as the default domain, but that can
910
 
    be very slow on machines where DNS is broken.  So now we simply
911
 
    use the hostname.
912
 
    """
913
 
    import socket
914
 
 
915
 
    if sys.platform == 'win32':
916
 
        name = win32utils.get_user_name_unicode()
917
 
        if name is None:
918
 
            raise errors.BzrError("Cannot autodetect user name.\n"
919
 
                                  "Please, set your name with command like:\n"
920
 
                                  'bzr whoami "Your Name <name@domain.com>"')
921
 
        host = win32utils.get_host_name_unicode()
922
 
        if host is None:
923
 
            host = socket.gethostname()
924
 
        return name, (name + '@' + host)
925
 
 
926
 
    try:
927
 
        import pwd
928
 
        uid = os.getuid()
929
 
        try:
930
 
            w = pwd.getpwuid(uid)
931
 
        except KeyError:
932
 
            raise errors.BzrCommandError('Unable to determine your name.  '
933
 
                'Please use "bzr whoami" to set it.')
934
 
 
935
 
        # we try utf-8 first, because on many variants (like Linux),
936
 
        # /etc/passwd "should" be in utf-8, and because it's unlikely to give
937
 
        # false positives.  (many users will have their user encoding set to
938
 
        # latin-1, which cannot raise UnicodeError.)
939
 
        try:
940
 
            gecos = w.pw_gecos.decode('utf-8')
941
 
            encoding = 'utf-8'
942
 
        except UnicodeError:
943
 
            try:
944
 
                encoding = osutils.get_user_encoding()
945
 
                gecos = w.pw_gecos.decode(encoding)
946
 
            except UnicodeError:
947
 
                raise errors.BzrCommandError('Unable to determine your name.  '
948
 
                   'Use "bzr whoami" to set it.')
949
 
        try:
950
 
            username = w.pw_name.decode(encoding)
951
 
        except UnicodeError:
952
 
            raise errors.BzrCommandError('Unable to determine your name.  '
953
 
                'Use "bzr whoami" to set it.')
954
 
 
955
 
        comma = gecos.find(',')
956
 
        if comma == -1:
957
 
            realname = gecos
958
 
        else:
959
 
            realname = gecos[:comma]
960
 
        if not realname:
961
 
            realname = username
962
 
 
963
 
    except ImportError:
964
 
        import getpass
965
 
        try:
966
 
            user_encoding = osutils.get_user_encoding()
967
 
            realname = username = getpass.getuser().decode(user_encoding)
968
 
        except UnicodeDecodeError:
969
 
            raise errors.BzrError("Can't decode username as %s." % \
970
 
                    user_encoding)
971
 
 
972
 
    return realname, (username + '@' + socket.gethostname())
973
 
 
974
 
 
975
1413
def parse_username(username):
976
1414
    """Parse e-mail username and return a (name, address) tuple."""
977
1415
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1020
1458
 
1021
1459
    def set_option(self, value, name, section=None):
1022
1460
        """Set a per-branch configuration option"""
 
1461
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1462
        # higher levels providing the right lock -- vila 20101004
1023
1463
        self.branch.lock_write()
1024
1464
        try:
1025
1465
            self._config.set_option(value, name, section)
1026
1466
        finally:
1027
1467
            self.branch.unlock()
1028
1468
 
 
1469
    def remove_option(self, option_name, section_name=None):
 
1470
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1471
        # higher levels providing the right lock -- vila 20101004
 
1472
        self.branch.lock_write()
 
1473
        try:
 
1474
            self._config.remove_option(option_name, section_name)
 
1475
        finally:
 
1476
            self.branch.unlock()
 
1477
 
1029
1478
 
1030
1479
class AuthenticationConfig(object):
1031
1480
    """The authentication configuration file based on a ini file.
1063
1512
        """Save the config file, only tests should use it for now."""
1064
1513
        conf_dir = os.path.dirname(self._filename)
1065
1514
        ensure_config_dir_exists(conf_dir)
1066
 
        self._get_config().write(file(self._filename, 'wb'))
 
1515
        f = file(self._filename, 'wb')
 
1516
        try:
 
1517
            self._get_config().write(f)
 
1518
        finally:
 
1519
            f.close()
1067
1520
 
1068
1521
    def _set_option(self, section_name, option_name, value):
1069
1522
        """Set an authentication configuration option"""
1470
1923
    """A Config that reads/writes a config file on a Transport.
1471
1924
 
1472
1925
    It is a low-level object that considers config data to be name/value pairs
1473
 
    that may be associated with a section.  Assigning meaning to the these
1474
 
    values is done at higher levels like TreeConfig.
 
1926
    that may be associated with a section.  Assigning meaning to these values
 
1927
    is done at higher levels like TreeConfig.
1475
1928
    """
1476
1929
 
1477
1930
    def __init__(self, transport, filename):
1510
1963
            configobj.setdefault(section, {})[name] = value
1511
1964
        self._set_configobj(configobj)
1512
1965
 
 
1966
    def remove_option(self, option_name, section_name=None):
 
1967
        configobj = self._get_configobj()
 
1968
        if section_name is None:
 
1969
            del configobj[option_name]
 
1970
        else:
 
1971
            del configobj[section_name][option_name]
 
1972
        self._set_configobj(configobj)
 
1973
 
1513
1974
    def _get_config_file(self):
1514
1975
        try:
1515
1976
            return StringIO(self._transport.get_bytes(self._filename))
1517
1978
            return StringIO()
1518
1979
 
1519
1980
    def _get_configobj(self):
1520
 
        return ConfigObj(self._get_config_file(), encoding='utf-8')
 
1981
        f = self._get_config_file()
 
1982
        try:
 
1983
            return ConfigObj(f, encoding='utf-8')
 
1984
        finally:
 
1985
            f.close()
1521
1986
 
1522
1987
    def _set_configobj(self, configobj):
1523
1988
        out_file = StringIO()
1524
1989
        configobj.write(out_file)
1525
1990
        out_file.seek(0)
1526
1991
        self._transport.put_file(self._filename, out_file)
 
1992
 
 
1993
 
 
1994
class cmd_config(commands.Command):
 
1995
    __doc__ = """Display, set or remove a configuration option.
 
1996
 
 
1997
    Display the active value for a given option.
 
1998
 
 
1999
    If --all is specified, NAME is interpreted as a regular expression and all
 
2000
    matching options are displayed mentioning their scope. The active value
 
2001
    that bzr will take into account is the first one displayed for each option.
 
2002
 
 
2003
    If no NAME is given, --all .* is implied.
 
2004
 
 
2005
    Setting a value is achieved by using name=value without spaces. The value
 
2006
    is set in the most relevant scope and can be checked by displaying the
 
2007
    option again.
 
2008
    """
 
2009
 
 
2010
    takes_args = ['name?']
 
2011
 
 
2012
    takes_options = [
 
2013
        'directory',
 
2014
        # FIXME: This should be a registry option so that plugins can register
 
2015
        # their own config files (or not) -- vila 20101002
 
2016
        commands.Option('scope', help='Reduce the scope to the specified'
 
2017
                        ' configuration file',
 
2018
                        type=unicode),
 
2019
        commands.Option('all',
 
2020
            help='Display all the defined values for the matching options.',
 
2021
            ),
 
2022
        commands.Option('remove', help='Remove the option from'
 
2023
                        ' the configuration file'),
 
2024
        ]
 
2025
 
 
2026
    @commands.display_command
 
2027
    def run(self, name=None, all=False, directory=None, scope=None,
 
2028
            remove=False):
 
2029
        if directory is None:
 
2030
            directory = '.'
 
2031
        directory = urlutils.normalize_url(directory)
 
2032
        if remove and all:
 
2033
            raise errors.BzrError(
 
2034
                '--all and --remove are mutually exclusive.')
 
2035
        elif remove:
 
2036
            # Delete the option in the given scope
 
2037
            self._remove_config_option(name, directory, scope)
 
2038
        elif name is None:
 
2039
            # Defaults to all options
 
2040
            self._show_matching_options('.*', directory, scope)
 
2041
        else:
 
2042
            try:
 
2043
                name, value = name.split('=', 1)
 
2044
            except ValueError:
 
2045
                # Display the option(s) value(s)
 
2046
                if all:
 
2047
                    self._show_matching_options(name, directory, scope)
 
2048
                else:
 
2049
                    self._show_value(name, directory, scope)
 
2050
            else:
 
2051
                if all:
 
2052
                    raise errors.BzrError(
 
2053
                        'Only one option can be set.')
 
2054
                # Set the option value
 
2055
                self._set_config_option(name, value, directory, scope)
 
2056
 
 
2057
    def _get_configs(self, directory, scope=None):
 
2058
        """Iterate the configurations specified by ``directory`` and ``scope``.
 
2059
 
 
2060
        :param directory: Where the configurations are derived from.
 
2061
 
 
2062
        :param scope: A specific config to start from.
 
2063
        """
 
2064
        if scope is not None:
 
2065
            if scope == 'bazaar':
 
2066
                yield GlobalConfig()
 
2067
            elif scope == 'locations':
 
2068
                yield LocationConfig(directory)
 
2069
            elif scope == 'branch':
 
2070
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
2071
                    directory)
 
2072
                yield br.get_config()
 
2073
        else:
 
2074
            try:
 
2075
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
2076
                    directory)
 
2077
                yield br.get_config()
 
2078
            except errors.NotBranchError:
 
2079
                yield LocationConfig(directory)
 
2080
                yield GlobalConfig()
 
2081
 
 
2082
    def _show_value(self, name, directory, scope):
 
2083
        displayed = False
 
2084
        for c in self._get_configs(directory, scope):
 
2085
            if displayed:
 
2086
                break
 
2087
            for (oname, value, section, conf_id, parser) in c._get_options():
 
2088
                if name == oname:
 
2089
                    # Display only the first value and exit
 
2090
 
 
2091
                    # FIXME: We need to use get_user_option to take policies
 
2092
                    # into account and we need to make sure the option exists
 
2093
                    # too (hence the two for loops), this needs a better API
 
2094
                    # -- vila 20101117
 
2095
                    value = c.get_user_option(name)
 
2096
                    # Quote the value appropriately
 
2097
                    value = parser._quote(value)
 
2098
                    self.outf.write('%s\n' % (value,))
 
2099
                    displayed = True
 
2100
                    break
 
2101
        if not displayed:
 
2102
            raise errors.NoSuchConfigOption(name)
 
2103
 
 
2104
    def _show_matching_options(self, name, directory, scope):
 
2105
        name = re.compile(name)
 
2106
        # We want any error in the regexp to be raised *now* so we need to
 
2107
        # avoid the delay introduced by the lazy regexp.
 
2108
        name._compile_and_collapse()
 
2109
        cur_conf_id = None
 
2110
        cur_section = None
 
2111
        for c in self._get_configs(directory, scope):
 
2112
            for (oname, value, section, conf_id, parser) in c._get_options():
 
2113
                if name.search(oname):
 
2114
                    if cur_conf_id != conf_id:
 
2115
                        # Explain where the options are defined
 
2116
                        self.outf.write('%s:\n' % (conf_id,))
 
2117
                        cur_conf_id = conf_id
 
2118
                        cur_section = None
 
2119
                    if (section not in (None, 'DEFAULT')
 
2120
                        and cur_section != section):
 
2121
                        # Display the section if it's not the default (or only)
 
2122
                        # one.
 
2123
                        self.outf.write('  [%s]\n' % (section,))
 
2124
                        cur_section = section
 
2125
                    self.outf.write('  %s = %s\n' % (oname, value))
 
2126
 
 
2127
    def _set_config_option(self, name, value, directory, scope):
 
2128
        for conf in self._get_configs(directory, scope):
 
2129
            conf.set_user_option(name, value)
 
2130
            break
 
2131
        else:
 
2132
            raise errors.NoSuchConfig(scope)
 
2133
 
 
2134
    def _remove_config_option(self, name, directory, scope):
 
2135
        if name is None:
 
2136
            raise errors.BzrCommandError(
 
2137
                '--remove expects an option to remove.')
 
2138
        removed = False
 
2139
        for conf in self._get_configs(directory, scope):
 
2140
            for (section_name, section, conf_id) in conf._get_sections():
 
2141
                if scope is not None and conf_id != scope:
 
2142
                    # Not the right configuration file
 
2143
                    continue
 
2144
                if name in section:
 
2145
                    if conf_id != conf.config_id():
 
2146
                        conf = self._get_configs(directory, conf_id).next()
 
2147
                    # We use the first section in the first config where the
 
2148
                    # option is defined to remove it
 
2149
                    conf.remove_user_option(name, section_name)
 
2150
                    removed = True
 
2151
                    break
 
2152
            break
 
2153
        else:
 
2154
            raise errors.NoSuchConfig(scope)
 
2155
        if not removed:
 
2156
            raise errors.NoSuchConfigOption(name)