~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Vincent Ladeuil
  • Date: 2010-06-17 16:54:26 UTC
  • mto: This revision was merged to the branch mainline in revision 5306.
  • Revision ID: v.ladeuil+lp@free.fr-20100617165426-741tbmgwi62a9zub
Pass BZR_PLUGINS_AT and BZR_DISABLE_PLINGS to the subprocess fpr test_import_tariff

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
70
68
from bzrlib.lazy_import import lazy_import
71
69
lazy_import(globals(), """
72
70
import errno
73
 
import fnmatch
 
71
from fnmatch import fnmatch
74
72
import re
75
73
from cStringIO import StringIO
76
74
 
77
75
import bzrlib
78
76
from bzrlib import (
79
 
    atomicfile,
80
 
    bzrdir,
81
77
    debug,
82
78
    errors,
83
 
    lockdir,
84
79
    mail_client,
85
80
    osutils,
86
81
    registry,
87
82
    symbol_versioning,
88
83
    trace,
89
 
    transport,
90
84
    ui,
91
85
    urlutils,
92
86
    win32utils,
155
149
    def __init__(self):
156
150
        super(Config, self).__init__()
157
151
 
158
 
    def config_id(self):
159
 
        """Returns a unique ID for the config."""
160
 
        raise NotImplementedError(self.config_id)
161
 
 
162
152
    def get_editor(self):
163
153
        """Get the users pop up editor."""
164
154
        raise NotImplementedError
361
351
class IniBasedConfig(Config):
362
352
    """A configuration policy that draws from ini files."""
363
353
 
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
    def __init__(self, get_filename):
370
355
        super(IniBasedConfig, self).__init__()
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
        self._get_filename = get_filename
383
357
        self._parser = None
384
358
 
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
    def _get_parser(self, file=None):
408
360
        if self._parser is not None:
409
361
            return self._parser
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')
 
362
        if file is None:
 
363
            input = self._get_filename()
420
364
        else:
421
 
            co_input = self.file_name
 
365
            input = file
422
366
        try:
423
 
            self._parser = ConfigObj(co_input, encoding='utf-8')
 
367
            self._parser = ConfigObj(input, encoding='utf-8')
424
368
        except configobj.ConfigObjError, e:
425
369
            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
428
370
        return self._parser
429
371
 
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
 
 
437
372
    def _get_matching_sections(self):
438
373
        """Return an ordered list of (section_name, extra_path) pairs.
439
374
 
450
385
        """Override this to define the section used by the config."""
451
386
        return "DEFAULT"
452
387
 
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
 
 
501
388
    def _get_option_policy(self, section, option_name):
502
389
        """Return the policy for the given (section, option_name) pair."""
503
390
        return POLICY_NONE
590
477
    def _get_nickname(self):
591
478
        return self.get_user_option('nickname')
592
479
 
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]
 
480
    def _write_config_file(self):
 
481
        f = file(self._get_filename(), "wb")
607
482
        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):
 
483
            osutils.copy_ownership_from_path(f.name)
 
484
            self._get_parser().write(f)
 
485
        finally:
 
486
            f.close()
 
487
 
 
488
 
 
489
class GlobalConfig(IniBasedConfig):
695
490
    """The configuration that should be used for a specific location."""
696
491
 
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
 
 
716
492
    def get_editor(self):
717
493
        return self._get_user_option('editor')
718
494
 
719
 
    @needs_write_lock
 
495
    def __init__(self):
 
496
        super(GlobalConfig, self).__init__(config_filename)
 
497
 
720
498
    def set_user_option(self, option, value):
721
499
        """Save option and its value in the configuration."""
722
500
        self._set_option(option, value, 'DEFAULT')
728
506
        else:
729
507
            return {}
730
508
 
731
 
    @needs_write_lock
732
509
    def set_alias(self, alias_name, alias_command):
733
510
        """Save the alias in the configuration."""
734
511
        self._set_option(alias_name, alias_command, 'ALIASES')
735
512
 
736
 
    @needs_write_lock
737
513
    def unset_alias(self, alias_name):
738
514
        """Unset an existing alias."""
739
 
        self.reload()
740
515
        aliases = self._get_parser().get('ALIASES')
741
516
        if not aliases or alias_name not in aliases:
742
517
            raise errors.NoSuchAlias(alias_name)
744
519
        self._write_config_file()
745
520
 
746
521
    def _set_option(self, option, value, section):
747
 
        self.reload()
 
522
        # FIXME: RBC 20051029 This should refresh the parser and also take a
 
523
        # file lock on bazaar.conf.
 
524
        conf_dir = os.path.dirname(self._get_filename())
 
525
        ensure_config_dir_exists(conf_dir)
748
526
        self._get_parser().setdefault(section, {})[option] = value
749
527
        self._write_config_file()
750
528
 
751
529
 
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):
 
530
class LocationConfig(IniBasedConfig):
777
531
    """A configuration object that gives the policy for a location."""
778
532
 
779
533
    def __init__(self, location):
780
 
        super(LocationConfig, self).__init__(
781
 
            file_name=locations_config_filename())
 
534
        name_generator = locations_config_filename
 
535
        if (not os.path.exists(name_generator()) and
 
536
                os.path.exists(branches_config_filename())):
 
537
            if sys.platform == 'win32':
 
538
                trace.warning('Please rename %s to %s'
 
539
                              % (branches_config_filename(),
 
540
                                 locations_config_filename()))
 
541
            else:
 
542
                trace.warning('Please rename ~/.bazaar/branches.conf'
 
543
                              ' to ~/.bazaar/locations.conf')
 
544
            name_generator = branches_config_filename
 
545
        super(LocationConfig, self).__init__(name_generator)
782
546
        # local file locations are looked up by local path, rather than
783
547
        # by file url. This is because the config file is a user
784
548
        # file, and we would rather not expose the user to file urls.
786
550
            location = urlutils.local_path_from_url(location)
787
551
        self.location = location
788
552
 
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
 
 
807
553
    def _get_matching_sections(self):
808
554
        """Return an ordered list of section names matching this location."""
809
555
        sections = self._get_parser()
826
572
            names = zip(location_names, section_names)
827
573
            matched = True
828
574
            for name in names:
829
 
                if not fnmatch.fnmatch(name[0], name[1]):
 
575
                if not fnmatch(name[0], name[1]):
830
576
                    matched = False
831
577
                    break
832
578
            if not matched:
837
583
                continue
838
584
            matches.append((len(section_names), section,
839
585
                            '/'.join(location_names[len(section_names):])))
840
 
        # put the longest (aka more specific) locations first
841
586
        matches.sort(reverse=True)
842
587
        sections = []
843
588
        for (length, section, extra_path) in matches:
850
595
                pass
851
596
        return sections
852
597
 
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
 
 
861
598
    def _get_option_policy(self, section, option_name):
862
599
        """Return the policy for the given (section, option_name) pair."""
863
600
        # check for the old 'recurse=False' flag
906
643
            if policy_key in self._get_parser()[section]:
907
644
                del self._get_parser()[section][policy_key]
908
645
 
909
 
    @needs_write_lock
910
646
    def set_user_option(self, option, value, store=STORE_LOCATION):
911
647
        """Save option and its value in the configuration."""
912
648
        if store not in [STORE_LOCATION,
914
650
                         STORE_LOCATION_APPENDPATH]:
915
651
            raise ValueError('bad storage policy %r for %r' %
916
652
                (store, option))
917
 
        self.reload()
 
653
        # FIXME: RBC 20051029 This should refresh the parser and also take a
 
654
        # file lock on locations.conf.
 
655
        conf_dir = os.path.dirname(self._get_filename())
 
656
        ensure_config_dir_exists(conf_dir)
918
657
        location = self.location
919
658
        if location.endswith('/'):
920
659
            location = location[:-1]
921
 
        parser = self._get_parser()
922
 
        if not location in parser and not location + '/' in parser:
923
 
            parser[location] = {}
924
 
        elif location + '/' in parser:
 
660
        if (not location in self._get_parser() and
 
661
            not location + '/' in self._get_parser()):
 
662
            self._get_parser()[location]={}
 
663
        elif location + '/' in self._get_parser():
925
664
            location = location + '/'
926
 
        parser[location][option]=value
 
665
        self._get_parser()[location][option]=value
927
666
        # the allowed values of store match the config policies
928
667
        self._set_option_policy(location, option, store)
929
668
        self._write_config_file()
932
671
class BranchConfig(Config):
933
672
    """A configuration object giving the policy for a branch."""
934
673
 
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
 
 
948
674
    def _get_branch_data_config(self):
949
675
        if self._branch_data_config is None:
950
676
            self._branch_data_config = TreeConfig(self.branch)
951
 
            self._branch_data_config.config_id = self.config_id
952
677
        return self._branch_data_config
953
678
 
954
679
    def _get_location_config(self):
1022
747
                return value
1023
748
        return None
1024
749
 
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
 
 
1050
750
    def set_user_option(self, name, value, store=STORE_BRANCH,
1051
751
        warn_masked=False):
1052
752
        if store == STORE_BRANCH:
1070
770
                        trace.warning('Value "%s" is masked by "%s" from'
1071
771
                                      ' branch.conf', value, mask_value)
1072
772
 
1073
 
    def remove_user_option(self, option_name, section_name=None):
1074
 
        self._get_branch_data_config().remove_option(option_name, section_name)
1075
 
 
1076
773
    def _gpg_signing_command(self):
1077
774
        """See Config.gpg_signing_command."""
1078
775
        return self._get_safe_value('_gpg_signing_command')
1079
776
 
 
777
    def __init__(self, branch):
 
778
        super(BranchConfig, self).__init__()
 
779
        self._location_config = None
 
780
        self._branch_data_config = None
 
781
        self._global_config = None
 
782
        self.branch = branch
 
783
        self.option_sources = (self._get_location_config,
 
784
                               self._get_branch_data_config,
 
785
                               self._get_global_config)
 
786
 
1080
787
    def _post_commit(self):
1081
788
        """See Config.post_commit."""
1082
789
        return self._get_safe_value('_post_commit')
1112
819
            parent_dir = os.path.dirname(path)
1113
820
            if not os.path.isdir(parent_dir):
1114
821
                trace.mutter('creating config parent directory: %r', parent_dir)
1115
 
                os.mkdir(parent_dir)
 
822
            os.mkdir(parent_dir)
1116
823
        trace.mutter('creating config directory: %r', path)
1117
824
        os.mkdir(path)
1118
825
        osutils.copy_ownership_from_path(path)
1146
853
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
1147
854
 
1148
855
 
 
856
def branches_config_filename():
 
857
    """Return per-user configuration ini file filename."""
 
858
    return osutils.pathjoin(config_dir(), 'branches.conf')
 
859
 
 
860
 
1149
861
def locations_config_filename():
1150
862
    """Return per-user configuration ini file filename."""
1151
863
    return osutils.pathjoin(config_dir(), 'locations.conf')
1236
948
 
1237
949
    def set_option(self, value, name, section=None):
1238
950
        """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
1241
951
        self.branch.lock_write()
1242
952
        try:
1243
953
            self._config.set_option(value, name, section)
1244
954
        finally:
1245
955
            self.branch.unlock()
1246
956
 
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
 
 
1256
957
 
1257
958
class AuthenticationConfig(object):
1258
959
    """The authentication configuration file based on a ini file.
1701
1402
    """A Config that reads/writes a config file on a Transport.
1702
1403
 
1703
1404
    It is a low-level object that considers config data to be name/value pairs
1704
 
    that may be associated with a section.  Assigning meaning to these values
1705
 
    is done at higher levels like TreeConfig.
 
1405
    that may be associated with a section.  Assigning meaning to the these
 
1406
    values is done at higher levels like TreeConfig.
1706
1407
    """
1707
1408
 
1708
1409
    def __init__(self, transport, filename):
1741
1442
            configobj.setdefault(section, {})[name] = value
1742
1443
        self._set_configobj(configobj)
1743
1444
 
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
 
 
1752
1445
    def _get_config_file(self):
1753
1446
        try:
1754
1447
            return StringIO(self._transport.get_bytes(self._filename))
1767
1460
        configobj.write(out_file)
1768
1461
        out_file.seek(0)
1769
1462
        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 MATCHING configuration options mentioning their scope (the
1776
 
    configuration file they are defined in). The active value that bzr will
1777
 
    take into account is the first one displayed.
1778
 
 
1779
 
    Setting a value is achieved by using name=value without spaces. The value
1780
 
    is set in the most relevant scope and can be checked by displaying the
1781
 
    option again.
1782
 
    """
1783
 
 
1784
 
    aliases = ['conf']
1785
 
    takes_args = ['matching?']
1786
 
 
1787
 
    takes_options = [
1788
 
        'directory',
1789
 
        # FIXME: This should be a registry option so that plugins can register
1790
 
        # their own config files (or not) -- vila 20101002
1791
 
        commands.Option('scope', help='Reduce the scope to the specified'
1792
 
                        ' configuration file',
1793
 
                        type=unicode),
1794
 
        commands.Option('remove', help='Remove the option from'
1795
 
                        ' the configuration file'),
1796
 
        ]
1797
 
 
1798
 
    @commands.display_command
1799
 
    def run(self, matching=None, directory=None, scope=None, remove=False):
1800
 
        if directory is None:
1801
 
            directory = '.'
1802
 
        directory = urlutils.normalize_url(directory)
1803
 
        if matching is None:
1804
 
            self._show_config('*', directory)
1805
 
        else:
1806
 
            if remove:
1807
 
                self._remove_config_option(matching, directory, scope)
1808
 
            else:
1809
 
                pos = matching.find('=')
1810
 
                if pos == -1:
1811
 
                    self._show_config(matching, directory)
1812
 
                else:
1813
 
                    self._set_config_option(matching[:pos], matching[pos+1:],
1814
 
                                            directory, scope)
1815
 
 
1816
 
    def _get_configs(self, directory, scope=None):
1817
 
        """Iterate the configurations specified by ``directory`` and ``scope``.
1818
 
 
1819
 
        :param directory: Where the configurations are derived from.
1820
 
 
1821
 
        :param scope: A specific config to start from.
1822
 
        """
1823
 
        if scope is not None:
1824
 
            if scope == 'bazaar':
1825
 
                yield GlobalConfig()
1826
 
            elif scope == 'locations':
1827
 
                yield LocationConfig(directory)
1828
 
            elif scope == 'branch':
1829
 
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
1830
 
                    directory)
1831
 
                yield br.get_config()
1832
 
        else:
1833
 
            try:
1834
 
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
1835
 
                    directory)
1836
 
                yield br.get_config()
1837
 
            except errors.NotBranchError:
1838
 
                yield LocationConfig(directory)
1839
 
                yield GlobalConfig()
1840
 
 
1841
 
    def _show_config(self, matching, directory):
1842
 
        # Turn the glob into a regexp
1843
 
        matching_re = re.compile(fnmatch.translate(matching))
1844
 
        cur_conf_id = None
1845
 
        for c in self._get_configs(directory):
1846
 
            for (name, value, section, conf_id) in c._get_options():
1847
 
                if matching_re.search(name):
1848
 
                    if cur_conf_id != conf_id:
1849
 
                        self.outf.write('%s:\n' % (conf_id,))
1850
 
                        cur_conf_id = conf_id
1851
 
                    self.outf.write('  %s = %s\n' % (name, value))
1852
 
 
1853
 
    def _set_config_option(self, name, value, directory, scope):
1854
 
        for conf in self._get_configs(directory, scope):
1855
 
            conf.set_user_option(name, value)
1856
 
            break
1857
 
        else:
1858
 
            raise errors.NoSuchConfig(scope)
1859
 
 
1860
 
    def _remove_config_option(self, name, directory, scope):
1861
 
        removed = False
1862
 
        for conf in self._get_configs(directory, scope):
1863
 
            for (section_name, section, conf_id) in conf._get_sections():
1864
 
                if scope is not None and conf_id != scope:
1865
 
                    # Not the right configuration file
1866
 
                    continue
1867
 
                if name in section:
1868
 
                    if conf_id != conf.config_id():
1869
 
                        conf = self._get_configs(directory, conf_id).next()
1870
 
                    # We use the first section in the first config where the
1871
 
                    # option is defined to remove it
1872
 
                    conf.remove_user_option(name, section_name)
1873
 
                    removed = True
1874
 
                    break
1875
 
            break
1876
 
        else:
1877
 
            raise errors.NoSuchConfig(scope)
1878
 
        if not removed:
1879
 
            raise errors.NoSuchConfigOption(name)