~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-05-06 11:40:10 UTC
  • mfrom: (3400.1.3 trivial)
  • Revision ID: pqm@pqm.ubuntu.com-20080506114010-jwclr2qtiekvawjg
Remove erroneous creation of branch-name file in cmd_branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2012 Canonical Ltd
 
1
# Copyright (C) 2005, 2007 Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
3
#            and others
4
4
#
14
14
#
15
15
# You should have received a copy of the GNU General Public License
16
16
# along with this program; if not, write to the Free Software
17
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
 
19
19
"""Configuration that affects the behaviour of Bazaar.
20
20
 
29
29
create_signatures=always|never|when-required(default)
30
30
gpg_signing_command=name-of-program
31
31
log_format=name-of-format
32
 
validate_signatures_in_log=true|false(default)
33
 
acceptable_keys=pattern1,pattern2
34
 
gpg_signing_key=amy@example.com
35
32
 
36
33
in locations.conf, you specify the url of a branch and options for it.
37
34
Wildcards may be used - * and ? as normal in shell completion. Options
40
37
[/home/robertc/source]
41
38
recurse=False|True(default)
42
39
email= as above
43
 
check_signatures= as above
 
40
check_signatures= as above 
44
41
create_signatures= as above.
45
 
validate_signatures_in_log=as above
46
 
acceptable_keys=as above
47
42
 
48
43
explanation of options
49
44
----------------------
50
45
editor - this option sets the pop up editor to use during commits.
51
46
email - this option sets the user id bzr will use when committing.
52
 
check_signatures - this option will control whether bzr will require good gpg
53
 
                   signatures, ignore them, or check them if they are
54
 
                   present.  Currently it is unused except that check_signatures
55
 
                   turns on create_signatures.
56
 
create_signatures - this option controls whether bzr will always create
57
 
                    gpg signatures or not on commits.  There is an unused
58
 
                    option which in future is expected to work if
59
 
                    branch settings require signatures.
 
47
check_signatures - this option controls whether bzr will require good gpg
 
48
                   signatures, ignore them, or check them if they are 
 
49
                   present.
 
50
create_signatures - this option controls whether bzr will always create 
 
51
                    gpg signatures, never create them, or create them if the
 
52
                    branch is configured to require them.
60
53
log_format - this option sets the default log format.  Possible values are
61
54
             long, short, line, or a plugin can register new formats.
62
 
validate_signatures_in_log - show GPG signature validity in log output
63
 
acceptable_keys - comma separated list of key patterns acceptable for
64
 
                  verify-signatures command
65
55
 
66
56
In bazaar.conf you can also define aliases in the ALIASES sections, example
67
57
 
72
62
up=pull
73
63
"""
74
64
 
75
 
from __future__ import absolute_import
76
 
from cStringIO import StringIO
77
65
import os
78
66
import sys
79
67
 
80
 
import bzrlib
81
 
from bzrlib.decorators import needs_write_lock
82
68
from bzrlib.lazy_import import lazy_import
83
69
lazy_import(globals(), """
84
 
import base64
85
 
import fnmatch
 
70
import errno
 
71
from fnmatch import fnmatch
86
72
import re
 
73
from cStringIO import StringIO
87
74
 
 
75
import bzrlib
88
76
from bzrlib import (
89
 
    atomicfile,
90
 
    controldir,
91
77
    debug,
92
 
    directory_service,
93
78
    errors,
94
 
    lazy_regex,
95
 
    library_state,
96
 
    lockdir,
97
 
    mergetools,
 
79
    mail_client,
98
80
    osutils,
99
81
    symbol_versioning,
100
82
    trace,
101
 
    transport,
102
83
    ui,
103
84
    urlutils,
104
85
    win32utils,
105
86
    )
106
 
from bzrlib.i18n import gettext
107
87
from bzrlib.util.configobj import configobj
108
88
""")
109
 
from bzrlib import (
110
 
    commands,
111
 
    hooks,
112
 
    lazy_regex,
113
 
    registry,
114
 
    )
115
 
from bzrlib.symbol_versioning import (
116
 
    deprecated_in,
117
 
    deprecated_method,
118
 
    )
119
89
 
120
90
 
121
91
CHECK_IF_POSSIBLE=0
152
122
STORE_GLOBAL = 4
153
123
 
154
124
 
155
 
def signature_policy_from_unicode(signature_string):
156
 
    """Convert a string to a signing policy."""
157
 
    if signature_string.lower() == 'check-available':
158
 
        return CHECK_IF_POSSIBLE
159
 
    if signature_string.lower() == 'ignore':
160
 
        return CHECK_NEVER
161
 
    if signature_string.lower() == 'require':
162
 
        return CHECK_ALWAYS
163
 
    raise ValueError("Invalid signatures policy '%s'"
164
 
                     % signature_string)
165
 
 
166
 
 
167
 
def signing_policy_from_unicode(signature_string):
168
 
    """Convert a string to a signing policy."""
169
 
    if signature_string.lower() == 'when-required':
170
 
        return SIGN_WHEN_REQUIRED
171
 
    if signature_string.lower() == 'never':
172
 
        return SIGN_NEVER
173
 
    if signature_string.lower() == 'always':
174
 
        return SIGN_ALWAYS
175
 
    raise ValueError("Invalid signing policy '%s'"
176
 
                     % signature_string)
177
 
 
178
 
 
179
125
class ConfigObj(configobj.ConfigObj):
180
126
 
181
 
    def __init__(self, infile=None, **kwargs):
182
 
        # We define our own interpolation mechanism calling it option expansion
183
 
        super(ConfigObj, self).__init__(infile=infile,
184
 
                                        interpolation=False,
185
 
                                        **kwargs)
186
 
 
187
127
    def get_bool(self, section, key):
188
128
        return self[section].as_bool(key)
189
129
 
200
140
class Config(object):
201
141
    """A configuration policy - what username, editor, gpg needs etc."""
202
142
 
203
 
    def __init__(self):
204
 
        super(Config, self).__init__()
205
 
 
206
 
    def config_id(self):
207
 
        """Returns a unique ID for the config."""
208
 
        raise NotImplementedError(self.config_id)
209
 
 
210
 
    def get_change_editor(self, old_tree, new_tree):
211
 
        from bzrlib import diff
212
 
        cmd = self._get_change_editor()
213
 
        if cmd is None:
214
 
            return None
215
 
        return diff.DiffFromTool.from_string(cmd, old_tree, new_tree,
216
 
                                             sys.stdout)
 
143
    def get_editor(self):
 
144
        """Get the users pop up editor."""
 
145
        raise NotImplementedError
 
146
 
 
147
    def get_mail_client(self):
 
148
        """Get a mail client to use"""
 
149
        selected_client = self.get_user_option('mail_client')
 
150
        try:
 
151
            mail_client_class = {
 
152
                None: mail_client.DefaultMail,
 
153
                # Specific clients
 
154
                'emacsclient': mail_client.EmacsMail,
 
155
                'evolution': mail_client.Evolution,
 
156
                'kmail': mail_client.KMail,
 
157
                'mutt': mail_client.Mutt,
 
158
                'thunderbird': mail_client.Thunderbird,
 
159
                # Generic options
 
160
                'default': mail_client.DefaultMail,
 
161
                'editor': mail_client.Editor,
 
162
                'mapi': mail_client.MAPIClient,
 
163
                'xdg-email': mail_client.XDGEmail,
 
164
            }[selected_client]
 
165
        except KeyError:
 
166
            raise errors.UnknownMailClient(selected_client)
 
167
        return mail_client_class(self)
217
168
 
218
169
    def _get_signature_checking(self):
219
170
        """Template method to override signature checking policy."""
221
172
    def _get_signing_policy(self):
222
173
        """Template method to override signature creation policy."""
223
174
 
224
 
    option_ref_re = None
225
 
 
226
 
    def expand_options(self, string, env=None):
227
 
        """Expand option references in the string in the configuration context.
228
 
 
229
 
        :param string: The string containing option to expand.
230
 
 
231
 
        :param env: An option dict defining additional configuration options or
232
 
            overriding existing ones.
233
 
 
234
 
        :returns: The expanded string.
235
 
        """
236
 
        return self._expand_options_in_string(string, env)
237
 
 
238
 
    def _expand_options_in_list(self, slist, env=None, _ref_stack=None):
239
 
        """Expand options in  a list of strings in the configuration context.
240
 
 
241
 
        :param slist: A list of strings.
242
 
 
243
 
        :param env: An option dict defining additional configuration options or
244
 
            overriding existing ones.
245
 
 
246
 
        :param _ref_stack: Private list containing the options being
247
 
            expanded to detect loops.
248
 
 
249
 
        :returns: The flatten list of expanded strings.
250
 
        """
251
 
        # expand options in each value separately flattening lists
252
 
        result = []
253
 
        for s in slist:
254
 
            value = self._expand_options_in_string(s, env, _ref_stack)
255
 
            if isinstance(value, list):
256
 
                result.extend(value)
257
 
            else:
258
 
                result.append(value)
259
 
        return result
260
 
 
261
 
    def _expand_options_in_string(self, string, env=None, _ref_stack=None):
262
 
        """Expand options in the string in the configuration context.
263
 
 
264
 
        :param string: The string to be expanded.
265
 
 
266
 
        :param env: An option dict defining additional configuration options or
267
 
            overriding existing ones.
268
 
 
269
 
        :param _ref_stack: Private list containing the options being
270
 
            expanded to detect loops.
271
 
 
272
 
        :returns: The expanded string.
273
 
        """
274
 
        if string is None:
275
 
            # Not much to expand there
276
 
            return None
277
 
        if _ref_stack is None:
278
 
            # What references are currently resolved (to detect loops)
279
 
            _ref_stack = []
280
 
        if self.option_ref_re is None:
281
 
            # We want to match the most embedded reference first (i.e. for
282
 
            # '{{foo}}' we will get '{foo}',
283
 
            # for '{bar{baz}}' we will get '{baz}'
284
 
            self.option_ref_re = re.compile('({[^{}]+})')
285
 
        result = string
286
 
        # We need to iterate until no more refs appear ({{foo}} will need two
287
 
        # iterations for example).
288
 
        while True:
289
 
            raw_chunks = self.option_ref_re.split(result)
290
 
            if len(raw_chunks) == 1:
291
 
                # Shorcut the trivial case: no refs
292
 
                return result
293
 
            chunks = []
294
 
            list_value = False
295
 
            # Split will isolate refs so that every other chunk is a ref
296
 
            chunk_is_ref = False
297
 
            for chunk in raw_chunks:
298
 
                if not chunk_is_ref:
299
 
                    if chunk:
300
 
                        # Keep only non-empty strings (or we get bogus empty
301
 
                        # slots when a list value is involved).
302
 
                        chunks.append(chunk)
303
 
                    chunk_is_ref = True
304
 
                else:
305
 
                    name = chunk[1:-1]
306
 
                    if name in _ref_stack:
307
 
                        raise errors.OptionExpansionLoop(string, _ref_stack)
308
 
                    _ref_stack.append(name)
309
 
                    value = self._expand_option(name, env, _ref_stack)
310
 
                    if value is None:
311
 
                        raise errors.ExpandingUnknownOption(name, string)
312
 
                    if isinstance(value, list):
313
 
                        list_value = True
314
 
                        chunks.extend(value)
315
 
                    else:
316
 
                        chunks.append(value)
317
 
                    _ref_stack.pop()
318
 
                    chunk_is_ref = False
319
 
            if list_value:
320
 
                # Once a list appears as the result of an expansion, all
321
 
                # callers will get a list result. This allows a consistent
322
 
                # behavior even when some options in the expansion chain
323
 
                # defined as strings (no comma in their value) but their
324
 
                # expanded value is a list.
325
 
                return self._expand_options_in_list(chunks, env, _ref_stack)
326
 
            else:
327
 
                result = ''.join(chunks)
328
 
        return result
329
 
 
330
 
    def _expand_option(self, name, env, _ref_stack):
331
 
        if env is not None and name in env:
332
 
            # Special case, values provided in env takes precedence over
333
 
            # anything else
334
 
            value = env[name]
335
 
        else:
336
 
            # FIXME: This is a limited implementation, what we really need is a
337
 
            # way to query the bzr config for the value of an option,
338
 
            # respecting the scope rules (That is, once we implement fallback
339
 
            # configs, getting the option value should restart from the top
340
 
            # config, not the current one) -- vila 20101222
341
 
            value = self.get_user_option(name, expand=False)
342
 
            if isinstance(value, list):
343
 
                value = self._expand_options_in_list(value, env, _ref_stack)
344
 
            else:
345
 
                value = self._expand_options_in_string(value, env, _ref_stack)
346
 
        return value
347
 
 
348
175
    def _get_user_option(self, option_name):
349
176
        """Template method to provide a user option."""
350
177
        return None
351
178
 
352
 
    def get_user_option(self, option_name, expand=True):
353
 
        """Get a generic option - no special process, no default.
354
 
 
355
 
        :param option_name: The queried option.
356
 
 
357
 
        :param expand: Whether options references should be expanded.
358
 
 
359
 
        :returns: The value of the option.
360
 
        """
361
 
        value = self._get_user_option(option_name)
362
 
        if expand:
363
 
            if isinstance(value, list):
364
 
                value = self._expand_options_in_list(value)
365
 
            elif isinstance(value, dict):
366
 
                trace.warning('Cannot expand "%s":'
367
 
                              ' Dicts do not support option expansion'
368
 
                              % (option_name,))
369
 
            else:
370
 
                value = self._expand_options_in_string(value)
371
 
        for hook in OldConfigHooks['get']:
372
 
            hook(self, option_name, value)
373
 
        return value
374
 
 
375
 
    def get_user_option_as_bool(self, option_name, expand=None, default=None):
376
 
        """Get a generic option as a boolean.
377
 
 
378
 
        :param expand: Allow expanding references to other config values.
379
 
        :param default: Default value if nothing is configured
380
 
        :return None if the option doesn't exist or its value can't be
381
 
            interpreted as a boolean. Returns True or False otherwise.
382
 
        """
383
 
        s = self.get_user_option(option_name, expand=expand)
384
 
        if s is None:
385
 
            # The option doesn't exist
386
 
            return default
387
 
        val = ui.bool_from_string(s)
388
 
        if val is None:
389
 
            # The value can't be interpreted as a boolean
390
 
            trace.warning('Value "%s" is not a boolean for "%s"',
391
 
                          s, option_name)
392
 
        return val
393
 
 
394
 
    def get_user_option_as_list(self, option_name, expand=None):
395
 
        """Get a generic option as a list - no special process, no default.
396
 
 
397
 
        :return None if the option doesn't exist. Returns the value as a list
398
 
            otherwise.
399
 
        """
400
 
        l = self.get_user_option(option_name, expand=expand)
401
 
        if isinstance(l, (str, unicode)):
402
 
            # A single value, most probably the user forgot (or didn't care to
403
 
            # add) the final ','
404
 
            l = [l]
405
 
        return l
406
 
 
407
 
    @deprecated_method(deprecated_in((2, 5, 0)))
408
 
    def get_user_option_as_int_from_SI(self, option_name, default=None):
409
 
        """Get a generic option from a human readable size in SI units, e.g 10MB
410
 
 
411
 
        Accepted suffixes are K,M,G. It is case-insensitive and may be followed
412
 
        by a trailing b (i.e. Kb, MB). This is intended to be practical and not
413
 
        pedantic.
414
 
 
415
 
        :return Integer, expanded to its base-10 value if a proper SI unit is 
416
 
            found. If the option doesn't exist, or isn't a value in 
417
 
            SI units, return default (which defaults to None)
418
 
        """
419
 
        val = self.get_user_option(option_name)
420
 
        if isinstance(val, list):
421
 
            val = val[0]
422
 
        if val is None:
423
 
            val = default
424
 
        else:
425
 
            p = re.compile("^(\d+)([kmg])*b*$", re.IGNORECASE)
426
 
            try:
427
 
                m = p.match(val)
428
 
                if m is not None:
429
 
                    val = int(m.group(1))
430
 
                    if m.group(2) is not None:
431
 
                        if m.group(2).lower() == 'k':
432
 
                            val *= 10**3
433
 
                        elif m.group(2).lower() == 'm':
434
 
                            val *= 10**6
435
 
                        elif m.group(2).lower() == 'g':
436
 
                            val *= 10**9
437
 
                else:
438
 
                    ui.ui_factory.show_warning(gettext('Invalid config value for "{0}" '
439
 
                                               ' value {1!r} is not an SI unit.').format(
440
 
                                                option_name, val))
441
 
                    val = default
442
 
            except TypeError:
443
 
                val = default
444
 
        return val
445
 
 
446
 
    @deprecated_method(deprecated_in((2, 5, 0)))
 
179
    def get_user_option(self, option_name):
 
180
        """Get a generic option - no special process, no default."""
 
181
        return self._get_user_option(option_name)
 
182
 
447
183
    def gpg_signing_command(self):
448
184
        """What program should be used to sign signatures?"""
449
185
        result = self._gpg_signing_command()
455
191
        """See gpg_signing_command()."""
456
192
        return None
457
193
 
458
 
    @deprecated_method(deprecated_in((2, 5, 0)))
459
194
    def log_format(self):
460
195
        """What log format should be used"""
461
196
        result = self._log_format()
467
202
        """See log_format()."""
468
203
        return None
469
204
 
470
 
    def validate_signatures_in_log(self):
471
 
        """Show GPG signature validity in log"""
472
 
        result = self._validate_signatures_in_log()
473
 
        if result == "true":
474
 
            result = True
475
 
        else:
476
 
            result = False
477
 
        return result
478
 
 
479
 
    def _validate_signatures_in_log(self):
480
 
        """See validate_signatures_in_log()."""
481
 
        return None
482
 
 
483
 
    @deprecated_method(deprecated_in((2, 5, 0)))
484
 
    def acceptable_keys(self):
485
 
        """Comma separated list of key patterns acceptable to 
486
 
        verify-signatures command"""
487
 
        result = self._acceptable_keys()
488
 
        return result
489
 
 
490
 
    def _acceptable_keys(self):
491
 
        """See acceptable_keys()."""
492
 
        return None
493
 
 
494
 
    @deprecated_method(deprecated_in((2, 5, 0)))
 
205
    def __init__(self):
 
206
        super(Config, self).__init__()
 
207
 
495
208
    def post_commit(self):
496
209
        """An ordered list of python functions to call.
497
210
 
509
222
 
510
223
    def username(self):
511
224
        """Return email-style username.
512
 
 
 
225
    
513
226
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
514
 
 
515
 
        $BZR_EMAIL can be set to override this, then
 
227
        
 
228
        $BZR_EMAIL can be set to override this (as well as the
 
229
        deprecated $BZREMAIL), then
516
230
        the concrete policy type is checked, and finally
517
231
        $EMAIL is examined.
518
 
        If no username can be found, errors.NoWhoami exception is raised.
 
232
        If none is found, a reasonable default is (hopefully)
 
233
        created.
 
234
    
 
235
        TODO: Check it's reasonably well-formed.
519
236
        """
520
237
        v = os.environ.get('BZR_EMAIL')
521
238
        if v:
522
 
            return v.decode(osutils.get_user_encoding())
 
239
            return v.decode(bzrlib.user_encoding)
 
240
 
523
241
        v = self._get_user_id()
524
242
        if v:
525
243
            return v
526
 
        return default_email()
527
 
 
528
 
    def ensure_username(self):
529
 
        """Raise errors.NoWhoami if username is not set.
530
 
 
531
 
        This method relies on the username() function raising the error.
532
 
        """
533
 
        self.username()
534
 
 
535
 
    @deprecated_method(deprecated_in((2, 5, 0)))
 
244
 
 
245
        v = os.environ.get('EMAIL')
 
246
        if v:
 
247
            return v.decode(bzrlib.user_encoding)
 
248
 
 
249
        name, email = _auto_user_id()
 
250
        if name:
 
251
            return '%s <%s>' % (name, email)
 
252
        else:
 
253
            return email
 
254
 
536
255
    def signature_checking(self):
537
256
        """What is the current policy for signature checking?."""
538
257
        policy = self._get_signature_checking()
540
259
            return policy
541
260
        return CHECK_IF_POSSIBLE
542
261
 
543
 
    @deprecated_method(deprecated_in((2, 5, 0)))
544
262
    def signing_policy(self):
545
263
        """What is the current policy for signature checking?."""
546
264
        policy = self._get_signing_policy()
548
266
            return policy
549
267
        return SIGN_WHEN_REQUIRED
550
268
 
551
 
    @deprecated_method(deprecated_in((2, 5, 0)))
552
269
    def signature_needed(self):
553
270
        """Is a signature needed when committing ?."""
554
271
        policy = self._get_signing_policy()
555
272
        if policy is None:
556
273
            policy = self._get_signature_checking()
557
274
            if policy is not None:
558
 
                #this warning should go away once check_signatures is
559
 
                #implemented (if not before)
560
275
                trace.warning("Please use create_signatures,"
561
276
                              " not check_signatures to set signing policy.")
 
277
            if policy == CHECK_ALWAYS:
 
278
                return True
562
279
        elif policy == SIGN_ALWAYS:
563
280
            return True
564
281
        return False
565
282
 
566
 
    @deprecated_method(deprecated_in((2, 5, 0)))
567
 
    def gpg_signing_key(self):
568
 
        """GPG user-id to sign commits"""
569
 
        key = self.get_user_option('gpg_signing_key')
570
 
        if key == "default" or key == None:
571
 
            return self.user_email()
572
 
        else:
573
 
            return key
574
 
 
575
283
    def get_alias(self, value):
576
284
        return self._get_alias(value)
577
285
 
593
301
                path = 'bzr'
594
302
            return path
595
303
 
596
 
    def suppress_warning(self, warning):
597
 
        """Should the warning be suppressed or emitted.
598
 
 
599
 
        :param warning: The name of the warning being tested.
600
 
 
601
 
        :returns: True if the warning should be suppressed, False otherwise.
602
 
        """
603
 
        warnings = self.get_user_option_as_list('suppress_warnings')
604
 
        if warnings is None or warning not in warnings:
605
 
            return False
606
 
        else:
607
 
            return True
608
 
 
609
 
    def get_merge_tools(self):
610
 
        tools = {}
611
 
        for (oname, value, section, conf_id, parser) in self._get_options():
612
 
            if oname.startswith('bzr.mergetool.'):
613
 
                tool_name = oname[len('bzr.mergetool.'):]
614
 
                tools[tool_name] = self.get_user_option(oname, False)
615
 
        trace.mutter('loaded merge tools: %r' % tools)
616
 
        return tools
617
 
 
618
 
    def find_merge_tool(self, name):
619
 
        # We fake a defaults mechanism here by checking if the given name can
620
 
        # be found in the known_merge_tools if it's not found in the config.
621
 
        # This should be done through the proposed config defaults mechanism
622
 
        # when it becomes available in the future.
623
 
        command_line = (self.get_user_option('bzr.mergetool.%s' % name,
624
 
                                             expand=False)
625
 
                        or mergetools.known_merge_tools.get(name, None))
626
 
        return command_line
627
 
 
628
 
 
629
 
class _ConfigHooks(hooks.Hooks):
630
 
    """A dict mapping hook names and a list of callables for configs.
631
 
    """
632
 
 
633
 
    def __init__(self):
634
 
        """Create the default hooks.
635
 
 
636
 
        These are all empty initially, because by default nothing should get
637
 
        notified.
638
 
        """
639
 
        super(_ConfigHooks, self).__init__('bzrlib.config', 'ConfigHooks')
640
 
        self.add_hook('load',
641
 
                      'Invoked when a config store is loaded.'
642
 
                      ' The signature is (store).',
643
 
                      (2, 4))
644
 
        self.add_hook('save',
645
 
                      'Invoked when a config store is saved.'
646
 
                      ' The signature is (store).',
647
 
                      (2, 4))
648
 
        # The hooks for config options
649
 
        self.add_hook('get',
650
 
                      'Invoked when a config option is read.'
651
 
                      ' The signature is (stack, name, value).',
652
 
                      (2, 4))
653
 
        self.add_hook('set',
654
 
                      'Invoked when a config option is set.'
655
 
                      ' The signature is (stack, name, value).',
656
 
                      (2, 4))
657
 
        self.add_hook('remove',
658
 
                      'Invoked when a config option is removed.'
659
 
                      ' The signature is (stack, name).',
660
 
                      (2, 4))
661
 
ConfigHooks = _ConfigHooks()
662
 
 
663
 
 
664
 
class _OldConfigHooks(hooks.Hooks):
665
 
    """A dict mapping hook names and a list of callables for configs.
666
 
    """
667
 
 
668
 
    def __init__(self):
669
 
        """Create the default hooks.
670
 
 
671
 
        These are all empty initially, because by default nothing should get
672
 
        notified.
673
 
        """
674
 
        super(_OldConfigHooks, self).__init__('bzrlib.config', 'OldConfigHooks')
675
 
        self.add_hook('load',
676
 
                      'Invoked when a config store is loaded.'
677
 
                      ' The signature is (config).',
678
 
                      (2, 4))
679
 
        self.add_hook('save',
680
 
                      'Invoked when a config store is saved.'
681
 
                      ' The signature is (config).',
682
 
                      (2, 4))
683
 
        # The hooks for config options
684
 
        self.add_hook('get',
685
 
                      'Invoked when a config option is read.'
686
 
                      ' The signature is (config, name, value).',
687
 
                      (2, 4))
688
 
        self.add_hook('set',
689
 
                      'Invoked when a config option is set.'
690
 
                      ' The signature is (config, name, value).',
691
 
                      (2, 4))
692
 
        self.add_hook('remove',
693
 
                      'Invoked when a config option is removed.'
694
 
                      ' The signature is (config, name).',
695
 
                      (2, 4))
696
 
OldConfigHooks = _OldConfigHooks()
697
 
 
698
304
 
699
305
class IniBasedConfig(Config):
700
306
    """A configuration policy that draws from ini files."""
701
307
 
702
 
    def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
703
 
                 file_name=None):
704
 
        """Base class for configuration files using an ini-like syntax.
705
 
 
706
 
        :param file_name: The configuration file path.
707
 
        """
708
 
        super(IniBasedConfig, self).__init__()
709
 
        self.file_name = file_name
710
 
        if symbol_versioning.deprecated_passed(get_filename):
711
 
            symbol_versioning.warn(
712
 
                'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
713
 
                ' Use file_name instead.',
714
 
                DeprecationWarning,
715
 
                stacklevel=2)
716
 
            if get_filename is not None:
717
 
                self.file_name = get_filename()
718
 
        else:
719
 
            self.file_name = file_name
720
 
        self._content = None
721
 
        self._parser = None
722
 
 
723
 
    @classmethod
724
 
    def from_string(cls, str_or_unicode, file_name=None, save=False):
725
 
        """Create a config object from a string.
726
 
 
727
 
        :param str_or_unicode: A string representing the file content. This will
728
 
            be utf-8 encoded.
729
 
 
730
 
        :param file_name: The configuration file path.
731
 
 
732
 
        :param _save: Whether the file should be saved upon creation.
733
 
        """
734
 
        conf = cls(file_name=file_name)
735
 
        conf._create_from_string(str_or_unicode, save)
736
 
        return conf
737
 
 
738
 
    def _create_from_string(self, str_or_unicode, save):
739
 
        self._content = StringIO(str_or_unicode.encode('utf-8'))
740
 
        # Some tests use in-memory configs, some other always need the config
741
 
        # file to exist on disk.
742
 
        if save:
743
 
            self._write_config_file()
744
 
 
745
 
    def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
 
308
    def _get_parser(self, file=None):
746
309
        if self._parser is not None:
747
310
            return self._parser
748
 
        if symbol_versioning.deprecated_passed(file):
749
 
            symbol_versioning.warn(
750
 
                'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
751
 
                ' Use IniBasedConfig(_content=xxx) instead.',
752
 
                DeprecationWarning,
753
 
                stacklevel=2)
754
 
        if self._content is not None:
755
 
            co_input = self._content
756
 
        elif self.file_name is None:
757
 
            raise AssertionError('We have no content to create the config')
 
311
        if file is None:
 
312
            input = self._get_filename()
758
313
        else:
759
 
            co_input = self.file_name
 
314
            input = file
760
315
        try:
761
 
            self._parser = ConfigObj(co_input, encoding='utf-8')
 
316
            self._parser = ConfigObj(input, encoding='utf-8')
762
317
        except configobj.ConfigObjError, e:
763
318
            raise errors.ParseConfigError(e.errors, e.config.filename)
764
 
        except UnicodeDecodeError:
765
 
            raise errors.ConfigContentError(self.file_name)
766
 
        # Make sure self.reload() will use the right file name
767
 
        self._parser.filename = self.file_name
768
 
        for hook in OldConfigHooks['load']:
769
 
            hook(self)
770
319
        return self._parser
771
320
 
772
 
    def reload(self):
773
 
        """Reload the config file from disk."""
774
 
        if self.file_name is None:
775
 
            raise AssertionError('We need a file name to reload the config')
776
 
        if self._parser is not None:
777
 
            self._parser.reload()
778
 
        for hook in ConfigHooks['load']:
779
 
            hook(self)
780
 
 
781
321
    def _get_matching_sections(self):
782
322
        """Return an ordered list of (section_name, extra_path) pairs.
783
323
 
794
334
        """Override this to define the section used by the config."""
795
335
        return "DEFAULT"
796
336
 
797
 
    def _get_sections(self, name=None):
798
 
        """Returns an iterator of the sections specified by ``name``.
799
 
 
800
 
        :param name: The section name. If None is supplied, the default
801
 
            configurations are yielded.
802
 
 
803
 
        :return: A tuple (name, section, config_id) for all sections that will
804
 
            be walked by user_get_option() in the 'right' order. The first one
805
 
            is where set_user_option() will update the value.
806
 
        """
807
 
        parser = self._get_parser()
808
 
        if name is not None:
809
 
            yield (name, parser[name], self.config_id())
810
 
        else:
811
 
            # No section name has been given so we fallback to the configobj
812
 
            # itself which holds the variables defined outside of any section.
813
 
            yield (None, parser, self.config_id())
814
 
 
815
 
    def _get_options(self, sections=None):
816
 
        """Return an ordered list of (name, value, section, config_id) tuples.
817
 
 
818
 
        All options are returned with their associated value and the section
819
 
        they appeared in. ``config_id`` is a unique identifier for the
820
 
        configuration file the option is defined in.
821
 
 
822
 
        :param sections: Default to ``_get_matching_sections`` if not
823
 
            specified. This gives a better control to daughter classes about
824
 
            which sections should be searched. This is a list of (name,
825
 
            configobj) tuples.
826
 
        """
827
 
        opts = []
828
 
        if sections is None:
829
 
            parser = self._get_parser()
830
 
            sections = []
831
 
            for (section_name, _) in self._get_matching_sections():
832
 
                try:
833
 
                    section = parser[section_name]
834
 
                except KeyError:
835
 
                    # This could happen for an empty file for which we define a
836
 
                    # DEFAULT section. FIXME: Force callers to provide sections
837
 
                    # instead ? -- vila 20100930
838
 
                    continue
839
 
                sections.append((section_name, section))
840
 
        config_id = self.config_id()
841
 
        for (section_name, section) in sections:
842
 
            for (name, value) in section.iteritems():
843
 
                yield (name, parser._quote(value), section_name,
844
 
                       config_id, parser)
845
 
 
846
337
    def _get_option_policy(self, section, option_name):
847
338
        """Return the policy for the given (section, option_name) pair."""
848
339
        return POLICY_NONE
849
340
 
850
 
    def _get_change_editor(self):
851
 
        return self.get_user_option('change_editor')
852
 
 
853
341
    def _get_signature_checking(self):
854
342
        """See Config._get_signature_checking."""
855
343
        policy = self._get_user_option('check_signatures')
856
344
        if policy:
857
 
            return signature_policy_from_unicode(policy)
 
345
            return self._string_to_signature_policy(policy)
858
346
 
859
347
    def _get_signing_policy(self):
860
348
        """See Config._get_signing_policy"""
861
349
        policy = self._get_user_option('create_signatures')
862
350
        if policy:
863
 
            return signing_policy_from_unicode(policy)
 
351
            return self._string_to_signing_policy(policy)
864
352
 
865
353
    def _get_user_id(self):
866
354
        """Get the user id from the 'email' key in the current section."""
899
387
        """See Config.log_format."""
900
388
        return self._get_user_option('log_format')
901
389
 
902
 
    def _validate_signatures_in_log(self):
903
 
        """See Config.validate_signatures_in_log."""
904
 
        return self._get_user_option('validate_signatures_in_log')
905
 
 
906
 
    def _acceptable_keys(self):
907
 
        """See Config.acceptable_keys."""
908
 
        return self._get_user_option('acceptable_keys')
909
 
 
 
390
    def __init__(self, get_filename):
 
391
        super(IniBasedConfig, self).__init__()
 
392
        self._get_filename = get_filename
 
393
        self._parser = None
 
394
        
910
395
    def _post_commit(self):
911
396
        """See Config.post_commit."""
912
397
        return self._get_user_option('post_commit')
913
398
 
 
399
    def _string_to_signature_policy(self, signature_string):
 
400
        """Convert a string to a signing policy."""
 
401
        if signature_string.lower() == 'check-available':
 
402
            return CHECK_IF_POSSIBLE
 
403
        if signature_string.lower() == 'ignore':
 
404
            return CHECK_NEVER
 
405
        if signature_string.lower() == 'require':
 
406
            return CHECK_ALWAYS
 
407
        raise errors.BzrError("Invalid signatures policy '%s'"
 
408
                              % signature_string)
 
409
 
 
410
    def _string_to_signing_policy(self, signature_string):
 
411
        """Convert a string to a signing policy."""
 
412
        if signature_string.lower() == 'when-required':
 
413
            return SIGN_WHEN_REQUIRED
 
414
        if signature_string.lower() == 'never':
 
415
            return SIGN_NEVER
 
416
        if signature_string.lower() == 'always':
 
417
            return SIGN_ALWAYS
 
418
        raise errors.BzrError("Invalid signing policy '%s'"
 
419
                              % signature_string)
 
420
 
914
421
    def _get_alias(self, value):
915
422
        try:
916
 
            return self._get_parser().get_value("ALIASES",
 
423
            return self._get_parser().get_value("ALIASES", 
917
424
                                                value)
918
425
        except KeyError:
919
426
            pass
921
428
    def _get_nickname(self):
922
429
        return self.get_user_option('nickname')
923
430
 
924
 
    def remove_user_option(self, option_name, section_name=None):
925
 
        """Remove a user option and save the configuration file.
926
 
 
927
 
        :param option_name: The option to be removed.
928
 
 
929
 
        :param section_name: The section the option is defined in, default to
930
 
            the default section.
931
 
        """
932
 
        self.reload()
933
 
        parser = self._get_parser()
934
 
        if section_name is None:
935
 
            section = parser
936
 
        else:
937
 
            section = parser[section_name]
938
 
        try:
939
 
            del section[option_name]
940
 
        except KeyError:
941
 
            raise errors.NoSuchConfigOption(option_name)
942
 
        self._write_config_file()
943
 
        for hook in OldConfigHooks['remove']:
944
 
            hook(self, option_name)
945
 
 
946
 
    def _write_config_file(self):
947
 
        if self.file_name is None:
948
 
            raise AssertionError('We cannot save, self.file_name is None')
949
 
        conf_dir = os.path.dirname(self.file_name)
950
 
        ensure_config_dir_exists(conf_dir)
951
 
        atomic_file = atomicfile.AtomicFile(self.file_name)
952
 
        self._get_parser().write(atomic_file)
953
 
        atomic_file.commit()
954
 
        atomic_file.close()
955
 
        osutils.copy_ownership_from_path(self.file_name)
956
 
        for hook in OldConfigHooks['save']:
957
 
            hook(self)
958
 
 
959
 
 
960
 
class LockableConfig(IniBasedConfig):
961
 
    """A configuration needing explicit locking for access.
962
 
 
963
 
    If several processes try to write the config file, the accesses need to be
964
 
    serialized.
965
 
 
966
 
    Daughter classes should decorate all methods that update a config with the
967
 
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
968
 
    ``_write_config_file()`` method. These methods (typically ``set_option()``
969
 
    and variants must reload the config file from disk before calling
970
 
    ``_write_config_file()``), this can be achieved by calling the
971
 
    ``self.reload()`` method. Note that the lock scope should cover both the
972
 
    reading and the writing of the config file which is why the decorator can't
973
 
    be applied to ``_write_config_file()`` only.
974
 
 
975
 
    This should be enough to implement the following logic:
976
 
    - lock for exclusive write access,
977
 
    - reload the config file from disk,
978
 
    - set the new value
979
 
    - unlock
980
 
 
981
 
    This logic guarantees that a writer can update a value without erasing an
982
 
    update made by another writer.
983
 
    """
984
 
 
985
 
    lock_name = 'lock'
986
 
 
987
 
    def __init__(self, file_name):
988
 
        super(LockableConfig, self).__init__(file_name=file_name)
989
 
        self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
990
 
        # FIXME: It doesn't matter that we don't provide possible_transports
991
 
        # below since this is currently used only for local config files ;
992
 
        # local transports are not shared. But if/when we start using
993
 
        # LockableConfig for other kind of transports, we will need to reuse
994
 
        # whatever connection is already established -- vila 20100929
995
 
        self.transport = transport.get_transport_from_path(self.dir)
996
 
        self._lock = lockdir.LockDir(self.transport, self.lock_name)
997
 
 
998
 
    def _create_from_string(self, unicode_bytes, save):
999
 
        super(LockableConfig, self)._create_from_string(unicode_bytes, False)
1000
 
        if save:
1001
 
            # We need to handle the saving here (as opposed to IniBasedConfig)
1002
 
            # to be able to lock
1003
 
            self.lock_write()
1004
 
            self._write_config_file()
1005
 
            self.unlock()
1006
 
 
1007
 
    def lock_write(self, token=None):
1008
 
        """Takes a write lock in the directory containing the config file.
1009
 
 
1010
 
        If the directory doesn't exist it is created.
1011
 
        """
1012
 
        ensure_config_dir_exists(self.dir)
1013
 
        return self._lock.lock_write(token)
1014
 
 
1015
 
    def unlock(self):
1016
 
        self._lock.unlock()
1017
 
 
1018
 
    def break_lock(self):
1019
 
        self._lock.break_lock()
1020
 
 
1021
 
    @needs_write_lock
1022
 
    def remove_user_option(self, option_name, section_name=None):
1023
 
        super(LockableConfig, self).remove_user_option(option_name,
1024
 
                                                       section_name)
1025
 
 
1026
 
    def _write_config_file(self):
1027
 
        if self._lock is None or not self._lock.is_held:
1028
 
            # NB: if the following exception is raised it probably means a
1029
 
            # missing @needs_write_lock decorator on one of the callers.
1030
 
            raise errors.ObjectNotLocked(self)
1031
 
        super(LockableConfig, self)._write_config_file()
1032
 
 
1033
 
 
1034
 
class GlobalConfig(LockableConfig):
 
431
 
 
432
class GlobalConfig(IniBasedConfig):
1035
433
    """The configuration that should be used for a specific location."""
1036
434
 
 
435
    def get_editor(self):
 
436
        return self._get_user_option('editor')
 
437
 
1037
438
    def __init__(self):
1038
 
        super(GlobalConfig, self).__init__(file_name=config_filename())
1039
 
 
1040
 
    def config_id(self):
1041
 
        return 'bazaar'
1042
 
 
1043
 
    @classmethod
1044
 
    def from_string(cls, str_or_unicode, save=False):
1045
 
        """Create a config object from a string.
1046
 
 
1047
 
        :param str_or_unicode: A string representing the file content. This
1048
 
            will be utf-8 encoded.
1049
 
 
1050
 
        :param save: Whether the file should be saved upon creation.
1051
 
        """
1052
 
        conf = cls()
1053
 
        conf._create_from_string(str_or_unicode, save)
1054
 
        return conf
1055
 
 
1056
 
    @needs_write_lock
 
439
        super(GlobalConfig, self).__init__(config_filename)
 
440
 
1057
441
    def set_user_option(self, option, value):
1058
442
        """Save option and its value in the configuration."""
1059
 
        self._set_option(option, value, 'DEFAULT')
1060
 
 
1061
 
    def get_aliases(self):
1062
 
        """Return the aliases section."""
1063
 
        if 'ALIASES' in self._get_parser():
1064
 
            return self._get_parser()['ALIASES']
1065
 
        else:
1066
 
            return {}
1067
 
 
1068
 
    @needs_write_lock
1069
 
    def set_alias(self, alias_name, alias_command):
1070
 
        """Save the alias in the configuration."""
1071
 
        self._set_option(alias_name, alias_command, 'ALIASES')
1072
 
 
1073
 
    @needs_write_lock
1074
 
    def unset_alias(self, alias_name):
1075
 
        """Unset an existing alias."""
1076
 
        self.reload()
1077
 
        aliases = self._get_parser().get('ALIASES')
1078
 
        if not aliases or alias_name not in aliases:
1079
 
            raise errors.NoSuchAlias(alias_name)
1080
 
        del aliases[alias_name]
1081
 
        self._write_config_file()
1082
 
 
1083
 
    def _set_option(self, option, value, section):
1084
 
        self.reload()
1085
 
        self._get_parser().setdefault(section, {})[option] = value
1086
 
        self._write_config_file()
1087
 
        for hook in OldConfigHooks['set']:
1088
 
            hook(self, option, value)
1089
 
 
1090
 
    def _get_sections(self, name=None):
1091
 
        """See IniBasedConfig._get_sections()."""
1092
 
        parser = self._get_parser()
1093
 
        # We don't give access to options defined outside of any section, we
1094
 
        # used the DEFAULT section by... default.
1095
 
        if name in (None, 'DEFAULT'):
1096
 
            # This could happen for an empty file where the DEFAULT section
1097
 
            # doesn't exist yet. So we force DEFAULT when yielding
1098
 
            name = 'DEFAULT'
1099
 
            if 'DEFAULT' not in parser:
1100
 
               parser['DEFAULT']= {}
1101
 
        yield (name, parser[name], self.config_id())
1102
 
 
1103
 
    @needs_write_lock
1104
 
    def remove_user_option(self, option_name, section_name=None):
1105
 
        if section_name is None:
1106
 
            # We need to force the default section.
1107
 
            section_name = 'DEFAULT'
1108
 
        # We need to avoid the LockableConfig implementation or we'll lock
1109
 
        # twice
1110
 
        super(LockableConfig, self).remove_user_option(option_name,
1111
 
                                                       section_name)
1112
 
 
1113
 
def _iter_for_location_by_parts(sections, location):
1114
 
    """Keep only the sessions matching the specified location.
1115
 
 
1116
 
    :param sections: An iterable of section names.
1117
 
 
1118
 
    :param location: An url or a local path to match against.
1119
 
 
1120
 
    :returns: An iterator of (section, extra_path, nb_parts) where nb is the
1121
 
        number of path components in the section name, section is the section
1122
 
        name and extra_path is the difference between location and the section
1123
 
        name.
1124
 
 
1125
 
    ``location`` will always be a local path and never a 'file://' url but the
1126
 
    section names themselves can be in either form.
1127
 
    """
1128
 
    location_parts = location.rstrip('/').split('/')
1129
 
 
1130
 
    for section in sections:
1131
 
        # location is a local path if possible, so we need to convert 'file://'
1132
 
        # urls in section names to local paths if necessary.
1133
 
 
1134
 
        # This also avoids having file:///path be a more exact
1135
 
        # match than '/path'.
1136
 
 
1137
 
        # FIXME: This still raises an issue if a user defines both file:///path
1138
 
        # *and* /path. Should we raise an error in this case -- vila 20110505
1139
 
 
1140
 
        if section.startswith('file://'):
1141
 
            section_path = urlutils.local_path_from_url(section)
1142
 
        else:
1143
 
            section_path = section
1144
 
        section_parts = section_path.rstrip('/').split('/')
1145
 
 
1146
 
        matched = True
1147
 
        if len(section_parts) > len(location_parts):
1148
 
            # More path components in the section, they can't match
1149
 
            matched = False
1150
 
        else:
1151
 
            # Rely on zip truncating in length to the length of the shortest
1152
 
            # argument sequence.
1153
 
            names = zip(location_parts, section_parts)
1154
 
            for name in names:
1155
 
                if not fnmatch.fnmatch(name[0], name[1]):
1156
 
                    matched = False
1157
 
                    break
1158
 
        if not matched:
1159
 
            continue
1160
 
        # build the path difference between the section and the location
1161
 
        extra_path = '/'.join(location_parts[len(section_parts):])
1162
 
        yield section, extra_path, len(section_parts)
1163
 
 
1164
 
 
1165
 
class LocationConfig(LockableConfig):
 
443
        # FIXME: RBC 20051029 This should refresh the parser and also take a
 
444
        # file lock on bazaar.conf.
 
445
        conf_dir = os.path.dirname(self._get_filename())
 
446
        ensure_config_dir_exists(conf_dir)
 
447
        if 'DEFAULT' not in self._get_parser():
 
448
            self._get_parser()['DEFAULT'] = {}
 
449
        self._get_parser()['DEFAULT'][option] = value
 
450
        f = open(self._get_filename(), 'wb')
 
451
        self._get_parser().write(f)
 
452
        f.close()
 
453
 
 
454
 
 
455
class LocationConfig(IniBasedConfig):
1166
456
    """A configuration object that gives the policy for a location."""
1167
457
 
1168
458
    def __init__(self, location):
1169
 
        super(LocationConfig, self).__init__(
1170
 
            file_name=locations_config_filename())
 
459
        name_generator = locations_config_filename
 
460
        if (not os.path.exists(name_generator()) and
 
461
                os.path.exists(branches_config_filename())):
 
462
            if sys.platform == 'win32':
 
463
                trace.warning('Please rename %s to %s'
 
464
                              % (branches_config_filename(),
 
465
                                 locations_config_filename()))
 
466
            else:
 
467
                trace.warning('Please rename ~/.bazaar/branches.conf'
 
468
                              ' to ~/.bazaar/locations.conf')
 
469
            name_generator = branches_config_filename
 
470
        super(LocationConfig, self).__init__(name_generator)
1171
471
        # local file locations are looked up by local path, rather than
1172
472
        # by file url. This is because the config file is a user
1173
473
        # file, and we would rather not expose the user to file urls.
1175
475
            location = urlutils.local_path_from_url(location)
1176
476
        self.location = location
1177
477
 
1178
 
    def config_id(self):
1179
 
        return 'locations'
1180
 
 
1181
 
    @classmethod
1182
 
    def from_string(cls, str_or_unicode, location, save=False):
1183
 
        """Create a config object from a string.
1184
 
 
1185
 
        :param str_or_unicode: A string representing the file content. This will
1186
 
            be utf-8 encoded.
1187
 
 
1188
 
        :param location: The location url to filter the configuration.
1189
 
 
1190
 
        :param save: Whether the file should be saved upon creation.
1191
 
        """
1192
 
        conf = cls(location)
1193
 
        conf._create_from_string(str_or_unicode, save)
1194
 
        return conf
1195
 
 
1196
478
    def _get_matching_sections(self):
1197
479
        """Return an ordered list of section names matching this location."""
1198
 
        matches = list(_iter_for_location_by_parts(self._get_parser(),
1199
 
                                                   self.location))
1200
 
        # put the longest (aka more specific) locations first
1201
 
        matches.sort(
1202
 
            key=lambda (section, extra_path, length): (length, section),
1203
 
            reverse=True)
1204
 
        for (section, extra_path, length) in matches:
1205
 
            yield section, extra_path
 
480
        sections = self._get_parser()
 
481
        location_names = self.location.split('/')
 
482
        if self.location.endswith('/'):
 
483
            del location_names[-1]
 
484
        matches=[]
 
485
        for section in sections:
 
486
            # location is a local path if possible, so we need
 
487
            # to convert 'file://' urls to local paths if necessary.
 
488
            # This also avoids having file:///path be a more exact
 
489
            # match than '/path'.
 
490
            if section.startswith('file://'):
 
491
                section_path = urlutils.local_path_from_url(section)
 
492
            else:
 
493
                section_path = section
 
494
            section_names = section_path.split('/')
 
495
            if section.endswith('/'):
 
496
                del section_names[-1]
 
497
            names = zip(location_names, section_names)
 
498
            matched = True
 
499
            for name in names:
 
500
                if not fnmatch(name[0], name[1]):
 
501
                    matched = False
 
502
                    break
 
503
            if not matched:
 
504
                continue
 
505
            # so, for the common prefix they matched.
 
506
            # if section is longer, no match.
 
507
            if len(section_names) > len(location_names):
 
508
                continue
 
509
            matches.append((len(section_names), section,
 
510
                            '/'.join(location_names[len(section_names):])))
 
511
        matches.sort(reverse=True)
 
512
        sections = []
 
513
        for (length, section, extra_path) in matches:
 
514
            sections.append((section, extra_path))
1206
515
            # should we stop looking for parent configs here?
1207
516
            try:
1208
517
                if self._get_parser()[section].as_bool('ignore_parents'):
1209
518
                    break
1210
519
            except KeyError:
1211
520
                pass
1212
 
 
1213
 
    def _get_sections(self, name=None):
1214
 
        """See IniBasedConfig._get_sections()."""
1215
 
        # We ignore the name here as the only sections handled are named with
1216
 
        # the location path and we don't expose embedded sections either.
1217
 
        parser = self._get_parser()
1218
 
        for name, extra_path in self._get_matching_sections():
1219
 
            yield (name, parser[name], self.config_id())
 
521
        return sections
1220
522
 
1221
523
    def _get_option_policy(self, section, option_name):
1222
524
        """Return the policy for the given (section, option_name) pair."""
1266
568
            if policy_key in self._get_parser()[section]:
1267
569
                del self._get_parser()[section][policy_key]
1268
570
 
1269
 
    @needs_write_lock
1270
571
    def set_user_option(self, option, value, store=STORE_LOCATION):
1271
572
        """Save option and its value in the configuration."""
1272
 
        if store not in [STORE_LOCATION,
 
573
        assert store in [STORE_LOCATION,
1273
574
                         STORE_LOCATION_NORECURSE,
1274
 
                         STORE_LOCATION_APPENDPATH]:
1275
 
            raise ValueError('bad storage policy %r for %r' %
1276
 
                (store, option))
1277
 
        self.reload()
 
575
                         STORE_LOCATION_APPENDPATH], 'bad storage policy'
 
576
        # FIXME: RBC 20051029 This should refresh the parser and also take a
 
577
        # file lock on locations.conf.
 
578
        conf_dir = os.path.dirname(self._get_filename())
 
579
        ensure_config_dir_exists(conf_dir)
1278
580
        location = self.location
1279
581
        if location.endswith('/'):
1280
582
            location = location[:-1]
1281
 
        parser = self._get_parser()
1282
 
        if not location in parser and not location + '/' in parser:
1283
 
            parser[location] = {}
1284
 
        elif location + '/' in parser:
 
583
        if (not location in self._get_parser() and
 
584
            not location + '/' in self._get_parser()):
 
585
            self._get_parser()[location]={}
 
586
        elif location + '/' in self._get_parser():
1285
587
            location = location + '/'
1286
 
        parser[location][option]=value
 
588
        self._get_parser()[location][option]=value
1287
589
        # the allowed values of store match the config policies
1288
590
        self._set_option_policy(location, option, store)
1289
 
        self._write_config_file()
1290
 
        for hook in OldConfigHooks['set']:
1291
 
            hook(self, option, value)
 
591
        self._get_parser().write(file(self._get_filename(), 'wb'))
1292
592
 
1293
593
 
1294
594
class BranchConfig(Config):
1295
595
    """A configuration object giving the policy for a branch."""
1296
596
 
1297
 
    def __init__(self, branch):
1298
 
        super(BranchConfig, self).__init__()
1299
 
        self._location_config = None
1300
 
        self._branch_data_config = None
1301
 
        self._global_config = None
1302
 
        self.branch = branch
1303
 
        self.option_sources = (self._get_location_config,
1304
 
                               self._get_branch_data_config,
1305
 
                               self._get_global_config)
1306
 
 
1307
 
    def config_id(self):
1308
 
        return 'branch'
1309
 
 
1310
597
    def _get_branch_data_config(self):
1311
598
        if self._branch_data_config is None:
1312
599
            self._branch_data_config = TreeConfig(self.branch)
1313
 
            self._branch_data_config.config_id = self.config_id
1314
600
        return self._branch_data_config
1315
601
 
1316
602
    def _get_location_config(self):
1337
623
 
1338
624
    def _get_safe_value(self, option_name):
1339
625
        """This variant of get_best_value never returns untrusted values.
1340
 
 
 
626
        
1341
627
        It does not return values from the branch data, because the branch may
1342
628
        not be controlled by the user.
1343
629
 
1352
638
 
1353
639
    def _get_user_id(self):
1354
640
        """Return the full user id for the branch.
1355
 
 
1356
 
        e.g. "John Hacker <jhacker@example.com>"
 
641
    
 
642
        e.g. "John Hacker <jhacker@foo.org>"
1357
643
        This is looked up in the email controlfile for the branch.
1358
644
        """
 
645
        try:
 
646
            return (self.branch.control_files._transport.get_bytes("email")
 
647
                    .decode(bzrlib.user_encoding)
 
648
                    .rstrip("\r\n"))
 
649
        except errors.NoSuchFile, e:
 
650
            pass
 
651
        
1359
652
        return self._get_best_value('_get_user_id')
1360
653
 
1361
 
    def _get_change_editor(self):
1362
 
        return self._get_best_value('_get_change_editor')
1363
 
 
1364
654
    def _get_signature_checking(self):
1365
655
        """See Config._get_signature_checking."""
1366
656
        return self._get_best_value('_get_signature_checking')
1377
667
                return value
1378
668
        return None
1379
669
 
1380
 
    def _get_sections(self, name=None):
1381
 
        """See IniBasedConfig.get_sections()."""
1382
 
        for source in self.option_sources:
1383
 
            for section in source()._get_sections(name):
1384
 
                yield section
1385
 
 
1386
 
    def _get_options(self, sections=None):
1387
 
        opts = []
1388
 
        # First the locations options
1389
 
        for option in self._get_location_config()._get_options():
1390
 
            yield option
1391
 
        # Then the branch options
1392
 
        branch_config = self._get_branch_data_config()
1393
 
        if sections is None:
1394
 
            sections = [('DEFAULT', branch_config._get_parser())]
1395
 
        # FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
1396
 
        # Config itself has no notion of sections :( -- vila 20101001
1397
 
        config_id = self.config_id()
1398
 
        for (section_name, section) in sections:
1399
 
            for (name, value) in section.iteritems():
1400
 
                yield (name, value, section_name,
1401
 
                       config_id, branch_config._get_parser())
1402
 
        # Then the global options
1403
 
        for option in self._get_global_config()._get_options():
1404
 
            yield option
1405
 
 
1406
670
    def set_user_option(self, name, value, store=STORE_BRANCH,
1407
671
        warn_masked=False):
1408
672
        if store == STORE_BRANCH:
1426
690
                        trace.warning('Value "%s" is masked by "%s" from'
1427
691
                                      ' branch.conf', value, mask_value)
1428
692
 
1429
 
    def remove_user_option(self, option_name, section_name=None):
1430
 
        self._get_branch_data_config().remove_option(option_name, section_name)
1431
693
 
1432
694
    def _gpg_signing_command(self):
1433
695
        """See Config.gpg_signing_command."""
1434
696
        return self._get_safe_value('_gpg_signing_command')
 
697
        
 
698
    def __init__(self, branch):
 
699
        super(BranchConfig, self).__init__()
 
700
        self._location_config = None
 
701
        self._branch_data_config = None
 
702
        self._global_config = None
 
703
        self.branch = branch
 
704
        self.option_sources = (self._get_location_config, 
 
705
                               self._get_branch_data_config,
 
706
                               self._get_global_config)
1435
707
 
1436
708
    def _post_commit(self):
1437
709
        """See Config.post_commit."""
1441
713
        value = self._get_explicit_nickname()
1442
714
        if value is not None:
1443
715
            return value
1444
 
        if self.branch.name:
1445
 
            return self.branch.name
1446
716
        return urlutils.unescape(self.branch.base.split('/')[-2])
1447
717
 
1448
718
    def has_explicit_nickname(self):
1456
726
        """See Config.log_format."""
1457
727
        return self._get_best_value('_log_format')
1458
728
 
1459
 
    def _validate_signatures_in_log(self):
1460
 
        """See Config.validate_signatures_in_log."""
1461
 
        return self._get_best_value('_validate_signatures_in_log')
1462
 
 
1463
 
    def _acceptable_keys(self):
1464
 
        """See Config.acceptable_keys."""
1465
 
        return self._get_best_value('_acceptable_keys')
1466
 
 
1467
729
 
1468
730
def ensure_config_dir_exists(path=None):
1469
731
    """Make sure a configuration directory exists.
1478
740
            parent_dir = os.path.dirname(path)
1479
741
            if not os.path.isdir(parent_dir):
1480
742
                trace.mutter('creating config parent directory: %r', parent_dir)
1481
 
                os.mkdir(parent_dir)
 
743
            os.mkdir(parent_dir)
1482
744
        trace.mutter('creating config directory: %r', path)
1483
745
        os.mkdir(path)
1484
 
        osutils.copy_ownership_from_path(path)
1485
746
 
1486
747
 
1487
748
def config_dir():
1488
 
    """Return per-user configuration directory as unicode string
1489
 
 
1490
 
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1491
 
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1492
 
    that will be used instead.
1493
 
 
 
749
    """Return per-user configuration directory.
 
750
 
 
751
    By default this is ~/.bazaar/
 
752
    
1494
753
    TODO: Global option --config-dir to override this.
1495
754
    """
1496
 
    base = osutils.path_from_environ('BZR_HOME')
 
755
    base = os.environ.get('BZR_HOME', None)
1497
756
    if sys.platform == 'win32':
1498
757
        if base is None:
1499
 
            base = win32utils.get_appdata_location()
1500
 
        if base is None:
1501
 
            base = win32utils.get_home_location()
1502
 
        # GZ 2012-02-01: Really the two level subdirs only make sense inside
1503
 
        #                APPDATA, but hard to move. See bug 348640 for more.
 
758
            base = win32utils.get_appdata_location_unicode()
 
759
        if base is None:
 
760
            base = os.environ.get('HOME', None)
 
761
        if base is None:
 
762
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
 
763
                                  ' or HOME set')
1504
764
        return osutils.pathjoin(base, 'bazaar', '2.0')
1505
 
    if base is None:
1506
 
        # GZ 2012-02-01: What should OSX use instead of XDG if anything?
1507
 
        if sys.platform != 'darwin':
1508
 
            xdg_dir = osutils.path_from_environ('XDG_CONFIG_HOME')
1509
 
            if xdg_dir is None:
1510
 
                xdg_dir = osutils.pathjoin(osutils._get_home_dir(), ".config")
1511
 
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1512
 
            if osutils.isdir(xdg_dir):
1513
 
                trace.mutter(
1514
 
                    "Using configuration in XDG directory %s." % xdg_dir)
1515
 
                return xdg_dir
1516
 
        base = osutils._get_home_dir()
1517
 
    return osutils.pathjoin(base, ".bazaar")
 
765
    else:
 
766
        # cygwin, linux, and darwin all have a $HOME directory
 
767
        if base is None:
 
768
            base = os.path.expanduser("~")
 
769
        return osutils.pathjoin(base, ".bazaar")
1518
770
 
1519
771
 
1520
772
def config_filename():
1522
774
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
1523
775
 
1524
776
 
 
777
def branches_config_filename():
 
778
    """Return per-user configuration ini file filename."""
 
779
    return osutils.pathjoin(config_dir(), 'branches.conf')
 
780
 
 
781
 
1525
782
def locations_config_filename():
1526
783
    """Return per-user configuration ini file filename."""
1527
784
    return osutils.pathjoin(config_dir(), 'locations.conf')
1537
794
    return osutils.pathjoin(config_dir(), 'ignore')
1538
795
 
1539
796
 
1540
 
def crash_dir():
1541
 
    """Return the directory name to store crash files.
1542
 
 
1543
 
    This doesn't implicitly create it.
1544
 
 
1545
 
    On Windows it's in the config directory; elsewhere it's /var/crash
1546
 
    which may be monitored by apport.  It can be overridden by
1547
 
    $APPORT_CRASH_DIR.
1548
 
    """
1549
 
    if sys.platform == 'win32':
1550
 
        return osutils.pathjoin(config_dir(), 'Crash')
1551
 
    else:
1552
 
        # XXX: hardcoded in apport_python_hook.py; therefore here too -- mbp
1553
 
        # 2010-01-31
1554
 
        return os.environ.get('APPORT_CRASH_DIR', '/var/crash')
1555
 
 
1556
 
 
1557
 
def xdg_cache_dir():
1558
 
    # See http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html
1559
 
    # Possibly this should be different on Windows?
1560
 
    e = os.environ.get('XDG_CACHE_DIR', None)
1561
 
    if e:
1562
 
        return e
1563
 
    else:
1564
 
        return os.path.expanduser('~/.cache')
1565
 
 
1566
 
 
1567
 
def _get_default_mail_domain(mailname_file='/etc/mailname'):
1568
 
    """If possible, return the assumed default email domain.
1569
 
 
1570
 
    :returns: string mail domain, or None.
1571
 
    """
1572
 
    if sys.platform == 'win32':
1573
 
        # No implementation yet; patches welcome
1574
 
        return None
1575
 
    try:
1576
 
        f = open(mailname_file)
1577
 
    except (IOError, OSError), e:
1578
 
        return None
1579
 
    try:
1580
 
        domain = f.readline().strip()
1581
 
        return domain
1582
 
    finally:
1583
 
        f.close()
1584
 
 
1585
 
 
1586
 
def default_email():
1587
 
    v = os.environ.get('BZR_EMAIL')
1588
 
    if v:
1589
 
        return v.decode(osutils.get_user_encoding())
1590
 
    v = os.environ.get('EMAIL')
1591
 
    if v:
1592
 
        return v.decode(osutils.get_user_encoding())
1593
 
    name, email = _auto_user_id()
1594
 
    if name and email:
1595
 
        return u'%s <%s>' % (name, email)
1596
 
    elif email:
1597
 
        return email
1598
 
    raise errors.NoWhoami()
1599
 
 
1600
 
 
1601
797
def _auto_user_id():
1602
798
    """Calculate automatic user identification.
1603
799
 
1604
 
    :returns: (realname, email), either of which may be None if they can't be
1605
 
    determined.
 
800
    Returns (realname, email).
1606
801
 
1607
802
    Only used when none is set in the environment or the id file.
1608
803
 
1609
 
    This only returns an email address if we can be fairly sure the 
1610
 
    address is reasonable, ie if /etc/mailname is set on unix.
1611
 
 
1612
 
    This doesn't use the FQDN as the default domain because that may be 
1613
 
    slow, and it doesn't use the hostname alone because that's not normally 
1614
 
    a reasonable address.
 
804
    This previously used the FQDN as the default domain, but that can
 
805
    be very slow on machines where DNS is broken.  So now we simply
 
806
    use the hostname.
1615
807
    """
 
808
    import socket
 
809
 
1616
810
    if sys.platform == 'win32':
1617
 
        # No implementation to reliably determine Windows default mail
1618
 
        # address; please add one.
1619
 
        return None, None
1620
 
 
1621
 
    default_mail_domain = _get_default_mail_domain()
1622
 
    if not default_mail_domain:
1623
 
        return None, None
1624
 
 
1625
 
    import pwd
1626
 
    uid = os.getuid()
 
811
        name = win32utils.get_user_name_unicode()
 
812
        if name is None:
 
813
            raise errors.BzrError("Cannot autodetect user name.\n"
 
814
                                  "Please, set your name with command like:\n"
 
815
                                  'bzr whoami "Your Name <name@domain.com>"')
 
816
        host = win32utils.get_host_name_unicode()
 
817
        if host is None:
 
818
            host = socket.gethostname()
 
819
        return name, (name + '@' + host)
 
820
 
1627
821
    try:
 
822
        import pwd
 
823
        uid = os.getuid()
1628
824
        w = pwd.getpwuid(uid)
1629
 
    except KeyError:
1630
 
        trace.mutter('no passwd entry for uid %d?' % uid)
1631
 
        return None, None
1632
 
 
1633
 
    # we try utf-8 first, because on many variants (like Linux),
1634
 
    # /etc/passwd "should" be in utf-8, and because it's unlikely to give
1635
 
    # false positives.  (many users will have their user encoding set to
1636
 
    # latin-1, which cannot raise UnicodeError.)
1637
 
    try:
1638
 
        gecos = w.pw_gecos.decode('utf-8')
1639
 
        encoding = 'utf-8'
1640
 
    except UnicodeError:
1641
 
        try:
1642
 
            encoding = osutils.get_user_encoding()
1643
 
            gecos = w.pw_gecos.decode(encoding)
1644
 
        except UnicodeError, e:
1645
 
            trace.mutter("cannot decode passwd entry %s" % w)
1646
 
            return None, None
1647
 
    try:
1648
 
        username = w.pw_name.decode(encoding)
1649
 
    except UnicodeError, e:
1650
 
        trace.mutter("cannot decode passwd entry %s" % w)
1651
 
        return None, None
1652
 
 
1653
 
    comma = gecos.find(',')
1654
 
    if comma == -1:
1655
 
        realname = gecos
1656
 
    else:
1657
 
        realname = gecos[:comma]
1658
 
 
1659
 
    return realname, (username + '@' + default_mail_domain)
 
825
 
 
826
        # we try utf-8 first, because on many variants (like Linux),
 
827
        # /etc/passwd "should" be in utf-8, and because it's unlikely to give
 
828
        # false positives.  (many users will have their user encoding set to
 
829
        # latin-1, which cannot raise UnicodeError.)
 
830
        try:
 
831
            gecos = w.pw_gecos.decode('utf-8')
 
832
            encoding = 'utf-8'
 
833
        except UnicodeError:
 
834
            try:
 
835
                gecos = w.pw_gecos.decode(bzrlib.user_encoding)
 
836
                encoding = bzrlib.user_encoding
 
837
            except UnicodeError:
 
838
                raise errors.BzrCommandError('Unable to determine your name.  '
 
839
                   'Use "bzr whoami" to set it.')
 
840
        try:
 
841
            username = w.pw_name.decode(encoding)
 
842
        except UnicodeError:
 
843
            raise errors.BzrCommandError('Unable to determine your name.  '
 
844
                'Use "bzr whoami" to set it.')
 
845
 
 
846
        comma = gecos.find(',')
 
847
        if comma == -1:
 
848
            realname = gecos
 
849
        else:
 
850
            realname = gecos[:comma]
 
851
        if not realname:
 
852
            realname = username
 
853
 
 
854
    except ImportError:
 
855
        import getpass
 
856
        try:
 
857
            realname = username = getpass.getuser().decode(bzrlib.user_encoding)
 
858
        except UnicodeDecodeError:
 
859
            raise errors.BzrError("Can't decode username as %s." % \
 
860
                    bzrlib.user_encoding)
 
861
 
 
862
    return realname, (username + '@' + socket.gethostname())
1660
863
 
1661
864
 
1662
865
def parse_username(username):
1671
874
def extract_email_address(e):
1672
875
    """Return just the address part of an email string.
1673
876
 
1674
 
    That is just the user@domain part, nothing else.
 
877
    That is just the user@domain part, nothing else. 
1675
878
    This part is required to contain only ascii characters.
1676
879
    If it can't be extracted, raises an error.
1677
880
 
1687
890
class TreeConfig(IniBasedConfig):
1688
891
    """Branch configuration data associated with its contents, not location"""
1689
892
 
1690
 
    # XXX: Really needs a better name, as this is not part of the tree! -- mbp 20080507
1691
 
 
1692
893
    def __init__(self, branch):
1693
 
        self._config = branch._get_config()
 
894
        transport = branch.control_files._transport
 
895
        self._config = TransportConfig(transport, 'branch.conf')
1694
896
        self.branch = branch
1695
897
 
1696
898
    def _get_parser(self, file=None):
1704
906
            return self._config.get_option(name, section, default)
1705
907
        finally:
1706
908
            self.branch.unlock()
 
909
        return result
1707
910
 
1708
911
    def set_option(self, value, name, section=None):
1709
912
        """Set a per-branch configuration option"""
1710
 
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
1711
 
        # higher levels providing the right lock -- vila 20101004
1712
913
        self.branch.lock_write()
1713
914
        try:
1714
915
            self._config.set_option(value, name, section)
1715
916
        finally:
1716
917
            self.branch.unlock()
1717
918
 
1718
 
    def remove_option(self, option_name, section_name=None):
1719
 
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
1720
 
        # higher levels providing the right lock -- vila 20101004
1721
 
        self.branch.lock_write()
1722
 
        try:
1723
 
            self._config.remove_option(option_name, section_name)
1724
 
        finally:
1725
 
            self.branch.unlock()
1726
 
 
1727
919
 
1728
920
class AuthenticationConfig(object):
1729
921
    """The authentication configuration file based on a ini file.
1755
947
            self._config = ConfigObj(self._input, encoding='utf-8')
1756
948
        except configobj.ConfigObjError, e:
1757
949
            raise errors.ParseConfigError(e.errors, e.config.filename)
1758
 
        except UnicodeError:
1759
 
            raise errors.ConfigContentError(self._filename)
1760
950
        return self._config
1761
951
 
1762
952
    def _save(self):
1763
953
        """Save the config file, only tests should use it for now."""
1764
954
        conf_dir = os.path.dirname(self._filename)
1765
955
        ensure_config_dir_exists(conf_dir)
1766
 
        f = file(self._filename, 'wb')
1767
 
        try:
1768
 
            self._get_config().write(f)
1769
 
        finally:
1770
 
            f.close()
 
956
        self._get_config().write(file(self._filename, 'wb'))
1771
957
 
1772
958
    def _set_option(self, section_name, option_name, value):
1773
959
        """Set an authentication configuration option"""
1779
965
        section[option_name] = value
1780
966
        self._save()
1781
967
 
1782
 
    def get_credentials(self, scheme, host, port=None, user=None, path=None,
1783
 
                        realm=None):
 
968
    def get_credentials(self, scheme, host, port=None, user=None, path=None):
1784
969
        """Returns the matching credentials from authentication.conf file.
1785
970
 
1786
971
        :param scheme: protocol
1793
978
 
1794
979
        :param path: the absolute path on the server (optional)
1795
980
 
1796
 
        :param realm: the http authentication realm (optional)
1797
 
 
1798
981
        :return: A dict containing the matching credentials or None.
1799
982
           This includes:
1800
983
           - name: the section name of the credentials in the
1801
984
             authentication.conf file,
1802
 
           - user: can't be different from the provided user if any,
1803
 
           - scheme: the server protocol,
1804
 
           - host: the server address,
1805
 
           - port: the server port (can be None),
1806
 
           - path: the absolute server path (can be None),
1807
 
           - realm: the http specific authentication realm (can be None),
 
985
           - user: can't de different from the provided user if any,
1808
986
           - password: the decoded password, could be None if the credential
1809
987
             defines only the user
1810
988
           - verify_certificates: https specific, True if the server
1812
990
        """
1813
991
        credentials = None
1814
992
        for auth_def_name, auth_def in self._get_config().items():
1815
 
            if type(auth_def) is not configobj.Section:
1816
 
                raise ValueError("%s defined outside a section" % auth_def_name)
1817
 
 
1818
993
            a_scheme, a_host, a_user, a_path = map(
1819
994
                auth_def.get, ['scheme', 'host', 'user', 'path'])
1820
995
 
1851
1026
            if a_user is None:
1852
1027
                # Can't find a user
1853
1028
                continue
1854
 
            # Prepare a credentials dictionary with additional keys
1855
 
            # for the credential providers
1856
1029
            credentials = dict(name=auth_def_name,
1857
 
                               user=a_user,
1858
 
                               scheme=a_scheme,
1859
 
                               host=host,
1860
 
                               port=port,
1861
 
                               path=path,
1862
 
                               realm=realm,
1863
 
                               password=auth_def.get('password', None),
 
1030
                               user=a_user, password=auth_def['password'],
1864
1031
                               verify_certificates=a_verify_certificates)
1865
 
            # Decode the password in the credentials (or get one)
1866
1032
            self.decode_password(credentials,
1867
1033
                                 auth_def.get('password_encoding', None))
1868
1034
            if 'auth' in debug.debug_flags:
1869
1035
                trace.mutter("Using authentication section: %r", auth_def_name)
1870
1036
            break
1871
1037
 
1872
 
        if credentials is None:
1873
 
            # No credentials were found in authentication.conf, try the fallback
1874
 
            # credentials stores.
1875
 
            credentials = credential_store_registry.get_fallback_credentials(
1876
 
                scheme, host, port, user, path, realm)
1877
 
 
1878
1038
        return credentials
1879
1039
 
1880
 
    def set_credentials(self, name, host, user, scheme=None, password=None,
1881
 
                        port=None, path=None, verify_certificates=None,
1882
 
                        realm=None):
1883
 
        """Set authentication credentials for a host.
1884
 
 
1885
 
        Any existing credentials with matching scheme, host, port and path
1886
 
        will be deleted, regardless of name.
1887
 
 
1888
 
        :param name: An arbitrary name to describe this set of credentials.
1889
 
        :param host: Name of the host that accepts these credentials.
1890
 
        :param user: The username portion of these credentials.
1891
 
        :param scheme: The URL scheme (e.g. ssh, http) the credentials apply
1892
 
            to.
1893
 
        :param password: Password portion of these credentials.
1894
 
        :param port: The IP port on the host that these credentials apply to.
1895
 
        :param path: A filesystem path on the host that these credentials
1896
 
            apply to.
1897
 
        :param verify_certificates: On https, verify server certificates if
1898
 
            True.
1899
 
        :param realm: The http authentication realm (optional).
1900
 
        """
1901
 
        values = {'host': host, 'user': user}
1902
 
        if password is not None:
1903
 
            values['password'] = password
1904
 
        if scheme is not None:
1905
 
            values['scheme'] = scheme
1906
 
        if port is not None:
1907
 
            values['port'] = '%d' % port
1908
 
        if path is not None:
1909
 
            values['path'] = path
1910
 
        if verify_certificates is not None:
1911
 
            values['verify_certificates'] = str(verify_certificates)
1912
 
        if realm is not None:
1913
 
            values['realm'] = realm
1914
 
        config = self._get_config()
1915
 
        for_deletion = []
1916
 
        for section, existing_values in config.items():
1917
 
            for key in ('scheme', 'host', 'port', 'path', 'realm'):
1918
 
                if existing_values.get(key) != values.get(key):
1919
 
                    break
1920
 
            else:
1921
 
                del config[section]
1922
 
        config.update({name: values})
1923
 
        self._save()
1924
 
 
1925
 
    def get_user(self, scheme, host, port=None, realm=None, path=None,
1926
 
                 prompt=None, ask=False, default=None):
 
1040
    def get_user(self, scheme, host, port=None,
 
1041
                 realm=None, path=None, prompt=None):
1927
1042
        """Get a user from authentication file.
1928
1043
 
1929
1044
        :param scheme: protocol
1936
1051
 
1937
1052
        :param path: the absolute path on the server (optional)
1938
1053
 
1939
 
        :param ask: Ask the user if there is no explicitly configured username 
1940
 
                    (optional)
1941
 
 
1942
 
        :param default: The username returned if none is defined (optional).
1943
 
 
1944
1054
        :return: The found user.
1945
1055
        """
1946
1056
        credentials = self.get_credentials(scheme, host, port, user=None,
1947
 
                                           path=path, realm=realm)
 
1057
                                           path=path)
1948
1058
        if credentials is not None:
1949
1059
            user = credentials['user']
1950
1060
        else:
1951
1061
            user = None
1952
 
        if user is None:
1953
 
            if ask:
1954
 
                if prompt is None:
1955
 
                    # Create a default prompt suitable for most cases
1956
 
                    prompt = u'%s' % (scheme.upper(),) + u' %(host)s username'
1957
 
                # Special handling for optional fields in the prompt
1958
 
                if port is not None:
1959
 
                    prompt_host = '%s:%d' % (host, port)
1960
 
                else:
1961
 
                    prompt_host = host
1962
 
                user = ui.ui_factory.get_username(prompt, host=prompt_host)
1963
 
            else:
1964
 
                user = default
1965
1062
        return user
1966
1063
 
1967
1064
    def get_password(self, scheme, host, user, port=None,
1982
1079
 
1983
1080
        :return: The found password or the one entered by the user.
1984
1081
        """
1985
 
        credentials = self.get_credentials(scheme, host, port, user, path,
1986
 
                                           realm)
 
1082
        credentials = self.get_credentials(scheme, host, port, user, path)
1987
1083
        if credentials is not None:
1988
1084
            password = credentials['password']
1989
 
            if password is not None and scheme is 'ssh':
1990
 
                trace.warning('password ignored in section [%s],'
1991
 
                              ' use an ssh agent instead'
1992
 
                              % credentials['name'])
1993
 
                password = None
1994
1085
        else:
1995
1086
            password = None
1996
1087
        # Prompt user only if we could't find a password
1997
1088
        if password is None:
1998
1089
            if prompt is None:
1999
 
                # Create a default prompt suitable for most cases
2000
 
                prompt = u'%s' % scheme.upper() + u' %(user)s@%(host)s password'
 
1090
                # Create a default prompt suitable for most of the cases
 
1091
                prompt = '%s' % scheme.upper() + ' %(user)s@%(host)s password'
2001
1092
            # Special handling for optional fields in the prompt
2002
1093
            if port is not None:
2003
1094
                prompt_host = '%s:%d' % (host, port)
2008
1099
        return password
2009
1100
 
2010
1101
    def decode_password(self, credentials, encoding):
2011
 
        try:
2012
 
            cs = credential_store_registry.get_credential_store(encoding)
2013
 
        except KeyError:
2014
 
            raise ValueError('%r is not a known password_encoding' % encoding)
2015
 
        credentials['password'] = cs.decode_password(credentials)
2016
 
        return credentials
2017
 
 
2018
 
 
2019
 
class CredentialStoreRegistry(registry.Registry):
2020
 
    """A class that registers credential stores.
2021
 
 
2022
 
    A credential store provides access to credentials via the password_encoding
2023
 
    field in authentication.conf sections.
2024
 
 
2025
 
    Except for stores provided by bzr itself, most stores are expected to be
2026
 
    provided by plugins that will therefore use
2027
 
    register_lazy(password_encoding, module_name, member_name, help=help,
2028
 
    fallback=fallback) to install themselves.
2029
 
 
2030
 
    A fallback credential store is one that is queried if no credentials can be
2031
 
    found via authentication.conf.
2032
 
    """
2033
 
 
2034
 
    def get_credential_store(self, encoding=None):
2035
 
        cs = self.get(encoding)
2036
 
        if callable(cs):
2037
 
            cs = cs()
2038
 
        return cs
2039
 
 
2040
 
    def is_fallback(self, name):
2041
 
        """Check if the named credentials store should be used as fallback."""
2042
 
        return self.get_info(name)
2043
 
 
2044
 
    def get_fallback_credentials(self, scheme, host, port=None, user=None,
2045
 
                                 path=None, realm=None):
2046
 
        """Request credentials from all fallback credentials stores.
2047
 
 
2048
 
        The first credentials store that can provide credentials wins.
2049
 
        """
2050
 
        credentials = None
2051
 
        for name in self.keys():
2052
 
            if not self.is_fallback(name):
2053
 
                continue
2054
 
            cs = self.get_credential_store(name)
2055
 
            credentials = cs.get_credentials(scheme, host, port, user,
2056
 
                                             path, realm)
2057
 
            if credentials is not None:
2058
 
                # We found some credentials
2059
 
                break
2060
 
        return credentials
2061
 
 
2062
 
    def register(self, key, obj, help=None, override_existing=False,
2063
 
                 fallback=False):
2064
 
        """Register a new object to a name.
2065
 
 
2066
 
        :param key: This is the key to use to request the object later.
2067
 
        :param obj: The object to register.
2068
 
        :param help: Help text for this entry. This may be a string or
2069
 
                a callable. If it is a callable, it should take two
2070
 
                parameters (registry, key): this registry and the key that
2071
 
                the help was registered under.
2072
 
        :param override_existing: Raise KeyErorr if False and something has
2073
 
                already been registered for that key. If True, ignore if there
2074
 
                is an existing key (always register the new value).
2075
 
        :param fallback: Whether this credential store should be 
2076
 
                used as fallback.
2077
 
        """
2078
 
        return super(CredentialStoreRegistry,
2079
 
                     self).register(key, obj, help, info=fallback,
2080
 
                                    override_existing=override_existing)
2081
 
 
2082
 
    def register_lazy(self, key, module_name, member_name,
2083
 
                      help=None, override_existing=False,
2084
 
                      fallback=False):
2085
 
        """Register a new credential store to be loaded on request.
2086
 
 
2087
 
        :param module_name: The python path to the module. Such as 'os.path'.
2088
 
        :param member_name: The member of the module to return.  If empty or
2089
 
                None, get() will return the module itself.
2090
 
        :param help: Help text for this entry. This may be a string or
2091
 
                a callable.
2092
 
        :param override_existing: If True, replace the existing object
2093
 
                with the new one. If False, if there is already something
2094
 
                registered with the same key, raise a KeyError
2095
 
        :param fallback: Whether this credential store should be 
2096
 
                used as fallback.
2097
 
        """
2098
 
        return super(CredentialStoreRegistry, self).register_lazy(
2099
 
            key, module_name, member_name, help,
2100
 
            info=fallback, override_existing=override_existing)
2101
 
 
2102
 
 
2103
 
credential_store_registry = CredentialStoreRegistry()
2104
 
 
2105
 
 
2106
 
class CredentialStore(object):
2107
 
    """An abstract class to implement storage for credentials"""
2108
 
 
2109
 
    def decode_password(self, credentials):
2110
 
        """Returns a clear text password for the provided credentials."""
2111
 
        raise NotImplementedError(self.decode_password)
2112
 
 
2113
 
    def get_credentials(self, scheme, host, port=None, user=None, path=None,
2114
 
                        realm=None):
2115
 
        """Return the matching credentials from this credential store.
2116
 
 
2117
 
        This method is only called on fallback credential stores.
2118
 
        """
2119
 
        raise NotImplementedError(self.get_credentials)
2120
 
 
2121
 
 
2122
 
 
2123
 
class PlainTextCredentialStore(CredentialStore):
2124
 
    __doc__ = """Plain text credential store for the authentication.conf file"""
2125
 
 
2126
 
    def decode_password(self, credentials):
2127
 
        """See CredentialStore.decode_password."""
2128
 
        return credentials['password']
2129
 
 
2130
 
 
2131
 
credential_store_registry.register('plain', PlainTextCredentialStore,
2132
 
                                   help=PlainTextCredentialStore.__doc__)
2133
 
credential_store_registry.default_key = 'plain'
2134
 
 
2135
 
 
2136
 
class Base64CredentialStore(CredentialStore):
2137
 
    __doc__ = """Base64 credential store for the authentication.conf file"""
2138
 
 
2139
 
    def decode_password(self, credentials):
2140
 
        """See CredentialStore.decode_password."""
2141
 
        # GZ 2012-07-28: Will raise binascii.Error if password is not base64,
2142
 
        #                should probably propogate as something more useful.
2143
 
        return base64.decodestring(credentials['password'])
2144
 
 
2145
 
credential_store_registry.register('base64', Base64CredentialStore,
2146
 
                                   help=Base64CredentialStore.__doc__)
2147
 
 
2148
 
 
2149
 
class BzrDirConfig(object):
2150
 
 
2151
 
    def __init__(self, bzrdir):
2152
 
        self._bzrdir = bzrdir
2153
 
        self._config = bzrdir._get_config()
2154
 
 
2155
 
    def set_default_stack_on(self, value):
2156
 
        """Set the default stacking location.
2157
 
 
2158
 
        It may be set to a location, or None.
2159
 
 
2160
 
        This policy affects all branches contained by this control dir, except
2161
 
        for those under repositories.
2162
 
        """
2163
 
        if self._config is None:
2164
 
            raise errors.BzrError("Cannot set configuration in %s"
2165
 
                                  % self._bzrdir)
2166
 
        if value is None:
2167
 
            self._config.set_option('', 'default_stack_on')
2168
 
        else:
2169
 
            self._config.set_option(value, 'default_stack_on')
2170
 
 
2171
 
    def get_default_stack_on(self):
2172
 
        """Return the default stacking location.
2173
 
 
2174
 
        This will either be a location, or None.
2175
 
 
2176
 
        This policy affects all branches contained by this control dir, except
2177
 
        for those under repositories.
2178
 
        """
2179
 
        if self._config is None:
2180
 
            return None
2181
 
        value = self._config.get_option('default_stack_on')
2182
 
        if value == '':
2183
 
            value = None
2184
 
        return value
 
1102
        return credentials
2185
1103
 
2186
1104
 
2187
1105
class TransportConfig(object):
2188
1106
    """A Config that reads/writes a config file on a Transport.
2189
1107
 
2190
1108
    It is a low-level object that considers config data to be name/value pairs
2191
 
    that may be associated with a section.  Assigning meaning to these values
2192
 
    is done at higher levels like TreeConfig.
 
1109
    that may be associated with a section.  Assigning meaning to the these
 
1110
    values is done at higher levels like TreeConfig.
2193
1111
    """
2194
1112
 
2195
1113
    def __init__(self, transport, filename):
2212
1130
                section_obj = configobj[section]
2213
1131
            except KeyError:
2214
1132
                return default
2215
 
        value = section_obj.get(name, default)
2216
 
        for hook in OldConfigHooks['get']:
2217
 
            hook(self, name, value)
2218
 
        return value
 
1133
        return section_obj.get(name, default)
2219
1134
 
2220
1135
    def set_option(self, value, name, section=None):
2221
1136
        """Set the value associated with a named option.
2229
1144
            configobj[name] = value
2230
1145
        else:
2231
1146
            configobj.setdefault(section, {})[name] = value
2232
 
        for hook in OldConfigHooks['set']:
2233
 
            hook(self, name, value)
2234
 
        self._set_configobj(configobj)
2235
 
 
2236
 
    def remove_option(self, option_name, section_name=None):
2237
 
        configobj = self._get_configobj()
2238
 
        if section_name is None:
2239
 
            del configobj[option_name]
2240
 
        else:
2241
 
            del configobj[section_name][option_name]
2242
 
        for hook in OldConfigHooks['remove']:
2243
 
            hook(self, option_name)
2244
 
        self._set_configobj(configobj)
2245
 
 
2246
 
    def _get_config_file(self):
2247
 
        try:
2248
 
            f = StringIO(self._transport.get_bytes(self._filename))
2249
 
            for hook in OldConfigHooks['load']:
2250
 
                hook(self)
2251
 
            return f
2252
 
        except errors.NoSuchFile:
2253
 
            return StringIO()
2254
 
        except errors.PermissionDenied, e:
2255
 
            trace.warning("Permission denied while trying to open "
2256
 
                "configuration file %s.", urlutils.unescape_for_display(
2257
 
                urlutils.join(self._transport.base, self._filename), "utf-8"))
2258
 
            return StringIO()
2259
 
 
2260
 
    def _external_url(self):
2261
 
        return urlutils.join(self._transport.external_url(), self._filename)
 
1147
        self._set_configobj(configobj)
2262
1148
 
2263
1149
    def _get_configobj(self):
2264
 
        f = self._get_config_file()
2265
1150
        try:
2266
 
            try:
2267
 
                conf = ConfigObj(f, encoding='utf-8')
2268
 
            except configobj.ConfigObjError, e:
2269
 
                raise errors.ParseConfigError(e.errors, self._external_url())
2270
 
            except UnicodeDecodeError:
2271
 
                raise errors.ConfigContentError(self._external_url())
2272
 
        finally:
2273
 
            f.close()
2274
 
        return conf
 
1151
            return ConfigObj(self._transport.get(self._filename),
 
1152
                             encoding='utf-8')
 
1153
        except errors.NoSuchFile:
 
1154
            return ConfigObj(encoding='utf-8')
2275
1155
 
2276
1156
    def _set_configobj(self, configobj):
2277
1157
        out_file = StringIO()
2278
1158
        configobj.write(out_file)
2279
1159
        out_file.seek(0)
2280
1160
        self._transport.put_file(self._filename, out_file)
2281
 
        for hook in OldConfigHooks['save']:
2282
 
            hook(self)
2283
 
 
2284
 
 
2285
 
class Option(object):
2286
 
    """An option definition.
2287
 
 
2288
 
    The option *values* are stored in config files and found in sections.
2289
 
 
2290
 
    Here we define various properties about the option itself, its default
2291
 
    value, how to convert it from stores, what to do when invalid values are
2292
 
    encoutered, in which config files it can be stored.
2293
 
    """
2294
 
 
2295
 
    def __init__(self, name, override_from_env=None,
2296
 
                 default=None, default_from_env=None,
2297
 
                 help=None, from_unicode=None, invalid=None, unquote=True):
2298
 
        """Build an option definition.
2299
 
 
2300
 
        :param name: the name used to refer to the option.
2301
 
 
2302
 
        :param override_from_env: A list of environment variables which can
2303
 
           provide override any configuration setting.
2304
 
 
2305
 
        :param default: the default value to use when none exist in the config
2306
 
            stores. This is either a string that ``from_unicode`` will convert
2307
 
            into the proper type, a callable returning a unicode string so that
2308
 
            ``from_unicode`` can be used on the return value, or a python
2309
 
            object that can be stringified (so only the empty list is supported
2310
 
            for example).
2311
 
 
2312
 
        :param default_from_env: A list of environment variables which can
2313
 
           provide a default value. 'default' will be used only if none of the
2314
 
           variables specified here are set in the environment.
2315
 
 
2316
 
        :param help: a doc string to explain the option to the user.
2317
 
 
2318
 
        :param from_unicode: a callable to convert the unicode string
2319
 
            representing the option value in a store. This is not called for
2320
 
            the default value.
2321
 
 
2322
 
        :param invalid: the action to be taken when an invalid value is
2323
 
            encountered in a store. This is called only when from_unicode is
2324
 
            invoked to convert a string and returns None or raise ValueError or
2325
 
            TypeError. Accepted values are: None (ignore invalid values),
2326
 
            'warning' (emit a warning), 'error' (emit an error message and
2327
 
            terminates).
2328
 
 
2329
 
        :param unquote: should the unicode value be unquoted before conversion.
2330
 
           This should be used only when the store providing the values cannot
2331
 
           safely unquote them (see http://pad.lv/906897). It is provided so
2332
 
           daughter classes can handle the quoting themselves.
2333
 
        """
2334
 
        if override_from_env is None:
2335
 
            override_from_env = []
2336
 
        if default_from_env is None:
2337
 
            default_from_env = []
2338
 
        self.name = name
2339
 
        self.override_from_env = override_from_env
2340
 
        # Convert the default value to a unicode string so all values are
2341
 
        # strings internally before conversion (via from_unicode) is attempted.
2342
 
        if default is None:
2343
 
            self.default = None
2344
 
        elif isinstance(default, list):
2345
 
            # Only the empty list is supported
2346
 
            if default:
2347
 
                raise AssertionError(
2348
 
                    'Only empty lists are supported as default values')
2349
 
            self.default = u','
2350
 
        elif isinstance(default, (str, unicode, bool, int, float)):
2351
 
            # Rely on python to convert strings, booleans and integers
2352
 
            self.default = u'%s' % (default,)
2353
 
        elif callable(default):
2354
 
            self.default = default
2355
 
        else:
2356
 
            # other python objects are not expected
2357
 
            raise AssertionError('%r is not supported as a default value'
2358
 
                                 % (default,))
2359
 
        self.default_from_env = default_from_env
2360
 
        self._help = help
2361
 
        self.from_unicode = from_unicode
2362
 
        self.unquote = unquote
2363
 
        if invalid and invalid not in ('warning', 'error'):
2364
 
            raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2365
 
        self.invalid = invalid
2366
 
 
2367
 
    @property
2368
 
    def help(self):
2369
 
        return self._help
2370
 
 
2371
 
    def convert_from_unicode(self, store, unicode_value):
2372
 
        if self.unquote and store is not None and unicode_value is not None:
2373
 
            unicode_value = store.unquote(unicode_value)
2374
 
        if self.from_unicode is None or unicode_value is None:
2375
 
            # Don't convert or nothing to convert
2376
 
            return unicode_value
2377
 
        try:
2378
 
            converted = self.from_unicode(unicode_value)
2379
 
        except (ValueError, TypeError):
2380
 
            # Invalid values are ignored
2381
 
            converted = None
2382
 
        if converted is None and self.invalid is not None:
2383
 
            # The conversion failed
2384
 
            if self.invalid == 'warning':
2385
 
                trace.warning('Value "%s" is not valid for "%s"',
2386
 
                              unicode_value, self.name)
2387
 
            elif self.invalid == 'error':
2388
 
                raise errors.ConfigOptionValueError(self.name, unicode_value)
2389
 
        return converted
2390
 
 
2391
 
    def get_override(self):
2392
 
        value = None
2393
 
        for var in self.override_from_env:
2394
 
            try:
2395
 
                # If the env variable is defined, its value takes precedence
2396
 
                value = os.environ[var].decode(osutils.get_user_encoding())
2397
 
                break
2398
 
            except KeyError:
2399
 
                continue
2400
 
        return value
2401
 
 
2402
 
    def get_default(self):
2403
 
        value = None
2404
 
        for var in self.default_from_env:
2405
 
            try:
2406
 
                # If the env variable is defined, its value is the default one
2407
 
                value = os.environ[var].decode(osutils.get_user_encoding())
2408
 
                break
2409
 
            except KeyError:
2410
 
                continue
2411
 
        if value is None:
2412
 
            # Otherwise, fallback to the value defined at registration
2413
 
            if callable(self.default):
2414
 
                value = self.default()
2415
 
                if not isinstance(value, unicode):
2416
 
                    raise AssertionError(
2417
 
                        "Callable default value for '%s' should be unicode"
2418
 
                        % (self.name))
2419
 
            else:
2420
 
                value = self.default
2421
 
        return value
2422
 
 
2423
 
    def get_help_topic(self):
2424
 
        return self.name
2425
 
 
2426
 
    def get_help_text(self, additional_see_also=None, plain=True):
2427
 
        result = self.help
2428
 
        from bzrlib import help_topics
2429
 
        result += help_topics._format_see_also(additional_see_also)
2430
 
        if plain:
2431
 
            result = help_topics.help_as_plain_text(result)
2432
 
        return result
2433
 
 
2434
 
 
2435
 
# Predefined converters to get proper values from store
2436
 
 
2437
 
def bool_from_store(unicode_str):
2438
 
    return ui.bool_from_string(unicode_str)
2439
 
 
2440
 
 
2441
 
def int_from_store(unicode_str):
2442
 
    return int(unicode_str)
2443
 
 
2444
 
 
2445
 
_unit_suffixes = dict(K=10**3, M=10**6, G=10**9)
2446
 
 
2447
 
def int_SI_from_store(unicode_str):
2448
 
    """Convert a human readable size in SI units, e.g 10MB into an integer.
2449
 
 
2450
 
    Accepted suffixes are K,M,G. It is case-insensitive and may be followed
2451
 
    by a trailing b (i.e. Kb, MB). This is intended to be practical and not
2452
 
    pedantic.
2453
 
 
2454
 
    :return Integer, expanded to its base-10 value if a proper SI unit is 
2455
 
        found, None otherwise.
2456
 
    """
2457
 
    regexp = "^(\d+)(([" + ''.join(_unit_suffixes) + "])b?)?$"
2458
 
    p = re.compile(regexp, re.IGNORECASE)
2459
 
    m = p.match(unicode_str)
2460
 
    val = None
2461
 
    if m is not None:
2462
 
        val, _, unit = m.groups()
2463
 
        val = int(val)
2464
 
        if unit:
2465
 
            try:
2466
 
                coeff = _unit_suffixes[unit.upper()]
2467
 
            except KeyError:
2468
 
                raise ValueError(gettext('{0} is not an SI unit.').format(unit))
2469
 
            val *= coeff
2470
 
    return val
2471
 
 
2472
 
 
2473
 
def float_from_store(unicode_str):
2474
 
    return float(unicode_str)
2475
 
 
2476
 
 
2477
 
# Use an empty dict to initialize an empty configobj avoiding all parsing and
2478
 
# encoding checks
2479
 
_list_converter_config = configobj.ConfigObj(
2480
 
    {}, encoding='utf-8', list_values=True, interpolation=False)
2481
 
 
2482
 
 
2483
 
class ListOption(Option):
2484
 
 
2485
 
    def __init__(self, name, default=None, default_from_env=None,
2486
 
                 help=None, invalid=None):
2487
 
        """A list Option definition.
2488
 
 
2489
 
        This overrides the base class so the conversion from a unicode string
2490
 
        can take quoting into account.
2491
 
        """
2492
 
        super(ListOption, self).__init__(
2493
 
            name, default=default, default_from_env=default_from_env,
2494
 
            from_unicode=self.from_unicode, help=help,
2495
 
            invalid=invalid, unquote=False)
2496
 
 
2497
 
    def from_unicode(self, unicode_str):
2498
 
        if not isinstance(unicode_str, basestring):
2499
 
            raise TypeError
2500
 
        # Now inject our string directly as unicode. All callers got their
2501
 
        # value from configobj, so values that need to be quoted are already
2502
 
        # properly quoted.
2503
 
        _list_converter_config.reset()
2504
 
        _list_converter_config._parse([u"list=%s" % (unicode_str,)])
2505
 
        maybe_list = _list_converter_config['list']
2506
 
        if isinstance(maybe_list, basestring):
2507
 
            if maybe_list:
2508
 
                # A single value, most probably the user forgot (or didn't care
2509
 
                # to add) the final ','
2510
 
                l = [maybe_list]
2511
 
            else:
2512
 
                # The empty string, convert to empty list
2513
 
                l = []
2514
 
        else:
2515
 
            # We rely on ConfigObj providing us with a list already
2516
 
            l = maybe_list
2517
 
        return l
2518
 
 
2519
 
 
2520
 
class RegistryOption(Option):
2521
 
    """Option for a choice from a registry."""
2522
 
 
2523
 
    def __init__(self, name, registry, default_from_env=None,
2524
 
                 help=None, invalid=None):
2525
 
        """A registry based Option definition.
2526
 
 
2527
 
        This overrides the base class so the conversion from a unicode string
2528
 
        can take quoting into account.
2529
 
        """
2530
 
        super(RegistryOption, self).__init__(
2531
 
            name, default=lambda: unicode(registry.default_key),
2532
 
            default_from_env=default_from_env,
2533
 
            from_unicode=self.from_unicode, help=help,
2534
 
            invalid=invalid, unquote=False)
2535
 
        self.registry = registry
2536
 
 
2537
 
    def from_unicode(self, unicode_str):
2538
 
        if not isinstance(unicode_str, basestring):
2539
 
            raise TypeError
2540
 
        try:
2541
 
            return self.registry.get(unicode_str)
2542
 
        except KeyError:
2543
 
            raise ValueError(
2544
 
                "Invalid value %s for %s."
2545
 
                "See help for a list of possible values." % (unicode_str,
2546
 
                    self.name))
2547
 
 
2548
 
    @property
2549
 
    def help(self):
2550
 
        ret = [self._help, "\n\nThe following values are supported:\n"]
2551
 
        for key in self.registry.keys():
2552
 
            ret.append(" %s - %s\n" % (key, self.registry.get_help(key)))
2553
 
        return "".join(ret)
2554
 
 
2555
 
 
2556
 
class OptionRegistry(registry.Registry):
2557
 
    """Register config options by their name.
2558
 
 
2559
 
    This overrides ``registry.Registry`` to simplify registration by acquiring
2560
 
    some information from the option object itself.
2561
 
    """
2562
 
 
2563
 
    def register(self, option):
2564
 
        """Register a new option to its name.
2565
 
 
2566
 
        :param option: The option to register. Its name is used as the key.
2567
 
        """
2568
 
        super(OptionRegistry, self).register(option.name, option,
2569
 
                                             help=option.help)
2570
 
 
2571
 
    def register_lazy(self, key, module_name, member_name):
2572
 
        """Register a new option to be loaded on request.
2573
 
 
2574
 
        :param key: the key to request the option later. Since the registration
2575
 
            is lazy, it should be provided and match the option name.
2576
 
 
2577
 
        :param module_name: the python path to the module. Such as 'os.path'.
2578
 
 
2579
 
        :param member_name: the member of the module to return.  If empty or 
2580
 
                None, get() will return the module itself.
2581
 
        """
2582
 
        super(OptionRegistry, self).register_lazy(key,
2583
 
                                                  module_name, member_name)
2584
 
 
2585
 
    def get_help(self, key=None):
2586
 
        """Get the help text associated with the given key"""
2587
 
        option = self.get(key)
2588
 
        the_help = option.help
2589
 
        if callable(the_help):
2590
 
            return the_help(self, key)
2591
 
        return the_help
2592
 
 
2593
 
 
2594
 
option_registry = OptionRegistry()
2595
 
 
2596
 
 
2597
 
# Registered options in lexicographical order
2598
 
 
2599
 
option_registry.register(
2600
 
    Option('append_revisions_only',
2601
 
           default=None, from_unicode=bool_from_store, invalid='warning',
2602
 
           help='''\
2603
 
Whether to only append revisions to the mainline.
2604
 
 
2605
 
If this is set to true, then it is not possible to change the
2606
 
existing mainline of the branch.
2607
 
'''))
2608
 
option_registry.register(
2609
 
    ListOption('acceptable_keys',
2610
 
           default=None,
2611
 
           help="""\
2612
 
List of GPG key patterns which are acceptable for verification.
2613
 
"""))
2614
 
option_registry.register(
2615
 
    Option('add.maximum_file_size',
2616
 
           default=u'20MB', from_unicode=int_SI_from_store,
2617
 
           help="""\
2618
 
Size above which files should be added manually.
2619
 
 
2620
 
Files below this size are added automatically when using ``bzr add`` without
2621
 
arguments.
2622
 
 
2623
 
A negative value means disable the size check.
2624
 
"""))
2625
 
option_registry.register(
2626
 
    Option('bound',
2627
 
           default=None, from_unicode=bool_from_store,
2628
 
           help="""\
2629
 
Is the branch bound to ``bound_location``.
2630
 
 
2631
 
If set to "True", the branch should act as a checkout, and push each commit to
2632
 
the bound_location.  This option is normally set by ``bind``/``unbind``.
2633
 
 
2634
 
See also: bound_location.
2635
 
"""))
2636
 
option_registry.register(
2637
 
    Option('bound_location',
2638
 
           default=None,
2639
 
           help="""\
2640
 
The location that commits should go to when acting as a checkout.
2641
 
 
2642
 
This option is normally set by ``bind``.
2643
 
 
2644
 
See also: bound.
2645
 
"""))
2646
 
option_registry.register(
2647
 
    Option('branch.fetch_tags', default=False,  from_unicode=bool_from_store,
2648
 
           help="""\
2649
 
Whether revisions associated with tags should be fetched.
2650
 
"""))
2651
 
option_registry.register_lazy(
2652
 
    'bzr.transform.orphan_policy', 'bzrlib.transform', 'opt_transform_orphan')
2653
 
option_registry.register(
2654
 
    Option('bzr.workingtree.worth_saving_limit', default=10,
2655
 
           from_unicode=int_from_store,  invalid='warning',
2656
 
           help='''\
2657
 
How many changes before saving the dirstate.
2658
 
 
2659
 
-1 means that we will never rewrite the dirstate file for only
2660
 
stat-cache changes. Regardless of this setting, we will always rewrite
2661
 
the dirstate file if a file is added/removed/renamed/etc. This flag only
2662
 
affects the behavior of updating the dirstate file after we notice that
2663
 
a file has been touched.
2664
 
'''))
2665
 
option_registry.register(
2666
 
    Option('bugtracker', default=None,
2667
 
           help='''\
2668
 
Default bug tracker to use.
2669
 
 
2670
 
This bug tracker will be used for example when marking bugs
2671
 
as fixed using ``bzr commit --fixes``, if no explicit
2672
 
bug tracker was specified.
2673
 
'''))
2674
 
option_registry.register(
2675
 
    Option('check_signatures', default=CHECK_IF_POSSIBLE,
2676
 
           from_unicode=signature_policy_from_unicode,
2677
 
           help='''\
2678
 
GPG checking policy.
2679
 
 
2680
 
Possible values: require, ignore, check-available (default)
2681
 
 
2682
 
this option will control whether bzr will require good gpg
2683
 
signatures, ignore them, or check them if they are
2684
 
present.
2685
 
'''))
2686
 
option_registry.register(
2687
 
    Option('child_submit_format',
2688
 
           help='''The preferred format of submissions to this branch.'''))
2689
 
option_registry.register(
2690
 
    Option('child_submit_to',
2691
 
           help='''Where submissions to this branch are mailed to.'''))
2692
 
option_registry.register(
2693
 
    Option('create_signatures', default=SIGN_WHEN_REQUIRED,
2694
 
           from_unicode=signing_policy_from_unicode,
2695
 
           help='''\
2696
 
GPG Signing policy.
2697
 
 
2698
 
Possible values: always, never, when-required (default)
2699
 
 
2700
 
This option controls whether bzr will always create
2701
 
gpg signatures or not on commits.
2702
 
'''))
2703
 
option_registry.register(
2704
 
    Option('dirstate.fdatasync', default=True,
2705
 
           from_unicode=bool_from_store,
2706
 
           help='''\
2707
 
Flush dirstate changes onto physical disk?
2708
 
 
2709
 
If true (default), working tree metadata changes are flushed through the
2710
 
OS buffers to physical disk.  This is somewhat slower, but means data
2711
 
should not be lost if the machine crashes.  See also repository.fdatasync.
2712
 
'''))
2713
 
option_registry.register(
2714
 
    ListOption('debug_flags', default=[],
2715
 
           help='Debug flags to activate.'))
2716
 
option_registry.register(
2717
 
    Option('default_format', default='2a',
2718
 
           help='Format used when creating branches.'))
2719
 
option_registry.register(
2720
 
    Option('dpush_strict', default=None,
2721
 
           from_unicode=bool_from_store,
2722
 
           help='''\
2723
 
The default value for ``dpush --strict``.
2724
 
 
2725
 
If present, defines the ``--strict`` option default value for checking
2726
 
uncommitted changes before pushing into a different VCS without any
2727
 
custom bzr metadata.
2728
 
'''))
2729
 
option_registry.register(
2730
 
    Option('editor',
2731
 
           help='The command called to launch an editor to enter a message.'))
2732
 
option_registry.register(
2733
 
    Option('email', override_from_env=['BZR_EMAIL'], default=default_email,
2734
 
           help='The users identity'))
2735
 
option_registry.register(
2736
 
    Option('gpg_signing_command',
2737
 
           default='gpg',
2738
 
           help="""\
2739
 
Program to use use for creating signatures.
2740
 
 
2741
 
This should support at least the -u and --clearsign options.
2742
 
"""))
2743
 
option_registry.register(
2744
 
    Option('gpg_signing_key',
2745
 
           default=None,
2746
 
           help="""\
2747
 
GPG key to use for signing.
2748
 
 
2749
 
This defaults to the first key associated with the users email.
2750
 
"""))
2751
 
option_registry.register(
2752
 
    Option('ignore_missing_extensions', default=False,
2753
 
           from_unicode=bool_from_store,
2754
 
           help='''\
2755
 
Control the missing extensions warning display.
2756
 
 
2757
 
The warning will not be emitted if set to True.
2758
 
'''))
2759
 
option_registry.register(
2760
 
    Option('language',
2761
 
           help='Language to translate messages into.'))
2762
 
option_registry.register(
2763
 
    Option('locks.steal_dead', default=False, from_unicode=bool_from_store,
2764
 
           help='''\
2765
 
Steal locks that appears to be dead.
2766
 
 
2767
 
If set to True, bzr will check if a lock is supposed to be held by an
2768
 
active process from the same user on the same machine. If the user and
2769
 
machine match, but no process with the given PID is active, then bzr
2770
 
will automatically break the stale lock, and create a new lock for
2771
 
this process.
2772
 
Otherwise, bzr will prompt as normal to break the lock.
2773
 
'''))
2774
 
option_registry.register(
2775
 
    Option('log_format', default='long',
2776
 
           help= '''\
2777
 
Log format to use when displaying revisions.
2778
 
 
2779
 
Standard log formats are ``long``, ``short`` and ``line``. Additional formats
2780
 
may be provided by plugins.
2781
 
'''))
2782
 
option_registry.register_lazy('mail_client', 'bzrlib.mail_client',
2783
 
    'opt_mail_client')
2784
 
option_registry.register(
2785
 
    Option('output_encoding',
2786
 
           help= 'Unicode encoding for output'
2787
 
           ' (terminal encoding if not specified).'))
2788
 
option_registry.register(
2789
 
    Option('parent_location',
2790
 
           default=None,
2791
 
           help="""\
2792
 
The location of the default branch for pull or merge.
2793
 
 
2794
 
This option is normally set when creating a branch, the first ``pull`` or by
2795
 
``pull --remember``.
2796
 
"""))
2797
 
option_registry.register(
2798
 
    Option('post_commit', default=None,
2799
 
           help='''\
2800
 
Post commit functions.
2801
 
 
2802
 
An ordered list of python functions to call, separated by spaces.
2803
 
 
2804
 
Each function takes branch, rev_id as parameters.
2805
 
'''))
2806
 
option_registry.register_lazy('progress_bar', 'bzrlib.ui.text',
2807
 
                              'opt_progress_bar')
2808
 
option_registry.register(
2809
 
    Option('public_branch',
2810
 
           default=None,
2811
 
           help="""\
2812
 
A publically-accessible version of this branch.
2813
 
 
2814
 
This implies that the branch setting this option is not publically-accessible.
2815
 
Used and set by ``bzr send``.
2816
 
"""))
2817
 
option_registry.register(
2818
 
    Option('push_location',
2819
 
           default=None,
2820
 
           help="""\
2821
 
The location of the default branch for push.
2822
 
 
2823
 
This option is normally set by the first ``push`` or ``push --remember``.
2824
 
"""))
2825
 
option_registry.register(
2826
 
    Option('push_strict', default=None,
2827
 
           from_unicode=bool_from_store,
2828
 
           help='''\
2829
 
The default value for ``push --strict``.
2830
 
 
2831
 
If present, defines the ``--strict`` option default value for checking
2832
 
uncommitted changes before sending a merge directive.
2833
 
'''))
2834
 
option_registry.register(
2835
 
    Option('repository.fdatasync', default=True,
2836
 
           from_unicode=bool_from_store,
2837
 
           help='''\
2838
 
Flush repository changes onto physical disk?
2839
 
 
2840
 
If true (default), repository changes are flushed through the OS buffers
2841
 
to physical disk.  This is somewhat slower, but means data should not be
2842
 
lost if the machine crashes.  See also dirstate.fdatasync.
2843
 
'''))
2844
 
option_registry.register_lazy('smtp_server',
2845
 
    'bzrlib.smtp_connection', 'smtp_server')
2846
 
option_registry.register_lazy('smtp_password',
2847
 
    'bzrlib.smtp_connection', 'smtp_password')
2848
 
option_registry.register_lazy('smtp_username',
2849
 
    'bzrlib.smtp_connection', 'smtp_username')
2850
 
option_registry.register(
2851
 
    Option('selftest.timeout',
2852
 
        default='600',
2853
 
        from_unicode=int_from_store,
2854
 
        help='Abort selftest if one test takes longer than this many seconds',
2855
 
        ))
2856
 
 
2857
 
option_registry.register(
2858
 
    Option('send_strict', default=None,
2859
 
           from_unicode=bool_from_store,
2860
 
           help='''\
2861
 
The default value for ``send --strict``.
2862
 
 
2863
 
If present, defines the ``--strict`` option default value for checking
2864
 
uncommitted changes before sending a bundle.
2865
 
'''))
2866
 
 
2867
 
option_registry.register(
2868
 
    Option('serve.client_timeout',
2869
 
           default=300.0, from_unicode=float_from_store,
2870
 
           help="If we wait for a new request from a client for more than"
2871
 
                " X seconds, consider the client idle, and hangup."))
2872
 
option_registry.register(
2873
 
    Option('stacked_on_location',
2874
 
           default=None,
2875
 
           help="""The location where this branch is stacked on."""))
2876
 
option_registry.register(
2877
 
    Option('submit_branch',
2878
 
           default=None,
2879
 
           help="""\
2880
 
The branch you intend to submit your current work to.
2881
 
 
2882
 
This is automatically set by ``bzr send`` and ``bzr merge``, and is also used
2883
 
by the ``submit:`` revision spec.
2884
 
"""))
2885
 
option_registry.register(
2886
 
    Option('submit_to',
2887
 
           help='''Where submissions from this branch are mailed to.'''))
2888
 
option_registry.register(
2889
 
    ListOption('suppress_warnings',
2890
 
           default=[],
2891
 
           help="List of warning classes to suppress."))
2892
 
option_registry.register(
2893
 
    Option('validate_signatures_in_log', default=False,
2894
 
           from_unicode=bool_from_store, invalid='warning',
2895
 
           help='''Whether to validate signatures in bzr log.'''))
2896
 
option_registry.register_lazy('ssl.ca_certs',
2897
 
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_ca_certs')
2898
 
 
2899
 
option_registry.register_lazy('ssl.cert_reqs',
2900
 
    'bzrlib.transport.http._urllib2_wrappers', 'opt_ssl_cert_reqs')
2901
 
 
2902
 
 
2903
 
class Section(object):
2904
 
    """A section defines a dict of option name => value.
2905
 
 
2906
 
    This is merely a read-only dict which can add some knowledge about the
2907
 
    options. It is *not* a python dict object though and doesn't try to mimic
2908
 
    its API.
2909
 
    """
2910
 
 
2911
 
    def __init__(self, section_id, options):
2912
 
        self.id = section_id
2913
 
        # We re-use the dict-like object received
2914
 
        self.options = options
2915
 
 
2916
 
    def get(self, name, default=None, expand=True):
2917
 
        return self.options.get(name, default)
2918
 
 
2919
 
    def iter_option_names(self):
2920
 
        for k in self.options.iterkeys():
2921
 
            yield k
2922
 
 
2923
 
    def __repr__(self):
2924
 
        # Mostly for debugging use
2925
 
        return "<config.%s id=%s>" % (self.__class__.__name__, self.id)
2926
 
 
2927
 
 
2928
 
_NewlyCreatedOption = object()
2929
 
"""Was the option created during the MutableSection lifetime"""
2930
 
_DeletedOption = object()
2931
 
"""Was the option deleted during the MutableSection lifetime"""
2932
 
 
2933
 
 
2934
 
class MutableSection(Section):
2935
 
    """A section allowing changes and keeping track of the original values."""
2936
 
 
2937
 
    def __init__(self, section_id, options):
2938
 
        super(MutableSection, self).__init__(section_id, options)
2939
 
        self.reset_changes()
2940
 
 
2941
 
    def set(self, name, value):
2942
 
        if name not in self.options:
2943
 
            # This is a new option
2944
 
            self.orig[name] = _NewlyCreatedOption
2945
 
        elif name not in self.orig:
2946
 
            self.orig[name] = self.get(name, None)
2947
 
        self.options[name] = value
2948
 
 
2949
 
    def remove(self, name):
2950
 
        if name not in self.orig and name in self.options:
2951
 
            self.orig[name] = self.get(name, None)
2952
 
        del self.options[name]
2953
 
 
2954
 
    def reset_changes(self):
2955
 
        self.orig = {}
2956
 
 
2957
 
    def apply_changes(self, dirty, store):
2958
 
        """Apply option value changes.
2959
 
 
2960
 
        ``self`` has been reloaded from the persistent storage. ``dirty``
2961
 
        contains the changes made since the previous loading.
2962
 
 
2963
 
        :param dirty: the mutable section containing the changes.
2964
 
 
2965
 
        :param store: the store containing the section
2966
 
        """
2967
 
        for k, expected in dirty.orig.iteritems():
2968
 
            actual = dirty.get(k, _DeletedOption)
2969
 
            reloaded = self.get(k, _NewlyCreatedOption)
2970
 
            if actual is _DeletedOption:
2971
 
                if k in self.options:
2972
 
                    self.remove(k)
2973
 
            else:
2974
 
                self.set(k, actual)
2975
 
            # Report concurrent updates in an ad-hoc way. This should only
2976
 
            # occurs when different processes try to update the same option
2977
 
            # which is not supported (as in: the config framework is not meant
2978
 
            # to be used as a sharing mechanism).
2979
 
            if expected != reloaded:
2980
 
                if actual is _DeletedOption:
2981
 
                    actual = '<DELETED>'
2982
 
                if reloaded is _NewlyCreatedOption:
2983
 
                    reloaded = '<CREATED>'
2984
 
                if expected is _NewlyCreatedOption:
2985
 
                    expected = '<CREATED>'
2986
 
                # Someone changed the value since we get it from the persistent
2987
 
                # storage.
2988
 
                trace.warning(gettext(
2989
 
                        "Option {0} in section {1} of {2} was changed"
2990
 
                        " from {3} to {4}. The {5} value will be saved.".format(
2991
 
                            k, self.id, store.external_url(), expected,
2992
 
                            reloaded, actual)))
2993
 
        # No need to keep track of these changes
2994
 
        self.reset_changes()
2995
 
 
2996
 
 
2997
 
class Store(object):
2998
 
    """Abstract interface to persistent storage for configuration options."""
2999
 
 
3000
 
    readonly_section_class = Section
3001
 
    mutable_section_class = MutableSection
3002
 
 
3003
 
    def __init__(self):
3004
 
        # Which sections need to be saved (by section id). We use a dict here
3005
 
        # so the dirty sections can be shared by multiple callers.
3006
 
        self.dirty_sections = {}
3007
 
 
3008
 
    def is_loaded(self):
3009
 
        """Returns True if the Store has been loaded.
3010
 
 
3011
 
        This is used to implement lazy loading and ensure the persistent
3012
 
        storage is queried only when needed.
3013
 
        """
3014
 
        raise NotImplementedError(self.is_loaded)
3015
 
 
3016
 
    def load(self):
3017
 
        """Loads the Store from persistent storage."""
3018
 
        raise NotImplementedError(self.load)
3019
 
 
3020
 
    def _load_from_string(self, bytes):
3021
 
        """Create a store from a string in configobj syntax.
3022
 
 
3023
 
        :param bytes: A string representing the file content.
3024
 
        """
3025
 
        raise NotImplementedError(self._load_from_string)
3026
 
 
3027
 
    def unload(self):
3028
 
        """Unloads the Store.
3029
 
 
3030
 
        This should make is_loaded() return False. This is used when the caller
3031
 
        knows that the persistent storage has changed or may have change since
3032
 
        the last load.
3033
 
        """
3034
 
        raise NotImplementedError(self.unload)
3035
 
 
3036
 
    def quote(self, value):
3037
 
        """Quote a configuration option value for storing purposes.
3038
 
 
3039
 
        This allows Stacks to present values as they will be stored.
3040
 
        """
3041
 
        return value
3042
 
 
3043
 
    def unquote(self, value):
3044
 
        """Unquote a configuration option value into unicode.
3045
 
 
3046
 
        The received value is quoted as stored.
3047
 
        """
3048
 
        return value
3049
 
 
3050
 
    def save(self):
3051
 
        """Saves the Store to persistent storage."""
3052
 
        raise NotImplementedError(self.save)
3053
 
 
3054
 
    def _need_saving(self):
3055
 
        for s in self.dirty_sections.values():
3056
 
            if s.orig:
3057
 
                # At least one dirty section contains a modification
3058
 
                return True
3059
 
        return False
3060
 
 
3061
 
    def apply_changes(self, dirty_sections):
3062
 
        """Apply changes from dirty sections while checking for coherency.
3063
 
 
3064
 
        The Store content is discarded and reloaded from persistent storage to
3065
 
        acquire up-to-date values.
3066
 
 
3067
 
        Dirty sections are MutableSection which kept track of the value they
3068
 
        are expected to update.
3069
 
        """
3070
 
        # We need an up-to-date version from the persistent storage, unload the
3071
 
        # store. The reload will occur when needed (triggered by the first
3072
 
        # get_mutable_section() call below.
3073
 
        self.unload()
3074
 
        # Apply the changes from the preserved dirty sections
3075
 
        for section_id, dirty in dirty_sections.iteritems():
3076
 
            clean = self.get_mutable_section(section_id)
3077
 
            clean.apply_changes(dirty, self)
3078
 
        # Everything is clean now
3079
 
        self.dirty_sections = {}
3080
 
 
3081
 
    def save_changes(self):
3082
 
        """Saves the Store to persistent storage if changes occurred.
3083
 
 
3084
 
        Apply the changes recorded in the mutable sections to a store content
3085
 
        refreshed from persistent storage.
3086
 
        """
3087
 
        raise NotImplementedError(self.save_changes)
3088
 
 
3089
 
    def external_url(self):
3090
 
        raise NotImplementedError(self.external_url)
3091
 
 
3092
 
    def get_sections(self):
3093
 
        """Returns an ordered iterable of existing sections.
3094
 
 
3095
 
        :returns: An iterable of (store, section).
3096
 
        """
3097
 
        raise NotImplementedError(self.get_sections)
3098
 
 
3099
 
    def get_mutable_section(self, section_id=None):
3100
 
        """Returns the specified mutable section.
3101
 
 
3102
 
        :param section_id: The section identifier
3103
 
        """
3104
 
        raise NotImplementedError(self.get_mutable_section)
3105
 
 
3106
 
    def __repr__(self):
3107
 
        # Mostly for debugging use
3108
 
        return "<config.%s(%s)>" % (self.__class__.__name__,
3109
 
                                    self.external_url())
3110
 
 
3111
 
 
3112
 
class CommandLineStore(Store):
3113
 
    "A store to carry command line overrides for the config options."""
3114
 
 
3115
 
    def __init__(self, opts=None):
3116
 
        super(CommandLineStore, self).__init__()
3117
 
        if opts is None:
3118
 
            opts = {}
3119
 
        self.options = {}
3120
 
        self.id = 'cmdline'
3121
 
 
3122
 
    def _reset(self):
3123
 
        # The dict should be cleared but not replaced so it can be shared.
3124
 
        self.options.clear()
3125
 
 
3126
 
    def _from_cmdline(self, overrides):
3127
 
        # Reset before accepting new definitions
3128
 
        self._reset()
3129
 
        for over in overrides:
3130
 
            try:
3131
 
                name, value = over.split('=', 1)
3132
 
            except ValueError:
3133
 
                raise errors.BzrCommandError(
3134
 
                    gettext("Invalid '%s', should be of the form 'name=value'")
3135
 
                    % (over,))
3136
 
            self.options[name] = value
3137
 
 
3138
 
    def external_url(self):
3139
 
        # Not an url but it makes debugging easier and is never needed
3140
 
        # otherwise
3141
 
        return 'cmdline'
3142
 
 
3143
 
    def get_sections(self):
3144
 
        yield self,  self.readonly_section_class(None, self.options)
3145
 
 
3146
 
 
3147
 
class IniFileStore(Store):
3148
 
    """A config Store using ConfigObj for storage.
3149
 
 
3150
 
    :ivar _config_obj: Private member to hold the ConfigObj instance used to
3151
 
        serialize/deserialize the config file.
3152
 
    """
3153
 
 
3154
 
    def __init__(self):
3155
 
        """A config Store using ConfigObj for storage.
3156
 
        """
3157
 
        super(IniFileStore, self).__init__()
3158
 
        self._config_obj = None
3159
 
 
3160
 
    def is_loaded(self):
3161
 
        return self._config_obj != None
3162
 
 
3163
 
    def unload(self):
3164
 
        self._config_obj = None
3165
 
        self.dirty_sections = {}
3166
 
 
3167
 
    def _load_content(self):
3168
 
        """Load the config file bytes.
3169
 
 
3170
 
        This should be provided by subclasses
3171
 
 
3172
 
        :return: Byte string
3173
 
        """
3174
 
        raise NotImplementedError(self._load_content)
3175
 
 
3176
 
    def _save_content(self, content):
3177
 
        """Save the config file bytes.
3178
 
 
3179
 
        This should be provided by subclasses
3180
 
 
3181
 
        :param content: Config file bytes to write
3182
 
        """
3183
 
        raise NotImplementedError(self._save_content)
3184
 
 
3185
 
    def load(self):
3186
 
        """Load the store from the associated file."""
3187
 
        if self.is_loaded():
3188
 
            return
3189
 
        content = self._load_content()
3190
 
        self._load_from_string(content)
3191
 
        for hook in ConfigHooks['load']:
3192
 
            hook(self)
3193
 
 
3194
 
    def _load_from_string(self, bytes):
3195
 
        """Create a config store from a string.
3196
 
 
3197
 
        :param bytes: A string representing the file content.
3198
 
        """
3199
 
        if self.is_loaded():
3200
 
            raise AssertionError('Already loaded: %r' % (self._config_obj,))
3201
 
        co_input = StringIO(bytes)
3202
 
        try:
3203
 
            # The config files are always stored utf8-encoded
3204
 
            self._config_obj = ConfigObj(co_input, encoding='utf-8',
3205
 
                                         list_values=False)
3206
 
        except configobj.ConfigObjError, e:
3207
 
            self._config_obj = None
3208
 
            raise errors.ParseConfigError(e.errors, self.external_url())
3209
 
        except UnicodeDecodeError:
3210
 
            raise errors.ConfigContentError(self.external_url())
3211
 
 
3212
 
    def save_changes(self):
3213
 
        if not self.is_loaded():
3214
 
            # Nothing to save
3215
 
            return
3216
 
        if not self._need_saving():
3217
 
            return
3218
 
        # Preserve the current version
3219
 
        dirty_sections = dict(self.dirty_sections.items())
3220
 
        self.apply_changes(dirty_sections)
3221
 
        # Save to the persistent storage
3222
 
        self.save()
3223
 
 
3224
 
    def save(self):
3225
 
        if not self.is_loaded():
3226
 
            # Nothing to save
3227
 
            return
3228
 
        out = StringIO()
3229
 
        self._config_obj.write(out)
3230
 
        self._save_content(out.getvalue())
3231
 
        for hook in ConfigHooks['save']:
3232
 
            hook(self)
3233
 
 
3234
 
    def get_sections(self):
3235
 
        """Get the configobj section in the file order.
3236
 
 
3237
 
        :returns: An iterable of (store, section).
3238
 
        """
3239
 
        # We need a loaded store
3240
 
        try:
3241
 
            self.load()
3242
 
        except (errors.NoSuchFile, errors.PermissionDenied):
3243
 
            # If the file can't be read, there is no sections
3244
 
            return
3245
 
        cobj = self._config_obj
3246
 
        if cobj.scalars:
3247
 
            yield self, self.readonly_section_class(None, cobj)
3248
 
        for section_name in cobj.sections:
3249
 
            yield (self,
3250
 
                   self.readonly_section_class(section_name,
3251
 
                                               cobj[section_name]))
3252
 
 
3253
 
    def get_mutable_section(self, section_id=None):
3254
 
        # We need a loaded store
3255
 
        try:
3256
 
            self.load()
3257
 
        except errors.NoSuchFile:
3258
 
            # The file doesn't exist, let's pretend it was empty
3259
 
            self._load_from_string('')
3260
 
        if section_id in self.dirty_sections:
3261
 
            # We already created a mutable section for this id
3262
 
            return self.dirty_sections[section_id]
3263
 
        if section_id is None:
3264
 
            section = self._config_obj
3265
 
        else:
3266
 
            section = self._config_obj.setdefault(section_id, {})
3267
 
        mutable_section = self.mutable_section_class(section_id, section)
3268
 
        # All mutable sections can become dirty
3269
 
        self.dirty_sections[section_id] = mutable_section
3270
 
        return mutable_section
3271
 
 
3272
 
    def quote(self, value):
3273
 
        try:
3274
 
            # configobj conflates automagical list values and quoting
3275
 
            self._config_obj.list_values = True
3276
 
            return self._config_obj._quote(value)
3277
 
        finally:
3278
 
            self._config_obj.list_values = False
3279
 
 
3280
 
    def unquote(self, value):
3281
 
        if value and isinstance(value, basestring):
3282
 
            # _unquote doesn't handle None nor empty strings nor anything that
3283
 
            # is not a string, really.
3284
 
            value = self._config_obj._unquote(value)
3285
 
        return value
3286
 
 
3287
 
    def external_url(self):
3288
 
        # Since an IniFileStore can be used without a file (at least in tests),
3289
 
        # it's better to provide something than raising a NotImplementedError.
3290
 
        # All daughter classes are supposed to provide an implementation
3291
 
        # anyway.
3292
 
        return 'In-Process Store, no URL'
3293
 
 
3294
 
 
3295
 
class TransportIniFileStore(IniFileStore):
3296
 
    """IniFileStore that loads files from a transport.
3297
 
 
3298
 
    :ivar transport: The transport object where the config file is located.
3299
 
 
3300
 
    :ivar file_name: The config file basename in the transport directory.
3301
 
    """
3302
 
 
3303
 
    def __init__(self, transport, file_name):
3304
 
        """A Store using a ini file on a Transport
3305
 
 
3306
 
        :param transport: The transport object where the config file is located.
3307
 
        :param file_name: The config file basename in the transport directory.
3308
 
        """
3309
 
        super(TransportIniFileStore, self).__init__()
3310
 
        self.transport = transport
3311
 
        self.file_name = file_name
3312
 
 
3313
 
    def _load_content(self):
3314
 
        try:
3315
 
            return self.transport.get_bytes(self.file_name)
3316
 
        except errors.PermissionDenied:
3317
 
            trace.warning("Permission denied while trying to load "
3318
 
                          "configuration store %s.", self.external_url())
3319
 
            raise
3320
 
 
3321
 
    def _save_content(self, content):
3322
 
        self.transport.put_bytes(self.file_name, content)
3323
 
 
3324
 
    def external_url(self):
3325
 
        # FIXME: external_url should really accepts an optional relpath
3326
 
        # parameter (bug #750169) :-/ -- vila 2011-04-04
3327
 
        # The following will do in the interim but maybe we don't want to
3328
 
        # expose a path here but rather a config ID and its associated
3329
 
        # object </hand wawe>.
3330
 
        return urlutils.join(self.transport.external_url(), self.file_name)
3331
 
 
3332
 
 
3333
 
# Note that LockableConfigObjStore inherits from ConfigObjStore because we need
3334
 
# unlockable stores for use with objects that can already ensure the locking
3335
 
# (think branches). If different stores (not based on ConfigObj) are created,
3336
 
# they may face the same issue.
3337
 
 
3338
 
 
3339
 
class LockableIniFileStore(TransportIniFileStore):
3340
 
    """A ConfigObjStore using locks on save to ensure store integrity."""
3341
 
 
3342
 
    def __init__(self, transport, file_name, lock_dir_name=None):
3343
 
        """A config Store using ConfigObj for storage.
3344
 
 
3345
 
        :param transport: The transport object where the config file is located.
3346
 
 
3347
 
        :param file_name: The config file basename in the transport directory.
3348
 
        """
3349
 
        if lock_dir_name is None:
3350
 
            lock_dir_name = 'lock'
3351
 
        self.lock_dir_name = lock_dir_name
3352
 
        super(LockableIniFileStore, self).__init__(transport, file_name)
3353
 
        self._lock = lockdir.LockDir(self.transport, self.lock_dir_name)
3354
 
 
3355
 
    def lock_write(self, token=None):
3356
 
        """Takes a write lock in the directory containing the config file.
3357
 
 
3358
 
        If the directory doesn't exist it is created.
3359
 
        """
3360
 
        # FIXME: This doesn't check the ownership of the created directories as
3361
 
        # ensure_config_dir_exists does. It should if the transport is local
3362
 
        # -- vila 2011-04-06
3363
 
        self.transport.create_prefix()
3364
 
        return self._lock.lock_write(token)
3365
 
 
3366
 
    def unlock(self):
3367
 
        self._lock.unlock()
3368
 
 
3369
 
    def break_lock(self):
3370
 
        self._lock.break_lock()
3371
 
 
3372
 
    @needs_write_lock
3373
 
    def save(self):
3374
 
        # We need to be able to override the undecorated implementation
3375
 
        self.save_without_locking()
3376
 
 
3377
 
    def save_without_locking(self):
3378
 
        super(LockableIniFileStore, self).save()
3379
 
 
3380
 
 
3381
 
# FIXME: global, bazaar, shouldn't that be 'user' instead or even
3382
 
# 'user_defaults' as opposed to 'user_overrides', 'system_defaults'
3383
 
# (/etc/bzr/bazaar.conf) and 'system_overrides' ? -- vila 2011-04-05
3384
 
 
3385
 
# FIXME: Moreover, we shouldn't need classes for these stores either, factory
3386
 
# functions or a registry will make it easier and clearer for tests, focusing
3387
 
# on the relevant parts of the API that needs testing -- vila 20110503 (based
3388
 
# on a poolie's remark)
3389
 
class GlobalStore(LockableIniFileStore):
3390
 
    """A config store for global options.
3391
 
 
3392
 
    There is a single GlobalStore for a given process.
3393
 
    """
3394
 
 
3395
 
    def __init__(self, possible_transports=None):
3396
 
        t = transport.get_transport_from_path(
3397
 
            config_dir(), possible_transports=possible_transports)
3398
 
        super(GlobalStore, self).__init__(t, 'bazaar.conf')
3399
 
        self.id = 'bazaar'
3400
 
 
3401
 
 
3402
 
class LocationStore(LockableIniFileStore):
3403
 
    """A config store for global options.
3404
 
 
3405
 
    There is a single GlobalStore for a given process.
3406
 
    """
3407
 
 
3408
 
    def __init__(self, possible_transports=None):
3409
 
        t = transport.get_transport_from_path(
3410
 
            config_dir(), possible_transports=possible_transports)
3411
 
        super(LocationStore, self).__init__(t, 'locations.conf')
3412
 
        self.id = 'locations'
3413
 
 
3414
 
 
3415
 
class BranchStore(TransportIniFileStore):
3416
 
    """A config store for branch options.
3417
 
 
3418
 
    There is a single BranchStore for a given branch.
3419
 
    """
3420
 
 
3421
 
    def __init__(self, branch):
3422
 
        super(BranchStore, self).__init__(branch.control_transport,
3423
 
                                          'branch.conf')
3424
 
        self.branch = branch
3425
 
        self.id = 'branch'
3426
 
 
3427
 
 
3428
 
class ControlStore(LockableIniFileStore):
3429
 
 
3430
 
    def __init__(self, bzrdir):
3431
 
        super(ControlStore, self).__init__(bzrdir.transport,
3432
 
                                          'control.conf',
3433
 
                                           lock_dir_name='branch_lock')
3434
 
        self.id = 'control'
3435
 
 
3436
 
 
3437
 
class SectionMatcher(object):
3438
 
    """Select sections into a given Store.
3439
 
 
3440
 
    This is intended to be used to postpone getting an iterable of sections
3441
 
    from a store.
3442
 
    """
3443
 
 
3444
 
    def __init__(self, store):
3445
 
        self.store = store
3446
 
 
3447
 
    def get_sections(self):
3448
 
        # This is where we require loading the store so we can see all defined
3449
 
        # sections.
3450
 
        sections = self.store.get_sections()
3451
 
        # Walk the revisions in the order provided
3452
 
        for store, s in sections:
3453
 
            if self.match(s):
3454
 
                yield store, s
3455
 
 
3456
 
    def match(self, section):
3457
 
        """Does the proposed section match.
3458
 
 
3459
 
        :param section: A Section object.
3460
 
 
3461
 
        :returns: True if the section matches, False otherwise.
3462
 
        """
3463
 
        raise NotImplementedError(self.match)
3464
 
 
3465
 
 
3466
 
class NameMatcher(SectionMatcher):
3467
 
 
3468
 
    def __init__(self, store, section_id):
3469
 
        super(NameMatcher, self).__init__(store)
3470
 
        self.section_id = section_id
3471
 
 
3472
 
    def match(self, section):
3473
 
        return section.id == self.section_id
3474
 
 
3475
 
 
3476
 
class LocationSection(Section):
3477
 
 
3478
 
    def __init__(self, section, extra_path, branch_name=None):
3479
 
        super(LocationSection, self).__init__(section.id, section.options)
3480
 
        self.extra_path = extra_path
3481
 
        if branch_name is None:
3482
 
            branch_name = ''
3483
 
        self.locals = {'relpath': extra_path,
3484
 
                       'basename': urlutils.basename(extra_path),
3485
 
                       'branchname': branch_name}
3486
 
 
3487
 
    def get(self, name, default=None, expand=True):
3488
 
        value = super(LocationSection, self).get(name, default)
3489
 
        if value is not None and expand:
3490
 
            policy_name = self.get(name + ':policy', None)
3491
 
            policy = _policy_value.get(policy_name, POLICY_NONE)
3492
 
            if policy == POLICY_APPENDPATH:
3493
 
                value = urlutils.join(value, self.extra_path)
3494
 
            # expand section local options right now (since POLICY_APPENDPATH
3495
 
            # will never add options references, it's ok to expand after it).
3496
 
            chunks = []
3497
 
            for is_ref, chunk in iter_option_refs(value):
3498
 
                if not is_ref:
3499
 
                    chunks.append(chunk)
3500
 
                else:
3501
 
                    ref = chunk[1:-1]
3502
 
                    if ref in self.locals:
3503
 
                        chunks.append(self.locals[ref])
3504
 
                    else:
3505
 
                        chunks.append(chunk)
3506
 
            value = ''.join(chunks)
3507
 
        return value
3508
 
 
3509
 
 
3510
 
class StartingPathMatcher(SectionMatcher):
3511
 
    """Select sections for a given location respecting the Store order."""
3512
 
 
3513
 
    # FIXME: Both local paths and urls can be used for section names as well as
3514
 
    # ``location`` to stay consistent with ``LocationMatcher`` which itself
3515
 
    # inherited the fuzziness from the previous ``LocationConfig``
3516
 
    # implementation. We probably need to revisit which encoding is allowed for
3517
 
    # both ``location`` and section names and how we normalize
3518
 
    # them. http://pad.lv/85479, http://pad.lv/437009 and http://359320 are
3519
 
    # related too. -- vila 2012-01-04
3520
 
 
3521
 
    def __init__(self, store, location):
3522
 
        super(StartingPathMatcher, self).__init__(store)
3523
 
        if location.startswith('file://'):
3524
 
            location = urlutils.local_path_from_url(location)
3525
 
        self.location = location
3526
 
 
3527
 
    def get_sections(self):
3528
 
        """Get all sections matching ``location`` in the store.
3529
 
 
3530
 
        The most generic sections are described first in the store, then more
3531
 
        specific ones can be provided for reduced scopes.
3532
 
 
3533
 
        The returned section are therefore returned in the reversed order so
3534
 
        the most specific ones can be found first.
3535
 
        """
3536
 
        location_parts = self.location.rstrip('/').split('/')
3537
 
        store = self.store
3538
 
        sections = []
3539
 
        # Later sections are more specific, they should be returned first
3540
 
        for _, section in reversed(list(store.get_sections())):
3541
 
            if section.id is None:
3542
 
                # The no-name section is always included if present
3543
 
                yield store, LocationSection(section, self.location)
3544
 
                continue
3545
 
            section_path = section.id
3546
 
            if section_path.startswith('file://'):
3547
 
                # the location is already a local path or URL, convert the
3548
 
                # section id to the same format
3549
 
                section_path = urlutils.local_path_from_url(section_path)
3550
 
            if (self.location.startswith(section_path)
3551
 
                or fnmatch.fnmatch(self.location, section_path)):
3552
 
                section_parts = section_path.rstrip('/').split('/')
3553
 
                extra_path = '/'.join(location_parts[len(section_parts):])
3554
 
                yield store, LocationSection(section, extra_path)
3555
 
 
3556
 
 
3557
 
class LocationMatcher(SectionMatcher):
3558
 
 
3559
 
    def __init__(self, store, location):
3560
 
        super(LocationMatcher, self).__init__(store)
3561
 
        url, params = urlutils.split_segment_parameters(location)
3562
 
        if location.startswith('file://'):
3563
 
            location = urlutils.local_path_from_url(location)
3564
 
        self.location = location
3565
 
        branch_name = params.get('branch')
3566
 
        if branch_name is None:
3567
 
            self.branch_name = urlutils.basename(self.location)
3568
 
        else:
3569
 
            self.branch_name = urlutils.unescape(branch_name)
3570
 
 
3571
 
    def _get_matching_sections(self):
3572
 
        """Get all sections matching ``location``."""
3573
 
        # We slightly diverge from LocalConfig here by allowing the no-name
3574
 
        # section as the most generic one and the lower priority.
3575
 
        no_name_section = None
3576
 
        all_sections = []
3577
 
        # Filter out the no_name_section so _iter_for_location_by_parts can be
3578
 
        # used (it assumes all sections have a name).
3579
 
        for _, section in self.store.get_sections():
3580
 
            if section.id is None:
3581
 
                no_name_section = section
3582
 
            else:
3583
 
                all_sections.append(section)
3584
 
        # Unfortunately _iter_for_location_by_parts deals with section names so
3585
 
        # we have to resync.
3586
 
        filtered_sections = _iter_for_location_by_parts(
3587
 
            [s.id for s in all_sections], self.location)
3588
 
        iter_all_sections = iter(all_sections)
3589
 
        matching_sections = []
3590
 
        if no_name_section is not None:
3591
 
            matching_sections.append(
3592
 
                (0, LocationSection(no_name_section, self.location)))
3593
 
        for section_id, extra_path, length in filtered_sections:
3594
 
            # a section id is unique for a given store so it's safe to take the
3595
 
            # first matching section while iterating. Also, all filtered
3596
 
            # sections are part of 'all_sections' and will always be found
3597
 
            # there.
3598
 
            while True:
3599
 
                section = iter_all_sections.next()
3600
 
                if section_id == section.id:
3601
 
                    section = LocationSection(section, extra_path,
3602
 
                                              self.branch_name)
3603
 
                    matching_sections.append((length, section))
3604
 
                    break
3605
 
        return matching_sections
3606
 
 
3607
 
    def get_sections(self):
3608
 
        # Override the default implementation as we want to change the order
3609
 
        matching_sections = self._get_matching_sections()
3610
 
        # We want the longest (aka more specific) locations first
3611
 
        sections = sorted(matching_sections,
3612
 
                          key=lambda (length, section): (length, section.id),
3613
 
                          reverse=True)
3614
 
        # Sections mentioning 'ignore_parents' restrict the selection
3615
 
        for _, section in sections:
3616
 
            # FIXME: We really want to use as_bool below -- vila 2011-04-07
3617
 
            ignore = section.get('ignore_parents', None)
3618
 
            if ignore is not None:
3619
 
                ignore = ui.bool_from_string(ignore)
3620
 
            if ignore:
3621
 
                break
3622
 
            # Finally, we have a valid section
3623
 
            yield self.store, section
3624
 
 
3625
 
 
3626
 
_option_ref_re = lazy_regex.lazy_compile('({[^{}\n]+})')
3627
 
"""Describes an expandable option reference.
3628
 
 
3629
 
We want to match the most embedded reference first.
3630
 
 
3631
 
I.e. for '{{foo}}' we will get '{foo}',
3632
 
for '{bar{baz}}' we will get '{baz}'
3633
 
"""
3634
 
 
3635
 
def iter_option_refs(string):
3636
 
    # Split isolate refs so every other chunk is a ref
3637
 
    is_ref = False
3638
 
    for chunk  in _option_ref_re.split(string):
3639
 
        yield is_ref, chunk
3640
 
        is_ref = not is_ref
3641
 
 
3642
 
# FIXME: _shared_stores should be an attribute of a library state once a
3643
 
# library_state object is always available.
3644
 
_shared_stores = {}
3645
 
_shared_stores_at_exit_installed = False
3646
 
 
3647
 
class Stack(object):
3648
 
    """A stack of configurations where an option can be defined"""
3649
 
 
3650
 
    def __init__(self, sections_def, store=None, mutable_section_id=None):
3651
 
        """Creates a stack of sections with an optional store for changes.
3652
 
 
3653
 
        :param sections_def: A list of Section or callables that returns an
3654
 
            iterable of Section. This defines the Sections for the Stack and
3655
 
            can be called repeatedly if needed.
3656
 
 
3657
 
        :param store: The optional Store where modifications will be
3658
 
            recorded. If none is specified, no modifications can be done.
3659
 
 
3660
 
        :param mutable_section_id: The id of the MutableSection where changes
3661
 
            are recorded. This requires the ``store`` parameter to be
3662
 
            specified.
3663
 
        """
3664
 
        self.sections_def = sections_def
3665
 
        self.store = store
3666
 
        self.mutable_section_id = mutable_section_id
3667
 
 
3668
 
    def iter_sections(self):
3669
 
        """Iterate all the defined sections."""
3670
 
        # Ensuring lazy loading is achieved by delaying section matching (which
3671
 
        # implies querying the persistent storage) until it can't be avoided
3672
 
        # anymore by using callables to describe (possibly empty) section
3673
 
        # lists.
3674
 
        for sections in self.sections_def:
3675
 
            for store, section in sections():
3676
 
                yield store, section
3677
 
 
3678
 
    def get(self, name, expand=True, convert=True):
3679
 
        """Return the *first* option value found in the sections.
3680
 
 
3681
 
        This is where we guarantee that sections coming from Store are loaded
3682
 
        lazily: the loading is delayed until we need to either check that an
3683
 
        option exists or get its value, which in turn may require to discover
3684
 
        in which sections it can be defined. Both of these (section and option
3685
 
        existence) require loading the store (even partially).
3686
 
 
3687
 
        :param name: The queried option.
3688
 
 
3689
 
        :param expand: Whether options references should be expanded.
3690
 
 
3691
 
        :param convert: Whether the option value should be converted from
3692
 
            unicode (do nothing for non-registered options).
3693
 
 
3694
 
        :returns: The value of the option.
3695
 
        """
3696
 
        # FIXME: No caching of options nor sections yet -- vila 20110503
3697
 
        value = None
3698
 
        found_store = None # Where the option value has been found
3699
 
        # If the option is registered, it may provide additional info about
3700
 
        # value handling
3701
 
        try:
3702
 
            opt = option_registry.get(name)
3703
 
        except KeyError:
3704
 
            # Not registered
3705
 
            opt = None
3706
 
 
3707
 
        def expand_and_convert(val):
3708
 
            # This may need to be called in different contexts if the value is
3709
 
            # None or ends up being None during expansion or conversion.
3710
 
            if val is not None:
3711
 
                if expand:
3712
 
                    if isinstance(val, basestring):
3713
 
                        val = self._expand_options_in_string(val)
3714
 
                    else:
3715
 
                        trace.warning('Cannot expand "%s":'
3716
 
                                      ' %s does not support option expansion'
3717
 
                                      % (name, type(val)))
3718
 
                if opt is None:
3719
 
                    val = found_store.unquote(val)
3720
 
                elif convert:
3721
 
                    val = opt.convert_from_unicode(found_store, val)
3722
 
            return val
3723
 
 
3724
 
        # First of all, check if the environment can override the configuration
3725
 
        # value
3726
 
        if opt is not None and opt.override_from_env:
3727
 
            value = opt.get_override()
3728
 
            value = expand_and_convert(value)
3729
 
        if value is None:
3730
 
            for store, section in self.iter_sections():
3731
 
                value = section.get(name)
3732
 
                if value is not None:
3733
 
                    found_store = store
3734
 
                    break
3735
 
            value = expand_and_convert(value)
3736
 
            if opt is not None and value is None:
3737
 
                # If the option is registered, it may provide a default value
3738
 
                value = opt.get_default()
3739
 
                value = expand_and_convert(value)
3740
 
        for hook in ConfigHooks['get']:
3741
 
            hook(self, name, value)
3742
 
        return value
3743
 
 
3744
 
    def expand_options(self, string, env=None):
3745
 
        """Expand option references in the string in the configuration context.
3746
 
 
3747
 
        :param string: The string containing option(s) to expand.
3748
 
 
3749
 
        :param env: An option dict defining additional configuration options or
3750
 
            overriding existing ones.
3751
 
 
3752
 
        :returns: The expanded string.
3753
 
        """
3754
 
        return self._expand_options_in_string(string, env)
3755
 
 
3756
 
    def _expand_options_in_string(self, string, env=None, _refs=None):
3757
 
        """Expand options in the string in the configuration context.
3758
 
 
3759
 
        :param string: The string to be expanded.
3760
 
 
3761
 
        :param env: An option dict defining additional configuration options or
3762
 
            overriding existing ones.
3763
 
 
3764
 
        :param _refs: Private list (FIFO) containing the options being expanded
3765
 
            to detect loops.
3766
 
 
3767
 
        :returns: The expanded string.
3768
 
        """
3769
 
        if string is None:
3770
 
            # Not much to expand there
3771
 
            return None
3772
 
        if _refs is None:
3773
 
            # What references are currently resolved (to detect loops)
3774
 
            _refs = []
3775
 
        result = string
3776
 
        # We need to iterate until no more refs appear ({{foo}} will need two
3777
 
        # iterations for example).
3778
 
        expanded = True
3779
 
        while expanded:
3780
 
            expanded = False
3781
 
            chunks = []
3782
 
            for is_ref, chunk in iter_option_refs(result):
3783
 
                if not is_ref:
3784
 
                    chunks.append(chunk)
3785
 
                else:
3786
 
                    expanded = True
3787
 
                    name = chunk[1:-1]
3788
 
                    if name in _refs:
3789
 
                        raise errors.OptionExpansionLoop(string, _refs)
3790
 
                    _refs.append(name)
3791
 
                    value = self._expand_option(name, env, _refs)
3792
 
                    if value is None:
3793
 
                        raise errors.ExpandingUnknownOption(name, string)
3794
 
                    chunks.append(value)
3795
 
                    _refs.pop()
3796
 
            result = ''.join(chunks)
3797
 
        return result
3798
 
 
3799
 
    def _expand_option(self, name, env, _refs):
3800
 
        if env is not None and name in env:
3801
 
            # Special case, values provided in env takes precedence over
3802
 
            # anything else
3803
 
            value = env[name]
3804
 
        else:
3805
 
            value = self.get(name, expand=False, convert=False)
3806
 
            value = self._expand_options_in_string(value, env, _refs)
3807
 
        return value
3808
 
 
3809
 
    def _get_mutable_section(self):
3810
 
        """Get the MutableSection for the Stack.
3811
 
 
3812
 
        This is where we guarantee that the mutable section is lazily loaded:
3813
 
        this means we won't load the corresponding store before setting a value
3814
 
        or deleting an option. In practice the store will often be loaded but
3815
 
        this helps catching some programming errors.
3816
 
        """
3817
 
        store = self.store
3818
 
        section = store.get_mutable_section(self.mutable_section_id)
3819
 
        return store, section
3820
 
 
3821
 
    def set(self, name, value):
3822
 
        """Set a new value for the option."""
3823
 
        store, section = self._get_mutable_section()
3824
 
        section.set(name, store.quote(value))
3825
 
        for hook in ConfigHooks['set']:
3826
 
            hook(self, name, value)
3827
 
 
3828
 
    def remove(self, name):
3829
 
        """Remove an existing option."""
3830
 
        _, section = self._get_mutable_section()
3831
 
        section.remove(name)
3832
 
        for hook in ConfigHooks['remove']:
3833
 
            hook(self, name)
3834
 
 
3835
 
    def __repr__(self):
3836
 
        # Mostly for debugging use
3837
 
        return "<config.%s(%s)>" % (self.__class__.__name__, id(self))
3838
 
 
3839
 
    def _get_overrides(self):
3840
 
        # FIXME: Hack around library_state.initialize never called
3841
 
        if bzrlib.global_state is not None:
3842
 
            return bzrlib.global_state.cmdline_overrides.get_sections()
3843
 
        return []
3844
 
 
3845
 
    def get_shared_store(self, store, state=None):
3846
 
        """Get a known shared store.
3847
 
 
3848
 
        Store urls uniquely identify them and are used to ensure a single copy
3849
 
        is shared across all users.
3850
 
 
3851
 
        :param store: The store known to the caller.
3852
 
 
3853
 
        :param state: The library state where the known stores are kept.
3854
 
 
3855
 
        :returns: The store received if it's not a known one, an already known
3856
 
            otherwise.
3857
 
        """
3858
 
        if state is None:
3859
 
            state = bzrlib.global_state
3860
 
        if state is None:
3861
 
            global _shared_stores_at_exit_installed
3862
 
            stores = _shared_stores
3863
 
            def save_config_changes():
3864
 
                for k, store in stores.iteritems():
3865
 
                    store.save_changes()
3866
 
            if not _shared_stores_at_exit_installed:
3867
 
                # FIXME: Ugly hack waiting for library_state to always be
3868
 
                # available. -- vila 20120731
3869
 
                import atexit
3870
 
                atexit.register(save_config_changes)
3871
 
                _shared_stores_at_exit_installed = True
3872
 
        else:
3873
 
            stores = state.config_stores
3874
 
        url = store.external_url()
3875
 
        try:
3876
 
            return stores[url]
3877
 
        except KeyError:
3878
 
            stores[url] = store
3879
 
            return store
3880
 
 
3881
 
 
3882
 
class MemoryStack(Stack):
3883
 
    """A configuration stack defined from a string.
3884
 
 
3885
 
    This is mainly intended for tests and requires no disk resources.
3886
 
    """
3887
 
 
3888
 
    def __init__(self, content=None):
3889
 
        """Create an in-memory stack from a given content.
3890
 
 
3891
 
        It uses a single store based on configobj and support reading and
3892
 
        writing options.
3893
 
 
3894
 
        :param content: The initial content of the store. If None, the store is
3895
 
            not loaded and ``_load_from_string`` can and should be used if
3896
 
            needed.
3897
 
        """
3898
 
        store = IniFileStore()
3899
 
        if content is not None:
3900
 
            store._load_from_string(content)
3901
 
        super(MemoryStack, self).__init__(
3902
 
            [store.get_sections], store)
3903
 
 
3904
 
 
3905
 
class _CompatibleStack(Stack):
3906
 
    """Place holder for compatibility with previous design.
3907
 
 
3908
 
    This is intended to ease the transition from the Config-based design to the
3909
 
    Stack-based design and should not be used nor relied upon by plugins.
3910
 
 
3911
 
    One assumption made here is that the daughter classes will all use Stores
3912
 
    derived from LockableIniFileStore).
3913
 
 
3914
 
    It implements set() and remove () by re-loading the store before applying
3915
 
    the modification and saving it.
3916
 
 
3917
 
    The long term plan being to implement a single write by store to save
3918
 
    all modifications, this class should not be used in the interim.
3919
 
    """
3920
 
 
3921
 
    def set(self, name, value):
3922
 
        # Force a reload
3923
 
        self.store.unload()
3924
 
        super(_CompatibleStack, self).set(name, value)
3925
 
        # Force a write to persistent storage
3926
 
        self.store.save()
3927
 
 
3928
 
    def remove(self, name):
3929
 
        # Force a reload
3930
 
        self.store.unload()
3931
 
        super(_CompatibleStack, self).remove(name)
3932
 
        # Force a write to persistent storage
3933
 
        self.store.save()
3934
 
 
3935
 
 
3936
 
class GlobalStack(Stack):
3937
 
    """Global options only stack.
3938
 
 
3939
 
    The following sections are queried:
3940
 
 
3941
 
    * command-line overrides,
3942
 
 
3943
 
    * the 'DEFAULT' section in bazaar.conf
3944
 
 
3945
 
    This stack will use the ``DEFAULT`` section in bazaar.conf as its
3946
 
    MutableSection.
3947
 
    """
3948
 
 
3949
 
    def __init__(self):
3950
 
        gstore = self.get_shared_store(GlobalStore())
3951
 
        super(GlobalStack, self).__init__(
3952
 
            [self._get_overrides,
3953
 
             NameMatcher(gstore, 'DEFAULT').get_sections],
3954
 
            gstore, mutable_section_id='DEFAULT')
3955
 
 
3956
 
 
3957
 
class LocationStack(Stack):
3958
 
    """Per-location options falling back to global options stack.
3959
 
 
3960
 
 
3961
 
    The following sections are queried:
3962
 
 
3963
 
    * command-line overrides,
3964
 
 
3965
 
    * the sections matching ``location`` in ``locations.conf``, the order being
3966
 
      defined by the number of path components in the section glob, higher
3967
 
      numbers first (from most specific section to most generic).
3968
 
 
3969
 
    * the 'DEFAULT' section in bazaar.conf
3970
 
 
3971
 
    This stack will use the ``location`` section in locations.conf as its
3972
 
    MutableSection.
3973
 
    """
3974
 
 
3975
 
    def __init__(self, location):
3976
 
        """Make a new stack for a location and global configuration.
3977
 
 
3978
 
        :param location: A URL prefix to """
3979
 
        lstore = self.get_shared_store(LocationStore())
3980
 
        if location.startswith('file://'):
3981
 
            location = urlutils.local_path_from_url(location)
3982
 
        gstore = self.get_shared_store(GlobalStore())
3983
 
        super(LocationStack, self).__init__(
3984
 
            [self._get_overrides,
3985
 
             LocationMatcher(lstore, location).get_sections,
3986
 
             NameMatcher(gstore, 'DEFAULT').get_sections],
3987
 
            lstore, mutable_section_id=location)
3988
 
 
3989
 
 
3990
 
class BranchStack(Stack):
3991
 
    """Per-location options falling back to branch then global options stack.
3992
 
 
3993
 
    The following sections are queried:
3994
 
 
3995
 
    * command-line overrides,
3996
 
 
3997
 
    * the sections matching ``location`` in ``locations.conf``, the order being
3998
 
      defined by the number of path components in the section glob, higher
3999
 
      numbers first (from most specific section to most generic),
4000
 
 
4001
 
    * the no-name section in branch.conf,
4002
 
 
4003
 
    * the ``DEFAULT`` section in ``bazaar.conf``.
4004
 
 
4005
 
    This stack will use the no-name section in ``branch.conf`` as its
4006
 
    MutableSection.
4007
 
    """
4008
 
 
4009
 
    def __init__(self, branch):
4010
 
        lstore = self.get_shared_store(LocationStore())
4011
 
        bstore = branch._get_config_store()
4012
 
        gstore = self.get_shared_store(GlobalStore())
4013
 
        super(BranchStack, self).__init__(
4014
 
            [self._get_overrides,
4015
 
             LocationMatcher(lstore, branch.base).get_sections,
4016
 
             NameMatcher(bstore, None).get_sections,
4017
 
             NameMatcher(gstore, 'DEFAULT').get_sections],
4018
 
            bstore)
4019
 
        self.branch = branch
4020
 
 
4021
 
    def lock_write(self, token=None):
4022
 
        return self.branch.lock_write(token)
4023
 
 
4024
 
    def unlock(self):
4025
 
        return self.branch.unlock()
4026
 
 
4027
 
    @needs_write_lock
4028
 
    def set(self, name, value):
4029
 
        super(BranchStack, self).set(name, value)
4030
 
        # Unlocking the branch will trigger a store.save_changes() so the last
4031
 
        # unlock saves all the changes.
4032
 
 
4033
 
    @needs_write_lock
4034
 
    def remove(self, name):
4035
 
        super(BranchStack, self).remove(name)
4036
 
        # Unlocking the branch will trigger a store.save_changes() so the last
4037
 
        # unlock saves all the changes.
4038
 
 
4039
 
 
4040
 
class RemoteControlStack(Stack):
4041
 
    """Remote control-only options stack."""
4042
 
 
4043
 
    # FIXME 2011-11-22 JRV This should probably be renamed to avoid confusion
4044
 
    # with the stack used for remote bzr dirs. RemoteControlStack only uses
4045
 
    # control.conf and is used only for stack options.
4046
 
 
4047
 
    def __init__(self, bzrdir):
4048
 
        cstore = bzrdir._get_config_store()
4049
 
        super(RemoteControlStack, self).__init__(
4050
 
            [NameMatcher(cstore, None).get_sections],
4051
 
            cstore)
4052
 
        self.bzrdir = bzrdir
4053
 
 
4054
 
 
4055
 
class BranchOnlyStack(Stack):
4056
 
    """Branch-only options stack."""
4057
 
 
4058
 
    # FIXME: _BranchOnlyStack only uses branch.conf and is used only for the
4059
 
    # stacked_on_location options waiting for http://pad.lv/832042 to be fixed.
4060
 
    # -- vila 2011-12-16
4061
 
 
4062
 
    def __init__(self, branch):
4063
 
        bstore = branch._get_config_store()
4064
 
        super(BranchOnlyStack, self).__init__(
4065
 
            [NameMatcher(bstore, None).get_sections],
4066
 
            bstore)
4067
 
        self.branch = branch
4068
 
 
4069
 
    def lock_write(self, token=None):
4070
 
        return self.branch.lock_write(token)
4071
 
 
4072
 
    def unlock(self):
4073
 
        return self.branch.unlock()
4074
 
 
4075
 
    @needs_write_lock
4076
 
    def set(self, name, value):
4077
 
        super(BranchOnlyStack, self).set(name, value)
4078
 
        # Force a write to persistent storage
4079
 
        self.store.save_changes()
4080
 
 
4081
 
    @needs_write_lock
4082
 
    def remove(self, name):
4083
 
        super(BranchOnlyStack, self).remove(name)
4084
 
        # Force a write to persistent storage
4085
 
        self.store.save_changes()
4086
 
 
4087
 
 
4088
 
class cmd_config(commands.Command):
4089
 
    __doc__ = """Display, set or remove a configuration option.
4090
 
 
4091
 
    Display the active value for option NAME.
4092
 
 
4093
 
    If --all is specified, NAME is interpreted as a regular expression and all
4094
 
    matching options are displayed mentioning their scope and without resolving
4095
 
    option references in the value). The active value that bzr will take into
4096
 
    account is the first one displayed for each option.
4097
 
 
4098
 
    If NAME is not given, --all .* is implied (all options are displayed for the
4099
 
    current scope).
4100
 
 
4101
 
    Setting a value is achieved by using NAME=value without spaces. The value
4102
 
    is set in the most relevant scope and can be checked by displaying the
4103
 
    option again.
4104
 
 
4105
 
    Removing a value is achieved by using --remove NAME.
4106
 
    """
4107
 
 
4108
 
    takes_args = ['name?']
4109
 
 
4110
 
    takes_options = [
4111
 
        'directory',
4112
 
        # FIXME: This should be a registry option so that plugins can register
4113
 
        # their own config files (or not) and will also address
4114
 
        # http://pad.lv/788991 -- vila 20101115
4115
 
        commands.Option('scope', help='Reduce the scope to the specified'
4116
 
                        ' configuration file.',
4117
 
                        type=unicode),
4118
 
        commands.Option('all',
4119
 
            help='Display all the defined values for the matching options.',
4120
 
            ),
4121
 
        commands.Option('remove', help='Remove the option from'
4122
 
                        ' the configuration file.'),
4123
 
        ]
4124
 
 
4125
 
    _see_also = ['configuration']
4126
 
 
4127
 
    @commands.display_command
4128
 
    def run(self, name=None, all=False, directory=None, scope=None,
4129
 
            remove=False):
4130
 
        if directory is None:
4131
 
            directory = '.'
4132
 
        directory = directory_service.directories.dereference(directory)
4133
 
        directory = urlutils.normalize_url(directory)
4134
 
        if remove and all:
4135
 
            raise errors.BzrError(
4136
 
                '--all and --remove are mutually exclusive.')
4137
 
        elif remove:
4138
 
            # Delete the option in the given scope
4139
 
            self._remove_config_option(name, directory, scope)
4140
 
        elif name is None:
4141
 
            # Defaults to all options
4142
 
            self._show_matching_options('.*', directory, scope)
4143
 
        else:
4144
 
            try:
4145
 
                name, value = name.split('=', 1)
4146
 
            except ValueError:
4147
 
                # Display the option(s) value(s)
4148
 
                if all:
4149
 
                    self._show_matching_options(name, directory, scope)
4150
 
                else:
4151
 
                    self._show_value(name, directory, scope)
4152
 
            else:
4153
 
                if all:
4154
 
                    raise errors.BzrError(
4155
 
                        'Only one option can be set.')
4156
 
                # Set the option value
4157
 
                self._set_config_option(name, value, directory, scope)
4158
 
 
4159
 
    def _get_stack(self, directory, scope=None, write_access=False):
4160
 
        """Get the configuration stack specified by ``directory`` and ``scope``.
4161
 
 
4162
 
        :param directory: Where the configurations are derived from.
4163
 
 
4164
 
        :param scope: A specific config to start from.
4165
 
 
4166
 
        :param write_access: Whether a write access to the stack will be
4167
 
            attempted.
4168
 
        """
4169
 
        # FIXME: scope should allow access to plugin-specific stacks (even
4170
 
        # reduced to the plugin-specific store), related to
4171
 
        # http://pad.lv/788991 -- vila 2011-11-15
4172
 
        if scope is not None:
4173
 
            if scope == 'bazaar':
4174
 
                return GlobalStack()
4175
 
            elif scope == 'locations':
4176
 
                return LocationStack(directory)
4177
 
            elif scope == 'branch':
4178
 
                (_, br, _) = (
4179
 
                    controldir.ControlDir.open_containing_tree_or_branch(
4180
 
                        directory))
4181
 
                if write_access:
4182
 
                    self.add_cleanup(br.lock_write().unlock)
4183
 
                return br.get_config_stack()
4184
 
            raise errors.NoSuchConfig(scope)
4185
 
        else:
4186
 
            try:
4187
 
                (_, br, _) = (
4188
 
                    controldir.ControlDir.open_containing_tree_or_branch(
4189
 
                        directory))
4190
 
                if write_access:
4191
 
                    self.add_cleanup(br.lock_write().unlock)
4192
 
                return br.get_config_stack()
4193
 
            except errors.NotBranchError:
4194
 
                return LocationStack(directory)
4195
 
 
4196
 
    def _quote_multiline(self, value):
4197
 
        if '\n' in value:
4198
 
            value = '"""' + value + '"""'
4199
 
        return value
4200
 
 
4201
 
    def _show_value(self, name, directory, scope):
4202
 
        conf = self._get_stack(directory, scope)
4203
 
        value = conf.get(name, expand=True, convert=False)
4204
 
        if value is not None:
4205
 
            # Quote the value appropriately
4206
 
            value = self._quote_multiline(value)
4207
 
            self.outf.write('%s\n' % (value,))
4208
 
        else:
4209
 
            raise errors.NoSuchConfigOption(name)
4210
 
 
4211
 
    def _show_matching_options(self, name, directory, scope):
4212
 
        name = lazy_regex.lazy_compile(name)
4213
 
        # We want any error in the regexp to be raised *now* so we need to
4214
 
        # avoid the delay introduced by the lazy regexp.  But, we still do
4215
 
        # want the nicer errors raised by lazy_regex.
4216
 
        name._compile_and_collapse()
4217
 
        cur_store_id = None
4218
 
        cur_section = None
4219
 
        conf = self._get_stack(directory, scope)
4220
 
        for store, section in conf.iter_sections():
4221
 
            for oname in section.iter_option_names():
4222
 
                if name.search(oname):
4223
 
                    if cur_store_id != store.id:
4224
 
                        # Explain where the options are defined
4225
 
                        self.outf.write('%s:\n' % (store.id,))
4226
 
                        cur_store_id = store.id
4227
 
                        cur_section = None
4228
 
                    if (section.id is not None and cur_section != section.id):
4229
 
                        # Display the section id as it appears in the store
4230
 
                        # (None doesn't appear by definition)
4231
 
                        self.outf.write('  [%s]\n' % (section.id,))
4232
 
                        cur_section = section.id
4233
 
                    value = section.get(oname, expand=False)
4234
 
                    # Quote the value appropriately
4235
 
                    value = self._quote_multiline(value)
4236
 
                    self.outf.write('  %s = %s\n' % (oname, value))
4237
 
 
4238
 
    def _set_config_option(self, name, value, directory, scope):
4239
 
        conf = self._get_stack(directory, scope, write_access=True)
4240
 
        conf.set(name, value)
4241
 
 
4242
 
    def _remove_config_option(self, name, directory, scope):
4243
 
        if name is None:
4244
 
            raise errors.BzrCommandError(
4245
 
                '--remove expects an option to remove.')
4246
 
        conf = self._get_stack(directory, scope, write_access=True)
4247
 
        try:
4248
 
            conf.remove(name)
4249
 
        except KeyError:
4250
 
            raise errors.NoSuchConfigOption(name)
4251
 
 
4252
 
 
4253
 
# Test registries
4254
 
#
4255
 
# We need adapters that can build a Store or a Stack in a test context. Test
4256
 
# classes, based on TestCaseWithTransport, can use the registry to parametrize
4257
 
# themselves. The builder will receive a test instance and should return a
4258
 
# ready-to-use store or stack.  Plugins that define new store/stacks can also
4259
 
# register themselves here to be tested against the tests defined in
4260
 
# bzrlib.tests.test_config. Note that the builder can be called multiple times
4261
 
# for the same test.
4262
 
 
4263
 
# The registered object should be a callable receiving a test instance
4264
 
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Store
4265
 
# object.
4266
 
test_store_builder_registry = registry.Registry()
4267
 
 
4268
 
# The registered object should be a callable receiving a test instance
4269
 
# parameter (inheriting from tests.TestCaseWithTransport) and returning a Stack
4270
 
# object.
4271
 
test_stack_builder_registry = registry.Registry()