/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Gordon Tyler
  • Date: 2011-01-19 13:25:22 UTC
  • mfrom: (5620 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5632.
  • Revision ID: gordon@doxxx.net-20110119132522-snhfnvq2jq8tmp1j
Merged bzr.dev into mergetools.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
3
#            and others
4
4
#
65
65
import os
66
66
import sys
67
67
 
 
68
from bzrlib import commands
 
69
from bzrlib.decorators import needs_write_lock
68
70
from bzrlib.lazy_import import lazy_import
69
71
lazy_import(globals(), """
70
72
import errno
71
 
from fnmatch import fnmatch
 
73
import fnmatch
72
74
import re
73
75
from cStringIO import StringIO
74
76
 
75
77
import bzrlib
76
78
from bzrlib import (
 
79
    atomicfile,
 
80
    bzrdir,
77
81
    debug,
78
82
    errors,
 
83
    lockdir,
79
84
    mail_client,
 
85
    mergetools,
80
86
    osutils,
81
87
    registry,
82
88
    symbol_versioning,
83
89
    trace,
 
90
    transport,
84
91
    ui,
85
92
    urlutils,
86
93
    win32utils,
149
156
    def __init__(self):
150
157
        super(Config, self).__init__()
151
158
 
 
159
    def config_id(self):
 
160
        """Returns a unique ID for the config."""
 
161
        raise NotImplementedError(self.config_id)
 
162
 
152
163
    def get_editor(self):
153
164
        """Get the users pop up editor."""
154
165
        raise NotImplementedError
257
268
 
258
269
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
259
270
 
260
 
        $BZR_EMAIL can be set to override this (as well as the
261
 
        deprecated $BZREMAIL), then
 
271
        $BZR_EMAIL can be set to override this, then
262
272
        the concrete policy type is checked, and finally
263
273
        $EMAIL is examined.
264
 
        If none is found, a reasonable default is (hopefully)
265
 
        created.
 
274
        If no username can be found, errors.NoWhoami exception is raised.
266
275
 
267
276
        TODO: Check it's reasonably well-formed.
268
277
        """
278
287
        if v:
279
288
            return v.decode(osutils.get_user_encoding())
280
289
 
281
 
        name, email = _auto_user_id()
282
 
        if name:
283
 
            return '%s <%s>' % (name, email)
284
 
        else:
285
 
            return email
 
290
        raise errors.NoWhoami()
 
291
 
 
292
    def ensure_username(self):
 
293
        """Raise errors.NoWhoami if username is not set.
 
294
 
 
295
        This method relies on the username() function raising the error.
 
296
        """
 
297
        self.username()
286
298
 
287
299
    def signature_checking(self):
288
300
        """What is the current policy for signature checking?."""
346
358
        else:
347
359
            return True
348
360
 
 
361
    def get_merge_tools(self):
 
362
        tools = {}
 
363
        for (oname, value, section, conf_id, parser) in self._get_options():
 
364
            if oname.startswith('bzr.mergetool.'):
 
365
                tool_name = oname[len('bzr.mergetool.'):]
 
366
                tools[tool_name] = mergetools.MergeTool(tool_name, value)
 
367
        trace.mutter('loaded merge tools: %r' % tools)
 
368
        return tools.values()
 
369
 
 
370
    def find_merge_tool(self, name):
 
371
        # We fake a defaults mechanism here by checking if the given name can 
 
372
        # be found in the known_merge_tools if it's not found in the config.
 
373
        # This should be done through the proposed config defaults mechanism
 
374
        # when it becomes available in the future.
 
375
        command_line = (self.get_user_option('bzr.mergetool.%s' % name) or
 
376
                        mergetools.known_merge_tools.get(name, None))
 
377
        if command_line is None:
 
378
            return None
 
379
        return mergetools.MergeTool(name, command_line)
 
380
 
 
381
    def get_default_merge_tool(self):
 
382
        return self.get_user_option('bzr.default_mergetool')
 
383
 
349
384
 
350
385
class IniBasedConfig(Config):
351
386
    """A configuration policy that draws from ini files."""
352
387
 
353
 
    def __init__(self, get_filename):
 
388
    def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
 
389
                 file_name=None):
 
390
        """Base class for configuration files using an ini-like syntax.
 
391
 
 
392
        :param file_name: The configuration file path.
 
393
        """
354
394
        super(IniBasedConfig, self).__init__()
355
 
        self._get_filename = get_filename
 
395
        self.file_name = file_name
 
396
        if symbol_versioning.deprecated_passed(get_filename):
 
397
            symbol_versioning.warn(
 
398
                'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
 
399
                ' Use file_name instead.',
 
400
                DeprecationWarning,
 
401
                stacklevel=2)
 
402
            if get_filename is not None:
 
403
                self.file_name = get_filename()
 
404
        else:
 
405
            self.file_name = file_name
 
406
        self._content = None
356
407
        self._parser = None
357
408
 
358
 
    def _get_parser(self, file=None):
 
409
    @classmethod
 
410
    def from_string(cls, str_or_unicode, file_name=None, save=False):
 
411
        """Create a config object from a string.
 
412
 
 
413
        :param str_or_unicode: A string representing the file content. This will
 
414
            be utf-8 encoded.
 
415
 
 
416
        :param file_name: The configuration file path.
 
417
 
 
418
        :param _save: Whether the file should be saved upon creation.
 
419
        """
 
420
        conf = cls(file_name=file_name)
 
421
        conf._create_from_string(str_or_unicode, save)
 
422
        return conf
 
423
 
 
424
    def _create_from_string(self, str_or_unicode, save):
 
425
        self._content = StringIO(str_or_unicode.encode('utf-8'))
 
426
        # Some tests use in-memory configs, some other always need the config
 
427
        # file to exist on disk.
 
428
        if save:
 
429
            self._write_config_file()
 
430
 
 
431
    def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
359
432
        if self._parser is not None:
360
433
            return self._parser
361
 
        if file is None:
362
 
            input = self._get_filename()
 
434
        if symbol_versioning.deprecated_passed(file):
 
435
            symbol_versioning.warn(
 
436
                'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
 
437
                ' Use IniBasedConfig(_content=xxx) instead.',
 
438
                DeprecationWarning,
 
439
                stacklevel=2)
 
440
        if self._content is not None:
 
441
            co_input = self._content
 
442
        elif self.file_name is None:
 
443
            raise AssertionError('We have no content to create the config')
363
444
        else:
364
 
            input = file
 
445
            co_input = self.file_name
365
446
        try:
366
 
            self._parser = ConfigObj(input, encoding='utf-8')
 
447
            self._parser = ConfigObj(co_input, encoding='utf-8')
367
448
        except configobj.ConfigObjError, e:
368
449
            raise errors.ParseConfigError(e.errors, e.config.filename)
 
450
        # Make sure self.reload() will use the right file name
 
451
        self._parser.filename = self.file_name
369
452
        return self._parser
370
453
 
 
454
    def reload(self):
 
455
        """Reload the config file from disk."""
 
456
        if self.file_name is None:
 
457
            raise AssertionError('We need a file name to reload the config')
 
458
        if self._parser is not None:
 
459
            self._parser.reload()
 
460
 
371
461
    def _get_matching_sections(self):
372
462
        """Return an ordered list of (section_name, extra_path) pairs.
373
463
 
384
474
        """Override this to define the section used by the config."""
385
475
        return "DEFAULT"
386
476
 
 
477
    def _get_sections(self, name=None):
 
478
        """Returns an iterator of the sections specified by ``name``.
 
479
 
 
480
        :param name: The section name. If None is supplied, the default
 
481
            configurations are yielded.
 
482
 
 
483
        :return: A tuple (name, section, config_id) for all sections that will
 
484
            be walked by user_get_option() in the 'right' order. The first one
 
485
            is where set_user_option() will update the value.
 
486
        """
 
487
        parser = self._get_parser()
 
488
        if name is not None:
 
489
            yield (name, parser[name], self.config_id())
 
490
        else:
 
491
            # No section name has been given so we fallback to the configobj
 
492
            # itself which holds the variables defined outside of any section.
 
493
            yield (None, parser, self.config_id())
 
494
 
 
495
    def _get_options(self, sections=None):
 
496
        """Return an ordered list of (name, value, section, config_id) tuples.
 
497
 
 
498
        All options are returned with their associated value and the section
 
499
        they appeared in. ``config_id`` is a unique identifier for the
 
500
        configuration file the option is defined in.
 
501
 
 
502
        :param sections: Default to ``_get_matching_sections`` if not
 
503
            specified. This gives a better control to daughter classes about
 
504
            which sections should be searched. This is a list of (name,
 
505
            configobj) tuples.
 
506
        """
 
507
        opts = []
 
508
        if sections is None:
 
509
            parser = self._get_parser()
 
510
            sections = []
 
511
            for (section_name, _) in self._get_matching_sections():
 
512
                try:
 
513
                    section = parser[section_name]
 
514
                except KeyError:
 
515
                    # This could happen for an empty file for which we define a
 
516
                    # DEFAULT section. FIXME: Force callers to provide sections
 
517
                    # instead ? -- vila 20100930
 
518
                    continue
 
519
                sections.append((section_name, section))
 
520
        config_id = self.config_id()
 
521
        for (section_name, section) in sections:
 
522
            for (name, value) in section.iteritems():
 
523
                yield (name, parser._quote(value), section_name,
 
524
                       config_id, parser)
 
525
 
387
526
    def _get_option_policy(self, section, option_name):
388
527
        """Return the policy for the given (section, option_name) pair."""
389
528
        return POLICY_NONE
476
615
    def _get_nickname(self):
477
616
        return self.get_user_option('nickname')
478
617
 
479
 
 
480
 
class GlobalConfig(IniBasedConfig):
 
618
    def remove_user_option(self, option_name, section_name=None):
 
619
        """Remove a user option and save the configuration file.
 
620
 
 
621
        :param option_name: The option to be removed.
 
622
 
 
623
        :param section_name: The section the option is defined in, default to
 
624
            the default section.
 
625
        """
 
626
        self.reload()
 
627
        parser = self._get_parser()
 
628
        if section_name is None:
 
629
            section = parser
 
630
        else:
 
631
            section = parser[section_name]
 
632
        try:
 
633
            del section[option_name]
 
634
        except KeyError:
 
635
            raise errors.NoSuchConfigOption(option_name)
 
636
        self._write_config_file()
 
637
 
 
638
    def _write_config_file(self):
 
639
        if self.file_name is None:
 
640
            raise AssertionError('We cannot save, self.file_name is None')
 
641
        conf_dir = os.path.dirname(self.file_name)
 
642
        ensure_config_dir_exists(conf_dir)
 
643
        atomic_file = atomicfile.AtomicFile(self.file_name)
 
644
        self._get_parser().write(atomic_file)
 
645
        atomic_file.commit()
 
646
        atomic_file.close()
 
647
        osutils.copy_ownership_from_path(self.file_name)
 
648
 
 
649
 
 
650
class LockableConfig(IniBasedConfig):
 
651
    """A configuration needing explicit locking for access.
 
652
 
 
653
    If several processes try to write the config file, the accesses need to be
 
654
    serialized.
 
655
 
 
656
    Daughter classes should decorate all methods that update a config with the
 
657
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
 
658
    ``_write_config_file()`` method. These methods (typically ``set_option()``
 
659
    and variants must reload the config file from disk before calling
 
660
    ``_write_config_file()``), this can be achieved by calling the
 
661
    ``self.reload()`` method. Note that the lock scope should cover both the
 
662
    reading and the writing of the config file which is why the decorator can't
 
663
    be applied to ``_write_config_file()`` only.
 
664
 
 
665
    This should be enough to implement the following logic:
 
666
    - lock for exclusive write access,
 
667
    - reload the config file from disk,
 
668
    - set the new value
 
669
    - unlock
 
670
 
 
671
    This logic guarantees that a writer can update a value without erasing an
 
672
    update made by another writer.
 
673
    """
 
674
 
 
675
    lock_name = 'lock'
 
676
 
 
677
    def __init__(self, file_name):
 
678
        super(LockableConfig, self).__init__(file_name=file_name)
 
679
        self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
 
680
        self.transport = transport.get_transport(self.dir)
 
681
        self._lock = lockdir.LockDir(self.transport, 'lock')
 
682
 
 
683
    def _create_from_string(self, unicode_bytes, save):
 
684
        super(LockableConfig, self)._create_from_string(unicode_bytes, False)
 
685
        if save:
 
686
            # We need to handle the saving here (as opposed to IniBasedConfig)
 
687
            # to be able to lock
 
688
            self.lock_write()
 
689
            self._write_config_file()
 
690
            self.unlock()
 
691
 
 
692
    def lock_write(self, token=None):
 
693
        """Takes a write lock in the directory containing the config file.
 
694
 
 
695
        If the directory doesn't exist it is created.
 
696
        """
 
697
        ensure_config_dir_exists(self.dir)
 
698
        return self._lock.lock_write(token)
 
699
 
 
700
    def unlock(self):
 
701
        self._lock.unlock()
 
702
 
 
703
    def break_lock(self):
 
704
        self._lock.break_lock()
 
705
 
 
706
    @needs_write_lock
 
707
    def remove_user_option(self, option_name, section_name=None):
 
708
        super(LockableConfig, self).remove_user_option(option_name,
 
709
                                                       section_name)
 
710
 
 
711
    def _write_config_file(self):
 
712
        if self._lock is None or not self._lock.is_held:
 
713
            # NB: if the following exception is raised it probably means a
 
714
            # missing @needs_write_lock decorator on one of the callers.
 
715
            raise errors.ObjectNotLocked(self)
 
716
        super(LockableConfig, self)._write_config_file()
 
717
 
 
718
 
 
719
class GlobalConfig(LockableConfig):
481
720
    """The configuration that should be used for a specific location."""
482
721
 
 
722
    def __init__(self):
 
723
        super(GlobalConfig, self).__init__(file_name=config_filename())
 
724
 
 
725
    def config_id(self):
 
726
        return 'bazaar'
 
727
 
 
728
    @classmethod
 
729
    def from_string(cls, str_or_unicode, save=False):
 
730
        """Create a config object from a string.
 
731
 
 
732
        :param str_or_unicode: A string representing the file content. This
 
733
            will be utf-8 encoded.
 
734
 
 
735
        :param save: Whether the file should be saved upon creation.
 
736
        """
 
737
        conf = cls()
 
738
        conf._create_from_string(str_or_unicode, save)
 
739
        return conf
 
740
 
483
741
    def get_editor(self):
484
742
        return self._get_user_option('editor')
485
743
 
486
 
    def __init__(self):
487
 
        super(GlobalConfig, self).__init__(config_filename)
488
 
 
 
744
    @needs_write_lock
489
745
    def set_user_option(self, option, value):
490
746
        """Save option and its value in the configuration."""
491
747
        self._set_option(option, value, 'DEFAULT')
497
753
        else:
498
754
            return {}
499
755
 
 
756
    @needs_write_lock
500
757
    def set_alias(self, alias_name, alias_command):
501
758
        """Save the alias in the configuration."""
502
759
        self._set_option(alias_name, alias_command, 'ALIASES')
503
760
 
 
761
    @needs_write_lock
504
762
    def unset_alias(self, alias_name):
505
763
        """Unset an existing alias."""
 
764
        self.reload()
506
765
        aliases = self._get_parser().get('ALIASES')
507
766
        if not aliases or alias_name not in aliases:
508
767
            raise errors.NoSuchAlias(alias_name)
510
769
        self._write_config_file()
511
770
 
512
771
    def _set_option(self, option, value, section):
513
 
        # FIXME: RBC 20051029 This should refresh the parser and also take a
514
 
        # file lock on bazaar.conf.
515
 
        conf_dir = os.path.dirname(self._get_filename())
516
 
        ensure_config_dir_exists(conf_dir)
 
772
        self.reload()
517
773
        self._get_parser().setdefault(section, {})[option] = value
518
774
        self._write_config_file()
519
775
 
520
 
    def _write_config_file(self):
521
 
        path = self._get_filename()
522
 
        f = open(path, 'wb')
523
 
        osutils.copy_ownership_from_path(path)
524
 
        self._get_parser().write(f)
525
 
        f.close()
526
 
 
527
 
 
528
 
class LocationConfig(IniBasedConfig):
 
776
 
 
777
    def _get_sections(self, name=None):
 
778
        """See IniBasedConfig._get_sections()."""
 
779
        parser = self._get_parser()
 
780
        # We don't give access to options defined outside of any section, we
 
781
        # used the DEFAULT section by... default.
 
782
        if name in (None, 'DEFAULT'):
 
783
            # This could happen for an empty file where the DEFAULT section
 
784
            # doesn't exist yet. So we force DEFAULT when yielding
 
785
            name = 'DEFAULT'
 
786
            if 'DEFAULT' not in parser:
 
787
               parser['DEFAULT']= {}
 
788
        yield (name, parser[name], self.config_id())
 
789
 
 
790
    @needs_write_lock
 
791
    def remove_user_option(self, option_name, section_name=None):
 
792
        if section_name is None:
 
793
            # We need to force the default section.
 
794
            section_name = 'DEFAULT'
 
795
        # We need to avoid the LockableConfig implementation or we'll lock
 
796
        # twice
 
797
        super(LockableConfig, self).remove_user_option(option_name,
 
798
                                                       section_name)
 
799
 
 
800
 
 
801
class LocationConfig(LockableConfig):
529
802
    """A configuration object that gives the policy for a location."""
530
803
 
531
804
    def __init__(self, location):
532
 
        name_generator = locations_config_filename
533
 
        if (not os.path.exists(name_generator()) and
534
 
                os.path.exists(branches_config_filename())):
535
 
            if sys.platform == 'win32':
536
 
                trace.warning('Please rename %s to %s'
537
 
                              % (branches_config_filename(),
538
 
                                 locations_config_filename()))
539
 
            else:
540
 
                trace.warning('Please rename ~/.bazaar/branches.conf'
541
 
                              ' to ~/.bazaar/locations.conf')
542
 
            name_generator = branches_config_filename
543
 
        super(LocationConfig, self).__init__(name_generator)
 
805
        super(LocationConfig, self).__init__(
 
806
            file_name=locations_config_filename())
544
807
        # local file locations are looked up by local path, rather than
545
808
        # by file url. This is because the config file is a user
546
809
        # file, and we would rather not expose the user to file urls.
548
811
            location = urlutils.local_path_from_url(location)
549
812
        self.location = location
550
813
 
 
814
    def config_id(self):
 
815
        return 'locations'
 
816
 
 
817
    @classmethod
 
818
    def from_string(cls, str_or_unicode, location, save=False):
 
819
        """Create a config object from a string.
 
820
 
 
821
        :param str_or_unicode: A string representing the file content. This will
 
822
            be utf-8 encoded.
 
823
 
 
824
        :param location: The location url to filter the configuration.
 
825
 
 
826
        :param save: Whether the file should be saved upon creation.
 
827
        """
 
828
        conf = cls(location)
 
829
        conf._create_from_string(str_or_unicode, save)
 
830
        return conf
 
831
 
551
832
    def _get_matching_sections(self):
552
833
        """Return an ordered list of section names matching this location."""
553
834
        sections = self._get_parser()
570
851
            names = zip(location_names, section_names)
571
852
            matched = True
572
853
            for name in names:
573
 
                if not fnmatch(name[0], name[1]):
 
854
                if not fnmatch.fnmatch(name[0], name[1]):
574
855
                    matched = False
575
856
                    break
576
857
            if not matched:
581
862
                continue
582
863
            matches.append((len(section_names), section,
583
864
                            '/'.join(location_names[len(section_names):])))
 
865
        # put the longest (aka more specific) locations first
584
866
        matches.sort(reverse=True)
585
867
        sections = []
586
868
        for (length, section, extra_path) in matches:
593
875
                pass
594
876
        return sections
595
877
 
 
878
    def _get_sections(self, name=None):
 
879
        """See IniBasedConfig._get_sections()."""
 
880
        # We ignore the name here as the only sections handled are named with
 
881
        # the location path and we don't expose embedded sections either.
 
882
        parser = self._get_parser()
 
883
        for name, extra_path in self._get_matching_sections():
 
884
            yield (name, parser[name], self.config_id())
 
885
 
596
886
    def _get_option_policy(self, section, option_name):
597
887
        """Return the policy for the given (section, option_name) pair."""
598
888
        # check for the old 'recurse=False' flag
641
931
            if policy_key in self._get_parser()[section]:
642
932
                del self._get_parser()[section][policy_key]
643
933
 
 
934
    @needs_write_lock
644
935
    def set_user_option(self, option, value, store=STORE_LOCATION):
645
936
        """Save option and its value in the configuration."""
646
937
        if store not in [STORE_LOCATION,
648
939
                         STORE_LOCATION_APPENDPATH]:
649
940
            raise ValueError('bad storage policy %r for %r' %
650
941
                (store, option))
651
 
        # FIXME: RBC 20051029 This should refresh the parser and also take a
652
 
        # file lock on locations.conf.
653
 
        conf_dir = os.path.dirname(self._get_filename())
654
 
        ensure_config_dir_exists(conf_dir)
 
942
        self.reload()
655
943
        location = self.location
656
944
        if location.endswith('/'):
657
945
            location = location[:-1]
658
 
        if (not location in self._get_parser() and
659
 
            not location + '/' in self._get_parser()):
660
 
            self._get_parser()[location]={}
661
 
        elif location + '/' in self._get_parser():
 
946
        parser = self._get_parser()
 
947
        if not location in parser and not location + '/' in parser:
 
948
            parser[location] = {}
 
949
        elif location + '/' in parser:
662
950
            location = location + '/'
663
 
        self._get_parser()[location][option]=value
 
951
        parser[location][option]=value
664
952
        # the allowed values of store match the config policies
665
953
        self._set_option_policy(location, option, store)
666
 
        self._get_parser().write(file(self._get_filename(), 'wb'))
 
954
        self._write_config_file()
667
955
 
668
956
 
669
957
class BranchConfig(Config):
670
958
    """A configuration object giving the policy for a branch."""
671
959
 
 
960
    def __init__(self, branch):
 
961
        super(BranchConfig, self).__init__()
 
962
        self._location_config = None
 
963
        self._branch_data_config = None
 
964
        self._global_config = None
 
965
        self.branch = branch
 
966
        self.option_sources = (self._get_location_config,
 
967
                               self._get_branch_data_config,
 
968
                               self._get_global_config)
 
969
 
 
970
    def config_id(self):
 
971
        return 'branch'
 
972
 
672
973
    def _get_branch_data_config(self):
673
974
        if self._branch_data_config is None:
674
975
            self._branch_data_config = TreeConfig(self.branch)
 
976
            self._branch_data_config.config_id = self.config_id
675
977
        return self._branch_data_config
676
978
 
677
979
    def _get_location_config(self):
745
1047
                return value
746
1048
        return None
747
1049
 
 
1050
    def _get_sections(self, name=None):
 
1051
        """See IniBasedConfig.get_sections()."""
 
1052
        for source in self.option_sources:
 
1053
            for section in source()._get_sections(name):
 
1054
                yield section
 
1055
 
 
1056
    def _get_options(self, sections=None):
 
1057
        opts = []
 
1058
        # First the locations options
 
1059
        for option in self._get_location_config()._get_options():
 
1060
            yield option
 
1061
        # Then the branch options
 
1062
        branch_config = self._get_branch_data_config()
 
1063
        if sections is None:
 
1064
            sections = [('DEFAULT', branch_config._get_parser())]
 
1065
        # FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
 
1066
        # Config itself has no notion of sections :( -- vila 20101001
 
1067
        config_id = self.config_id()
 
1068
        for (section_name, section) in sections:
 
1069
            for (name, value) in section.iteritems():
 
1070
                yield (name, value, section_name,
 
1071
                       config_id, branch_config._get_parser())
 
1072
        # Then the global options
 
1073
        for option in self._get_global_config()._get_options():
 
1074
            yield option
 
1075
 
748
1076
    def set_user_option(self, name, value, store=STORE_BRANCH,
749
1077
        warn_masked=False):
750
1078
        if store == STORE_BRANCH:
768
1096
                        trace.warning('Value "%s" is masked by "%s" from'
769
1097
                                      ' branch.conf', value, mask_value)
770
1098
 
 
1099
    def remove_user_option(self, option_name, section_name=None):
 
1100
        self._get_branch_data_config().remove_option(option_name, section_name)
 
1101
 
771
1102
    def _gpg_signing_command(self):
772
1103
        """See Config.gpg_signing_command."""
773
1104
        return self._get_safe_value('_gpg_signing_command')
774
1105
 
775
 
    def __init__(self, branch):
776
 
        super(BranchConfig, self).__init__()
777
 
        self._location_config = None
778
 
        self._branch_data_config = None
779
 
        self._global_config = None
780
 
        self.branch = branch
781
 
        self.option_sources = (self._get_location_config,
782
 
                               self._get_branch_data_config,
783
 
                               self._get_global_config)
784
 
 
785
1106
    def _post_commit(self):
786
1107
        """See Config.post_commit."""
787
1108
        return self._get_safe_value('_post_commit')
817
1138
            parent_dir = os.path.dirname(path)
818
1139
            if not os.path.isdir(parent_dir):
819
1140
                trace.mutter('creating config parent directory: %r', parent_dir)
820
 
            os.mkdir(parent_dir)
 
1141
                os.mkdir(parent_dir)
821
1142
        trace.mutter('creating config directory: %r', path)
822
1143
        os.mkdir(path)
823
1144
        osutils.copy_ownership_from_path(path)
826
1147
def config_dir():
827
1148
    """Return per-user configuration directory.
828
1149
 
829
 
    By default this is ~/.bazaar/
 
1150
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
 
1151
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
 
1152
    that will be used instead.
830
1153
 
831
1154
    TODO: Global option --config-dir to override this.
832
1155
    """
833
1156
    base = os.environ.get('BZR_HOME', None)
834
1157
    if sys.platform == 'win32':
 
1158
        # environ variables on Windows are in user encoding/mbcs. So decode
 
1159
        # before using one
 
1160
        if base is not None:
 
1161
            base = base.decode('mbcs')
835
1162
        if base is None:
836
1163
            base = win32utils.get_appdata_location_unicode()
837
1164
        if base is None:
838
1165
            base = os.environ.get('HOME', None)
 
1166
            if base is not None:
 
1167
                base = base.decode('mbcs')
839
1168
        if base is None:
840
1169
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
841
1170
                                  ' or HOME set')
842
1171
        return osutils.pathjoin(base, 'bazaar', '2.0')
 
1172
    elif sys.platform == 'darwin':
 
1173
        if base is None:
 
1174
            # this takes into account $HOME
 
1175
            base = os.path.expanduser("~")
 
1176
        return osutils.pathjoin(base, '.bazaar')
843
1177
    else:
844
 
        # cygwin, linux, and darwin all have a $HOME directory
845
1178
        if base is None:
 
1179
 
 
1180
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
 
1181
            if xdg_dir is None:
 
1182
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
 
1183
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
 
1184
            if osutils.isdir(xdg_dir):
 
1185
                trace.mutter(
 
1186
                    "Using configuration in XDG directory %s." % xdg_dir)
 
1187
                return xdg_dir
 
1188
 
846
1189
            base = os.path.expanduser("~")
847
1190
        return osutils.pathjoin(base, ".bazaar")
848
1191
 
852
1195
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
853
1196
 
854
1197
 
855
 
def branches_config_filename():
856
 
    """Return per-user configuration ini file filename."""
857
 
    return osutils.pathjoin(config_dir(), 'branches.conf')
858
 
 
859
 
 
860
1198
def locations_config_filename():
861
1199
    """Return per-user configuration ini file filename."""
862
1200
    return osutils.pathjoin(config_dir(), 'locations.conf')
899
1237
        return os.path.expanduser('~/.cache')
900
1238
 
901
1239
 
902
 
def _auto_user_id():
903
 
    """Calculate automatic user identification.
904
 
 
905
 
    Returns (realname, email).
906
 
 
907
 
    Only used when none is set in the environment or the id file.
908
 
 
909
 
    This previously used the FQDN as the default domain, but that can
910
 
    be very slow on machines where DNS is broken.  So now we simply
911
 
    use the hostname.
912
 
    """
913
 
    import socket
914
 
 
915
 
    if sys.platform == 'win32':
916
 
        name = win32utils.get_user_name_unicode()
917
 
        if name is None:
918
 
            raise errors.BzrError("Cannot autodetect user name.\n"
919
 
                                  "Please, set your name with command like:\n"
920
 
                                  'bzr whoami "Your Name <name@domain.com>"')
921
 
        host = win32utils.get_host_name_unicode()
922
 
        if host is None:
923
 
            host = socket.gethostname()
924
 
        return name, (name + '@' + host)
925
 
 
926
 
    try:
927
 
        import pwd
928
 
        uid = os.getuid()
929
 
        try:
930
 
            w = pwd.getpwuid(uid)
931
 
        except KeyError:
932
 
            raise errors.BzrCommandError('Unable to determine your name.  '
933
 
                'Please use "bzr whoami" to set it.')
934
 
 
935
 
        # we try utf-8 first, because on many variants (like Linux),
936
 
        # /etc/passwd "should" be in utf-8, and because it's unlikely to give
937
 
        # false positives.  (many users will have their user encoding set to
938
 
        # latin-1, which cannot raise UnicodeError.)
939
 
        try:
940
 
            gecos = w.pw_gecos.decode('utf-8')
941
 
            encoding = 'utf-8'
942
 
        except UnicodeError:
943
 
            try:
944
 
                encoding = osutils.get_user_encoding()
945
 
                gecos = w.pw_gecos.decode(encoding)
946
 
            except UnicodeError:
947
 
                raise errors.BzrCommandError('Unable to determine your name.  '
948
 
                   'Use "bzr whoami" to set it.')
949
 
        try:
950
 
            username = w.pw_name.decode(encoding)
951
 
        except UnicodeError:
952
 
            raise errors.BzrCommandError('Unable to determine your name.  '
953
 
                'Use "bzr whoami" to set it.')
954
 
 
955
 
        comma = gecos.find(',')
956
 
        if comma == -1:
957
 
            realname = gecos
958
 
        else:
959
 
            realname = gecos[:comma]
960
 
        if not realname:
961
 
            realname = username
962
 
 
963
 
    except ImportError:
964
 
        import getpass
965
 
        try:
966
 
            user_encoding = osutils.get_user_encoding()
967
 
            realname = username = getpass.getuser().decode(user_encoding)
968
 
        except UnicodeDecodeError:
969
 
            raise errors.BzrError("Can't decode username as %s." % \
970
 
                    user_encoding)
971
 
 
972
 
    return realname, (username + '@' + socket.gethostname())
973
 
 
974
 
 
975
1240
def parse_username(username):
976
1241
    """Parse e-mail username and return a (name, address) tuple."""
977
1242
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1020
1285
 
1021
1286
    def set_option(self, value, name, section=None):
1022
1287
        """Set a per-branch configuration option"""
 
1288
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1289
        # higher levels providing the right lock -- vila 20101004
1023
1290
        self.branch.lock_write()
1024
1291
        try:
1025
1292
            self._config.set_option(value, name, section)
1026
1293
        finally:
1027
1294
            self.branch.unlock()
1028
1295
 
 
1296
    def remove_option(self, option_name, section_name=None):
 
1297
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1298
        # higher levels providing the right lock -- vila 20101004
 
1299
        self.branch.lock_write()
 
1300
        try:
 
1301
            self._config.remove_option(option_name, section_name)
 
1302
        finally:
 
1303
            self.branch.unlock()
 
1304
 
1029
1305
 
1030
1306
class AuthenticationConfig(object):
1031
1307
    """The authentication configuration file based on a ini file.
1063
1339
        """Save the config file, only tests should use it for now."""
1064
1340
        conf_dir = os.path.dirname(self._filename)
1065
1341
        ensure_config_dir_exists(conf_dir)
1066
 
        self._get_config().write(file(self._filename, 'wb'))
 
1342
        f = file(self._filename, 'wb')
 
1343
        try:
 
1344
            self._get_config().write(f)
 
1345
        finally:
 
1346
            f.close()
1067
1347
 
1068
1348
    def _set_option(self, section_name, option_name, value):
1069
1349
        """Set an authentication configuration option"""
1470
1750
    """A Config that reads/writes a config file on a Transport.
1471
1751
 
1472
1752
    It is a low-level object that considers config data to be name/value pairs
1473
 
    that may be associated with a section.  Assigning meaning to the these
1474
 
    values is done at higher levels like TreeConfig.
 
1753
    that may be associated with a section.  Assigning meaning to these values
 
1754
    is done at higher levels like TreeConfig.
1475
1755
    """
1476
1756
 
1477
1757
    def __init__(self, transport, filename):
1510
1790
            configobj.setdefault(section, {})[name] = value
1511
1791
        self._set_configobj(configobj)
1512
1792
 
 
1793
    def remove_option(self, option_name, section_name=None):
 
1794
        configobj = self._get_configobj()
 
1795
        if section_name is None:
 
1796
            del configobj[option_name]
 
1797
        else:
 
1798
            del configobj[section_name][option_name]
 
1799
        self._set_configobj(configobj)
 
1800
 
1513
1801
    def _get_config_file(self):
1514
1802
        try:
1515
1803
            return StringIO(self._transport.get_bytes(self._filename))
1517
1805
            return StringIO()
1518
1806
 
1519
1807
    def _get_configobj(self):
1520
 
        return ConfigObj(self._get_config_file(), encoding='utf-8')
 
1808
        f = self._get_config_file()
 
1809
        try:
 
1810
            return ConfigObj(f, encoding='utf-8')
 
1811
        finally:
 
1812
            f.close()
1521
1813
 
1522
1814
    def _set_configobj(self, configobj):
1523
1815
        out_file = StringIO()
1524
1816
        configobj.write(out_file)
1525
1817
        out_file.seek(0)
1526
1818
        self._transport.put_file(self._filename, out_file)
 
1819
 
 
1820
 
 
1821
class cmd_config(commands.Command):
 
1822
    __doc__ = """Display, set or remove a configuration option.
 
1823
 
 
1824
    Display the active value for a given option.
 
1825
 
 
1826
    If --all is specified, NAME is interpreted as a regular expression and all
 
1827
    matching options are displayed mentioning their scope. The active value
 
1828
    that bzr will take into account is the first one displayed for each option.
 
1829
 
 
1830
    If no NAME is given, --all .* is implied.
 
1831
 
 
1832
    Setting a value is achieved by using name=value without spaces. The value
 
1833
    is set in the most relevant scope and can be checked by displaying the
 
1834
    option again.
 
1835
    """
 
1836
 
 
1837
    takes_args = ['name?']
 
1838
 
 
1839
    takes_options = [
 
1840
        'directory',
 
1841
        # FIXME: This should be a registry option so that plugins can register
 
1842
        # their own config files (or not) -- vila 20101002
 
1843
        commands.Option('scope', help='Reduce the scope to the specified'
 
1844
                        ' configuration file',
 
1845
                        type=unicode),
 
1846
        commands.Option('all',
 
1847
            help='Display all the defined values for the matching options.',
 
1848
            ),
 
1849
        commands.Option('remove', help='Remove the option from'
 
1850
                        ' the configuration file'),
 
1851
        ]
 
1852
 
 
1853
    @commands.display_command
 
1854
    def run(self, name=None, all=False, directory=None, scope=None,
 
1855
            remove=False):
 
1856
        if directory is None:
 
1857
            directory = '.'
 
1858
        directory = urlutils.normalize_url(directory)
 
1859
        if remove and all:
 
1860
            raise errors.BzrError(
 
1861
                '--all and --remove are mutually exclusive.')
 
1862
        elif remove:
 
1863
            # Delete the option in the given scope
 
1864
            self._remove_config_option(name, directory, scope)
 
1865
        elif name is None:
 
1866
            # Defaults to all options
 
1867
            self._show_matching_options('.*', directory, scope)
 
1868
        else:
 
1869
            try:
 
1870
                name, value = name.split('=', 1)
 
1871
            except ValueError:
 
1872
                # Display the option(s) value(s)
 
1873
                if all:
 
1874
                    self._show_matching_options(name, directory, scope)
 
1875
                else:
 
1876
                    self._show_value(name, directory, scope)
 
1877
            else:
 
1878
                if all:
 
1879
                    raise errors.BzrError(
 
1880
                        'Only one option can be set.')
 
1881
                # Set the option value
 
1882
                self._set_config_option(name, value, directory, scope)
 
1883
 
 
1884
    def _get_configs(self, directory, scope=None):
 
1885
        """Iterate the configurations specified by ``directory`` and ``scope``.
 
1886
 
 
1887
        :param directory: Where the configurations are derived from.
 
1888
 
 
1889
        :param scope: A specific config to start from.
 
1890
        """
 
1891
        if scope is not None:
 
1892
            if scope == 'bazaar':
 
1893
                yield GlobalConfig()
 
1894
            elif scope == 'locations':
 
1895
                yield LocationConfig(directory)
 
1896
            elif scope == 'branch':
 
1897
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1898
                    directory)
 
1899
                yield br.get_config()
 
1900
        else:
 
1901
            try:
 
1902
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1903
                    directory)
 
1904
                yield br.get_config()
 
1905
            except errors.NotBranchError:
 
1906
                yield LocationConfig(directory)
 
1907
                yield GlobalConfig()
 
1908
 
 
1909
    def _show_value(self, name, directory, scope):
 
1910
        displayed = False
 
1911
        for c in self._get_configs(directory, scope):
 
1912
            if displayed:
 
1913
                break
 
1914
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1915
                if name == oname:
 
1916
                    # Display only the first value and exit
 
1917
 
 
1918
                    # FIXME: We need to use get_user_option to take policies
 
1919
                    # into account and we need to make sure the option exists
 
1920
                    # too (hence the two for loops), this needs a better API
 
1921
                    # -- vila 20101117
 
1922
                    value = c.get_user_option(name)
 
1923
                    # Quote the value appropriately
 
1924
                    value = parser._quote(value)
 
1925
                    self.outf.write('%s\n' % (value,))
 
1926
                    displayed = True
 
1927
                    break
 
1928
        if not displayed:
 
1929
            raise errors.NoSuchConfigOption(name)
 
1930
 
 
1931
    def _show_matching_options(self, name, directory, scope):
 
1932
        name = re.compile(name)
 
1933
        # We want any error in the regexp to be raised *now* so we need to
 
1934
        # avoid the delay introduced by the lazy regexp.
 
1935
        name._compile_and_collapse()
 
1936
        cur_conf_id = None
 
1937
        cur_section = None
 
1938
        for c in self._get_configs(directory, scope):
 
1939
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1940
                if name.search(oname):
 
1941
                    if cur_conf_id != conf_id:
 
1942
                        # Explain where the options are defined
 
1943
                        self.outf.write('%s:\n' % (conf_id,))
 
1944
                        cur_conf_id = conf_id
 
1945
                        cur_section = None
 
1946
                    if (section not in (None, 'DEFAULT')
 
1947
                        and cur_section != section):
 
1948
                        # Display the section if it's not the default (or only)
 
1949
                        # one.
 
1950
                        self.outf.write('  [%s]\n' % (section,))
 
1951
                        cur_section = section
 
1952
                    self.outf.write('  %s = %s\n' % (oname, value))
 
1953
 
 
1954
    def _set_config_option(self, name, value, directory, scope):
 
1955
        for conf in self._get_configs(directory, scope):
 
1956
            conf.set_user_option(name, value)
 
1957
            break
 
1958
        else:
 
1959
            raise errors.NoSuchConfig(scope)
 
1960
 
 
1961
    def _remove_config_option(self, name, directory, scope):
 
1962
        if name is None:
 
1963
            raise errors.BzrCommandError(
 
1964
                '--remove expects an option to remove.')
 
1965
        removed = False
 
1966
        for conf in self._get_configs(directory, scope):
 
1967
            for (section_name, section, conf_id) in conf._get_sections():
 
1968
                if scope is not None and conf_id != scope:
 
1969
                    # Not the right configuration file
 
1970
                    continue
 
1971
                if name in section:
 
1972
                    if conf_id != conf.config_id():
 
1973
                        conf = self._get_configs(directory, conf_id).next()
 
1974
                    # We use the first section in the first config where the
 
1975
                    # option is defined to remove it
 
1976
                    conf.remove_user_option(name, section_name)
 
1977
                    removed = True
 
1978
                    break
 
1979
            break
 
1980
        else:
 
1981
            raise errors.NoSuchConfig(scope)
 
1982
        if not removed:
 
1983
            raise errors.NoSuchConfigOption(name)