~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Jelmer Vernooij
  • Date: 2012-04-02 01:44:26 UTC
  • mfrom: (6518 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6519.
  • Revision ID: jelmer@samba.org-20120402014426-0o5qtysohyl006b2
merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
195
195
        return self[section][name]
196
196
 
197
197
 
198
 
# FIXME: Until we can guarantee that each config file is loaded once and
199
 
# only once for a given bzrlib session, we don't want to re-read the file every
200
 
# time we query for an option so we cache the value (bad ! watch out for tests
201
 
# needing to restore the proper value). -- vila 20110219
202
 
_expand_default_value = None
203
 
def _get_expand_default_value():
204
 
    global _expand_default_value
205
 
    if _expand_default_value is not None:
206
 
        return _expand_default_value
207
 
    conf = GlobalConfig()
208
 
    # Note that we must not use None for the expand value below or we'll run
209
 
    # into infinite recursion. Using False really would be quite silly ;)
210
 
    expand = conf.get_user_option_as_bool('bzr.config.expand', expand=True)
211
 
    if expand is None:
212
 
        # This is an opt-in feature, you *really* need to clearly say you want
213
 
        # to activate it !
214
 
        expand = False
215
 
    _expand_default_value = expand
216
 
    return expand
217
 
 
218
 
 
219
198
class Config(object):
220
199
    """A configuration policy - what username, editor, gpg needs etc."""
221
200
 
226
205
        """Returns a unique ID for the config."""
227
206
        raise NotImplementedError(self.config_id)
228
207
 
229
 
    @deprecated_method(deprecated_in((2, 4, 0)))
230
 
    def get_editor(self):
231
 
        """Get the users pop up editor."""
232
 
        raise NotImplementedError
233
 
 
234
208
    def get_change_editor(self, old_tree, new_tree):
235
209
        from bzrlib import diff
236
210
        cmd = self._get_change_editor()
373
347
        """Template method to provide a user option."""
374
348
        return None
375
349
 
376
 
    def get_user_option(self, option_name, expand=None):
 
350
    def get_user_option(self, option_name, expand=True):
377
351
        """Get a generic option - no special process, no default.
378
352
 
379
353
        :param option_name: The queried option.
382
356
 
383
357
        :returns: The value of the option.
384
358
        """
385
 
        if expand is None:
386
 
            expand = _get_expand_default_value()
387
359
        value = self._get_user_option(option_name)
388
360
        if expand:
389
361
            if isinstance(value, list):
637
609
        for (oname, value, section, conf_id, parser) in self._get_options():
638
610
            if oname.startswith('bzr.mergetool.'):
639
611
                tool_name = oname[len('bzr.mergetool.'):]
640
 
                tools[tool_name] = self.get_user_option(oname)
 
612
                tools[tool_name] = self.get_user_option(oname, False)
641
613
        trace.mutter('loaded merge tools: %r' % tools)
642
614
        return tools
643
615
 
1079
1051
        conf._create_from_string(str_or_unicode, save)
1080
1052
        return conf
1081
1053
 
1082
 
    @deprecated_method(deprecated_in((2, 4, 0)))
1083
 
    def get_editor(self):
1084
 
        return self._get_user_option('editor')
1085
 
 
1086
1054
    @needs_write_lock
1087
1055
    def set_user_option(self, option, value):
1088
1056
        """Save option and its value in the configuration."""
2174
2142
 
2175
2143
        It may be set to a location, or None.
2176
2144
 
2177
 
        This policy affects all branches contained by this bzrdir, except for
2178
 
        those under repositories.
 
2145
        This policy affects all branches contained by this control dir, except
 
2146
        for those under repositories.
2179
2147
        """
2180
2148
        if self._config is None:
2181
2149
            raise errors.BzrError("Cannot set configuration in %s" % self._bzrdir)
2189
2157
 
2190
2158
        This will either be a location, or None.
2191
2159
 
2192
 
        This policy affects all branches contained by this bzrdir, except for
2193
 
        those under repositories.
 
2160
        This policy affects all branches contained by this control dir, except
 
2161
        for those under repositories.
2194
2162
        """
2195
2163
        if self._config is None:
2196
2164
            return None
2435
2403
                value = self.default
2436
2404
        return value
2437
2405
 
 
2406
    def get_help_topic(self):
 
2407
        return self.name
 
2408
 
2438
2409
    def get_help_text(self, additional_see_also=None, plain=True):
2439
2410
        result = self.help
2440
2411
        from bzrlib import help_topics
2985
2956
            # Report concurrent updates in an ad-hoc way. This should only
2986
2957
            # occurs when different processes try to update the same option
2987
2958
            # which is not supported (as in: the config framework is not meant
2988
 
            # to be used a sharing mechanism).
 
2959
            # to be used as a sharing mechanism).
2989
2960
            if expected != reloaded:
2990
2961
                if actual is _DeletedOption:
2991
2962
                    actual = '<DELETED>'
3011
2982
    mutable_section_class = MutableSection
3012
2983
 
3013
2984
    def __init__(self):
3014
 
        # Which sections need to be saved
3015
 
        self.dirty_sections = []
 
2985
        # Which sections need to be saved (by section id). We use a dict here
 
2986
        # so the dirty sections can be shared by multiple callers.
 
2987
        self.dirty_sections = {}
3016
2988
 
3017
2989
    def is_loaded(self):
3018
2990
        """Returns True if the Store has been loaded.
3061
3033
        raise NotImplementedError(self.save)
3062
3034
 
3063
3035
    def _need_saving(self):
3064
 
        for s in self.dirty_sections:
 
3036
        for s in self.dirty_sections.values():
3065
3037
            if s.orig:
3066
3038
                # At least one dirty section contains a modification
3067
3039
                return True
3081
3053
        # get_mutable_section() call below.
3082
3054
        self.unload()
3083
3055
        # Apply the changes from the preserved dirty sections
3084
 
        for dirty in dirty_sections:
3085
 
            clean = self.get_mutable_section(dirty.id)
 
3056
        for section_id, dirty in dirty_sections.iteritems():
 
3057
            clean = self.get_mutable_section(section_id)
3086
3058
            clean.apply_changes(dirty, self)
3087
3059
        # Everything is clean now
3088
 
        self.dirty_sections = []
 
3060
        self.dirty_sections = {}
3089
3061
 
3090
3062
    def save_changes(self):
3091
3063
        """Saves the Store to persistent storage if changes occurred.
3171
3143
 
3172
3144
    def unload(self):
3173
3145
        self._config_obj = None
3174
 
        self.dirty_sections = []
 
3146
        self.dirty_sections = {}
3175
3147
 
3176
3148
    def _load_content(self):
3177
3149
        """Load the config file bytes.
3225
3197
        if not self._need_saving():
3226
3198
            return
3227
3199
        # Preserve the current version
3228
 
        current = self._config_obj
3229
 
        dirty_sections = list(self.dirty_sections)
 
3200
        dirty_sections = dict(self.dirty_sections.items())
3230
3201
        self.apply_changes(dirty_sections)
3231
3202
        # Save to the persistent storage
3232
3203
        self.save()
3267
3238
        except errors.NoSuchFile:
3268
3239
            # The file doesn't exist, let's pretend it was empty
3269
3240
            self._load_from_string('')
 
3241
        if section_id in self.dirty_sections:
 
3242
            # We already created a mutable section for this id
 
3243
            return self.dirty_sections[section_id]
3270
3244
        if section_id is None:
3271
3245
            section = self._config_obj
3272
3246
        else:
3273
3247
            section = self._config_obj.setdefault(section_id, {})
3274
3248
        mutable_section = self.mutable_section_class(section_id, section)
3275
3249
        # All mutable sections can become dirty
3276
 
        self.dirty_sections.append(mutable_section)
 
3250
        self.dirty_sections[section_id] = mutable_section
3277
3251
        return mutable_section
3278
3252
 
3279
3253
    def quote(self, value):
3655
3629
            for store, section in sections():
3656
3630
                yield store, section
3657
3631
 
3658
 
    def get(self, name, expand=None, convert=True):
 
3632
    def get(self, name, expand=True, convert=True):
3659
3633
        """Return the *first* option value found in the sections.
3660
3634
 
3661
3635
        This is where we guarantee that sections coming from Store are loaded
3674
3648
        :returns: The value of the option.
3675
3649
        """
3676
3650
        # FIXME: No caching of options nor sections yet -- vila 20110503
3677
 
        if expand is None:
3678
 
            expand = _get_expand_default_value()
3679
3651
        value = None
3680
3652
        found_store = None # Where the option value has been found
3681
3653
        # If the option is registered, it may provide additional info about