~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Paul Stewart
  • Date: 2011-08-05 22:18:05 UTC
  • mto: This revision was merged to the branch mainline in revision 6069.
  • Revision ID: paulbrianstewart@gmail.com-20110805221805-nuex1ervc465ruvg
Updated the empty commit message text to use double quote marks rather than single quotes so it will work with Windows re John A Meinel's comment

Show diffs side-by-side

added added

removed removed

Lines of Context:
172
172
# FIXME: Until we can guarantee that each config file is loaded once and
173
173
# only once for a given bzrlib session, we don't want to re-read the file every
174
174
# 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
 
175
# needing to restore the proper value).This shouldn't be part of 2.4.0 final,
 
176
# yell at mgz^W vila and the RM if this is still present at that time
 
177
# -- vila 20110219
176
178
_expand_default_value = None
177
179
def _get_expand_default_value():
178
180
    global _expand_default_value
1511
1513
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
1512
1514
                                  ' or HOME set')
1513
1515
        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':
 
1516
    elif sys.platform == 'darwin':
1518
1517
        if base is None:
1519
1518
            # this takes into account $HOME
1520
1519
            base = os.path.expanduser("~")
1521
1520
        return osutils.pathjoin(base, '.bazaar')
1522
1521
    else:
1523
1522
        if base is None:
 
1523
 
1524
1524
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
1525
1525
            if xdg_dir is None:
1526
1526
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
1529
1529
                trace.mutter(
1530
1530
                    "Using configuration in XDG directory %s." % xdg_dir)
1531
1531
                return xdg_dir
 
1532
 
1532
1533
            base = os.path.expanduser("~")
1533
1534
        return osutils.pathjoin(base, ".bazaar")
1534
1535
 
2270
2271
    The option *values* are stored in config files and found in sections.
2271
2272
 
2272
2273
    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.
 
2274
    value, in which config files it can be stored, etc (TBC).
2275
2275
    """
2276
2276
 
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
 
        """
 
2277
    def __init__(self, name, default=None):
2299
2278
        self.name = name
2300
2279
        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
2280
 
2307
2281
    def get_default(self):
2308
2282
        return self.default
2309
2283
 
2310
 
# Predefined converters to get proper values from store
2311
 
 
2312
 
def bool_from_store(unicode_str):
2313
 
    return ui.bool_from_string(unicode_str)
2314
 
 
2315
 
 
2316
 
def int_from_store(unicode_str):
2317
 
    return int(unicode_str)
2318
 
 
2319
 
 
2320
 
def list_from_store(unicode_str):
2321
 
    # ConfigObj return '' instead of u''. Use 'str' below to catch all cases.
2322
 
    if isinstance(unicode_str, (str, unicode)):
2323
 
        if unicode_str:
2324
 
            # A single value, most probably the user forgot (or didn't care to
2325
 
            # add) the final ','
2326
 
            l = [unicode_str]
2327
 
        else:
2328
 
            # The empty string, convert to empty list
2329
 
            l = []
2330
 
    else:
2331
 
        # We rely on ConfigObj providing us with a list already
2332
 
        l = unicode_str
2333
 
    return l
2334
 
 
2335
 
 
2336
 
class OptionRegistry(registry.Registry):
2337
 
    """Register config options by their name.
2338
 
 
2339
 
    This overrides ``registry.Registry`` to simplify registration by acquiring
2340
 
    some information from the option object itself.
2341
 
    """
2342
 
 
2343
 
    def register(self, option):
2344
 
        """Register a new option to its name.
2345
 
 
2346
 
        :param option: The option to register. Its name is used as the key.
2347
 
        """
2348
 
        super(OptionRegistry, self).register(option.name, option,
2349
 
                                             help=option.help)
2350
 
 
2351
 
    def register_lazy(self, key, module_name, member_name):
2352
 
        """Register a new option to be loaded on request.
2353
 
 
2354
 
        :param key: This is the key to use to request the option later. Since
2355
 
            the registration is lazy, it should be provided and match the
2356
 
            option name.
2357
 
 
2358
 
        :param module_name: The python path to the module. Such as 'os.path'.
2359
 
 
2360
 
        :param member_name: The member of the module to return.  If empty or
2361
 
                None, get() will return the module itself.
2362
 
        """
2363
 
        super(OptionRegistry, self).register_lazy(key,
2364
 
                                                  module_name, member_name)
2365
 
 
2366
 
    def get_help(self, key=None):
2367
 
        """Get the help text associated with the given key"""
2368
 
        option = self.get(key)
2369
 
        the_help = option.help
2370
 
        if callable(the_help):
2371
 
            return the_help(self, key)
2372
 
        return the_help
2373
 
 
2374
 
 
2375
 
option_registry = OptionRegistry()
2376
 
 
2377
 
 
2378
 
# Registered options in lexicographical order
2379
 
 
2380
 
option_registry.register(
2381
 
    Option('dirstate.fdatasync', default=True, from_unicode=bool_from_store,
2382
 
           help='''
2383
 
Flush dirstate changes onto physical disk?
2384
 
 
2385
 
If true (default), working tree metadata changes are flushed through the
2386
 
OS buffers to physical disk.  This is somewhat slower, but means data
2387
 
should not be lost if the machine crashes.  See also repository.fdatasync.
2388
 
'''))
2389
 
option_registry.register(
2390
 
    Option('default_format', default='2a',
2391
 
           help='Format used when creating branches.'))
2392
 
option_registry.register(
2393
 
    Option('editor',
2394
 
           help='The command called to launch an editor to enter a message.'))
2395
 
option_registry.register(
2396
 
    Option('language',
2397
 
           help='Language to translate messages into.'))
2398
 
option_registry.register(
2399
 
    Option('output_encoding',
2400
 
           help= 'Unicode encoding for output'
2401
 
           ' (terminal encoding if not specified).'))
2402
 
option_registry.register(
2403
 
    Option('repository.fdatasync', default=True, from_unicode=bool_from_store,
2404
 
           help='''\
2405
 
Flush repository changes onto physical disk?
2406
 
 
2407
 
If true (default), repository changes are flushed through the OS buffers
2408
 
to physical disk.  This is somewhat slower, but means data should not be
2409
 
lost if the machine crashes.  See also dirstate.fdatasync.
2410
 
'''))
 
2284
 
 
2285
# Options registry
 
2286
 
 
2287
option_registry = registry.Registry()
 
2288
 
 
2289
 
 
2290
option_registry.register(
 
2291
    'editor', Option('editor'),
 
2292
    help='The command called to launch an editor to enter a message.')
2411
2293
 
2412
2294
 
2413
2295
class Section(object):
2680
2562
class GlobalStore(LockableIniFileStore):
2681
2563
 
2682
2564
    def __init__(self, possible_transports=None):
2683
 
        t = transport.get_transport_from_path(
2684
 
            config_dir(), possible_transports=possible_transports)
 
2565
        t = transport.get_transport_from_path(config_dir(),
 
2566
                                    possible_transports=possible_transports)
2685
2567
        super(GlobalStore, self).__init__(t, 'bazaar.conf')
2686
2568
 
2687
2569
 
2688
2570
class LocationStore(LockableIniFileStore):
2689
2571
 
2690
2572
    def __init__(self, possible_transports=None):
2691
 
        t = transport.get_transport_from_path(
2692
 
            config_dir(), possible_transports=possible_transports)
 
2573
        t = transport.get_transport_from_path(config_dir(),
 
2574
                                    possible_transports=possible_transports)
2693
2575
        super(LocationStore, self).__init__(t, 'locations.conf')
2694
2576
 
2695
2577
 
2861
2743
                    break
2862
2744
            if value is not None:
2863
2745
                break
2864
 
        # If the option is registered, it may provide additional info about
2865
 
        # value handling
2866
 
        try:
2867
 
            opt = option_registry.get(name)
2868
 
        except KeyError:
2869
 
            # Not registered
2870
 
            opt = None
2871
 
        if (opt is not None and opt.from_unicode is not None
2872
 
            and value is not None):
2873
 
            # If a value exists and the option provides a converter, use it
2874
 
            try:
2875
 
                converted = opt.from_unicode(value)
2876
 
            except (ValueError, TypeError):
2877
 
                # Invalid values are ignored
2878
 
                converted = None
2879
 
            if converted is None and opt.invalid is not None:
2880
 
                # The conversion failed
2881
 
                if opt.invalid == 'warning':
2882
 
                    trace.warning('Value "%s" is not valid for "%s"',
2883
 
                                  value, name)
2884
 
                elif opt.invalid == 'error':
2885
 
                    raise errors.ConfigOptionValueError(name, value)
2886
 
            value = converted
2887
2746
        if value is None:
2888
2747
            # If the option is registered, it may provide a default value
 
2748
            try:
 
2749
                opt = option_registry.get(name)
 
2750
            except KeyError:
 
2751
                # Not registered
 
2752
                opt = None
2889
2753
            if opt is not None:
2890
2754
                value = opt.get_default()
2891
2755
        for hook in ConfigHooks['get']:
2957
2821
class LocationStack(_CompatibleStack):
2958
2822
 
2959
2823
    def __init__(self, location):
2960
 
        """Make a new stack for a location and global configuration.
2961
 
        
2962
 
        :param location: A URL prefix to """
2963
2824
        lstore = LocationStore()
2964
2825
        matcher = LocationMatcher(lstore, location)
2965
2826
        gstore = GlobalStore()