~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Zearin
  • Date: 2010-11-12 22:08:18 UTC
  • mto: (5570.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5572.
  • Revision ID: zearin@users.sourceforge.net-20101112220818-mb62len4zyxr8qvd
Fixed capitalization of XML and HTTP.  Fixed by hand and only where appropriate (e.g., left http://some/url lowercase, but capitalized "When making an HTTP request…").

Show diffs side-by-side

added added

removed removed

Lines of Context:
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, value, section_name, config_id)
 
500
 
387
501
    def _get_option_policy(self, section, option_name):
388
502
        """Return the policy for the given (section, option_name) pair."""
389
503
        return POLICY_NONE
476
590
    def _get_nickname(self):
477
591
        return self.get_user_option('nickname')
478
592
 
479
 
 
480
 
class GlobalConfig(IniBasedConfig):
 
593
    def remove_user_option(self, option_name, section_name=None):
 
594
        """Remove a user option and save the configuration file.
 
595
 
 
596
        :param option_name: The option to be removed.
 
597
 
 
598
        :param section_name: The section the option is defined in, default to
 
599
            the default section.
 
600
        """
 
601
        self.reload()
 
602
        parser = self._get_parser()
 
603
        if section_name is None:
 
604
            section = parser
 
605
        else:
 
606
            section = parser[section_name]
 
607
        try:
 
608
            del section[option_name]
 
609
        except KeyError:
 
610
            raise errors.NoSuchConfigOption(option_name)
 
611
        self._write_config_file()
 
612
 
 
613
    def _write_config_file(self):
 
614
        if self.file_name is None:
 
615
            raise AssertionError('We cannot save, self.file_name is None')
 
616
        conf_dir = os.path.dirname(self.file_name)
 
617
        ensure_config_dir_exists(conf_dir)
 
618
        atomic_file = atomicfile.AtomicFile(self.file_name)
 
619
        self._get_parser().write(atomic_file)
 
620
        atomic_file.commit()
 
621
        atomic_file.close()
 
622
        osutils.copy_ownership_from_path(self.file_name)
 
623
 
 
624
 
 
625
class LockableConfig(IniBasedConfig):
 
626
    """A configuration needing explicit locking for access.
 
627
 
 
628
    If several processes try to write the config file, the accesses need to be
 
629
    serialized.
 
630
 
 
631
    Daughter classes should decorate all methods that update a config with the
 
632
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
 
633
    ``_write_config_file()`` method. These methods (typically ``set_option()``
 
634
    and variants must reload the config file from disk before calling
 
635
    ``_write_config_file()``), this can be achieved by calling the
 
636
    ``self.reload()`` method. Note that the lock scope should cover both the
 
637
    reading and the writing of the config file which is why the decorator can't
 
638
    be applied to ``_write_config_file()`` only.
 
639
 
 
640
    This should be enough to implement the following logic:
 
641
    - lock for exclusive write access,
 
642
    - reload the config file from disk,
 
643
    - set the new value
 
644
    - unlock
 
645
 
 
646
    This logic guarantees that a writer can update a value without erasing an
 
647
    update made by another writer.
 
648
    """
 
649
 
 
650
    lock_name = 'lock'
 
651
 
 
652
    def __init__(self, file_name):
 
653
        super(LockableConfig, self).__init__(file_name=file_name)
 
654
        self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
 
655
        self.transport = transport.get_transport(self.dir)
 
656
        self._lock = lockdir.LockDir(self.transport, 'lock')
 
657
 
 
658
    def _create_from_string(self, unicode_bytes, save):
 
659
        super(LockableConfig, self)._create_from_string(unicode_bytes, False)
 
660
        if save:
 
661
            # We need to handle the saving here (as opposed to IniBasedConfig)
 
662
            # to be able to lock
 
663
            self.lock_write()
 
664
            self._write_config_file()
 
665
            self.unlock()
 
666
 
 
667
    def lock_write(self, token=None):
 
668
        """Takes a write lock in the directory containing the config file.
 
669
 
 
670
        If the directory doesn't exist it is created.
 
671
        """
 
672
        ensure_config_dir_exists(self.dir)
 
673
        return self._lock.lock_write(token)
 
674
 
 
675
    def unlock(self):
 
676
        self._lock.unlock()
 
677
 
 
678
    def break_lock(self):
 
679
        self._lock.break_lock()
 
680
 
 
681
    @needs_write_lock
 
682
    def remove_user_option(self, option_name, section_name=None):
 
683
        super(LockableConfig, self).remove_user_option(option_name,
 
684
                                                       section_name)
 
685
 
 
686
    def _write_config_file(self):
 
687
        if self._lock is None or not self._lock.is_held:
 
688
            # NB: if the following exception is raised it probably means a
 
689
            # missing @needs_write_lock decorator on one of the callers.
 
690
            raise errors.ObjectNotLocked(self)
 
691
        super(LockableConfig, self)._write_config_file()
 
692
 
 
693
 
 
694
class GlobalConfig(LockableConfig):
481
695
    """The configuration that should be used for a specific location."""
482
696
 
 
697
    def __init__(self):
 
698
        super(GlobalConfig, self).__init__(file_name=config_filename())
 
699
 
 
700
    def config_id(self):
 
701
        return 'bazaar'
 
702
 
 
703
    @classmethod
 
704
    def from_string(cls, str_or_unicode, save=False):
 
705
        """Create a config object from a string.
 
706
 
 
707
        :param str_or_unicode: A string representing the file content. This
 
708
            will be utf-8 encoded.
 
709
 
 
710
        :param save: Whether the file should be saved upon creation.
 
711
        """
 
712
        conf = cls()
 
713
        conf._create_from_string(str_or_unicode, save)
 
714
        return conf
 
715
 
483
716
    def get_editor(self):
484
717
        return self._get_user_option('editor')
485
718
 
486
 
    def __init__(self):
487
 
        super(GlobalConfig, self).__init__(config_filename)
488
 
 
 
719
    @needs_write_lock
489
720
    def set_user_option(self, option, value):
490
721
        """Save option and its value in the configuration."""
491
722
        self._set_option(option, value, 'DEFAULT')
497
728
        else:
498
729
            return {}
499
730
 
 
731
    @needs_write_lock
500
732
    def set_alias(self, alias_name, alias_command):
501
733
        """Save the alias in the configuration."""
502
734
        self._set_option(alias_name, alias_command, 'ALIASES')
503
735
 
 
736
    @needs_write_lock
504
737
    def unset_alias(self, alias_name):
505
738
        """Unset an existing alias."""
 
739
        self.reload()
506
740
        aliases = self._get_parser().get('ALIASES')
507
741
        if not aliases or alias_name not in aliases:
508
742
            raise errors.NoSuchAlias(alias_name)
510
744
        self._write_config_file()
511
745
 
512
746
    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)
 
747
        self.reload()
517
748
        self._get_parser().setdefault(section, {})[option] = value
518
749
        self._write_config_file()
519
750
 
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):
 
751
 
 
752
    def _get_sections(self, name=None):
 
753
        """See IniBasedConfig._get_sections()."""
 
754
        parser = self._get_parser()
 
755
        # We don't give access to options defined outside of any section, we
 
756
        # used the DEFAULT section by... default.
 
757
        if name in (None, 'DEFAULT'):
 
758
            # This could happen for an empty file where the DEFAULT section
 
759
            # doesn't exist yet. So we force DEFAULT when yielding
 
760
            name = 'DEFAULT'
 
761
            if 'DEFAULT' not in parser:
 
762
               parser['DEFAULT']= {}
 
763
        yield (name, parser[name], self.config_id())
 
764
 
 
765
    @needs_write_lock
 
766
    def remove_user_option(self, option_name, section_name=None):
 
767
        if section_name is None:
 
768
            # We need to force the default section.
 
769
            section_name = 'DEFAULT'
 
770
        # We need to avoid the LockableConfig implementation or we'll lock
 
771
        # twice
 
772
        super(LockableConfig, self).remove_user_option(option_name,
 
773
                                                       section_name)
 
774
 
 
775
 
 
776
class LocationConfig(LockableConfig):
529
777
    """A configuration object that gives the policy for a location."""
530
778
 
531
779
    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)
 
780
        super(LocationConfig, self).__init__(
 
781
            file_name=locations_config_filename())
544
782
        # local file locations are looked up by local path, rather than
545
783
        # by file url. This is because the config file is a user
546
784
        # file, and we would rather not expose the user to file urls.
548
786
            location = urlutils.local_path_from_url(location)
549
787
        self.location = location
550
788
 
 
789
    def config_id(self):
 
790
        return 'locations'
 
791
 
 
792
    @classmethod
 
793
    def from_string(cls, str_or_unicode, location, save=False):
 
794
        """Create a config object from a string.
 
795
 
 
796
        :param str_or_unicode: A string representing the file content. This will
 
797
            be utf-8 encoded.
 
798
 
 
799
        :param location: The location url to filter the configuration.
 
800
 
 
801
        :param save: Whether the file should be saved upon creation.
 
802
        """
 
803
        conf = cls(location)
 
804
        conf._create_from_string(str_or_unicode, save)
 
805
        return conf
 
806
 
551
807
    def _get_matching_sections(self):
552
808
        """Return an ordered list of section names matching this location."""
553
809
        sections = self._get_parser()
570
826
            names = zip(location_names, section_names)
571
827
            matched = True
572
828
            for name in names:
573
 
                if not fnmatch(name[0], name[1]):
 
829
                if not fnmatch.fnmatch(name[0], name[1]):
574
830
                    matched = False
575
831
                    break
576
832
            if not matched:
581
837
                continue
582
838
            matches.append((len(section_names), section,
583
839
                            '/'.join(location_names[len(section_names):])))
 
840
        # put the longest (aka more specific) locations first
584
841
        matches.sort(reverse=True)
585
842
        sections = []
586
843
        for (length, section, extra_path) in matches:
593
850
                pass
594
851
        return sections
595
852
 
 
853
    def _get_sections(self, name=None):
 
854
        """See IniBasedConfig._get_sections()."""
 
855
        # We ignore the name here as the only sections handled are named with
 
856
        # the location path and we don't expose embedded sections either.
 
857
        parser = self._get_parser()
 
858
        for name, extra_path in self._get_matching_sections():
 
859
            yield (name, parser[name], self.config_id())
 
860
 
596
861
    def _get_option_policy(self, section, option_name):
597
862
        """Return the policy for the given (section, option_name) pair."""
598
863
        # check for the old 'recurse=False' flag
641
906
            if policy_key in self._get_parser()[section]:
642
907
                del self._get_parser()[section][policy_key]
643
908
 
 
909
    @needs_write_lock
644
910
    def set_user_option(self, option, value, store=STORE_LOCATION):
645
911
        """Save option and its value in the configuration."""
646
912
        if store not in [STORE_LOCATION,
648
914
                         STORE_LOCATION_APPENDPATH]:
649
915
            raise ValueError('bad storage policy %r for %r' %
650
916
                (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)
 
917
        self.reload()
655
918
        location = self.location
656
919
        if location.endswith('/'):
657
920
            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():
 
921
        parser = self._get_parser()
 
922
        if not location in parser and not location + '/' in parser:
 
923
            parser[location] = {}
 
924
        elif location + '/' in parser:
662
925
            location = location + '/'
663
 
        self._get_parser()[location][option]=value
 
926
        parser[location][option]=value
664
927
        # the allowed values of store match the config policies
665
928
        self._set_option_policy(location, option, store)
666
 
        self._get_parser().write(file(self._get_filename(), 'wb'))
 
929
        self._write_config_file()
667
930
 
668
931
 
669
932
class BranchConfig(Config):
670
933
    """A configuration object giving the policy for a branch."""
671
934
 
 
935
    def __init__(self, branch):
 
936
        super(BranchConfig, self).__init__()
 
937
        self._location_config = None
 
938
        self._branch_data_config = None
 
939
        self._global_config = None
 
940
        self.branch = branch
 
941
        self.option_sources = (self._get_location_config,
 
942
                               self._get_branch_data_config,
 
943
                               self._get_global_config)
 
944
 
 
945
    def config_id(self):
 
946
        return 'branch'
 
947
 
672
948
    def _get_branch_data_config(self):
673
949
        if self._branch_data_config is None:
674
950
            self._branch_data_config = TreeConfig(self.branch)
 
951
            self._branch_data_config.config_id = self.config_id
675
952
        return self._branch_data_config
676
953
 
677
954
    def _get_location_config(self):
745
1022
                return value
746
1023
        return None
747
1024
 
 
1025
    def _get_sections(self, name=None):
 
1026
        """See IniBasedConfig.get_sections()."""
 
1027
        for source in self.option_sources:
 
1028
            for section in source()._get_sections(name):
 
1029
                yield section
 
1030
 
 
1031
    def _get_options(self, sections=None):
 
1032
        opts = []
 
1033
        # First the locations options
 
1034
        for option in self._get_location_config()._get_options():
 
1035
            yield option
 
1036
        # Then the branch options
 
1037
        branch_config = self._get_branch_data_config()
 
1038
        if sections is None:
 
1039
            sections = [('DEFAULT', branch_config._get_parser())]
 
1040
        # FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
 
1041
        # Config itself has no notion of sections :( -- vila 20101001
 
1042
        config_id = self.config_id()
 
1043
        for (section_name, section) in sections:
 
1044
            for (name, value) in section.iteritems():
 
1045
                yield (name, value, section_name, config_id)
 
1046
        # Then the global options
 
1047
        for option in self._get_global_config()._get_options():
 
1048
            yield option
 
1049
 
748
1050
    def set_user_option(self, name, value, store=STORE_BRANCH,
749
1051
        warn_masked=False):
750
1052
        if store == STORE_BRANCH:
768
1070
                        trace.warning('Value "%s" is masked by "%s" from'
769
1071
                                      ' branch.conf', value, mask_value)
770
1072
 
 
1073
    def remove_user_option(self, option_name, section_name=None):
 
1074
        self._get_branch_data_config().remove_option(option_name, section_name)
 
1075
 
771
1076
    def _gpg_signing_command(self):
772
1077
        """See Config.gpg_signing_command."""
773
1078
        return self._get_safe_value('_gpg_signing_command')
774
1079
 
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
1080
    def _post_commit(self):
786
1081
        """See Config.post_commit."""
787
1082
        return self._get_safe_value('_post_commit')
817
1112
            parent_dir = os.path.dirname(path)
818
1113
            if not os.path.isdir(parent_dir):
819
1114
                trace.mutter('creating config parent directory: %r', parent_dir)
820
 
            os.mkdir(parent_dir)
 
1115
                os.mkdir(parent_dir)
821
1116
        trace.mutter('creating config directory: %r', path)
822
1117
        os.mkdir(path)
823
1118
        osutils.copy_ownership_from_path(path)
841
1136
                                  ' or HOME set')
842
1137
        return osutils.pathjoin(base, 'bazaar', '2.0')
843
1138
    else:
844
 
        # cygwin, linux, and darwin all have a $HOME directory
845
1139
        if base is None:
846
1140
            base = os.path.expanduser("~")
847
1141
        return osutils.pathjoin(base, ".bazaar")
852
1146
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
853
1147
 
854
1148
 
855
 
def branches_config_filename():
856
 
    """Return per-user configuration ini file filename."""
857
 
    return osutils.pathjoin(config_dir(), 'branches.conf')
858
 
 
859
 
 
860
1149
def locations_config_filename():
861
1150
    """Return per-user configuration ini file filename."""
862
1151
    return osutils.pathjoin(config_dir(), 'locations.conf')
899
1188
        return os.path.expanduser('~/.cache')
900
1189
 
901
1190
 
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
1191
def parse_username(username):
976
1192
    """Parse e-mail username and return a (name, address) tuple."""
977
1193
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1020
1236
 
1021
1237
    def set_option(self, value, name, section=None):
1022
1238
        """Set a per-branch configuration option"""
 
1239
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1240
        # higher levels providing the right lock -- vila 20101004
1023
1241
        self.branch.lock_write()
1024
1242
        try:
1025
1243
            self._config.set_option(value, name, section)
1026
1244
        finally:
1027
1245
            self.branch.unlock()
1028
1246
 
 
1247
    def remove_option(self, option_name, section_name=None):
 
1248
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1249
        # higher levels providing the right lock -- vila 20101004
 
1250
        self.branch.lock_write()
 
1251
        try:
 
1252
            self._config.remove_option(option_name, section_name)
 
1253
        finally:
 
1254
            self.branch.unlock()
 
1255
 
1029
1256
 
1030
1257
class AuthenticationConfig(object):
1031
1258
    """The authentication configuration file based on a ini file.
1063
1290
        """Save the config file, only tests should use it for now."""
1064
1291
        conf_dir = os.path.dirname(self._filename)
1065
1292
        ensure_config_dir_exists(conf_dir)
1066
 
        self._get_config().write(file(self._filename, 'wb'))
 
1293
        f = file(self._filename, 'wb')
 
1294
        try:
 
1295
            self._get_config().write(f)
 
1296
        finally:
 
1297
            f.close()
1067
1298
 
1068
1299
    def _set_option(self, section_name, option_name, value):
1069
1300
        """Set an authentication configuration option"""
1470
1701
    """A Config that reads/writes a config file on a Transport.
1471
1702
 
1472
1703
    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.
 
1704
    that may be associated with a section.  Assigning meaning to these values
 
1705
    is done at higher levels like TreeConfig.
1475
1706
    """
1476
1707
 
1477
1708
    def __init__(self, transport, filename):
1510
1741
            configobj.setdefault(section, {})[name] = value
1511
1742
        self._set_configobj(configobj)
1512
1743
 
 
1744
    def remove_option(self, option_name, section_name=None):
 
1745
        configobj = self._get_configobj()
 
1746
        if section_name is None:
 
1747
            del configobj[option_name]
 
1748
        else:
 
1749
            del configobj[section_name][option_name]
 
1750
        self._set_configobj(configobj)
 
1751
 
1513
1752
    def _get_config_file(self):
1514
1753
        try:
1515
1754
            return StringIO(self._transport.get_bytes(self._filename))
1517
1756
            return StringIO()
1518
1757
 
1519
1758
    def _get_configobj(self):
1520
 
        return ConfigObj(self._get_config_file(), encoding='utf-8')
 
1759
        f = self._get_config_file()
 
1760
        try:
 
1761
            return ConfigObj(f, encoding='utf-8')
 
1762
        finally:
 
1763
            f.close()
1521
1764
 
1522
1765
    def _set_configobj(self, configobj):
1523
1766
        out_file = StringIO()
1524
1767
        configobj.write(out_file)
1525
1768
        out_file.seek(0)
1526
1769
        self._transport.put_file(self._filename, out_file)
 
1770
 
 
1771
 
 
1772
class cmd_config(commands.Command):
 
1773
    __doc__ = """Display, set or remove a configuration option.
 
1774
 
 
1775
    Display the active value for a given option.
 
1776
 
 
1777
    If --all is specified, NAME is interpreted as a regular expression and all
 
1778
    matching options are displayed mentioning their scope. The active value
 
1779
    that bzr will take into account is the first one displayed for each option.
 
1780
 
 
1781
    If no NAME is given, --all .* is implied.
 
1782
 
 
1783
    Setting a value is achieved by using name=value without spaces. The value
 
1784
    is set in the most relevant scope and can be checked by displaying the
 
1785
    option again.
 
1786
    """
 
1787
 
 
1788
    takes_args = ['name?']
 
1789
 
 
1790
    takes_options = [
 
1791
        'directory',
 
1792
        # FIXME: This should be a registry option so that plugins can register
 
1793
        # their own config files (or not) -- vila 20101002
 
1794
        commands.Option('scope', help='Reduce the scope to the specified'
 
1795
                        ' configuration file',
 
1796
                        type=unicode),
 
1797
        commands.Option('all',
 
1798
            help='Display all the defined values for the matching options.',
 
1799
            ),
 
1800
        commands.Option('remove', help='Remove the option from'
 
1801
                        ' the configuration file'),
 
1802
        ]
 
1803
 
 
1804
    @commands.display_command
 
1805
    def run(self, name=None, all=False, directory=None, scope=None,
 
1806
            remove=False):
 
1807
        if directory is None:
 
1808
            directory = '.'
 
1809
        directory = urlutils.normalize_url(directory)
 
1810
        if remove and all:
 
1811
            raise errors.BzrError(
 
1812
                '--all and --remove are mutually exclusive.')
 
1813
        elif remove:
 
1814
            # Delete the option in the given scope
 
1815
            self._remove_config_option(name, directory, scope)
 
1816
        elif name is None:
 
1817
            # Defaults to all options
 
1818
            self._show_matching_options('.*', directory, scope)
 
1819
        else:
 
1820
            try:
 
1821
                name, value = name.split('=', 1)
 
1822
            except ValueError:
 
1823
                # Display the option(s) value(s)
 
1824
                if all:
 
1825
                    self._show_matching_options(name, directory, scope)
 
1826
                else:
 
1827
                    self._show_value(name, directory, scope)
 
1828
            else:
 
1829
                if all:
 
1830
                    raise errors.BzrError(
 
1831
                        'Only one option can be set.')
 
1832
                # Set the option value
 
1833
                self._set_config_option(name, value, directory, scope)
 
1834
 
 
1835
    def _get_configs(self, directory, scope=None):
 
1836
        """Iterate the configurations specified by ``directory`` and ``scope``.
 
1837
 
 
1838
        :param directory: Where the configurations are derived from.
 
1839
 
 
1840
        :param scope: A specific config to start from.
 
1841
        """
 
1842
        if scope is not None:
 
1843
            if scope == 'bazaar':
 
1844
                yield GlobalConfig()
 
1845
            elif scope == 'locations':
 
1846
                yield LocationConfig(directory)
 
1847
            elif scope == 'branch':
 
1848
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1849
                    directory)
 
1850
                yield br.get_config()
 
1851
        else:
 
1852
            try:
 
1853
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1854
                    directory)
 
1855
                yield br.get_config()
 
1856
            except errors.NotBranchError:
 
1857
                yield LocationConfig(directory)
 
1858
                yield GlobalConfig()
 
1859
 
 
1860
    def _show_value(self, name, directory, scope):
 
1861
        displayed = False
 
1862
        for c in self._get_configs(directory, scope):
 
1863
            if displayed:
 
1864
                break
 
1865
            for (oname, value, section, conf_id) in c._get_options():
 
1866
                if name == oname:
 
1867
                    # Display only the first value and exit
 
1868
                    self.outf.write('%s\n' % (value))
 
1869
                    displayed = True
 
1870
                    break
 
1871
        if not displayed:
 
1872
            raise errors.NoSuchConfigOption(name)
 
1873
 
 
1874
    def _show_matching_options(self, name, directory, scope):
 
1875
        name = re.compile(name)
 
1876
        # We want any error in the regexp to be raised *now* so we need to
 
1877
        # avoid the delay introduced by the lazy regexp.
 
1878
        name._compile_and_collapse()
 
1879
        cur_conf_id = None
 
1880
        for c in self._get_configs(directory, scope):
 
1881
            for (oname, value, section, conf_id) in c._get_options():
 
1882
                if name.search(oname):
 
1883
                    if cur_conf_id != conf_id:
 
1884
                        # Explain where the options are defined
 
1885
                        self.outf.write('%s:\n' % (conf_id,))
 
1886
                        cur_conf_id = conf_id
 
1887
                    self.outf.write('  %s = %s\n' % (oname, value))
 
1888
 
 
1889
    def _set_config_option(self, name, value, directory, scope):
 
1890
        for conf in self._get_configs(directory, scope):
 
1891
            conf.set_user_option(name, value)
 
1892
            break
 
1893
        else:
 
1894
            raise errors.NoSuchConfig(scope)
 
1895
 
 
1896
    def _remove_config_option(self, name, directory, scope):
 
1897
        if name is None:
 
1898
            raise errors.BzrCommandError(
 
1899
                '--remove expects an option to remove.')
 
1900
        removed = False
 
1901
        for conf in self._get_configs(directory, scope):
 
1902
            for (section_name, section, conf_id) in conf._get_sections():
 
1903
                if scope is not None and conf_id != scope:
 
1904
                    # Not the right configuration file
 
1905
                    continue
 
1906
                if name in section:
 
1907
                    if conf_id != conf.config_id():
 
1908
                        conf = self._get_configs(directory, conf_id).next()
 
1909
                    # We use the first section in the first config where the
 
1910
                    # option is defined to remove it
 
1911
                    conf.remove_user_option(name, section_name)
 
1912
                    removed = True
 
1913
                    break
 
1914
            break
 
1915
        else:
 
1916
            raise errors.NoSuchConfig(scope)
 
1917
        if not removed:
 
1918
            raise errors.NoSuchConfigOption(name)