/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: Vincent Ladeuil
  • Date: 2011-05-17 15:14:38 UTC
  • mfrom: (5050.73.3 2.2)
  • mto: (5609.39.5 2.3)
  • mto: This revision was merged to the branch mainline in revision 5885.
  • Revision ID: v.ladeuil+lp@free.fr-20110517151438-j75xuw2zm9alk9a5
Merge 2.2 into 2.3 resolving conflicts

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
#
63
63
"""
64
64
 
65
65
import os
 
66
import string
66
67
import sys
67
68
 
 
69
from bzrlib import commands
 
70
from bzrlib.decorators import needs_write_lock
68
71
from bzrlib.lazy_import import lazy_import
69
72
lazy_import(globals(), """
70
73
import errno
71
 
from fnmatch import fnmatch
 
74
import fnmatch
72
75
import re
73
76
from cStringIO import StringIO
74
77
 
75
78
import bzrlib
76
79
from bzrlib import (
 
80
    atomicfile,
 
81
    bzrdir,
77
82
    debug,
78
83
    errors,
 
84
    lockdir,
79
85
    mail_client,
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.
266
 
 
267
 
        TODO: Check it's reasonably well-formed.
 
274
        If no username can be found, errors.NoWhoami exception is raised.
268
275
        """
269
276
        v = os.environ.get('BZR_EMAIL')
270
277
        if v:
271
278
            return v.decode(osutils.get_user_encoding())
272
 
 
273
279
        v = self._get_user_id()
274
280
        if v:
275
281
            return v
276
 
 
277
282
        v = os.environ.get('EMAIL')
278
283
        if v:
279
284
            return v.decode(osutils.get_user_encoding())
280
 
 
281
285
        name, email = _auto_user_id()
282
 
        if name:
 
286
        if name and email:
283
287
            return '%s <%s>' % (name, email)
284
 
        else:
 
288
        elif email:
285
289
            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?."""
350
362
class IniBasedConfig(Config):
351
363
    """A configuration policy that draws from ini files."""
352
364
 
353
 
    def __init__(self, get_filename):
 
365
    def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
 
366
                 file_name=None):
 
367
        """Base class for configuration files using an ini-like syntax.
 
368
 
 
369
        :param file_name: The configuration file path.
 
370
        """
354
371
        super(IniBasedConfig, self).__init__()
355
 
        self._get_filename = get_filename
 
372
        self.file_name = file_name
 
373
        if symbol_versioning.deprecated_passed(get_filename):
 
374
            symbol_versioning.warn(
 
375
                'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
 
376
                ' Use file_name instead.',
 
377
                DeprecationWarning,
 
378
                stacklevel=2)
 
379
            if get_filename is not None:
 
380
                self.file_name = get_filename()
 
381
        else:
 
382
            self.file_name = file_name
 
383
        self._content = None
356
384
        self._parser = None
357
385
 
358
 
    def _get_parser(self, file=None):
 
386
    @classmethod
 
387
    def from_string(cls, str_or_unicode, file_name=None, save=False):
 
388
        """Create a config object from a string.
 
389
 
 
390
        :param str_or_unicode: A string representing the file content. This will
 
391
            be utf-8 encoded.
 
392
 
 
393
        :param file_name: The configuration file path.
 
394
 
 
395
        :param _save: Whether the file should be saved upon creation.
 
396
        """
 
397
        conf = cls(file_name=file_name)
 
398
        conf._create_from_string(str_or_unicode, save)
 
399
        return conf
 
400
 
 
401
    def _create_from_string(self, str_or_unicode, save):
 
402
        self._content = StringIO(str_or_unicode.encode('utf-8'))
 
403
        # Some tests use in-memory configs, some other always need the config
 
404
        # file to exist on disk.
 
405
        if save:
 
406
            self._write_config_file()
 
407
 
 
408
    def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
359
409
        if self._parser is not None:
360
410
            return self._parser
361
 
        if file is None:
362
 
            input = self._get_filename()
 
411
        if symbol_versioning.deprecated_passed(file):
 
412
            symbol_versioning.warn(
 
413
                'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
 
414
                ' Use IniBasedConfig(_content=xxx) instead.',
 
415
                DeprecationWarning,
 
416
                stacklevel=2)
 
417
        if self._content is not None:
 
418
            co_input = self._content
 
419
        elif self.file_name is None:
 
420
            raise AssertionError('We have no content to create the config')
363
421
        else:
364
 
            input = file
 
422
            co_input = self.file_name
365
423
        try:
366
 
            self._parser = ConfigObj(input, encoding='utf-8')
 
424
            self._parser = ConfigObj(co_input, encoding='utf-8')
367
425
        except configobj.ConfigObjError, e:
368
426
            raise errors.ParseConfigError(e.errors, e.config.filename)
 
427
        # Make sure self.reload() will use the right file name
 
428
        self._parser.filename = self.file_name
369
429
        return self._parser
370
430
 
 
431
    def reload(self):
 
432
        """Reload the config file from disk."""
 
433
        if self.file_name is None:
 
434
            raise AssertionError('We need a file name to reload the config')
 
435
        if self._parser is not None:
 
436
            self._parser.reload()
 
437
 
371
438
    def _get_matching_sections(self):
372
439
        """Return an ordered list of (section_name, extra_path) pairs.
373
440
 
384
451
        """Override this to define the section used by the config."""
385
452
        return "DEFAULT"
386
453
 
 
454
    def _get_sections(self, name=None):
 
455
        """Returns an iterator of the sections specified by ``name``.
 
456
 
 
457
        :param name: The section name. If None is supplied, the default
 
458
            configurations are yielded.
 
459
 
 
460
        :return: A tuple (name, section, config_id) for all sections that will
 
461
            be walked by user_get_option() in the 'right' order. The first one
 
462
            is where set_user_option() will update the value.
 
463
        """
 
464
        parser = self._get_parser()
 
465
        if name is not None:
 
466
            yield (name, parser[name], self.config_id())
 
467
        else:
 
468
            # No section name has been given so we fallback to the configobj
 
469
            # itself which holds the variables defined outside of any section.
 
470
            yield (None, parser, self.config_id())
 
471
 
 
472
    def _get_options(self, sections=None):
 
473
        """Return an ordered list of (name, value, section, config_id) tuples.
 
474
 
 
475
        All options are returned with their associated value and the section
 
476
        they appeared in. ``config_id`` is a unique identifier for the
 
477
        configuration file the option is defined in.
 
478
 
 
479
        :param sections: Default to ``_get_matching_sections`` if not
 
480
            specified. This gives a better control to daughter classes about
 
481
            which sections should be searched. This is a list of (name,
 
482
            configobj) tuples.
 
483
        """
 
484
        opts = []
 
485
        if sections is None:
 
486
            parser = self._get_parser()
 
487
            sections = []
 
488
            for (section_name, _) in self._get_matching_sections():
 
489
                try:
 
490
                    section = parser[section_name]
 
491
                except KeyError:
 
492
                    # This could happen for an empty file for which we define a
 
493
                    # DEFAULT section. FIXME: Force callers to provide sections
 
494
                    # instead ? -- vila 20100930
 
495
                    continue
 
496
                sections.append((section_name, section))
 
497
        config_id = self.config_id()
 
498
        for (section_name, section) in sections:
 
499
            for (name, value) in section.iteritems():
 
500
                yield (name, parser._quote(value), section_name,
 
501
                       config_id, parser)
 
502
 
387
503
    def _get_option_policy(self, section, option_name):
388
504
        """Return the policy for the given (section, option_name) pair."""
389
505
        return POLICY_NONE
476
592
    def _get_nickname(self):
477
593
        return self.get_user_option('nickname')
478
594
 
479
 
 
480
 
class GlobalConfig(IniBasedConfig):
 
595
    def remove_user_option(self, option_name, section_name=None):
 
596
        """Remove a user option and save the configuration file.
 
597
 
 
598
        :param option_name: The option to be removed.
 
599
 
 
600
        :param section_name: The section the option is defined in, default to
 
601
            the default section.
 
602
        """
 
603
        self.reload()
 
604
        parser = self._get_parser()
 
605
        if section_name is None:
 
606
            section = parser
 
607
        else:
 
608
            section = parser[section_name]
 
609
        try:
 
610
            del section[option_name]
 
611
        except KeyError:
 
612
            raise errors.NoSuchConfigOption(option_name)
 
613
        self._write_config_file()
 
614
 
 
615
    def _write_config_file(self):
 
616
        if self.file_name is None:
 
617
            raise AssertionError('We cannot save, self.file_name is None')
 
618
        conf_dir = os.path.dirname(self.file_name)
 
619
        ensure_config_dir_exists(conf_dir)
 
620
        atomic_file = atomicfile.AtomicFile(self.file_name)
 
621
        self._get_parser().write(atomic_file)
 
622
        atomic_file.commit()
 
623
        atomic_file.close()
 
624
        osutils.copy_ownership_from_path(self.file_name)
 
625
 
 
626
 
 
627
class LockableConfig(IniBasedConfig):
 
628
    """A configuration needing explicit locking for access.
 
629
 
 
630
    If several processes try to write the config file, the accesses need to be
 
631
    serialized.
 
632
 
 
633
    Daughter classes should decorate all methods that update a config with the
 
634
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
 
635
    ``_write_config_file()`` method. These methods (typically ``set_option()``
 
636
    and variants must reload the config file from disk before calling
 
637
    ``_write_config_file()``), this can be achieved by calling the
 
638
    ``self.reload()`` method. Note that the lock scope should cover both the
 
639
    reading and the writing of the config file which is why the decorator can't
 
640
    be applied to ``_write_config_file()`` only.
 
641
 
 
642
    This should be enough to implement the following logic:
 
643
    - lock for exclusive write access,
 
644
    - reload the config file from disk,
 
645
    - set the new value
 
646
    - unlock
 
647
 
 
648
    This logic guarantees that a writer can update a value without erasing an
 
649
    update made by another writer.
 
650
    """
 
651
 
 
652
    lock_name = 'lock'
 
653
 
 
654
    def __init__(self, file_name):
 
655
        super(LockableConfig, self).__init__(file_name=file_name)
 
656
        self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
 
657
        self.transport = transport.get_transport(self.dir)
 
658
        self._lock = lockdir.LockDir(self.transport, 'lock')
 
659
 
 
660
    def _create_from_string(self, unicode_bytes, save):
 
661
        super(LockableConfig, self)._create_from_string(unicode_bytes, False)
 
662
        if save:
 
663
            # We need to handle the saving here (as opposed to IniBasedConfig)
 
664
            # to be able to lock
 
665
            self.lock_write()
 
666
            self._write_config_file()
 
667
            self.unlock()
 
668
 
 
669
    def lock_write(self, token=None):
 
670
        """Takes a write lock in the directory containing the config file.
 
671
 
 
672
        If the directory doesn't exist it is created.
 
673
        """
 
674
        ensure_config_dir_exists(self.dir)
 
675
        return self._lock.lock_write(token)
 
676
 
 
677
    def unlock(self):
 
678
        self._lock.unlock()
 
679
 
 
680
    def break_lock(self):
 
681
        self._lock.break_lock()
 
682
 
 
683
    @needs_write_lock
 
684
    def remove_user_option(self, option_name, section_name=None):
 
685
        super(LockableConfig, self).remove_user_option(option_name,
 
686
                                                       section_name)
 
687
 
 
688
    def _write_config_file(self):
 
689
        if self._lock is None or not self._lock.is_held:
 
690
            # NB: if the following exception is raised it probably means a
 
691
            # missing @needs_write_lock decorator on one of the callers.
 
692
            raise errors.ObjectNotLocked(self)
 
693
        super(LockableConfig, self)._write_config_file()
 
694
 
 
695
 
 
696
class GlobalConfig(LockableConfig):
481
697
    """The configuration that should be used for a specific location."""
482
698
 
 
699
    def __init__(self):
 
700
        super(GlobalConfig, self).__init__(file_name=config_filename())
 
701
 
 
702
    def config_id(self):
 
703
        return 'bazaar'
 
704
 
 
705
    @classmethod
 
706
    def from_string(cls, str_or_unicode, save=False):
 
707
        """Create a config object from a string.
 
708
 
 
709
        :param str_or_unicode: A string representing the file content. This
 
710
            will be utf-8 encoded.
 
711
 
 
712
        :param save: Whether the file should be saved upon creation.
 
713
        """
 
714
        conf = cls()
 
715
        conf._create_from_string(str_or_unicode, save)
 
716
        return conf
 
717
 
483
718
    def get_editor(self):
484
719
        return self._get_user_option('editor')
485
720
 
486
 
    def __init__(self):
487
 
        super(GlobalConfig, self).__init__(config_filename)
488
 
 
 
721
    @needs_write_lock
489
722
    def set_user_option(self, option, value):
490
723
        """Save option and its value in the configuration."""
491
724
        self._set_option(option, value, 'DEFAULT')
497
730
        else:
498
731
            return {}
499
732
 
 
733
    @needs_write_lock
500
734
    def set_alias(self, alias_name, alias_command):
501
735
        """Save the alias in the configuration."""
502
736
        self._set_option(alias_name, alias_command, 'ALIASES')
503
737
 
 
738
    @needs_write_lock
504
739
    def unset_alias(self, alias_name):
505
740
        """Unset an existing alias."""
 
741
        self.reload()
506
742
        aliases = self._get_parser().get('ALIASES')
507
743
        if not aliases or alias_name not in aliases:
508
744
            raise errors.NoSuchAlias(alias_name)
510
746
        self._write_config_file()
511
747
 
512
748
    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)
 
749
        self.reload()
517
750
        self._get_parser().setdefault(section, {})[option] = value
518
751
        self._write_config_file()
519
752
 
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):
 
753
 
 
754
    def _get_sections(self, name=None):
 
755
        """See IniBasedConfig._get_sections()."""
 
756
        parser = self._get_parser()
 
757
        # We don't give access to options defined outside of any section, we
 
758
        # used the DEFAULT section by... default.
 
759
        if name in (None, 'DEFAULT'):
 
760
            # This could happen for an empty file where the DEFAULT section
 
761
            # doesn't exist yet. So we force DEFAULT when yielding
 
762
            name = 'DEFAULT'
 
763
            if 'DEFAULT' not in parser:
 
764
               parser['DEFAULT']= {}
 
765
        yield (name, parser[name], self.config_id())
 
766
 
 
767
    @needs_write_lock
 
768
    def remove_user_option(self, option_name, section_name=None):
 
769
        if section_name is None:
 
770
            # We need to force the default section.
 
771
            section_name = 'DEFAULT'
 
772
        # We need to avoid the LockableConfig implementation or we'll lock
 
773
        # twice
 
774
        super(LockableConfig, self).remove_user_option(option_name,
 
775
                                                       section_name)
 
776
 
 
777
 
 
778
class LocationConfig(LockableConfig):
529
779
    """A configuration object that gives the policy for a location."""
530
780
 
531
781
    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)
 
782
        super(LocationConfig, self).__init__(
 
783
            file_name=locations_config_filename())
544
784
        # local file locations are looked up by local path, rather than
545
785
        # by file url. This is because the config file is a user
546
786
        # file, and we would rather not expose the user to file urls.
548
788
            location = urlutils.local_path_from_url(location)
549
789
        self.location = location
550
790
 
 
791
    def config_id(self):
 
792
        return 'locations'
 
793
 
 
794
    @classmethod
 
795
    def from_string(cls, str_or_unicode, location, save=False):
 
796
        """Create a config object from a string.
 
797
 
 
798
        :param str_or_unicode: A string representing the file content. This will
 
799
            be utf-8 encoded.
 
800
 
 
801
        :param location: The location url to filter the configuration.
 
802
 
 
803
        :param save: Whether the file should be saved upon creation.
 
804
        """
 
805
        conf = cls(location)
 
806
        conf._create_from_string(str_or_unicode, save)
 
807
        return conf
 
808
 
551
809
    def _get_matching_sections(self):
552
810
        """Return an ordered list of section names matching this location."""
553
811
        sections = self._get_parser()
570
828
            names = zip(location_names, section_names)
571
829
            matched = True
572
830
            for name in names:
573
 
                if not fnmatch(name[0], name[1]):
 
831
                if not fnmatch.fnmatch(name[0], name[1]):
574
832
                    matched = False
575
833
                    break
576
834
            if not matched:
581
839
                continue
582
840
            matches.append((len(section_names), section,
583
841
                            '/'.join(location_names[len(section_names):])))
 
842
        # put the longest (aka more specific) locations first
584
843
        matches.sort(reverse=True)
585
844
        sections = []
586
845
        for (length, section, extra_path) in matches:
593
852
                pass
594
853
        return sections
595
854
 
 
855
    def _get_sections(self, name=None):
 
856
        """See IniBasedConfig._get_sections()."""
 
857
        # We ignore the name here as the only sections handled are named with
 
858
        # the location path and we don't expose embedded sections either.
 
859
        parser = self._get_parser()
 
860
        for name, extra_path in self._get_matching_sections():
 
861
            yield (name, parser[name], self.config_id())
 
862
 
596
863
    def _get_option_policy(self, section, option_name):
597
864
        """Return the policy for the given (section, option_name) pair."""
598
865
        # check for the old 'recurse=False' flag
641
908
            if policy_key in self._get_parser()[section]:
642
909
                del self._get_parser()[section][policy_key]
643
910
 
 
911
    @needs_write_lock
644
912
    def set_user_option(self, option, value, store=STORE_LOCATION):
645
913
        """Save option and its value in the configuration."""
646
914
        if store not in [STORE_LOCATION,
648
916
                         STORE_LOCATION_APPENDPATH]:
649
917
            raise ValueError('bad storage policy %r for %r' %
650
918
                (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)
 
919
        self.reload()
655
920
        location = self.location
656
921
        if location.endswith('/'):
657
922
            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():
 
923
        parser = self._get_parser()
 
924
        if not location in parser and not location + '/' in parser:
 
925
            parser[location] = {}
 
926
        elif location + '/' in parser:
662
927
            location = location + '/'
663
 
        self._get_parser()[location][option]=value
 
928
        parser[location][option]=value
664
929
        # the allowed values of store match the config policies
665
930
        self._set_option_policy(location, option, store)
666
 
        self._get_parser().write(file(self._get_filename(), 'wb'))
 
931
        self._write_config_file()
667
932
 
668
933
 
669
934
class BranchConfig(Config):
670
935
    """A configuration object giving the policy for a branch."""
671
936
 
 
937
    def __init__(self, branch):
 
938
        super(BranchConfig, self).__init__()
 
939
        self._location_config = None
 
940
        self._branch_data_config = None
 
941
        self._global_config = None
 
942
        self.branch = branch
 
943
        self.option_sources = (self._get_location_config,
 
944
                               self._get_branch_data_config,
 
945
                               self._get_global_config)
 
946
 
 
947
    def config_id(self):
 
948
        return 'branch'
 
949
 
672
950
    def _get_branch_data_config(self):
673
951
        if self._branch_data_config is None:
674
952
            self._branch_data_config = TreeConfig(self.branch)
 
953
            self._branch_data_config.config_id = self.config_id
675
954
        return self._branch_data_config
676
955
 
677
956
    def _get_location_config(self):
745
1024
                return value
746
1025
        return None
747
1026
 
 
1027
    def _get_sections(self, name=None):
 
1028
        """See IniBasedConfig.get_sections()."""
 
1029
        for source in self.option_sources:
 
1030
            for section in source()._get_sections(name):
 
1031
                yield section
 
1032
 
 
1033
    def _get_options(self, sections=None):
 
1034
        opts = []
 
1035
        # First the locations options
 
1036
        for option in self._get_location_config()._get_options():
 
1037
            yield option
 
1038
        # Then the branch options
 
1039
        branch_config = self._get_branch_data_config()
 
1040
        if sections is None:
 
1041
            sections = [('DEFAULT', branch_config._get_parser())]
 
1042
        # FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
 
1043
        # Config itself has no notion of sections :( -- vila 20101001
 
1044
        config_id = self.config_id()
 
1045
        for (section_name, section) in sections:
 
1046
            for (name, value) in section.iteritems():
 
1047
                yield (name, value, section_name,
 
1048
                       config_id, branch_config._get_parser())
 
1049
        # Then the global options
 
1050
        for option in self._get_global_config()._get_options():
 
1051
            yield option
 
1052
 
748
1053
    def set_user_option(self, name, value, store=STORE_BRANCH,
749
1054
        warn_masked=False):
750
1055
        if store == STORE_BRANCH:
768
1073
                        trace.warning('Value "%s" is masked by "%s" from'
769
1074
                                      ' branch.conf', value, mask_value)
770
1075
 
 
1076
    def remove_user_option(self, option_name, section_name=None):
 
1077
        self._get_branch_data_config().remove_option(option_name, section_name)
 
1078
 
771
1079
    def _gpg_signing_command(self):
772
1080
        """See Config.gpg_signing_command."""
773
1081
        return self._get_safe_value('_gpg_signing_command')
774
1082
 
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
1083
    def _post_commit(self):
786
1084
        """See Config.post_commit."""
787
1085
        return self._get_safe_value('_post_commit')
817
1115
            parent_dir = os.path.dirname(path)
818
1116
            if not os.path.isdir(parent_dir):
819
1117
                trace.mutter('creating config parent directory: %r', parent_dir)
820
 
            os.mkdir(parent_dir)
 
1118
                os.mkdir(parent_dir)
821
1119
        trace.mutter('creating config directory: %r', path)
822
1120
        os.mkdir(path)
823
1121
        osutils.copy_ownership_from_path(path)
826
1124
def config_dir():
827
1125
    """Return per-user configuration directory.
828
1126
 
829
 
    By default this is ~/.bazaar/
 
1127
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
 
1128
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
 
1129
    that will be used instead.
830
1130
 
831
1131
    TODO: Global option --config-dir to override this.
832
1132
    """
833
1133
    base = os.environ.get('BZR_HOME', None)
834
1134
    if sys.platform == 'win32':
 
1135
        # environ variables on Windows are in user encoding/mbcs. So decode
 
1136
        # before using one
 
1137
        if base is not None:
 
1138
            base = base.decode('mbcs')
835
1139
        if base is None:
836
1140
            base = win32utils.get_appdata_location_unicode()
837
1141
        if base is None:
838
1142
            base = os.environ.get('HOME', None)
 
1143
            if base is not None:
 
1144
                base = base.decode('mbcs')
839
1145
        if base is None:
840
1146
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
841
1147
                                  ' or HOME set')
842
1148
        return osutils.pathjoin(base, 'bazaar', '2.0')
 
1149
    elif sys.platform == 'darwin':
 
1150
        if base is None:
 
1151
            # this takes into account $HOME
 
1152
            base = os.path.expanduser("~")
 
1153
        return osutils.pathjoin(base, '.bazaar')
843
1154
    else:
844
 
        # cygwin, linux, and darwin all have a $HOME directory
845
1155
        if base is None:
 
1156
 
 
1157
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
 
1158
            if xdg_dir is None:
 
1159
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
 
1160
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
 
1161
            if osutils.isdir(xdg_dir):
 
1162
                trace.mutter(
 
1163
                    "Using configuration in XDG directory %s." % xdg_dir)
 
1164
                return xdg_dir
 
1165
 
846
1166
            base = os.path.expanduser("~")
847
1167
        return osutils.pathjoin(base, ".bazaar")
848
1168
 
852
1172
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
853
1173
 
854
1174
 
855
 
def branches_config_filename():
856
 
    """Return per-user configuration ini file filename."""
857
 
    return osutils.pathjoin(config_dir(), 'branches.conf')
858
 
 
859
 
 
860
1175
def locations_config_filename():
861
1176
    """Return per-user configuration ini file filename."""
862
1177
    return osutils.pathjoin(config_dir(), 'locations.conf')
899
1214
        return os.path.expanduser('~/.cache')
900
1215
 
901
1216
 
 
1217
def _get_default_mail_domain():
 
1218
    """If possible, return the assumed default email domain.
 
1219
 
 
1220
    :returns: string mail domain, or None.
 
1221
    """
 
1222
    if sys.platform == 'win32':
 
1223
        # No implementation yet; patches welcome
 
1224
        return None
 
1225
    try:
 
1226
        f = open('/etc/mailname')
 
1227
    except (IOError, OSError), e:
 
1228
        return None
 
1229
    try:
 
1230
        domain = f.read().strip()
 
1231
        return domain
 
1232
    finally:
 
1233
        f.close()
 
1234
 
 
1235
 
902
1236
def _auto_user_id():
903
1237
    """Calculate automatic user identification.
904
1238
 
905
 
    Returns (realname, email).
 
1239
    :returns: (realname, email), either of which may be None if they can't be
 
1240
    determined.
906
1241
 
907
1242
    Only used when none is set in the environment or the id file.
908
1243
 
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.
 
1244
    This only returns an email address if we can be fairly sure the 
 
1245
    address is reasonable, ie if /etc/mailname is set on unix.
 
1246
 
 
1247
    This doesn't use the FQDN as the default domain because that may be 
 
1248
    slow, and it doesn't use the hostname alone because that's not normally 
 
1249
    a reasonable address.
912
1250
    """
913
 
    import socket
914
 
 
915
1251
    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())
 
1252
        # No implementation to reliably determine Windows default mail
 
1253
        # address; please add one.
 
1254
        return None, None
 
1255
 
 
1256
    default_mail_domain = _get_default_mail_domain()
 
1257
    if not default_mail_domain:
 
1258
        return None, None
 
1259
 
 
1260
    import pwd
 
1261
    uid = os.getuid()
 
1262
    try:
 
1263
        w = pwd.getpwuid(uid)
 
1264
    except KeyError:
 
1265
        mutter('no passwd entry for uid %d?' % uid)
 
1266
        return None, None
 
1267
 
 
1268
    # we try utf-8 first, because on many variants (like Linux),
 
1269
    # /etc/passwd "should" be in utf-8, and because it's unlikely to give
 
1270
    # false positives.  (many users will have their user encoding set to
 
1271
    # latin-1, which cannot raise UnicodeError.)
 
1272
    try:
 
1273
        gecos = w.pw_gecos.decode('utf-8')
 
1274
        encoding = 'utf-8'
 
1275
    except UnicodeError:
 
1276
        try:
 
1277
            encoding = osutils.get_user_encoding()
 
1278
            gecos = w.pw_gecos.decode(encoding)
 
1279
        except UnicodeError, e:
 
1280
            mutter("cannot decode passwd entry %s" % w)
 
1281
            return None, None
 
1282
    try:
 
1283
        username = w.pw_name.decode(encoding)
 
1284
    except UnicodeError, e:
 
1285
        mutter("cannot decode passwd entry %s" % w)
 
1286
        return None, None
 
1287
 
 
1288
    comma = gecos.find(',')
 
1289
    if comma == -1:
 
1290
        realname = gecos
 
1291
    else:
 
1292
        realname = gecos[:comma]
 
1293
 
 
1294
    return realname, (username + '@' + default_mail_domain)
973
1295
 
974
1296
 
975
1297
def parse_username(username):
1020
1342
 
1021
1343
    def set_option(self, value, name, section=None):
1022
1344
        """Set a per-branch configuration option"""
 
1345
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1346
        # higher levels providing the right lock -- vila 20101004
1023
1347
        self.branch.lock_write()
1024
1348
        try:
1025
1349
            self._config.set_option(value, name, section)
1026
1350
        finally:
1027
1351
            self.branch.unlock()
1028
1352
 
 
1353
    def remove_option(self, option_name, section_name=None):
 
1354
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1355
        # higher levels providing the right lock -- vila 20101004
 
1356
        self.branch.lock_write()
 
1357
        try:
 
1358
            self._config.remove_option(option_name, section_name)
 
1359
        finally:
 
1360
            self.branch.unlock()
 
1361
 
1029
1362
 
1030
1363
class AuthenticationConfig(object):
1031
1364
    """The authentication configuration file based on a ini file.
1063
1396
        """Save the config file, only tests should use it for now."""
1064
1397
        conf_dir = os.path.dirname(self._filename)
1065
1398
        ensure_config_dir_exists(conf_dir)
1066
 
        self._get_config().write(file(self._filename, 'wb'))
 
1399
        f = file(self._filename, 'wb')
 
1400
        try:
 
1401
            self._get_config().write(f)
 
1402
        finally:
 
1403
            f.close()
1067
1404
 
1068
1405
    def _set_option(self, section_name, option_name, value):
1069
1406
        """Set an authentication configuration option"""
1470
1807
    """A Config that reads/writes a config file on a Transport.
1471
1808
 
1472
1809
    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.
 
1810
    that may be associated with a section.  Assigning meaning to these values
 
1811
    is done at higher levels like TreeConfig.
1475
1812
    """
1476
1813
 
1477
1814
    def __init__(self, transport, filename):
1510
1847
            configobj.setdefault(section, {})[name] = value
1511
1848
        self._set_configobj(configobj)
1512
1849
 
 
1850
    def remove_option(self, option_name, section_name=None):
 
1851
        configobj = self._get_configobj()
 
1852
        if section_name is None:
 
1853
            del configobj[option_name]
 
1854
        else:
 
1855
            del configobj[section_name][option_name]
 
1856
        self._set_configobj(configobj)
 
1857
 
1513
1858
    def _get_config_file(self):
1514
1859
        try:
1515
1860
            return StringIO(self._transport.get_bytes(self._filename))
1517
1862
            return StringIO()
1518
1863
 
1519
1864
    def _get_configobj(self):
1520
 
        return ConfigObj(self._get_config_file(), encoding='utf-8')
 
1865
        f = self._get_config_file()
 
1866
        try:
 
1867
            return ConfigObj(f, encoding='utf-8')
 
1868
        finally:
 
1869
            f.close()
1521
1870
 
1522
1871
    def _set_configobj(self, configobj):
1523
1872
        out_file = StringIO()
1524
1873
        configobj.write(out_file)
1525
1874
        out_file.seek(0)
1526
1875
        self._transport.put_file(self._filename, out_file)
 
1876
 
 
1877
 
 
1878
class cmd_config(commands.Command):
 
1879
    __doc__ = """Display, set or remove a configuration option.
 
1880
 
 
1881
    Display the active value for a given option.
 
1882
 
 
1883
    If --all is specified, NAME is interpreted as a regular expression and all
 
1884
    matching options are displayed mentioning their scope. The active value
 
1885
    that bzr will take into account is the first one displayed for each option.
 
1886
 
 
1887
    If no NAME is given, --all .* is implied.
 
1888
 
 
1889
    Setting a value is achieved by using name=value without spaces. The value
 
1890
    is set in the most relevant scope and can be checked by displaying the
 
1891
    option again.
 
1892
    """
 
1893
 
 
1894
    takes_args = ['name?']
 
1895
 
 
1896
    takes_options = [
 
1897
        'directory',
 
1898
        # FIXME: This should be a registry option so that plugins can register
 
1899
        # their own config files (or not) -- vila 20101002
 
1900
        commands.Option('scope', help='Reduce the scope to the specified'
 
1901
                        ' configuration file',
 
1902
                        type=unicode),
 
1903
        commands.Option('all',
 
1904
            help='Display all the defined values for the matching options.',
 
1905
            ),
 
1906
        commands.Option('remove', help='Remove the option from'
 
1907
                        ' the configuration file'),
 
1908
        ]
 
1909
 
 
1910
    @commands.display_command
 
1911
    def run(self, name=None, all=False, directory=None, scope=None,
 
1912
            remove=False):
 
1913
        if directory is None:
 
1914
            directory = '.'
 
1915
        directory = urlutils.normalize_url(directory)
 
1916
        if remove and all:
 
1917
            raise errors.BzrError(
 
1918
                '--all and --remove are mutually exclusive.')
 
1919
        elif remove:
 
1920
            # Delete the option in the given scope
 
1921
            self._remove_config_option(name, directory, scope)
 
1922
        elif name is None:
 
1923
            # Defaults to all options
 
1924
            self._show_matching_options('.*', directory, scope)
 
1925
        else:
 
1926
            try:
 
1927
                name, value = name.split('=', 1)
 
1928
            except ValueError:
 
1929
                # Display the option(s) value(s)
 
1930
                if all:
 
1931
                    self._show_matching_options(name, directory, scope)
 
1932
                else:
 
1933
                    self._show_value(name, directory, scope)
 
1934
            else:
 
1935
                if all:
 
1936
                    raise errors.BzrError(
 
1937
                        'Only one option can be set.')
 
1938
                # Set the option value
 
1939
                self._set_config_option(name, value, directory, scope)
 
1940
 
 
1941
    def _get_configs(self, directory, scope=None):
 
1942
        """Iterate the configurations specified by ``directory`` and ``scope``.
 
1943
 
 
1944
        :param directory: Where the configurations are derived from.
 
1945
 
 
1946
        :param scope: A specific config to start from.
 
1947
        """
 
1948
        if scope is not None:
 
1949
            if scope == 'bazaar':
 
1950
                yield GlobalConfig()
 
1951
            elif scope == 'locations':
 
1952
                yield LocationConfig(directory)
 
1953
            elif scope == 'branch':
 
1954
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1955
                    directory)
 
1956
                yield br.get_config()
 
1957
        else:
 
1958
            try:
 
1959
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1960
                    directory)
 
1961
                yield br.get_config()
 
1962
            except errors.NotBranchError:
 
1963
                yield LocationConfig(directory)
 
1964
                yield GlobalConfig()
 
1965
 
 
1966
    def _show_value(self, name, directory, scope):
 
1967
        displayed = False
 
1968
        for c in self._get_configs(directory, scope):
 
1969
            if displayed:
 
1970
                break
 
1971
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1972
                if name == oname:
 
1973
                    # Display only the first value and exit
 
1974
 
 
1975
                    # FIXME: We need to use get_user_option to take policies
 
1976
                    # into account and we need to make sure the option exists
 
1977
                    # too (hence the two for loops), this needs a better API
 
1978
                    # -- vila 20101117
 
1979
                    value = c.get_user_option(name)
 
1980
                    # Quote the value appropriately
 
1981
                    value = parser._quote(value)
 
1982
                    self.outf.write('%s\n' % (value,))
 
1983
                    displayed = True
 
1984
                    break
 
1985
        if not displayed:
 
1986
            raise errors.NoSuchConfigOption(name)
 
1987
 
 
1988
    def _show_matching_options(self, name, directory, scope):
 
1989
        name = re.compile(name)
 
1990
        # We want any error in the regexp to be raised *now* so we need to
 
1991
        # avoid the delay introduced by the lazy regexp.
 
1992
        name._compile_and_collapse()
 
1993
        cur_conf_id = None
 
1994
        cur_section = None
 
1995
        for c in self._get_configs(directory, scope):
 
1996
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1997
                if name.search(oname):
 
1998
                    if cur_conf_id != conf_id:
 
1999
                        # Explain where the options are defined
 
2000
                        self.outf.write('%s:\n' % (conf_id,))
 
2001
                        cur_conf_id = conf_id
 
2002
                        cur_section = None
 
2003
                    if (section not in (None, 'DEFAULT')
 
2004
                        and cur_section != section):
 
2005
                        # Display the section if it's not the default (or only)
 
2006
                        # one.
 
2007
                        self.outf.write('  [%s]\n' % (section,))
 
2008
                        cur_section = section
 
2009
                    self.outf.write('  %s = %s\n' % (oname, value))
 
2010
 
 
2011
    def _set_config_option(self, name, value, directory, scope):
 
2012
        for conf in self._get_configs(directory, scope):
 
2013
            conf.set_user_option(name, value)
 
2014
            break
 
2015
        else:
 
2016
            raise errors.NoSuchConfig(scope)
 
2017
 
 
2018
    def _remove_config_option(self, name, directory, scope):
 
2019
        if name is None:
 
2020
            raise errors.BzrCommandError(
 
2021
                '--remove expects an option to remove.')
 
2022
        removed = False
 
2023
        for conf in self._get_configs(directory, scope):
 
2024
            for (section_name, section, conf_id) in conf._get_sections():
 
2025
                if scope is not None and conf_id != scope:
 
2026
                    # Not the right configuration file
 
2027
                    continue
 
2028
                if name in section:
 
2029
                    if conf_id != conf.config_id():
 
2030
                        conf = self._get_configs(directory, conf_id).next()
 
2031
                    # We use the first section in the first config where the
 
2032
                    # option is defined to remove it
 
2033
                    conf.remove_user_option(name, section_name)
 
2034
                    removed = True
 
2035
                    break
 
2036
            break
 
2037
        else:
 
2038
            raise errors.NoSuchConfig(scope)
 
2039
        if not removed:
 
2040
            raise errors.NoSuchConfigOption(name)