~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Martin Pool
  • Date: 2011-07-04 22:04:55 UTC
  • mto: This revision was merged to the branch mainline in revision 6017.
  • Revision ID: mbp@canonical.com-20110704220455-1y5wa5akhuc9zq6h
Clean up transport tests to use addCleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
log_format=name-of-format
32
32
validate_signatures_in_log=true|false(default)
33
33
acceptable_keys=pattern1,pattern2
34
 
gpg_signing_key=amy@example.com
35
34
 
36
35
in locations.conf, you specify the url of a branch and options for it.
37
36
Wildcards may be used - * and ? as normal in shell completion. Options
172
171
# FIXME: Until we can guarantee that each config file is loaded once and
173
172
# only once for a given bzrlib session, we don't want to re-read the file every
174
173
# time we query for an option so we cache the value (bad ! watch out for tests
175
 
# needing to restore the proper value). -- vila 20110219
 
174
# needing to restore the proper value).This shouldn't be part of 2.4.0 final,
 
175
# yell at mgz^W vila and the RM if this is still present at that time
 
176
# -- vila 20110219
176
177
_expand_default_value = None
177
178
def _get_expand_default_value():
178
179
    global _expand_default_value
535
536
            return True
536
537
        return False
537
538
 
538
 
    def gpg_signing_key(self):
539
 
        """GPG user-id to sign commits"""
540
 
        key = self.get_user_option('gpg_signing_key')
541
 
        if key == "default" or key == None:
542
 
            return self.user_email()
543
 
        else:
544
 
            return key
545
 
 
546
539
    def get_alias(self, value):
547
540
        return self._get_alias(value)
548
541
 
1511
1504
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
1512
1505
                                  ' or HOME set')
1513
1506
        return osutils.pathjoin(base, 'bazaar', '2.0')
1514
 
    else:
1515
 
        if base is not None:
1516
 
            base = base.decode(osutils._fs_enc)
1517
 
    if sys.platform == 'darwin':
 
1507
    elif sys.platform == 'darwin':
1518
1508
        if base is None:
1519
1509
            # this takes into account $HOME
1520
1510
            base = os.path.expanduser("~")
1521
1511
        return osutils.pathjoin(base, '.bazaar')
1522
1512
    else:
1523
1513
        if base is None:
 
1514
 
1524
1515
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
1525
1516
            if xdg_dir is None:
1526
1517
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
1529
1520
                trace.mutter(
1530
1521
                    "Using configuration in XDG directory %s." % xdg_dir)
1531
1522
                return xdg_dir
 
1523
 
1532
1524
            base = os.path.expanduser("~")
1533
1525
        return osutils.pathjoin(base, ".bazaar")
1534
1526
 
2270
2262
    The option *values* are stored in config files and found in sections.
2271
2263
 
2272
2264
    Here we define various properties about the option itself, its default
2273
 
    value, how to convert it from stores, what to do when invalid values are
2274
 
    encoutered, in which config files it can be stored.
 
2265
    value, in which config files it can be stored, etc (TBC).
2275
2266
    """
2276
2267
 
2277
 
    def __init__(self, name, default=None, help=None, from_unicode=None,
2278
 
                 invalid=None):
2279
 
        """Build an option definition.
2280
 
 
2281
 
        :param name: the name used to refer to the option.
2282
 
 
2283
 
        :param default: the default value to use when none exist in the config
2284
 
            stores.
2285
 
 
2286
 
        :param help: a doc string to explain the option to the user.
2287
 
 
2288
 
        :param from_unicode: a callable to convert the unicode string
2289
 
            representing the option value in a store. This is not called for
2290
 
            the default value.
2291
 
 
2292
 
        :param invalid: the action to be taken when an invalid value is
2293
 
            encountered in a store. This is called only when from_unicode is
2294
 
            invoked to convert a string and returns None or raise ValueError or
2295
 
            TypeError. Accepted values are: None (ignore invalid values),
2296
 
            'warning' (emit a warning), 'error' (emit an error message and
2297
 
            terminates).
2298
 
        """
 
2268
    def __init__(self, name, default=None):
2299
2269
        self.name = name
2300
2270
        self.default = default
2301
 
        self.help = help
2302
 
        self.from_unicode = from_unicode
2303
 
        if invalid and invalid not in ('warning', 'error'):
2304
 
            raise AssertionError("%s not supported for 'invalid'" % (invalid,))
2305
 
        self.invalid = invalid
2306
2271
 
2307
2272
    def get_default(self):
2308
2273
        return self.default
2309
2274
 
2310
 
    def get_help_text(self, additional_see_also=None, plain=True):
2311
 
        result = self.help
2312
 
        from bzrlib import help_topics
2313
 
        result += help_topics._format_see_also(additional_see_also)
2314
 
        if plain:
2315
 
            result = help_topics.help_as_plain_text(result)
2316
 
        return result
2317
 
 
2318
 
 
2319
 
# Predefined converters to get proper values from store
2320
 
 
2321
 
def bool_from_store(unicode_str):
2322
 
    return ui.bool_from_string(unicode_str)
2323
 
 
2324
 
 
2325
 
def int_from_store(unicode_str):
2326
 
    return int(unicode_str)
2327
 
 
2328
 
 
2329
 
def list_from_store(unicode_str):
2330
 
    # ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
2331
 
    if isinstance(unicode_str, (str, unicode)):
2332
 
        if unicode_str:
2333
 
            # A single value, most probably the user forgot (or didn't care to
2334
 
            # add) the final ','
2335
 
            l = [unicode_str]
2336
 
        else:
2337
 
            # The empty string, convert to empty list
2338
 
            l = []
2339
 
    else:
2340
 
        # We rely on ConfigObj providing us with a list already
2341
 
        l = unicode_str
2342
 
    return l
2343
 
 
2344
 
 
2345
 
class OptionRegistry(registry.Registry):
2346
 
    """Register config options by their name.
2347
 
 
2348
 
    This overrides ``registry.Registry`` to simplify registration by acquiring
2349
 
    some information from the option object itself.
2350
 
    """
2351
 
 
2352
 
    def register(self, option):
2353
 
        """Register a new option to its name.
2354
 
 
2355
 
        :param option: The option to register. Its name is used as the key.
2356
 
        """
2357
 
        super(OptionRegistry, self).register(option.name, option,
2358
 
                                             help=option.help)
2359
 
 
2360
 
    def register_lazy(self, key, module_name, member_name):
2361
 
        """Register a new option to be loaded on request.
2362
 
 
2363
 
        :param key: the key to request the option later. Since the registration
2364
 
            is lazy, it should be provided and match the option name.
2365
 
 
2366
 
        :param module_name: the python path to the module. Such as 'os.path'.
2367
 
 
2368
 
        :param member_name: the member of the module to return.  If empty or 
2369
 
                None, get() will return the module itself.
2370
 
        """
2371
 
        super(OptionRegistry, self).register_lazy(key,
2372
 
                                                  module_name, member_name)
2373
 
 
2374
 
    def get_help(self, key=None):
2375
 
        """Get the help text associated with the given key"""
2376
 
        option = self.get(key)
2377
 
        the_help = option.help
2378
 
        if callable(the_help):
2379
 
            return the_help(self, key)
2380
 
        return the_help
2381
 
 
2382
 
 
2383
 
option_registry = OptionRegistry()
2384
 
 
2385
 
 
2386
 
# Registered options in lexicographical order
2387
 
 
2388
 
option_registry.register(
2389
 
    Option('bzr.workingtree.worth_saving_limit', default=10,
2390
 
           from_unicode=int_from_store,  invalid='warning',
2391
 
           help='''\
2392
 
How many changes before saving the dirstate.
2393
 
 
2394
 
-1 means that we will never rewrite the dirstate file for only
2395
 
stat-cache changes. Regardless of this setting, we will always rewrite
2396
 
the dirstate file if a file is added/removed/renamed/etc. This flag only
2397
 
affects the behavior of updating the dirstate file after we notice that
2398
 
a file has been touched.
2399
 
'''))
2400
 
option_registry.register(
2401
 
    Option('dirstate.fdatasync', default=True,
2402
 
           from_unicode=bool_from_store,
2403
 
           help='''\
2404
 
Flush dirstate changes onto physical disk?
2405
 
 
2406
 
If true (default), working tree metadata changes are flushed through the
2407
 
OS buffers to physical disk.  This is somewhat slower, but means data
2408
 
should not be lost if the machine crashes.  See also repository.fdatasync.
2409
 
'''))
2410
 
option_registry.register(
2411
 
    Option('debug_flags', default=[], from_unicode=list_from_store,
2412
 
           help='Debug flags to activate.'))
2413
 
option_registry.register(
2414
 
    Option('default_format', default='2a',
2415
 
           help='Format used when creating branches.'))
2416
 
option_registry.register(
2417
 
    Option('editor',
2418
 
           help='The command called to launch an editor to enter a message.'))
2419
 
option_registry.register(
2420
 
    Option('ignore_missing_extensions', default=False,
2421
 
           from_unicode=bool_from_store,
2422
 
           help='''\
2423
 
Control the missing extensions warning display.
2424
 
 
2425
 
The warning will not be emitted if set to True.
2426
 
'''))
2427
 
option_registry.register(
2428
 
    Option('language',
2429
 
           help='Language to translate messages into.'))
2430
 
option_registry.register(
2431
 
    Option('locks.steal_dead', default=False, from_unicode=bool_from_store,
2432
 
           help='''\
2433
 
Steal locks that appears to be dead.
2434
 
 
2435
 
If set to True, bzr will check if a lock is supposed to be held by an
2436
 
active process from the same user on the same machine. If the user and
2437
 
machine match, but no process with the given PID is active, then bzr
2438
 
will automatically break the stale lock, and create a new lock for
2439
 
this process.
2440
 
Otherwise, bzr will prompt as normal to break the lock.
2441
 
'''))
2442
 
option_registry.register(
2443
 
    Option('output_encoding',
2444
 
           help= 'Unicode encoding for output'
2445
 
           ' (terminal encoding if not specified).'))
2446
 
option_registry.register(
2447
 
    Option('repository.fdatasync', default=True, from_unicode=bool_from_store,
2448
 
           help='''\
2449
 
Flush repository changes onto physical disk?
2450
 
 
2451
 
If true (default), repository changes are flushed through the OS buffers
2452
 
to physical disk.  This is somewhat slower, but means data should not be
2453
 
lost if the machine crashes.  See also dirstate.fdatasync.
2454
 
'''))
 
2275
 
 
2276
# Options registry
 
2277
 
 
2278
option_registry = registry.Registry()
 
2279
 
 
2280
 
 
2281
option_registry.register(
 
2282
    'editor', Option('editor'),
 
2283
    help='The command called to launch an editor to enter a message.')
2455
2284
 
2456
2285
 
2457
2286
class Section(object):
2724
2553
class GlobalStore(LockableIniFileStore):
2725
2554
 
2726
2555
    def __init__(self, possible_transports=None):
2727
 
        t = transport.get_transport_from_path(
2728
 
            config_dir(), possible_transports=possible_transports)
 
2556
        t = transport.get_transport(config_dir(),
 
2557
                                    possible_transports=possible_transports)
2729
2558
        super(GlobalStore, self).__init__(t, 'bazaar.conf')
2730
2559
 
2731
2560
 
2732
2561
class LocationStore(LockableIniFileStore):
2733
2562
 
2734
2563
    def __init__(self, possible_transports=None):
2735
 
        t = transport.get_transport_from_path(
2736
 
            config_dir(), possible_transports=possible_transports)
 
2564
        t = transport.get_transport(config_dir(),
 
2565
                                    possible_transports=possible_transports)
2737
2566
        super(LocationStore, self).__init__(t, 'locations.conf')
2738
2567
 
2739
2568
 
2905
2734
                    break
2906
2735
            if value is not None:
2907
2736
                break
2908
 
        # If the option is registered, it may provide additional info about
2909
 
        # value handling
2910
 
        try:
2911
 
            opt = option_registry.get(name)
2912
 
        except KeyError:
2913
 
            # Not registered
2914
 
            opt = None
2915
 
        if (opt is not None and opt.from_unicode is not None
2916
 
            and value is not None):
2917
 
            # If a value exists and the option provides a converter, use it
2918
 
            try:
2919
 
                converted = opt.from_unicode(value)
2920
 
            except (ValueError, TypeError):
2921
 
                # Invalid values are ignored
2922
 
                converted = None
2923
 
            if converted is None and opt.invalid is not None:
2924
 
                # The conversion failed
2925
 
                if opt.invalid == 'warning':
2926
 
                    trace.warning('Value "%s" is not valid for "%s"',
2927
 
                                  value, name)
2928
 
                elif opt.invalid == 'error':
2929
 
                    raise errors.ConfigOptionValueError(name, value)
2930
 
            value = converted
2931
2737
        if value is None:
2932
2738
            # If the option is registered, it may provide a default value
 
2739
            try:
 
2740
                opt = option_registry.get(name)
 
2741
            except KeyError:
 
2742
                # Not registered
 
2743
                opt = None
2933
2744
            if opt is not None:
2934
2745
                value = opt.get_default()
2935
2746
        for hook in ConfigHooks['get']:
3001
2812
class LocationStack(_CompatibleStack):
3002
2813
 
3003
2814
    def __init__(self, location):
3004
 
        """Make a new stack for a location and global configuration.
3005
 
        
3006
 
        :param location: A URL prefix to """
3007
2815
        lstore = LocationStore()
3008
2816
        matcher = LocationMatcher(lstore, location)
3009
2817
        gstore = GlobalStore()