/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: 2010-12-06 14:01:44 UTC
  • mto: (5321.1.101 mergetools)
  • mto: This revision was merged to the branch mainline in revision 5632.
  • Revision ID: v.ladeuil+lp@free.fr-20101206140144-yz3cp2paek953gp4
More cleanup.

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,
 
85
    mergetools,
80
86
    osutils,
81
87
    registry,
82
88
    symbol_versioning,
83
89
    trace,
 
90
    transport,
84
91
    ui,
85
92
    urlutils,
86
93
    win32utils,
149
156
    def __init__(self):
150
157
        super(Config, self).__init__()
151
158
 
 
159
    def config_id(self):
 
160
        """Returns a unique ID for the config."""
 
161
        raise NotImplementedError(self.config_id)
 
162
 
152
163
    def get_editor(self):
153
164
        """Get the users pop up editor."""
154
165
        raise NotImplementedError
257
268
 
258
269
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
259
270
 
260
 
        $BZR_EMAIL can be set to override this (as well as the
261
 
        deprecated $BZREMAIL), then
 
271
        $BZR_EMAIL can be set to override this, then
262
272
        the concrete policy type is checked, and finally
263
273
        $EMAIL is examined.
264
 
        If none is found, a reasonable default is (hopefully)
265
 
        created.
 
274
        If no username can be found, errors.NoWhoami exception is raised.
266
275
 
267
276
        TODO: Check it's reasonably well-formed.
268
277
        """
278
287
        if v:
279
288
            return v.decode(osutils.get_user_encoding())
280
289
 
281
 
        name, email = _auto_user_id()
282
 
        if name:
283
 
            return '%s <%s>' % (name, email)
284
 
        else:
285
 
            return email
 
290
        raise errors.NoWhoami()
 
291
 
 
292
    def ensure_username(self):
 
293
        """Raise errors.NoWhoami if username is not set.
 
294
 
 
295
        This method relies on the username() function raising the error.
 
296
        """
 
297
        self.username()
286
298
 
287
299
    def signature_checking(self):
288
300
        """What is the current policy for signature checking?."""
346
358
        else:
347
359
            return True
348
360
 
 
361
    def get_merge_tools(self):
 
362
        tools = []
 
363
        for (oname, value, section, conf_id, parser) in self._get_options():
 
364
            if oname.startswith('bzr.mergetool.'):
 
365
                tools.append(mergetools.MergeTool(oname[len('bzr.mergetool.'):],
 
366
                                                  value))
 
367
        trace.mutter('loaded merge tools: %r' % tools)
 
368
        return tools
 
369
 
 
370
    def set_merge_tools(self, tools):
 
371
        # remove entries from config for tools which do not appear in
 
372
        # merge_tools
 
373
        tool_names = [tool.name for tool in tools]
 
374
        for (oname, value, section, conf_id, parser) in self._get_options():
 
375
            if oname.startswith('bzr.mergetool.'):
 
376
                if oname[len('bzr.mergetool.'):] not in tool_names:
 
377
                    self.remove_user_option(oname)
 
378
        # set config entries
 
379
        for tool in tools:
 
380
            oname = 'bzr.mergetool.%s' % tool.name
 
381
            value = tool.command_line
 
382
            if oname == '' or value == '':
 
383
                continue
 
384
            self.set_user_option(oname, value)
 
385
 
 
386
    def _find_merge_tool(self, name):
 
387
        commandline = self.get_user_option('bzr.mergetool.%s' % name)
 
388
        if commandline is None:
 
389
            return None
 
390
        return mergetools.MergeTool(name, commandline)
 
391
 
 
392
    def get_default_merge_tool(self):
 
393
        name = self.get_user_option('bzr.default_mergetool')
 
394
        if name is None:
 
395
            trace.mutter('no default merge tool defined')
 
396
            return None
 
397
        tool = self._find_merge_tool(name)
 
398
        trace.mutter('found default merge tool: %r', tool)
 
399
        return tool
 
400
 
 
401
    def set_default_merge_tool(self, name):
 
402
        if name is None:
 
403
            self.remove_user_option('bzr.default_mergetool')
 
404
        else:
 
405
            if isinstance(name, mergetools.MergeTool):
 
406
                name = name.get_name()
 
407
            if self._find_merge_tool(name) is None:
 
408
                raise errors.BzrError('invalid merge tool name: %r' % name)
 
409
            trace.mutter('setting default merge tool: %s', name)
 
410
            self.set_user_option('bzr.default_mergetool', name)
 
411
 
349
412
 
350
413
class IniBasedConfig(Config):
351
414
    """A configuration policy that draws from ini files."""
352
415
 
353
 
    def __init__(self, get_filename):
 
416
    def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
 
417
                 file_name=None):
 
418
        """Base class for configuration files using an ini-like syntax.
 
419
 
 
420
        :param file_name: The configuration file path.
 
421
        """
354
422
        super(IniBasedConfig, self).__init__()
355
 
        self._get_filename = get_filename
 
423
        self.file_name = file_name
 
424
        if symbol_versioning.deprecated_passed(get_filename):
 
425
            symbol_versioning.warn(
 
426
                'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
 
427
                ' Use file_name instead.',
 
428
                DeprecationWarning,
 
429
                stacklevel=2)
 
430
            if get_filename is not None:
 
431
                self.file_name = get_filename()
 
432
        else:
 
433
            self.file_name = file_name
 
434
        self._content = None
356
435
        self._parser = None
357
436
 
358
 
    def _get_parser(self, file=None):
 
437
    @classmethod
 
438
    def from_string(cls, str_or_unicode, file_name=None, save=False):
 
439
        """Create a config object from a string.
 
440
 
 
441
        :param str_or_unicode: A string representing the file content. This will
 
442
            be utf-8 encoded.
 
443
 
 
444
        :param file_name: The configuration file path.
 
445
 
 
446
        :param _save: Whether the file should be saved upon creation.
 
447
        """
 
448
        conf = cls(file_name=file_name)
 
449
        conf._create_from_string(str_or_unicode, save)
 
450
        return conf
 
451
 
 
452
    def _create_from_string(self, str_or_unicode, save):
 
453
        self._content = StringIO(str_or_unicode.encode('utf-8'))
 
454
        # Some tests use in-memory configs, some other always need the config
 
455
        # file to exist on disk.
 
456
        if save:
 
457
            self._write_config_file()
 
458
 
 
459
    def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
359
460
        if self._parser is not None:
360
461
            return self._parser
361
 
        if file is None:
362
 
            input = self._get_filename()
 
462
        if symbol_versioning.deprecated_passed(file):
 
463
            symbol_versioning.warn(
 
464
                'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
 
465
                ' Use IniBasedConfig(_content=xxx) instead.',
 
466
                DeprecationWarning,
 
467
                stacklevel=2)
 
468
        if self._content is not None:
 
469
            co_input = self._content
 
470
        elif self.file_name is None:
 
471
            raise AssertionError('We have no content to create the config')
363
472
        else:
364
 
            input = file
 
473
            co_input = self.file_name
365
474
        try:
366
 
            self._parser = ConfigObj(input, encoding='utf-8')
 
475
            self._parser = ConfigObj(co_input, encoding='utf-8')
367
476
        except configobj.ConfigObjError, e:
368
477
            raise errors.ParseConfigError(e.errors, e.config.filename)
 
478
        # Make sure self.reload() will use the right file name
 
479
        self._parser.filename = self.file_name
369
480
        return self._parser
370
481
 
 
482
    def reload(self):
 
483
        """Reload the config file from disk."""
 
484
        if self.file_name is None:
 
485
            raise AssertionError('We need a file name to reload the config')
 
486
        if self._parser is not None:
 
487
            self._parser.reload()
 
488
 
371
489
    def _get_matching_sections(self):
372
490
        """Return an ordered list of (section_name, extra_path) pairs.
373
491
 
384
502
        """Override this to define the section used by the config."""
385
503
        return "DEFAULT"
386
504
 
 
505
    def _get_sections(self, name=None):
 
506
        """Returns an iterator of the sections specified by ``name``.
 
507
 
 
508
        :param name: The section name. If None is supplied, the default
 
509
            configurations are yielded.
 
510
 
 
511
        :return: A tuple (name, section, config_id) for all sections that will
 
512
            be walked by user_get_option() in the 'right' order. The first one
 
513
            is where set_user_option() will update the value.
 
514
        """
 
515
        parser = self._get_parser()
 
516
        if name is not None:
 
517
            yield (name, parser[name], self.config_id())
 
518
        else:
 
519
            # No section name has been given so we fallback to the configobj
 
520
            # itself which holds the variables defined outside of any section.
 
521
            yield (None, parser, self.config_id())
 
522
 
 
523
    def _get_options(self, sections=None):
 
524
        """Return an ordered list of (name, value, section, config_id) tuples.
 
525
 
 
526
        All options are returned with their associated value and the section
 
527
        they appeared in. ``config_id`` is a unique identifier for the
 
528
        configuration file the option is defined in.
 
529
 
 
530
        :param sections: Default to ``_get_matching_sections`` if not
 
531
            specified. This gives a better control to daughter classes about
 
532
            which sections should be searched. This is a list of (name,
 
533
            configobj) tuples.
 
534
        """
 
535
        opts = []
 
536
        if sections is None:
 
537
            parser = self._get_parser()
 
538
            sections = []
 
539
            for (section_name, _) in self._get_matching_sections():
 
540
                try:
 
541
                    section = parser[section_name]
 
542
                except KeyError:
 
543
                    # This could happen for an empty file for which we define a
 
544
                    # DEFAULT section. FIXME: Force callers to provide sections
 
545
                    # instead ? -- vila 20100930
 
546
                    continue
 
547
                sections.append((section_name, section))
 
548
        config_id = self.config_id()
 
549
        for (section_name, section) in sections:
 
550
            for (name, value) in section.iteritems():
 
551
                yield (name, parser._quote(value), section_name,
 
552
                       config_id, parser)
 
553
 
387
554
    def _get_option_policy(self, section, option_name):
388
555
        """Return the policy for the given (section, option_name) pair."""
389
556
        return POLICY_NONE
476
643
    def _get_nickname(self):
477
644
        return self.get_user_option('nickname')
478
645
 
479
 
 
480
 
class GlobalConfig(IniBasedConfig):
 
646
    def remove_user_option(self, option_name, section_name=None):
 
647
        """Remove a user option and save the configuration file.
 
648
 
 
649
        :param option_name: The option to be removed.
 
650
 
 
651
        :param section_name: The section the option is defined in, default to
 
652
            the default section.
 
653
        """
 
654
        self.reload()
 
655
        parser = self._get_parser()
 
656
        if section_name is None:
 
657
            section = parser
 
658
        else:
 
659
            section = parser[section_name]
 
660
        try:
 
661
            del section[option_name]
 
662
        except KeyError:
 
663
            raise errors.NoSuchConfigOption(option_name)
 
664
        self._write_config_file()
 
665
 
 
666
    def _write_config_file(self):
 
667
        if self.file_name is None:
 
668
            raise AssertionError('We cannot save, self.file_name is None')
 
669
        conf_dir = os.path.dirname(self.file_name)
 
670
        ensure_config_dir_exists(conf_dir)
 
671
        atomic_file = atomicfile.AtomicFile(self.file_name)
 
672
        self._get_parser().write(atomic_file)
 
673
        atomic_file.commit()
 
674
        atomic_file.close()
 
675
        osutils.copy_ownership_from_path(self.file_name)
 
676
 
 
677
 
 
678
class LockableConfig(IniBasedConfig):
 
679
    """A configuration needing explicit locking for access.
 
680
 
 
681
    If several processes try to write the config file, the accesses need to be
 
682
    serialized.
 
683
 
 
684
    Daughter classes should decorate all methods that update a config with the
 
685
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
 
686
    ``_write_config_file()`` method. These methods (typically ``set_option()``
 
687
    and variants must reload the config file from disk before calling
 
688
    ``_write_config_file()``), this can be achieved by calling the
 
689
    ``self.reload()`` method. Note that the lock scope should cover both the
 
690
    reading and the writing of the config file which is why the decorator can't
 
691
    be applied to ``_write_config_file()`` only.
 
692
 
 
693
    This should be enough to implement the following logic:
 
694
    - lock for exclusive write access,
 
695
    - reload the config file from disk,
 
696
    - set the new value
 
697
    - unlock
 
698
 
 
699
    This logic guarantees that a writer can update a value without erasing an
 
700
    update made by another writer.
 
701
    """
 
702
 
 
703
    lock_name = 'lock'
 
704
 
 
705
    def __init__(self, file_name):
 
706
        super(LockableConfig, self).__init__(file_name=file_name)
 
707
        self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
 
708
        self.transport = transport.get_transport(self.dir)
 
709
        self._lock = lockdir.LockDir(self.transport, 'lock')
 
710
 
 
711
    def _create_from_string(self, unicode_bytes, save):
 
712
        super(LockableConfig, self)._create_from_string(unicode_bytes, False)
 
713
        if save:
 
714
            # We need to handle the saving here (as opposed to IniBasedConfig)
 
715
            # to be able to lock
 
716
            self.lock_write()
 
717
            self._write_config_file()
 
718
            self.unlock()
 
719
 
 
720
    def lock_write(self, token=None):
 
721
        """Takes a write lock in the directory containing the config file.
 
722
 
 
723
        If the directory doesn't exist it is created.
 
724
        """
 
725
        ensure_config_dir_exists(self.dir)
 
726
        return self._lock.lock_write(token)
 
727
 
 
728
    def unlock(self):
 
729
        self._lock.unlock()
 
730
 
 
731
    def break_lock(self):
 
732
        self._lock.break_lock()
 
733
 
 
734
    @needs_write_lock
 
735
    def remove_user_option(self, option_name, section_name=None):
 
736
        super(LockableConfig, self).remove_user_option(option_name,
 
737
                                                       section_name)
 
738
 
 
739
    def _write_config_file(self):
 
740
        if self._lock is None or not self._lock.is_held:
 
741
            # NB: if the following exception is raised it probably means a
 
742
            # missing @needs_write_lock decorator on one of the callers.
 
743
            raise errors.ObjectNotLocked(self)
 
744
        super(LockableConfig, self)._write_config_file()
 
745
 
 
746
 
 
747
class GlobalConfig(LockableConfig):
481
748
    """The configuration that should be used for a specific location."""
482
749
 
 
750
    def __init__(self):
 
751
        super(GlobalConfig, self).__init__(file_name=config_filename())
 
752
 
 
753
    def config_id(self):
 
754
        return 'bazaar'
 
755
 
 
756
    @classmethod
 
757
    def from_string(cls, str_or_unicode, save=False):
 
758
        """Create a config object from a string.
 
759
 
 
760
        :param str_or_unicode: A string representing the file content. This
 
761
            will be utf-8 encoded.
 
762
 
 
763
        :param save: Whether the file should be saved upon creation.
 
764
        """
 
765
        conf = cls()
 
766
        conf._create_from_string(str_or_unicode, save)
 
767
        return conf
 
768
 
483
769
    def get_editor(self):
484
770
        return self._get_user_option('editor')
485
771
 
486
 
    def __init__(self):
487
 
        super(GlobalConfig, self).__init__(config_filename)
488
 
 
 
772
    @needs_write_lock
489
773
    def set_user_option(self, option, value):
490
774
        """Save option and its value in the configuration."""
491
775
        self._set_option(option, value, 'DEFAULT')
497
781
        else:
498
782
            return {}
499
783
 
 
784
    @needs_write_lock
500
785
    def set_alias(self, alias_name, alias_command):
501
786
        """Save the alias in the configuration."""
502
787
        self._set_option(alias_name, alias_command, 'ALIASES')
503
788
 
 
789
    @needs_write_lock
504
790
    def unset_alias(self, alias_name):
505
791
        """Unset an existing alias."""
 
792
        self.reload()
506
793
        aliases = self._get_parser().get('ALIASES')
507
794
        if not aliases or alias_name not in aliases:
508
795
            raise errors.NoSuchAlias(alias_name)
510
797
        self._write_config_file()
511
798
 
512
799
    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)
 
800
        self.reload()
517
801
        self._get_parser().setdefault(section, {})[option] = value
518
802
        self._write_config_file()
519
803
 
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):
 
804
 
 
805
    def _get_sections(self, name=None):
 
806
        """See IniBasedConfig._get_sections()."""
 
807
        parser = self._get_parser()
 
808
        # We don't give access to options defined outside of any section, we
 
809
        # used the DEFAULT section by... default.
 
810
        if name in (None, 'DEFAULT'):
 
811
            # This could happen for an empty file where the DEFAULT section
 
812
            # doesn't exist yet. So we force DEFAULT when yielding
 
813
            name = 'DEFAULT'
 
814
            if 'DEFAULT' not in parser:
 
815
               parser['DEFAULT']= {}
 
816
        yield (name, parser[name], self.config_id())
 
817
 
 
818
    @needs_write_lock
 
819
    def remove_user_option(self, option_name, section_name=None):
 
820
        if section_name is None:
 
821
            # We need to force the default section.
 
822
            section_name = 'DEFAULT'
 
823
        # We need to avoid the LockableConfig implementation or we'll lock
 
824
        # twice
 
825
        super(LockableConfig, self).remove_user_option(option_name,
 
826
                                                       section_name)
 
827
 
 
828
 
 
829
class LocationConfig(LockableConfig):
529
830
    """A configuration object that gives the policy for a location."""
530
831
 
531
832
    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)
 
833
        super(LocationConfig, self).__init__(
 
834
            file_name=locations_config_filename())
544
835
        # local file locations are looked up by local path, rather than
545
836
        # by file url. This is because the config file is a user
546
837
        # file, and we would rather not expose the user to file urls.
548
839
            location = urlutils.local_path_from_url(location)
549
840
        self.location = location
550
841
 
 
842
    def config_id(self):
 
843
        return 'locations'
 
844
 
 
845
    @classmethod
 
846
    def from_string(cls, str_or_unicode, location, save=False):
 
847
        """Create a config object from a string.
 
848
 
 
849
        :param str_or_unicode: A string representing the file content. This will
 
850
            be utf-8 encoded.
 
851
 
 
852
        :param location: The location url to filter the configuration.
 
853
 
 
854
        :param save: Whether the file should be saved upon creation.
 
855
        """
 
856
        conf = cls(location)
 
857
        conf._create_from_string(str_or_unicode, save)
 
858
        return conf
 
859
 
551
860
    def _get_matching_sections(self):
552
861
        """Return an ordered list of section names matching this location."""
553
862
        sections = self._get_parser()
570
879
            names = zip(location_names, section_names)
571
880
            matched = True
572
881
            for name in names:
573
 
                if not fnmatch(name[0], name[1]):
 
882
                if not fnmatch.fnmatch(name[0], name[1]):
574
883
                    matched = False
575
884
                    break
576
885
            if not matched:
581
890
                continue
582
891
            matches.append((len(section_names), section,
583
892
                            '/'.join(location_names[len(section_names):])))
 
893
        # put the longest (aka more specific) locations first
584
894
        matches.sort(reverse=True)
585
895
        sections = []
586
896
        for (length, section, extra_path) in matches:
593
903
                pass
594
904
        return sections
595
905
 
 
906
    def _get_sections(self, name=None):
 
907
        """See IniBasedConfig._get_sections()."""
 
908
        # We ignore the name here as the only sections handled are named with
 
909
        # the location path and we don't expose embedded sections either.
 
910
        parser = self._get_parser()
 
911
        for name, extra_path in self._get_matching_sections():
 
912
            yield (name, parser[name], self.config_id())
 
913
 
596
914
    def _get_option_policy(self, section, option_name):
597
915
        """Return the policy for the given (section, option_name) pair."""
598
916
        # check for the old 'recurse=False' flag
641
959
            if policy_key in self._get_parser()[section]:
642
960
                del self._get_parser()[section][policy_key]
643
961
 
 
962
    @needs_write_lock
644
963
    def set_user_option(self, option, value, store=STORE_LOCATION):
645
964
        """Save option and its value in the configuration."""
646
965
        if store not in [STORE_LOCATION,
648
967
                         STORE_LOCATION_APPENDPATH]:
649
968
            raise ValueError('bad storage policy %r for %r' %
650
969
                (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)
 
970
        self.reload()
655
971
        location = self.location
656
972
        if location.endswith('/'):
657
973
            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():
 
974
        parser = self._get_parser()
 
975
        if not location in parser and not location + '/' in parser:
 
976
            parser[location] = {}
 
977
        elif location + '/' in parser:
662
978
            location = location + '/'
663
 
        self._get_parser()[location][option]=value
 
979
        parser[location][option]=value
664
980
        # the allowed values of store match the config policies
665
981
        self._set_option_policy(location, option, store)
666
 
        self._get_parser().write(file(self._get_filename(), 'wb'))
 
982
        self._write_config_file()
667
983
 
668
984
 
669
985
class BranchConfig(Config):
670
986
    """A configuration object giving the policy for a branch."""
671
987
 
 
988
    def __init__(self, branch):
 
989
        super(BranchConfig, self).__init__()
 
990
        self._location_config = None
 
991
        self._branch_data_config = None
 
992
        self._global_config = None
 
993
        self.branch = branch
 
994
        self.option_sources = (self._get_location_config,
 
995
                               self._get_branch_data_config,
 
996
                               self._get_global_config)
 
997
 
 
998
    def config_id(self):
 
999
        return 'branch'
 
1000
 
672
1001
    def _get_branch_data_config(self):
673
1002
        if self._branch_data_config is None:
674
1003
            self._branch_data_config = TreeConfig(self.branch)
 
1004
            self._branch_data_config.config_id = self.config_id
675
1005
        return self._branch_data_config
676
1006
 
677
1007
    def _get_location_config(self):
745
1075
                return value
746
1076
        return None
747
1077
 
 
1078
    def _get_sections(self, name=None):
 
1079
        """See IniBasedConfig.get_sections()."""
 
1080
        for source in self.option_sources:
 
1081
            for section in source()._get_sections(name):
 
1082
                yield section
 
1083
 
 
1084
    def _get_options(self, sections=None):
 
1085
        opts = []
 
1086
        # First the locations options
 
1087
        for option in self._get_location_config()._get_options():
 
1088
            yield option
 
1089
        # Then the branch options
 
1090
        branch_config = self._get_branch_data_config()
 
1091
        if sections is None:
 
1092
            sections = [('DEFAULT', branch_config._get_parser())]
 
1093
        # FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
 
1094
        # Config itself has no notion of sections :( -- vila 20101001
 
1095
        config_id = self.config_id()
 
1096
        for (section_name, section) in sections:
 
1097
            for (name, value) in section.iteritems():
 
1098
                yield (name, value, section_name,
 
1099
                       config_id, branch_config._get_parser())
 
1100
        # Then the global options
 
1101
        for option in self._get_global_config()._get_options():
 
1102
            yield option
 
1103
 
748
1104
    def set_user_option(self, name, value, store=STORE_BRANCH,
749
1105
        warn_masked=False):
750
1106
        if store == STORE_BRANCH:
768
1124
                        trace.warning('Value "%s" is masked by "%s" from'
769
1125
                                      ' branch.conf', value, mask_value)
770
1126
 
 
1127
    def remove_user_option(self, option_name, section_name=None):
 
1128
        self._get_branch_data_config().remove_option(option_name, section_name)
 
1129
 
771
1130
    def _gpg_signing_command(self):
772
1131
        """See Config.gpg_signing_command."""
773
1132
        return self._get_safe_value('_gpg_signing_command')
774
1133
 
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
1134
    def _post_commit(self):
786
1135
        """See Config.post_commit."""
787
1136
        return self._get_safe_value('_post_commit')
817
1166
            parent_dir = os.path.dirname(path)
818
1167
            if not os.path.isdir(parent_dir):
819
1168
                trace.mutter('creating config parent directory: %r', parent_dir)
820
 
            os.mkdir(parent_dir)
 
1169
                os.mkdir(parent_dir)
821
1170
        trace.mutter('creating config directory: %r', path)
822
1171
        os.mkdir(path)
823
1172
        osutils.copy_ownership_from_path(path)
826
1175
def config_dir():
827
1176
    """Return per-user configuration directory.
828
1177
 
829
 
    By default this is ~/.bazaar/
 
1178
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
 
1179
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
 
1180
    that will be used instead.
830
1181
 
831
1182
    TODO: Global option --config-dir to override this.
832
1183
    """
840
1191
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
841
1192
                                  ' or HOME set')
842
1193
        return osutils.pathjoin(base, 'bazaar', '2.0')
 
1194
    elif sys.platform == 'darwin':
 
1195
        if base is None:
 
1196
            # this takes into account $HOME
 
1197
            base = os.path.expanduser("~")
 
1198
        return osutils.pathjoin(base, '.bazaar')
843
1199
    else:
844
 
        # cygwin, linux, and darwin all have a $HOME directory
845
1200
        if base is None:
 
1201
 
 
1202
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
 
1203
            if xdg_dir is None:
 
1204
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
 
1205
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
 
1206
            if osutils.isdir(xdg_dir):
 
1207
                trace.mutter(
 
1208
                    "Using configuration in XDG directory %s." % xdg_dir)
 
1209
                return xdg_dir
 
1210
 
846
1211
            base = os.path.expanduser("~")
847
1212
        return osutils.pathjoin(base, ".bazaar")
848
1213
 
852
1217
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
853
1218
 
854
1219
 
855
 
def branches_config_filename():
856
 
    """Return per-user configuration ini file filename."""
857
 
    return osutils.pathjoin(config_dir(), 'branches.conf')
858
 
 
859
 
 
860
1220
def locations_config_filename():
861
1221
    """Return per-user configuration ini file filename."""
862
1222
    return osutils.pathjoin(config_dir(), 'locations.conf')
899
1259
        return os.path.expanduser('~/.cache')
900
1260
 
901
1261
 
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
1262
def parse_username(username):
976
1263
    """Parse e-mail username and return a (name, address) tuple."""
977
1264
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1020
1307
 
1021
1308
    def set_option(self, value, name, section=None):
1022
1309
        """Set a per-branch configuration option"""
 
1310
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1311
        # higher levels providing the right lock -- vila 20101004
1023
1312
        self.branch.lock_write()
1024
1313
        try:
1025
1314
            self._config.set_option(value, name, section)
1026
1315
        finally:
1027
1316
            self.branch.unlock()
1028
1317
 
 
1318
    def remove_option(self, option_name, section_name=None):
 
1319
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1320
        # higher levels providing the right lock -- vila 20101004
 
1321
        self.branch.lock_write()
 
1322
        try:
 
1323
            self._config.remove_option(option_name, section_name)
 
1324
        finally:
 
1325
            self.branch.unlock()
 
1326
 
1029
1327
 
1030
1328
class AuthenticationConfig(object):
1031
1329
    """The authentication configuration file based on a ini file.
1063
1361
        """Save the config file, only tests should use it for now."""
1064
1362
        conf_dir = os.path.dirname(self._filename)
1065
1363
        ensure_config_dir_exists(conf_dir)
1066
 
        self._get_config().write(file(self._filename, 'wb'))
 
1364
        f = file(self._filename, 'wb')
 
1365
        try:
 
1366
            self._get_config().write(f)
 
1367
        finally:
 
1368
            f.close()
1067
1369
 
1068
1370
    def _set_option(self, section_name, option_name, value):
1069
1371
        """Set an authentication configuration option"""
1470
1772
    """A Config that reads/writes a config file on a Transport.
1471
1773
 
1472
1774
    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.
 
1775
    that may be associated with a section.  Assigning meaning to these values
 
1776
    is done at higher levels like TreeConfig.
1475
1777
    """
1476
1778
 
1477
1779
    def __init__(self, transport, filename):
1510
1812
            configobj.setdefault(section, {})[name] = value
1511
1813
        self._set_configobj(configobj)
1512
1814
 
 
1815
    def remove_option(self, option_name, section_name=None):
 
1816
        configobj = self._get_configobj()
 
1817
        if section_name is None:
 
1818
            del configobj[option_name]
 
1819
        else:
 
1820
            del configobj[section_name][option_name]
 
1821
        self._set_configobj(configobj)
 
1822
 
1513
1823
    def _get_config_file(self):
1514
1824
        try:
1515
1825
            return StringIO(self._transport.get_bytes(self._filename))
1517
1827
            return StringIO()
1518
1828
 
1519
1829
    def _get_configobj(self):
1520
 
        return ConfigObj(self._get_config_file(), encoding='utf-8')
 
1830
        f = self._get_config_file()
 
1831
        try:
 
1832
            return ConfigObj(f, encoding='utf-8')
 
1833
        finally:
 
1834
            f.close()
1521
1835
 
1522
1836
    def _set_configobj(self, configobj):
1523
1837
        out_file = StringIO()
1524
1838
        configobj.write(out_file)
1525
1839
        out_file.seek(0)
1526
1840
        self._transport.put_file(self._filename, out_file)
 
1841
 
 
1842
 
 
1843
class cmd_config(commands.Command):
 
1844
    __doc__ = """Display, set or remove a configuration option.
 
1845
 
 
1846
    Display the active value for a given option.
 
1847
 
 
1848
    If --all is specified, NAME is interpreted as a regular expression and all
 
1849
    matching options are displayed mentioning their scope. The active value
 
1850
    that bzr will take into account is the first one displayed for each option.
 
1851
 
 
1852
    If no NAME is given, --all .* is implied.
 
1853
 
 
1854
    Setting a value is achieved by using name=value without spaces. The value
 
1855
    is set in the most relevant scope and can be checked by displaying the
 
1856
    option again.
 
1857
    """
 
1858
 
 
1859
    takes_args = ['name?']
 
1860
 
 
1861
    takes_options = [
 
1862
        'directory',
 
1863
        # FIXME: This should be a registry option so that plugins can register
 
1864
        # their own config files (or not) -- vila 20101002
 
1865
        commands.Option('scope', help='Reduce the scope to the specified'
 
1866
                        ' configuration file',
 
1867
                        type=unicode),
 
1868
        commands.Option('all',
 
1869
            help='Display all the defined values for the matching options.',
 
1870
            ),
 
1871
        commands.Option('remove', help='Remove the option from'
 
1872
                        ' the configuration file'),
 
1873
        ]
 
1874
 
 
1875
    @commands.display_command
 
1876
    def run(self, name=None, all=False, directory=None, scope=None,
 
1877
            remove=False):
 
1878
        if directory is None:
 
1879
            directory = '.'
 
1880
        directory = urlutils.normalize_url(directory)
 
1881
        if remove and all:
 
1882
            raise errors.BzrError(
 
1883
                '--all and --remove are mutually exclusive.')
 
1884
        elif remove:
 
1885
            # Delete the option in the given scope
 
1886
            self._remove_config_option(name, directory, scope)
 
1887
        elif name is None:
 
1888
            # Defaults to all options
 
1889
            self._show_matching_options('.*', directory, scope)
 
1890
        else:
 
1891
            try:
 
1892
                name, value = name.split('=', 1)
 
1893
            except ValueError:
 
1894
                # Display the option(s) value(s)
 
1895
                if all:
 
1896
                    self._show_matching_options(name, directory, scope)
 
1897
                else:
 
1898
                    self._show_value(name, directory, scope)
 
1899
            else:
 
1900
                if all:
 
1901
                    raise errors.BzrError(
 
1902
                        'Only one option can be set.')
 
1903
                # Set the option value
 
1904
                self._set_config_option(name, value, directory, scope)
 
1905
 
 
1906
    def _get_configs(self, directory, scope=None):
 
1907
        """Iterate the configurations specified by ``directory`` and ``scope``.
 
1908
 
 
1909
        :param directory: Where the configurations are derived from.
 
1910
 
 
1911
        :param scope: A specific config to start from.
 
1912
        """
 
1913
        if scope is not None:
 
1914
            if scope == 'bazaar':
 
1915
                yield GlobalConfig()
 
1916
            elif scope == 'locations':
 
1917
                yield LocationConfig(directory)
 
1918
            elif scope == 'branch':
 
1919
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1920
                    directory)
 
1921
                yield br.get_config()
 
1922
        else:
 
1923
            try:
 
1924
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1925
                    directory)
 
1926
                yield br.get_config()
 
1927
            except errors.NotBranchError:
 
1928
                yield LocationConfig(directory)
 
1929
                yield GlobalConfig()
 
1930
 
 
1931
    def _show_value(self, name, directory, scope):
 
1932
        displayed = False
 
1933
        for c in self._get_configs(directory, scope):
 
1934
            if displayed:
 
1935
                break
 
1936
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1937
                if name == oname:
 
1938
                    # Display only the first value and exit
 
1939
 
 
1940
                    # FIXME: We need to use get_user_option to take policies
 
1941
                    # into account and we need to make sure the option exists
 
1942
                    # too (hence the two for loops), this needs a better API
 
1943
                    # -- vila 20101117
 
1944
                    value = c.get_user_option(name)
 
1945
                    # Quote the value appropriately
 
1946
                    value = parser._quote(value)
 
1947
                    self.outf.write('%s\n' % (value,))
 
1948
                    displayed = True
 
1949
                    break
 
1950
        if not displayed:
 
1951
            raise errors.NoSuchConfigOption(name)
 
1952
 
 
1953
    def _show_matching_options(self, name, directory, scope):
 
1954
        name = re.compile(name)
 
1955
        # We want any error in the regexp to be raised *now* so we need to
 
1956
        # avoid the delay introduced by the lazy regexp.
 
1957
        name._compile_and_collapse()
 
1958
        cur_conf_id = None
 
1959
        cur_section = None
 
1960
        for c in self._get_configs(directory, scope):
 
1961
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1962
                if name.search(oname):
 
1963
                    if cur_conf_id != conf_id:
 
1964
                        # Explain where the options are defined
 
1965
                        self.outf.write('%s:\n' % (conf_id,))
 
1966
                        cur_conf_id = conf_id
 
1967
                        cur_section = None
 
1968
                    if (section not in (None, 'DEFAULT')
 
1969
                        and cur_section != section):
 
1970
                        # Display the section if it's not the default (or only)
 
1971
                        # one.
 
1972
                        self.outf.write('  [%s]\n' % (section,))
 
1973
                        cur_section = section
 
1974
                    self.outf.write('  %s = %s\n' % (oname, value))
 
1975
 
 
1976
    def _set_config_option(self, name, value, directory, scope):
 
1977
        for conf in self._get_configs(directory, scope):
 
1978
            conf.set_user_option(name, value)
 
1979
            break
 
1980
        else:
 
1981
            raise errors.NoSuchConfig(scope)
 
1982
 
 
1983
    def _remove_config_option(self, name, directory, scope):
 
1984
        if name is None:
 
1985
            raise errors.BzrCommandError(
 
1986
                '--remove expects an option to remove.')
 
1987
        removed = False
 
1988
        for conf in self._get_configs(directory, scope):
 
1989
            for (section_name, section, conf_id) in conf._get_sections():
 
1990
                if scope is not None and conf_id != scope:
 
1991
                    # Not the right configuration file
 
1992
                    continue
 
1993
                if name in section:
 
1994
                    if conf_id != conf.config_id():
 
1995
                        conf = self._get_configs(directory, conf_id).next()
 
1996
                    # We use the first section in the first config where the
 
1997
                    # option is defined to remove it
 
1998
                    conf.remove_user_option(name, section_name)
 
1999
                    removed = True
 
2000
                    break
 
2001
            break
 
2002
        else:
 
2003
            raise errors.NoSuchConfig(scope)
 
2004
        if not removed:
 
2005
            raise errors.NoSuchConfigOption(name)