~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Vincent Ladeuil
  • Date: 2011-01-20 21:15:10 UTC
  • mfrom: (5050.62.4 2.2)
  • mto: (5609.2.4 2.3)
  • mto: This revision was merged to the branch mainline in revision 5628.
  • Revision ID: v.ladeuil+lp@free.fr-20110120211510-9dl4tbl77dad86pl
Merge 2.2 into 2.3 including bugfix for #701940

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,
80
85
    osutils,
81
86
    registry,
82
87
    symbol_versioning,
83
88
    trace,
 
89
    transport,
84
90
    ui,
85
91
    urlutils,
86
92
    win32utils,
149
155
    def __init__(self):
150
156
        super(Config, self).__init__()
151
157
 
 
158
    def config_id(self):
 
159
        """Returns a unique ID for the config."""
 
160
        raise NotImplementedError(self.config_id)
 
161
 
152
162
    def get_editor(self):
153
163
        """Get the users pop up editor."""
154
164
        raise NotImplementedError
257
267
 
258
268
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
259
269
 
260
 
        $BZR_EMAIL can be set to override this (as well as the
261
 
        deprecated $BZREMAIL), then
 
270
        $BZR_EMAIL can be set to override this, then
262
271
        the concrete policy type is checked, and finally
263
272
        $EMAIL is examined.
264
 
        If none is found, a reasonable default is (hopefully)
265
 
        created.
 
273
        If no username can be found, errors.NoWhoami exception is raised.
266
274
 
267
275
        TODO: Check it's reasonably well-formed.
268
276
        """
278
286
        if v:
279
287
            return v.decode(osutils.get_user_encoding())
280
288
 
281
 
        name, email = _auto_user_id()
282
 
        if name:
283
 
            return '%s <%s>' % (name, email)
284
 
        else:
285
 
            return email
 
289
        raise errors.NoWhoami()
 
290
 
 
291
    def ensure_username(self):
 
292
        """Raise errors.NoWhoami if username is not set.
 
293
 
 
294
        This method relies on the username() function raising the error.
 
295
        """
 
296
        self.username()
286
297
 
287
298
    def signature_checking(self):
288
299
        """What is the current policy for signature checking?."""
350
361
class IniBasedConfig(Config):
351
362
    """A configuration policy that draws from ini files."""
352
363
 
353
 
    def __init__(self, get_filename):
 
364
    def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
 
365
                 file_name=None):
 
366
        """Base class for configuration files using an ini-like syntax.
 
367
 
 
368
        :param file_name: The configuration file path.
 
369
        """
354
370
        super(IniBasedConfig, self).__init__()
355
 
        self._get_filename = get_filename
 
371
        self.file_name = file_name
 
372
        if symbol_versioning.deprecated_passed(get_filename):
 
373
            symbol_versioning.warn(
 
374
                'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
 
375
                ' Use file_name instead.',
 
376
                DeprecationWarning,
 
377
                stacklevel=2)
 
378
            if get_filename is not None:
 
379
                self.file_name = get_filename()
 
380
        else:
 
381
            self.file_name = file_name
 
382
        self._content = None
356
383
        self._parser = None
357
384
 
358
 
    def _get_parser(self, file=None):
 
385
    @classmethod
 
386
    def from_string(cls, str_or_unicode, file_name=None, save=False):
 
387
        """Create a config object from a string.
 
388
 
 
389
        :param str_or_unicode: A string representing the file content. This will
 
390
            be utf-8 encoded.
 
391
 
 
392
        :param file_name: The configuration file path.
 
393
 
 
394
        :param _save: Whether the file should be saved upon creation.
 
395
        """
 
396
        conf = cls(file_name=file_name)
 
397
        conf._create_from_string(str_or_unicode, save)
 
398
        return conf
 
399
 
 
400
    def _create_from_string(self, str_or_unicode, save):
 
401
        self._content = StringIO(str_or_unicode.encode('utf-8'))
 
402
        # Some tests use in-memory configs, some other always need the config
 
403
        # file to exist on disk.
 
404
        if save:
 
405
            self._write_config_file()
 
406
 
 
407
    def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
359
408
        if self._parser is not None:
360
409
            return self._parser
361
 
        if file is None:
362
 
            input = self._get_filename()
 
410
        if symbol_versioning.deprecated_passed(file):
 
411
            symbol_versioning.warn(
 
412
                'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
 
413
                ' Use IniBasedConfig(_content=xxx) instead.',
 
414
                DeprecationWarning,
 
415
                stacklevel=2)
 
416
        if self._content is not None:
 
417
            co_input = self._content
 
418
        elif self.file_name is None:
 
419
            raise AssertionError('We have no content to create the config')
363
420
        else:
364
 
            input = file
 
421
            co_input = self.file_name
365
422
        try:
366
 
            self._parser = ConfigObj(input, encoding='utf-8')
 
423
            self._parser = ConfigObj(co_input, encoding='utf-8')
367
424
        except configobj.ConfigObjError, e:
368
425
            raise errors.ParseConfigError(e.errors, e.config.filename)
 
426
        # Make sure self.reload() will use the right file name
 
427
        self._parser.filename = self.file_name
369
428
        return self._parser
370
429
 
 
430
    def reload(self):
 
431
        """Reload the config file from disk."""
 
432
        if self.file_name is None:
 
433
            raise AssertionError('We need a file name to reload the config')
 
434
        if self._parser is not None:
 
435
            self._parser.reload()
 
436
 
371
437
    def _get_matching_sections(self):
372
438
        """Return an ordered list of (section_name, extra_path) pairs.
373
439
 
384
450
        """Override this to define the section used by the config."""
385
451
        return "DEFAULT"
386
452
 
 
453
    def _get_sections(self, name=None):
 
454
        """Returns an iterator of the sections specified by ``name``.
 
455
 
 
456
        :param name: The section name. If None is supplied, the default
 
457
            configurations are yielded.
 
458
 
 
459
        :return: A tuple (name, section, config_id) for all sections that will
 
460
            be walked by user_get_option() in the 'right' order. The first one
 
461
            is where set_user_option() will update the value.
 
462
        """
 
463
        parser = self._get_parser()
 
464
        if name is not None:
 
465
            yield (name, parser[name], self.config_id())
 
466
        else:
 
467
            # No section name has been given so we fallback to the configobj
 
468
            # itself which holds the variables defined outside of any section.
 
469
            yield (None, parser, self.config_id())
 
470
 
 
471
    def _get_options(self, sections=None):
 
472
        """Return an ordered list of (name, value, section, config_id) tuples.
 
473
 
 
474
        All options are returned with their associated value and the section
 
475
        they appeared in. ``config_id`` is a unique identifier for the
 
476
        configuration file the option is defined in.
 
477
 
 
478
        :param sections: Default to ``_get_matching_sections`` if not
 
479
            specified. This gives a better control to daughter classes about
 
480
            which sections should be searched. This is a list of (name,
 
481
            configobj) tuples.
 
482
        """
 
483
        opts = []
 
484
        if sections is None:
 
485
            parser = self._get_parser()
 
486
            sections = []
 
487
            for (section_name, _) in self._get_matching_sections():
 
488
                try:
 
489
                    section = parser[section_name]
 
490
                except KeyError:
 
491
                    # This could happen for an empty file for which we define a
 
492
                    # DEFAULT section. FIXME: Force callers to provide sections
 
493
                    # instead ? -- vila 20100930
 
494
                    continue
 
495
                sections.append((section_name, section))
 
496
        config_id = self.config_id()
 
497
        for (section_name, section) in sections:
 
498
            for (name, value) in section.iteritems():
 
499
                yield (name, parser._quote(value), section_name,
 
500
                       config_id, parser)
 
501
 
387
502
    def _get_option_policy(self, section, option_name):
388
503
        """Return the policy for the given (section, option_name) pair."""
389
504
        return POLICY_NONE
476
591
    def _get_nickname(self):
477
592
        return self.get_user_option('nickname')
478
593
 
479
 
 
480
 
class GlobalConfig(IniBasedConfig):
 
594
    def remove_user_option(self, option_name, section_name=None):
 
595
        """Remove a user option and save the configuration file.
 
596
 
 
597
        :param option_name: The option to be removed.
 
598
 
 
599
        :param section_name: The section the option is defined in, default to
 
600
            the default section.
 
601
        """
 
602
        self.reload()
 
603
        parser = self._get_parser()
 
604
        if section_name is None:
 
605
            section = parser
 
606
        else:
 
607
            section = parser[section_name]
 
608
        try:
 
609
            del section[option_name]
 
610
        except KeyError:
 
611
            raise errors.NoSuchConfigOption(option_name)
 
612
        self._write_config_file()
 
613
 
 
614
    def _write_config_file(self):
 
615
        if self.file_name is None:
 
616
            raise AssertionError('We cannot save, self.file_name is None')
 
617
        conf_dir = os.path.dirname(self.file_name)
 
618
        ensure_config_dir_exists(conf_dir)
 
619
        atomic_file = atomicfile.AtomicFile(self.file_name)
 
620
        self._get_parser().write(atomic_file)
 
621
        atomic_file.commit()
 
622
        atomic_file.close()
 
623
        osutils.copy_ownership_from_path(self.file_name)
 
624
 
 
625
 
 
626
class LockableConfig(IniBasedConfig):
 
627
    """A configuration needing explicit locking for access.
 
628
 
 
629
    If several processes try to write the config file, the accesses need to be
 
630
    serialized.
 
631
 
 
632
    Daughter classes should decorate all methods that update a config with the
 
633
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
 
634
    ``_write_config_file()`` method. These methods (typically ``set_option()``
 
635
    and variants must reload the config file from disk before calling
 
636
    ``_write_config_file()``), this can be achieved by calling the
 
637
    ``self.reload()`` method. Note that the lock scope should cover both the
 
638
    reading and the writing of the config file which is why the decorator can't
 
639
    be applied to ``_write_config_file()`` only.
 
640
 
 
641
    This should be enough to implement the following logic:
 
642
    - lock for exclusive write access,
 
643
    - reload the config file from disk,
 
644
    - set the new value
 
645
    - unlock
 
646
 
 
647
    This logic guarantees that a writer can update a value without erasing an
 
648
    update made by another writer.
 
649
    """
 
650
 
 
651
    lock_name = 'lock'
 
652
 
 
653
    def __init__(self, file_name):
 
654
        super(LockableConfig, self).__init__(file_name=file_name)
 
655
        self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
 
656
        self.transport = transport.get_transport(self.dir)
 
657
        self._lock = lockdir.LockDir(self.transport, 'lock')
 
658
 
 
659
    def _create_from_string(self, unicode_bytes, save):
 
660
        super(LockableConfig, self)._create_from_string(unicode_bytes, False)
 
661
        if save:
 
662
            # We need to handle the saving here (as opposed to IniBasedConfig)
 
663
            # to be able to lock
 
664
            self.lock_write()
 
665
            self._write_config_file()
 
666
            self.unlock()
 
667
 
 
668
    def lock_write(self, token=None):
 
669
        """Takes a write lock in the directory containing the config file.
 
670
 
 
671
        If the directory doesn't exist it is created.
 
672
        """
 
673
        ensure_config_dir_exists(self.dir)
 
674
        return self._lock.lock_write(token)
 
675
 
 
676
    def unlock(self):
 
677
        self._lock.unlock()
 
678
 
 
679
    def break_lock(self):
 
680
        self._lock.break_lock()
 
681
 
 
682
    @needs_write_lock
 
683
    def remove_user_option(self, option_name, section_name=None):
 
684
        super(LockableConfig, self).remove_user_option(option_name,
 
685
                                                       section_name)
 
686
 
 
687
    def _write_config_file(self):
 
688
        if self._lock is None or not self._lock.is_held:
 
689
            # NB: if the following exception is raised it probably means a
 
690
            # missing @needs_write_lock decorator on one of the callers.
 
691
            raise errors.ObjectNotLocked(self)
 
692
        super(LockableConfig, self)._write_config_file()
 
693
 
 
694
 
 
695
class GlobalConfig(LockableConfig):
481
696
    """The configuration that should be used for a specific location."""
482
697
 
 
698
    def __init__(self):
 
699
        super(GlobalConfig, self).__init__(file_name=config_filename())
 
700
 
 
701
    def config_id(self):
 
702
        return 'bazaar'
 
703
 
 
704
    @classmethod
 
705
    def from_string(cls, str_or_unicode, save=False):
 
706
        """Create a config object from a string.
 
707
 
 
708
        :param str_or_unicode: A string representing the file content. This
 
709
            will be utf-8 encoded.
 
710
 
 
711
        :param save: Whether the file should be saved upon creation.
 
712
        """
 
713
        conf = cls()
 
714
        conf._create_from_string(str_or_unicode, save)
 
715
        return conf
 
716
 
483
717
    def get_editor(self):
484
718
        return self._get_user_option('editor')
485
719
 
486
 
    def __init__(self):
487
 
        super(GlobalConfig, self).__init__(config_filename)
488
 
 
 
720
    @needs_write_lock
489
721
    def set_user_option(self, option, value):
490
722
        """Save option and its value in the configuration."""
491
723
        self._set_option(option, value, 'DEFAULT')
497
729
        else:
498
730
            return {}
499
731
 
 
732
    @needs_write_lock
500
733
    def set_alias(self, alias_name, alias_command):
501
734
        """Save the alias in the configuration."""
502
735
        self._set_option(alias_name, alias_command, 'ALIASES')
503
736
 
 
737
    @needs_write_lock
504
738
    def unset_alias(self, alias_name):
505
739
        """Unset an existing alias."""
 
740
        self.reload()
506
741
        aliases = self._get_parser().get('ALIASES')
507
742
        if not aliases or alias_name not in aliases:
508
743
            raise errors.NoSuchAlias(alias_name)
510
745
        self._write_config_file()
511
746
 
512
747
    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)
 
748
        self.reload()
517
749
        self._get_parser().setdefault(section, {})[option] = value
518
750
        self._write_config_file()
519
751
 
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):
 
752
 
 
753
    def _get_sections(self, name=None):
 
754
        """See IniBasedConfig._get_sections()."""
 
755
        parser = self._get_parser()
 
756
        # We don't give access to options defined outside of any section, we
 
757
        # used the DEFAULT section by... default.
 
758
        if name in (None, 'DEFAULT'):
 
759
            # This could happen for an empty file where the DEFAULT section
 
760
            # doesn't exist yet. So we force DEFAULT when yielding
 
761
            name = 'DEFAULT'
 
762
            if 'DEFAULT' not in parser:
 
763
               parser['DEFAULT']= {}
 
764
        yield (name, parser[name], self.config_id())
 
765
 
 
766
    @needs_write_lock
 
767
    def remove_user_option(self, option_name, section_name=None):
 
768
        if section_name is None:
 
769
            # We need to force the default section.
 
770
            section_name = 'DEFAULT'
 
771
        # We need to avoid the LockableConfig implementation or we'll lock
 
772
        # twice
 
773
        super(LockableConfig, self).remove_user_option(option_name,
 
774
                                                       section_name)
 
775
 
 
776
 
 
777
class LocationConfig(LockableConfig):
529
778
    """A configuration object that gives the policy for a location."""
530
779
 
531
780
    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)
 
781
        super(LocationConfig, self).__init__(
 
782
            file_name=locations_config_filename())
544
783
        # local file locations are looked up by local path, rather than
545
784
        # by file url. This is because the config file is a user
546
785
        # file, and we would rather not expose the user to file urls.
548
787
            location = urlutils.local_path_from_url(location)
549
788
        self.location = location
550
789
 
 
790
    def config_id(self):
 
791
        return 'locations'
 
792
 
 
793
    @classmethod
 
794
    def from_string(cls, str_or_unicode, location, save=False):
 
795
        """Create a config object from a string.
 
796
 
 
797
        :param str_or_unicode: A string representing the file content. This will
 
798
            be utf-8 encoded.
 
799
 
 
800
        :param location: The location url to filter the configuration.
 
801
 
 
802
        :param save: Whether the file should be saved upon creation.
 
803
        """
 
804
        conf = cls(location)
 
805
        conf._create_from_string(str_or_unicode, save)
 
806
        return conf
 
807
 
551
808
    def _get_matching_sections(self):
552
809
        """Return an ordered list of section names matching this location."""
553
810
        sections = self._get_parser()
570
827
            names = zip(location_names, section_names)
571
828
            matched = True
572
829
            for name in names:
573
 
                if not fnmatch(name[0], name[1]):
 
830
                if not fnmatch.fnmatch(name[0], name[1]):
574
831
                    matched = False
575
832
                    break
576
833
            if not matched:
581
838
                continue
582
839
            matches.append((len(section_names), section,
583
840
                            '/'.join(location_names[len(section_names):])))
 
841
        # put the longest (aka more specific) locations first
584
842
        matches.sort(reverse=True)
585
843
        sections = []
586
844
        for (length, section, extra_path) in matches:
593
851
                pass
594
852
        return sections
595
853
 
 
854
    def _get_sections(self, name=None):
 
855
        """See IniBasedConfig._get_sections()."""
 
856
        # We ignore the name here as the only sections handled are named with
 
857
        # the location path and we don't expose embedded sections either.
 
858
        parser = self._get_parser()
 
859
        for name, extra_path in self._get_matching_sections():
 
860
            yield (name, parser[name], self.config_id())
 
861
 
596
862
    def _get_option_policy(self, section, option_name):
597
863
        """Return the policy for the given (section, option_name) pair."""
598
864
        # check for the old 'recurse=False' flag
641
907
            if policy_key in self._get_parser()[section]:
642
908
                del self._get_parser()[section][policy_key]
643
909
 
 
910
    @needs_write_lock
644
911
    def set_user_option(self, option, value, store=STORE_LOCATION):
645
912
        """Save option and its value in the configuration."""
646
913
        if store not in [STORE_LOCATION,
648
915
                         STORE_LOCATION_APPENDPATH]:
649
916
            raise ValueError('bad storage policy %r for %r' %
650
917
                (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)
 
918
        self.reload()
655
919
        location = self.location
656
920
        if location.endswith('/'):
657
921
            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():
 
922
        parser = self._get_parser()
 
923
        if not location in parser and not location + '/' in parser:
 
924
            parser[location] = {}
 
925
        elif location + '/' in parser:
662
926
            location = location + '/'
663
 
        self._get_parser()[location][option]=value
 
927
        parser[location][option]=value
664
928
        # the allowed values of store match the config policies
665
929
        self._set_option_policy(location, option, store)
666
 
        self._get_parser().write(file(self._get_filename(), 'wb'))
 
930
        self._write_config_file()
667
931
 
668
932
 
669
933
class BranchConfig(Config):
670
934
    """A configuration object giving the policy for a branch."""
671
935
 
 
936
    def __init__(self, branch):
 
937
        super(BranchConfig, self).__init__()
 
938
        self._location_config = None
 
939
        self._branch_data_config = None
 
940
        self._global_config = None
 
941
        self.branch = branch
 
942
        self.option_sources = (self._get_location_config,
 
943
                               self._get_branch_data_config,
 
944
                               self._get_global_config)
 
945
 
 
946
    def config_id(self):
 
947
        return 'branch'
 
948
 
672
949
    def _get_branch_data_config(self):
673
950
        if self._branch_data_config is None:
674
951
            self._branch_data_config = TreeConfig(self.branch)
 
952
            self._branch_data_config.config_id = self.config_id
675
953
        return self._branch_data_config
676
954
 
677
955
    def _get_location_config(self):
745
1023
                return value
746
1024
        return None
747
1025
 
 
1026
    def _get_sections(self, name=None):
 
1027
        """See IniBasedConfig.get_sections()."""
 
1028
        for source in self.option_sources:
 
1029
            for section in source()._get_sections(name):
 
1030
                yield section
 
1031
 
 
1032
    def _get_options(self, sections=None):
 
1033
        opts = []
 
1034
        # First the locations options
 
1035
        for option in self._get_location_config()._get_options():
 
1036
            yield option
 
1037
        # Then the branch options
 
1038
        branch_config = self._get_branch_data_config()
 
1039
        if sections is None:
 
1040
            sections = [('DEFAULT', branch_config._get_parser())]
 
1041
        # FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
 
1042
        # Config itself has no notion of sections :( -- vila 20101001
 
1043
        config_id = self.config_id()
 
1044
        for (section_name, section) in sections:
 
1045
            for (name, value) in section.iteritems():
 
1046
                yield (name, value, section_name,
 
1047
                       config_id, branch_config._get_parser())
 
1048
        # Then the global options
 
1049
        for option in self._get_global_config()._get_options():
 
1050
            yield option
 
1051
 
748
1052
    def set_user_option(self, name, value, store=STORE_BRANCH,
749
1053
        warn_masked=False):
750
1054
        if store == STORE_BRANCH:
768
1072
                        trace.warning('Value "%s" is masked by "%s" from'
769
1073
                                      ' branch.conf', value, mask_value)
770
1074
 
 
1075
    def remove_user_option(self, option_name, section_name=None):
 
1076
        self._get_branch_data_config().remove_option(option_name, section_name)
 
1077
 
771
1078
    def _gpg_signing_command(self):
772
1079
        """See Config.gpg_signing_command."""
773
1080
        return self._get_safe_value('_gpg_signing_command')
774
1081
 
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
1082
    def _post_commit(self):
786
1083
        """See Config.post_commit."""
787
1084
        return self._get_safe_value('_post_commit')
817
1114
            parent_dir = os.path.dirname(path)
818
1115
            if not os.path.isdir(parent_dir):
819
1116
                trace.mutter('creating config parent directory: %r', parent_dir)
820
 
            os.mkdir(parent_dir)
 
1117
                os.mkdir(parent_dir)
821
1118
        trace.mutter('creating config directory: %r', path)
822
1119
        os.mkdir(path)
823
1120
        osutils.copy_ownership_from_path(path)
826
1123
def config_dir():
827
1124
    """Return per-user configuration directory.
828
1125
 
829
 
    By default this is ~/.bazaar/
 
1126
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
 
1127
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
 
1128
    that will be used instead.
830
1129
 
831
1130
    TODO: Global option --config-dir to override this.
832
1131
    """
833
1132
    base = os.environ.get('BZR_HOME', None)
834
1133
    if sys.platform == 'win32':
 
1134
        # environ variables on Windows are in user encoding/mbcs. So decode
 
1135
        # before using one
 
1136
        if base is not None:
 
1137
            base = base.decode('mbcs')
835
1138
        if base is None:
836
1139
            base = win32utils.get_appdata_location_unicode()
837
1140
        if base is None:
838
1141
            base = os.environ.get('HOME', None)
 
1142
            if base is not None:
 
1143
                base = base.decode('mbcs')
839
1144
        if base is None:
840
1145
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
841
1146
                                  ' or HOME set')
842
1147
        return osutils.pathjoin(base, 'bazaar', '2.0')
 
1148
    elif sys.platform == 'darwin':
 
1149
        if base is None:
 
1150
            # this takes into account $HOME
 
1151
            base = os.path.expanduser("~")
 
1152
        return osutils.pathjoin(base, '.bazaar')
843
1153
    else:
844
 
        # cygwin, linux, and darwin all have a $HOME directory
845
1154
        if base is None:
 
1155
 
 
1156
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
 
1157
            if xdg_dir is None:
 
1158
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
 
1159
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
 
1160
            if osutils.isdir(xdg_dir):
 
1161
                trace.mutter(
 
1162
                    "Using configuration in XDG directory %s." % xdg_dir)
 
1163
                return xdg_dir
 
1164
 
846
1165
            base = os.path.expanduser("~")
847
1166
        return osutils.pathjoin(base, ".bazaar")
848
1167
 
852
1171
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
853
1172
 
854
1173
 
855
 
def branches_config_filename():
856
 
    """Return per-user configuration ini file filename."""
857
 
    return osutils.pathjoin(config_dir(), 'branches.conf')
858
 
 
859
 
 
860
1174
def locations_config_filename():
861
1175
    """Return per-user configuration ini file filename."""
862
1176
    return osutils.pathjoin(config_dir(), 'locations.conf')
899
1213
        return os.path.expanduser('~/.cache')
900
1214
 
901
1215
 
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
1216
def parse_username(username):
976
1217
    """Parse e-mail username and return a (name, address) tuple."""
977
1218
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1020
1261
 
1021
1262
    def set_option(self, value, name, section=None):
1022
1263
        """Set a per-branch configuration option"""
 
1264
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1265
        # higher levels providing the right lock -- vila 20101004
1023
1266
        self.branch.lock_write()
1024
1267
        try:
1025
1268
            self._config.set_option(value, name, section)
1026
1269
        finally:
1027
1270
            self.branch.unlock()
1028
1271
 
 
1272
    def remove_option(self, option_name, section_name=None):
 
1273
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1274
        # higher levels providing the right lock -- vila 20101004
 
1275
        self.branch.lock_write()
 
1276
        try:
 
1277
            self._config.remove_option(option_name, section_name)
 
1278
        finally:
 
1279
            self.branch.unlock()
 
1280
 
1029
1281
 
1030
1282
class AuthenticationConfig(object):
1031
1283
    """The authentication configuration file based on a ini file.
1063
1315
        """Save the config file, only tests should use it for now."""
1064
1316
        conf_dir = os.path.dirname(self._filename)
1065
1317
        ensure_config_dir_exists(conf_dir)
1066
 
        self._get_config().write(file(self._filename, 'wb'))
 
1318
        f = file(self._filename, 'wb')
 
1319
        try:
 
1320
            self._get_config().write(f)
 
1321
        finally:
 
1322
            f.close()
1067
1323
 
1068
1324
    def _set_option(self, section_name, option_name, value):
1069
1325
        """Set an authentication configuration option"""
1470
1726
    """A Config that reads/writes a config file on a Transport.
1471
1727
 
1472
1728
    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.
 
1729
    that may be associated with a section.  Assigning meaning to these values
 
1730
    is done at higher levels like TreeConfig.
1475
1731
    """
1476
1732
 
1477
1733
    def __init__(self, transport, filename):
1510
1766
            configobj.setdefault(section, {})[name] = value
1511
1767
        self._set_configobj(configobj)
1512
1768
 
 
1769
    def remove_option(self, option_name, section_name=None):
 
1770
        configobj = self._get_configobj()
 
1771
        if section_name is None:
 
1772
            del configobj[option_name]
 
1773
        else:
 
1774
            del configobj[section_name][option_name]
 
1775
        self._set_configobj(configobj)
 
1776
 
1513
1777
    def _get_config_file(self):
1514
1778
        try:
1515
1779
            return StringIO(self._transport.get_bytes(self._filename))
1517
1781
            return StringIO()
1518
1782
 
1519
1783
    def _get_configobj(self):
1520
 
        return ConfigObj(self._get_config_file(), encoding='utf-8')
 
1784
        f = self._get_config_file()
 
1785
        try:
 
1786
            return ConfigObj(f, encoding='utf-8')
 
1787
        finally:
 
1788
            f.close()
1521
1789
 
1522
1790
    def _set_configobj(self, configobj):
1523
1791
        out_file = StringIO()
1524
1792
        configobj.write(out_file)
1525
1793
        out_file.seek(0)
1526
1794
        self._transport.put_file(self._filename, out_file)
 
1795
 
 
1796
 
 
1797
class cmd_config(commands.Command):
 
1798
    __doc__ = """Display, set or remove a configuration option.
 
1799
 
 
1800
    Display the active value for a given option.
 
1801
 
 
1802
    If --all is specified, NAME is interpreted as a regular expression and all
 
1803
    matching options are displayed mentioning their scope. The active value
 
1804
    that bzr will take into account is the first one displayed for each option.
 
1805
 
 
1806
    If no NAME is given, --all .* is implied.
 
1807
 
 
1808
    Setting a value is achieved by using name=value without spaces. The value
 
1809
    is set in the most relevant scope and can be checked by displaying the
 
1810
    option again.
 
1811
    """
 
1812
 
 
1813
    takes_args = ['name?']
 
1814
 
 
1815
    takes_options = [
 
1816
        'directory',
 
1817
        # FIXME: This should be a registry option so that plugins can register
 
1818
        # their own config files (or not) -- vila 20101002
 
1819
        commands.Option('scope', help='Reduce the scope to the specified'
 
1820
                        ' configuration file',
 
1821
                        type=unicode),
 
1822
        commands.Option('all',
 
1823
            help='Display all the defined values for the matching options.',
 
1824
            ),
 
1825
        commands.Option('remove', help='Remove the option from'
 
1826
                        ' the configuration file'),
 
1827
        ]
 
1828
 
 
1829
    @commands.display_command
 
1830
    def run(self, name=None, all=False, directory=None, scope=None,
 
1831
            remove=False):
 
1832
        if directory is None:
 
1833
            directory = '.'
 
1834
        directory = urlutils.normalize_url(directory)
 
1835
        if remove and all:
 
1836
            raise errors.BzrError(
 
1837
                '--all and --remove are mutually exclusive.')
 
1838
        elif remove:
 
1839
            # Delete the option in the given scope
 
1840
            self._remove_config_option(name, directory, scope)
 
1841
        elif name is None:
 
1842
            # Defaults to all options
 
1843
            self._show_matching_options('.*', directory, scope)
 
1844
        else:
 
1845
            try:
 
1846
                name, value = name.split('=', 1)
 
1847
            except ValueError:
 
1848
                # Display the option(s) value(s)
 
1849
                if all:
 
1850
                    self._show_matching_options(name, directory, scope)
 
1851
                else:
 
1852
                    self._show_value(name, directory, scope)
 
1853
            else:
 
1854
                if all:
 
1855
                    raise errors.BzrError(
 
1856
                        'Only one option can be set.')
 
1857
                # Set the option value
 
1858
                self._set_config_option(name, value, directory, scope)
 
1859
 
 
1860
    def _get_configs(self, directory, scope=None):
 
1861
        """Iterate the configurations specified by ``directory`` and ``scope``.
 
1862
 
 
1863
        :param directory: Where the configurations are derived from.
 
1864
 
 
1865
        :param scope: A specific config to start from.
 
1866
        """
 
1867
        if scope is not None:
 
1868
            if scope == 'bazaar':
 
1869
                yield GlobalConfig()
 
1870
            elif scope == 'locations':
 
1871
                yield LocationConfig(directory)
 
1872
            elif scope == 'branch':
 
1873
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1874
                    directory)
 
1875
                yield br.get_config()
 
1876
        else:
 
1877
            try:
 
1878
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1879
                    directory)
 
1880
                yield br.get_config()
 
1881
            except errors.NotBranchError:
 
1882
                yield LocationConfig(directory)
 
1883
                yield GlobalConfig()
 
1884
 
 
1885
    def _show_value(self, name, directory, scope):
 
1886
        displayed = False
 
1887
        for c in self._get_configs(directory, scope):
 
1888
            if displayed:
 
1889
                break
 
1890
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1891
                if name == oname:
 
1892
                    # Display only the first value and exit
 
1893
 
 
1894
                    # FIXME: We need to use get_user_option to take policies
 
1895
                    # into account and we need to make sure the option exists
 
1896
                    # too (hence the two for loops), this needs a better API
 
1897
                    # -- vila 20101117
 
1898
                    value = c.get_user_option(name)
 
1899
                    # Quote the value appropriately
 
1900
                    value = parser._quote(value)
 
1901
                    self.outf.write('%s\n' % (value,))
 
1902
                    displayed = True
 
1903
                    break
 
1904
        if not displayed:
 
1905
            raise errors.NoSuchConfigOption(name)
 
1906
 
 
1907
    def _show_matching_options(self, name, directory, scope):
 
1908
        name = re.compile(name)
 
1909
        # We want any error in the regexp to be raised *now* so we need to
 
1910
        # avoid the delay introduced by the lazy regexp.
 
1911
        name._compile_and_collapse()
 
1912
        cur_conf_id = None
 
1913
        cur_section = None
 
1914
        for c in self._get_configs(directory, scope):
 
1915
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1916
                if name.search(oname):
 
1917
                    if cur_conf_id != conf_id:
 
1918
                        # Explain where the options are defined
 
1919
                        self.outf.write('%s:\n' % (conf_id,))
 
1920
                        cur_conf_id = conf_id
 
1921
                        cur_section = None
 
1922
                    if (section not in (None, 'DEFAULT')
 
1923
                        and cur_section != section):
 
1924
                        # Display the section if it's not the default (or only)
 
1925
                        # one.
 
1926
                        self.outf.write('  [%s]\n' % (section,))
 
1927
                        cur_section = section
 
1928
                    self.outf.write('  %s = %s\n' % (oname, value))
 
1929
 
 
1930
    def _set_config_option(self, name, value, directory, scope):
 
1931
        for conf in self._get_configs(directory, scope):
 
1932
            conf.set_user_option(name, value)
 
1933
            break
 
1934
        else:
 
1935
            raise errors.NoSuchConfig(scope)
 
1936
 
 
1937
    def _remove_config_option(self, name, directory, scope):
 
1938
        if name is None:
 
1939
            raise errors.BzrCommandError(
 
1940
                '--remove expects an option to remove.')
 
1941
        removed = False
 
1942
        for conf in self._get_configs(directory, scope):
 
1943
            for (section_name, section, conf_id) in conf._get_sections():
 
1944
                if scope is not None and conf_id != scope:
 
1945
                    # Not the right configuration file
 
1946
                    continue
 
1947
                if name in section:
 
1948
                    if conf_id != conf.config_id():
 
1949
                        conf = self._get_configs(directory, conf_id).next()
 
1950
                    # We use the first section in the first config where the
 
1951
                    # option is defined to remove it
 
1952
                    conf.remove_user_option(name, section_name)
 
1953
                    removed = True
 
1954
                    break
 
1955
            break
 
1956
        else:
 
1957
            raise errors.NoSuchConfig(scope)
 
1958
        if not removed:
 
1959
            raise errors.NoSuchConfigOption(name)