/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: Robert Collins
  • Date: 2010-05-06 11:08:10 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506110810-h3j07fh5gmw54s25
Cleaner matcher matching revised unlocking protocol.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005-2010 Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
3
#            and others
4
4
#
65
65
import os
66
66
import sys
67
67
 
68
 
from bzrlib import commands
69
 
from bzrlib.decorators import needs_write_lock
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
 
    mergetools,
86
80
    osutils,
87
81
    registry,
88
82
    symbol_versioning,
89
83
    trace,
90
 
    transport,
91
84
    ui,
92
85
    urlutils,
93
86
    win32utils,
156
149
    def __init__(self):
157
150
        super(Config, self).__init__()
158
151
 
159
 
    def config_id(self):
160
 
        """Returns a unique ID for the config."""
161
 
        raise NotImplementedError(self.config_id)
162
 
 
163
152
    def get_editor(self):
164
153
        """Get the users pop up editor."""
165
154
        raise NotImplementedError
268
257
 
269
258
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
270
259
 
271
 
        $BZR_EMAIL can be set to override this, then
 
260
        $BZR_EMAIL can be set to override this (as well as the
 
261
        deprecated $BZREMAIL), then
272
262
        the concrete policy type is checked, and finally
273
263
        $EMAIL is examined.
274
 
        If no username can be found, errors.NoWhoami exception is raised.
 
264
        If none is found, a reasonable default is (hopefully)
 
265
        created.
275
266
 
276
267
        TODO: Check it's reasonably well-formed.
277
268
        """
287
278
        if v:
288
279
            return v.decode(osutils.get_user_encoding())
289
280
 
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()
 
281
        name, email = _auto_user_id()
 
282
        if name:
 
283
            return '%s <%s>' % (name, email)
 
284
        else:
 
285
            return email
298
286
 
299
287
    def signature_checking(self):
300
288
        """What is the current policy for signature checking?."""
358
346
        else:
359
347
            return True
360
348
 
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
 
                tool_name = oname[len('bzr.mergetool.'):]
366
 
                tools[tool_name] = value
367
 
        trace.mutter('loaded merge tools: %r' % tools)
368
 
        return tools
369
 
 
370
 
    def find_merge_tool(self, name):
371
 
        # We fake a defaults mechanism here by checking if the given name can 
372
 
        # be found in the known_merge_tools if it's not found in the config.
373
 
        # This should be done through the proposed config defaults mechanism
374
 
        # when it becomes available in the future.
375
 
        command_line = (self.get_user_option('bzr.mergetool.%s' % name) or
376
 
                        mergetools.known_merge_tools.get(name, None))
377
 
        return command_line
378
 
 
379
349
 
380
350
class IniBasedConfig(Config):
381
351
    """A configuration policy that draws from ini files."""
382
352
 
383
 
    def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
384
 
                 file_name=None):
385
 
        """Base class for configuration files using an ini-like syntax.
386
 
 
387
 
        :param file_name: The configuration file path.
388
 
        """
 
353
    def __init__(self, get_filename):
389
354
        super(IniBasedConfig, self).__init__()
390
 
        self.file_name = file_name
391
 
        if symbol_versioning.deprecated_passed(get_filename):
392
 
            symbol_versioning.warn(
393
 
                'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
394
 
                ' Use file_name instead.',
395
 
                DeprecationWarning,
396
 
                stacklevel=2)
397
 
            if get_filename is not None:
398
 
                self.file_name = get_filename()
399
 
        else:
400
 
            self.file_name = file_name
401
 
        self._content = None
 
355
        self._get_filename = get_filename
402
356
        self._parser = None
403
357
 
404
 
    @classmethod
405
 
    def from_string(cls, str_or_unicode, file_name=None, save=False):
406
 
        """Create a config object from a string.
407
 
 
408
 
        :param str_or_unicode: A string representing the file content. This will
409
 
            be utf-8 encoded.
410
 
 
411
 
        :param file_name: The configuration file path.
412
 
 
413
 
        :param _save: Whether the file should be saved upon creation.
414
 
        """
415
 
        conf = cls(file_name=file_name)
416
 
        conf._create_from_string(str_or_unicode, save)
417
 
        return conf
418
 
 
419
 
    def _create_from_string(self, str_or_unicode, save):
420
 
        self._content = StringIO(str_or_unicode.encode('utf-8'))
421
 
        # Some tests use in-memory configs, some other always need the config
422
 
        # file to exist on disk.
423
 
        if save:
424
 
            self._write_config_file()
425
 
 
426
 
    def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
 
358
    def _get_parser(self, file=None):
427
359
        if self._parser is not None:
428
360
            return self._parser
429
 
        if symbol_versioning.deprecated_passed(file):
430
 
            symbol_versioning.warn(
431
 
                'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
432
 
                ' Use IniBasedConfig(_content=xxx) instead.',
433
 
                DeprecationWarning,
434
 
                stacklevel=2)
435
 
        if self._content is not None:
436
 
            co_input = self._content
437
 
        elif self.file_name is None:
438
 
            raise AssertionError('We have no content to create the config')
 
361
        if file is None:
 
362
            input = self._get_filename()
439
363
        else:
440
 
            co_input = self.file_name
 
364
            input = file
441
365
        try:
442
 
            self._parser = ConfigObj(co_input, encoding='utf-8')
 
366
            self._parser = ConfigObj(input, encoding='utf-8')
443
367
        except configobj.ConfigObjError, e:
444
368
            raise errors.ParseConfigError(e.errors, e.config.filename)
445
 
        # Make sure self.reload() will use the right file name
446
 
        self._parser.filename = self.file_name
447
369
        return self._parser
448
370
 
449
 
    def reload(self):
450
 
        """Reload the config file from disk."""
451
 
        if self.file_name is None:
452
 
            raise AssertionError('We need a file name to reload the config')
453
 
        if self._parser is not None:
454
 
            self._parser.reload()
455
 
 
456
371
    def _get_matching_sections(self):
457
372
        """Return an ordered list of (section_name, extra_path) pairs.
458
373
 
469
384
        """Override this to define the section used by the config."""
470
385
        return "DEFAULT"
471
386
 
472
 
    def _get_sections(self, name=None):
473
 
        """Returns an iterator of the sections specified by ``name``.
474
 
 
475
 
        :param name: The section name. If None is supplied, the default
476
 
            configurations are yielded.
477
 
 
478
 
        :return: A tuple (name, section, config_id) for all sections that will
479
 
            be walked by user_get_option() in the 'right' order. The first one
480
 
            is where set_user_option() will update the value.
481
 
        """
482
 
        parser = self._get_parser()
483
 
        if name is not None:
484
 
            yield (name, parser[name], self.config_id())
485
 
        else:
486
 
            # No section name has been given so we fallback to the configobj
487
 
            # itself which holds the variables defined outside of any section.
488
 
            yield (None, parser, self.config_id())
489
 
 
490
 
    def _get_options(self, sections=None):
491
 
        """Return an ordered list of (name, value, section, config_id) tuples.
492
 
 
493
 
        All options are returned with their associated value and the section
494
 
        they appeared in. ``config_id`` is a unique identifier for the
495
 
        configuration file the option is defined in.
496
 
 
497
 
        :param sections: Default to ``_get_matching_sections`` if not
498
 
            specified. This gives a better control to daughter classes about
499
 
            which sections should be searched. This is a list of (name,
500
 
            configobj) tuples.
501
 
        """
502
 
        opts = []
503
 
        if sections is None:
504
 
            parser = self._get_parser()
505
 
            sections = []
506
 
            for (section_name, _) in self._get_matching_sections():
507
 
                try:
508
 
                    section = parser[section_name]
509
 
                except KeyError:
510
 
                    # This could happen for an empty file for which we define a
511
 
                    # DEFAULT section. FIXME: Force callers to provide sections
512
 
                    # instead ? -- vila 20100930
513
 
                    continue
514
 
                sections.append((section_name, section))
515
 
        config_id = self.config_id()
516
 
        for (section_name, section) in sections:
517
 
            for (name, value) in section.iteritems():
518
 
                yield (name, parser._quote(value), section_name,
519
 
                       config_id, parser)
520
 
 
521
387
    def _get_option_policy(self, section, option_name):
522
388
        """Return the policy for the given (section, option_name) pair."""
523
389
        return POLICY_NONE
610
476
    def _get_nickname(self):
611
477
        return self.get_user_option('nickname')
612
478
 
613
 
    def remove_user_option(self, option_name, section_name=None):
614
 
        """Remove a user option and save the configuration file.
615
 
 
616
 
        :param option_name: The option to be removed.
617
 
 
618
 
        :param section_name: The section the option is defined in, default to
619
 
            the default section.
620
 
        """
621
 
        self.reload()
622
 
        parser = self._get_parser()
623
 
        if section_name is None:
624
 
            section = parser
625
 
        else:
626
 
            section = parser[section_name]
627
 
        try:
628
 
            del section[option_name]
629
 
        except KeyError:
630
 
            raise errors.NoSuchConfigOption(option_name)
631
 
        self._write_config_file()
632
 
 
633
 
    def _write_config_file(self):
634
 
        if self.file_name is None:
635
 
            raise AssertionError('We cannot save, self.file_name is None')
636
 
        conf_dir = os.path.dirname(self.file_name)
637
 
        ensure_config_dir_exists(conf_dir)
638
 
        atomic_file = atomicfile.AtomicFile(self.file_name)
639
 
        self._get_parser().write(atomic_file)
640
 
        atomic_file.commit()
641
 
        atomic_file.close()
642
 
        osutils.copy_ownership_from_path(self.file_name)
643
 
 
644
 
 
645
 
class LockableConfig(IniBasedConfig):
646
 
    """A configuration needing explicit locking for access.
647
 
 
648
 
    If several processes try to write the config file, the accesses need to be
649
 
    serialized.
650
 
 
651
 
    Daughter classes should decorate all methods that update a config with the
652
 
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
653
 
    ``_write_config_file()`` method. These methods (typically ``set_option()``
654
 
    and variants must reload the config file from disk before calling
655
 
    ``_write_config_file()``), this can be achieved by calling the
656
 
    ``self.reload()`` method. Note that the lock scope should cover both the
657
 
    reading and the writing of the config file which is why the decorator can't
658
 
    be applied to ``_write_config_file()`` only.
659
 
 
660
 
    This should be enough to implement the following logic:
661
 
    - lock for exclusive write access,
662
 
    - reload the config file from disk,
663
 
    - set the new value
664
 
    - unlock
665
 
 
666
 
    This logic guarantees that a writer can update a value without erasing an
667
 
    update made by another writer.
668
 
    """
669
 
 
670
 
    lock_name = 'lock'
671
 
 
672
 
    def __init__(self, file_name):
673
 
        super(LockableConfig, self).__init__(file_name=file_name)
674
 
        self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
675
 
        self.transport = transport.get_transport(self.dir)
676
 
        self._lock = lockdir.LockDir(self.transport, 'lock')
677
 
 
678
 
    def _create_from_string(self, unicode_bytes, save):
679
 
        super(LockableConfig, self)._create_from_string(unicode_bytes, False)
680
 
        if save:
681
 
            # We need to handle the saving here (as opposed to IniBasedConfig)
682
 
            # to be able to lock
683
 
            self.lock_write()
684
 
            self._write_config_file()
685
 
            self.unlock()
686
 
 
687
 
    def lock_write(self, token=None):
688
 
        """Takes a write lock in the directory containing the config file.
689
 
 
690
 
        If the directory doesn't exist it is created.
691
 
        """
692
 
        ensure_config_dir_exists(self.dir)
693
 
        return self._lock.lock_write(token)
694
 
 
695
 
    def unlock(self):
696
 
        self._lock.unlock()
697
 
 
698
 
    def break_lock(self):
699
 
        self._lock.break_lock()
700
 
 
701
 
    @needs_write_lock
702
 
    def remove_user_option(self, option_name, section_name=None):
703
 
        super(LockableConfig, self).remove_user_option(option_name,
704
 
                                                       section_name)
705
 
 
706
 
    def _write_config_file(self):
707
 
        if self._lock is None or not self._lock.is_held:
708
 
            # NB: if the following exception is raised it probably means a
709
 
            # missing @needs_write_lock decorator on one of the callers.
710
 
            raise errors.ObjectNotLocked(self)
711
 
        super(LockableConfig, self)._write_config_file()
712
 
 
713
 
 
714
 
class GlobalConfig(LockableConfig):
 
479
 
 
480
class GlobalConfig(IniBasedConfig):
715
481
    """The configuration that should be used for a specific location."""
716
482
 
717
 
    def __init__(self):
718
 
        super(GlobalConfig, self).__init__(file_name=config_filename())
719
 
 
720
 
    def config_id(self):
721
 
        return 'bazaar'
722
 
 
723
 
    @classmethod
724
 
    def from_string(cls, str_or_unicode, save=False):
725
 
        """Create a config object from a string.
726
 
 
727
 
        :param str_or_unicode: A string representing the file content. This
728
 
            will be utf-8 encoded.
729
 
 
730
 
        :param save: Whether the file should be saved upon creation.
731
 
        """
732
 
        conf = cls()
733
 
        conf._create_from_string(str_or_unicode, save)
734
 
        return conf
735
 
 
736
483
    def get_editor(self):
737
484
        return self._get_user_option('editor')
738
485
 
739
 
    @needs_write_lock
 
486
    def __init__(self):
 
487
        super(GlobalConfig, self).__init__(config_filename)
 
488
 
740
489
    def set_user_option(self, option, value):
741
490
        """Save option and its value in the configuration."""
742
491
        self._set_option(option, value, 'DEFAULT')
748
497
        else:
749
498
            return {}
750
499
 
751
 
    @needs_write_lock
752
500
    def set_alias(self, alias_name, alias_command):
753
501
        """Save the alias in the configuration."""
754
502
        self._set_option(alias_name, alias_command, 'ALIASES')
755
503
 
756
 
    @needs_write_lock
757
504
    def unset_alias(self, alias_name):
758
505
        """Unset an existing alias."""
759
 
        self.reload()
760
506
        aliases = self._get_parser().get('ALIASES')
761
507
        if not aliases or alias_name not in aliases:
762
508
            raise errors.NoSuchAlias(alias_name)
764
510
        self._write_config_file()
765
511
 
766
512
    def _set_option(self, option, value, section):
767
 
        self.reload()
 
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)
768
517
        self._get_parser().setdefault(section, {})[option] = value
769
518
        self._write_config_file()
770
519
 
771
 
 
772
 
    def _get_sections(self, name=None):
773
 
        """See IniBasedConfig._get_sections()."""
774
 
        parser = self._get_parser()
775
 
        # We don't give access to options defined outside of any section, we
776
 
        # used the DEFAULT section by... default.
777
 
        if name in (None, 'DEFAULT'):
778
 
            # This could happen for an empty file where the DEFAULT section
779
 
            # doesn't exist yet. So we force DEFAULT when yielding
780
 
            name = 'DEFAULT'
781
 
            if 'DEFAULT' not in parser:
782
 
               parser['DEFAULT']= {}
783
 
        yield (name, parser[name], self.config_id())
784
 
 
785
 
    @needs_write_lock
786
 
    def remove_user_option(self, option_name, section_name=None):
787
 
        if section_name is None:
788
 
            # We need to force the default section.
789
 
            section_name = 'DEFAULT'
790
 
        # We need to avoid the LockableConfig implementation or we'll lock
791
 
        # twice
792
 
        super(LockableConfig, self).remove_user_option(option_name,
793
 
                                                       section_name)
794
 
 
795
 
 
796
 
class LocationConfig(LockableConfig):
 
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):
797
529
    """A configuration object that gives the policy for a location."""
798
530
 
799
531
    def __init__(self, location):
800
 
        super(LocationConfig, self).__init__(
801
 
            file_name=locations_config_filename())
 
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)
802
544
        # local file locations are looked up by local path, rather than
803
545
        # by file url. This is because the config file is a user
804
546
        # file, and we would rather not expose the user to file urls.
806
548
            location = urlutils.local_path_from_url(location)
807
549
        self.location = location
808
550
 
809
 
    def config_id(self):
810
 
        return 'locations'
811
 
 
812
 
    @classmethod
813
 
    def from_string(cls, str_or_unicode, location, save=False):
814
 
        """Create a config object from a string.
815
 
 
816
 
        :param str_or_unicode: A string representing the file content. This will
817
 
            be utf-8 encoded.
818
 
 
819
 
        :param location: The location url to filter the configuration.
820
 
 
821
 
        :param save: Whether the file should be saved upon creation.
822
 
        """
823
 
        conf = cls(location)
824
 
        conf._create_from_string(str_or_unicode, save)
825
 
        return conf
826
 
 
827
551
    def _get_matching_sections(self):
828
552
        """Return an ordered list of section names matching this location."""
829
553
        sections = self._get_parser()
846
570
            names = zip(location_names, section_names)
847
571
            matched = True
848
572
            for name in names:
849
 
                if not fnmatch.fnmatch(name[0], name[1]):
 
573
                if not fnmatch(name[0], name[1]):
850
574
                    matched = False
851
575
                    break
852
576
            if not matched:
857
581
                continue
858
582
            matches.append((len(section_names), section,
859
583
                            '/'.join(location_names[len(section_names):])))
860
 
        # put the longest (aka more specific) locations first
861
584
        matches.sort(reverse=True)
862
585
        sections = []
863
586
        for (length, section, extra_path) in matches:
870
593
                pass
871
594
        return sections
872
595
 
873
 
    def _get_sections(self, name=None):
874
 
        """See IniBasedConfig._get_sections()."""
875
 
        # We ignore the name here as the only sections handled are named with
876
 
        # the location path and we don't expose embedded sections either.
877
 
        parser = self._get_parser()
878
 
        for name, extra_path in self._get_matching_sections():
879
 
            yield (name, parser[name], self.config_id())
880
 
 
881
596
    def _get_option_policy(self, section, option_name):
882
597
        """Return the policy for the given (section, option_name) pair."""
883
598
        # check for the old 'recurse=False' flag
926
641
            if policy_key in self._get_parser()[section]:
927
642
                del self._get_parser()[section][policy_key]
928
643
 
929
 
    @needs_write_lock
930
644
    def set_user_option(self, option, value, store=STORE_LOCATION):
931
645
        """Save option and its value in the configuration."""
932
646
        if store not in [STORE_LOCATION,
934
648
                         STORE_LOCATION_APPENDPATH]:
935
649
            raise ValueError('bad storage policy %r for %r' %
936
650
                (store, option))
937
 
        self.reload()
 
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)
938
655
        location = self.location
939
656
        if location.endswith('/'):
940
657
            location = location[:-1]
941
 
        parser = self._get_parser()
942
 
        if not location in parser and not location + '/' in parser:
943
 
            parser[location] = {}
944
 
        elif location + '/' in parser:
 
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():
945
662
            location = location + '/'
946
 
        parser[location][option]=value
 
663
        self._get_parser()[location][option]=value
947
664
        # the allowed values of store match the config policies
948
665
        self._set_option_policy(location, option, store)
949
 
        self._write_config_file()
 
666
        self._get_parser().write(file(self._get_filename(), 'wb'))
950
667
 
951
668
 
952
669
class BranchConfig(Config):
953
670
    """A configuration object giving the policy for a branch."""
954
671
 
955
 
    def __init__(self, branch):
956
 
        super(BranchConfig, self).__init__()
957
 
        self._location_config = None
958
 
        self._branch_data_config = None
959
 
        self._global_config = None
960
 
        self.branch = branch
961
 
        self.option_sources = (self._get_location_config,
962
 
                               self._get_branch_data_config,
963
 
                               self._get_global_config)
964
 
 
965
 
    def config_id(self):
966
 
        return 'branch'
967
 
 
968
672
    def _get_branch_data_config(self):
969
673
        if self._branch_data_config is None:
970
674
            self._branch_data_config = TreeConfig(self.branch)
971
 
            self._branch_data_config.config_id = self.config_id
972
675
        return self._branch_data_config
973
676
 
974
677
    def _get_location_config(self):
1042
745
                return value
1043
746
        return None
1044
747
 
1045
 
    def _get_sections(self, name=None):
1046
 
        """See IniBasedConfig.get_sections()."""
1047
 
        for source in self.option_sources:
1048
 
            for section in source()._get_sections(name):
1049
 
                yield section
1050
 
 
1051
 
    def _get_options(self, sections=None):
1052
 
        opts = []
1053
 
        # First the locations options
1054
 
        for option in self._get_location_config()._get_options():
1055
 
            yield option
1056
 
        # Then the branch options
1057
 
        branch_config = self._get_branch_data_config()
1058
 
        if sections is None:
1059
 
            sections = [('DEFAULT', branch_config._get_parser())]
1060
 
        # FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
1061
 
        # Config itself has no notion of sections :( -- vila 20101001
1062
 
        config_id = self.config_id()
1063
 
        for (section_name, section) in sections:
1064
 
            for (name, value) in section.iteritems():
1065
 
                yield (name, value, section_name,
1066
 
                       config_id, branch_config._get_parser())
1067
 
        # Then the global options
1068
 
        for option in self._get_global_config()._get_options():
1069
 
            yield option
1070
 
 
1071
748
    def set_user_option(self, name, value, store=STORE_BRANCH,
1072
749
        warn_masked=False):
1073
750
        if store == STORE_BRANCH:
1091
768
                        trace.warning('Value "%s" is masked by "%s" from'
1092
769
                                      ' branch.conf', value, mask_value)
1093
770
 
1094
 
    def remove_user_option(self, option_name, section_name=None):
1095
 
        self._get_branch_data_config().remove_option(option_name, section_name)
1096
 
 
1097
771
    def _gpg_signing_command(self):
1098
772
        """See Config.gpg_signing_command."""
1099
773
        return self._get_safe_value('_gpg_signing_command')
1100
774
 
 
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
 
1101
785
    def _post_commit(self):
1102
786
        """See Config.post_commit."""
1103
787
        return self._get_safe_value('_post_commit')
1133
817
            parent_dir = os.path.dirname(path)
1134
818
            if not os.path.isdir(parent_dir):
1135
819
                trace.mutter('creating config parent directory: %r', parent_dir)
1136
 
                os.mkdir(parent_dir)
 
820
            os.mkdir(parent_dir)
1137
821
        trace.mutter('creating config directory: %r', path)
1138
822
        os.mkdir(path)
1139
823
        osutils.copy_ownership_from_path(path)
1142
826
def config_dir():
1143
827
    """Return per-user configuration directory.
1144
828
 
1145
 
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
1146
 
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
1147
 
    that will be used instead.
 
829
    By default this is ~/.bazaar/
1148
830
 
1149
831
    TODO: Global option --config-dir to override this.
1150
832
    """
1151
833
    base = os.environ.get('BZR_HOME', None)
1152
834
    if sys.platform == 'win32':
1153
 
        # environ variables on Windows are in user encoding/mbcs. So decode
1154
 
        # before using one
1155
 
        if base is not None:
1156
 
            base = base.decode('mbcs')
1157
835
        if base is None:
1158
836
            base = win32utils.get_appdata_location_unicode()
1159
837
        if base is None:
1160
838
            base = os.environ.get('HOME', None)
1161
 
            if base is not None:
1162
 
                base = base.decode('mbcs')
1163
839
        if base is None:
1164
840
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
1165
841
                                  ' or HOME set')
1166
842
        return osutils.pathjoin(base, 'bazaar', '2.0')
1167
 
    elif sys.platform == 'darwin':
1168
 
        if base is None:
1169
 
            # this takes into account $HOME
1170
 
            base = os.path.expanduser("~")
1171
 
        return osutils.pathjoin(base, '.bazaar')
1172
843
    else:
 
844
        # cygwin, linux, and darwin all have a $HOME directory
1173
845
        if base is None:
1174
 
 
1175
 
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
1176
 
            if xdg_dir is None:
1177
 
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
1178
 
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
1179
 
            if osutils.isdir(xdg_dir):
1180
 
                trace.mutter(
1181
 
                    "Using configuration in XDG directory %s." % xdg_dir)
1182
 
                return xdg_dir
1183
 
 
1184
846
            base = os.path.expanduser("~")
1185
847
        return osutils.pathjoin(base, ".bazaar")
1186
848
 
1190
852
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
1191
853
 
1192
854
 
 
855
def branches_config_filename():
 
856
    """Return per-user configuration ini file filename."""
 
857
    return osutils.pathjoin(config_dir(), 'branches.conf')
 
858
 
 
859
 
1193
860
def locations_config_filename():
1194
861
    """Return per-user configuration ini file filename."""
1195
862
    return osutils.pathjoin(config_dir(), 'locations.conf')
1232
899
        return os.path.expanduser('~/.cache')
1233
900
 
1234
901
 
 
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
 
1235
975
def parse_username(username):
1236
976
    """Parse e-mail username and return a (name, address) tuple."""
1237
977
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1280
1020
 
1281
1021
    def set_option(self, value, name, section=None):
1282
1022
        """Set a per-branch configuration option"""
1283
 
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
1284
 
        # higher levels providing the right lock -- vila 20101004
1285
1023
        self.branch.lock_write()
1286
1024
        try:
1287
1025
            self._config.set_option(value, name, section)
1288
1026
        finally:
1289
1027
            self.branch.unlock()
1290
1028
 
1291
 
    def remove_option(self, option_name, section_name=None):
1292
 
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
1293
 
        # higher levels providing the right lock -- vila 20101004
1294
 
        self.branch.lock_write()
1295
 
        try:
1296
 
            self._config.remove_option(option_name, section_name)
1297
 
        finally:
1298
 
            self.branch.unlock()
1299
 
 
1300
1029
 
1301
1030
class AuthenticationConfig(object):
1302
1031
    """The authentication configuration file based on a ini file.
1334
1063
        """Save the config file, only tests should use it for now."""
1335
1064
        conf_dir = os.path.dirname(self._filename)
1336
1065
        ensure_config_dir_exists(conf_dir)
1337
 
        f = file(self._filename, 'wb')
1338
 
        try:
1339
 
            self._get_config().write(f)
1340
 
        finally:
1341
 
            f.close()
 
1066
        self._get_config().write(file(self._filename, 'wb'))
1342
1067
 
1343
1068
    def _set_option(self, section_name, option_name, value):
1344
1069
        """Set an authentication configuration option"""
1745
1470
    """A Config that reads/writes a config file on a Transport.
1746
1471
 
1747
1472
    It is a low-level object that considers config data to be name/value pairs
1748
 
    that may be associated with a section.  Assigning meaning to these values
1749
 
    is done at higher levels like TreeConfig.
 
1473
    that may be associated with a section.  Assigning meaning to the these
 
1474
    values is done at higher levels like TreeConfig.
1750
1475
    """
1751
1476
 
1752
1477
    def __init__(self, transport, filename):
1785
1510
            configobj.setdefault(section, {})[name] = value
1786
1511
        self._set_configobj(configobj)
1787
1512
 
1788
 
    def remove_option(self, option_name, section_name=None):
1789
 
        configobj = self._get_configobj()
1790
 
        if section_name is None:
1791
 
            del configobj[option_name]
1792
 
        else:
1793
 
            del configobj[section_name][option_name]
1794
 
        self._set_configobj(configobj)
1795
 
 
1796
1513
    def _get_config_file(self):
1797
1514
        try:
1798
1515
            return StringIO(self._transport.get_bytes(self._filename))
1800
1517
            return StringIO()
1801
1518
 
1802
1519
    def _get_configobj(self):
1803
 
        f = self._get_config_file()
1804
 
        try:
1805
 
            return ConfigObj(f, encoding='utf-8')
1806
 
        finally:
1807
 
            f.close()
 
1520
        return ConfigObj(self._get_config_file(), encoding='utf-8')
1808
1521
 
1809
1522
    def _set_configobj(self, configobj):
1810
1523
        out_file = StringIO()
1811
1524
        configobj.write(out_file)
1812
1525
        out_file.seek(0)
1813
1526
        self._transport.put_file(self._filename, out_file)
1814
 
 
1815
 
 
1816
 
class cmd_config(commands.Command):
1817
 
    __doc__ = """Display, set or remove a configuration option.
1818
 
 
1819
 
    Display the active value for a given option.
1820
 
 
1821
 
    If --all is specified, NAME is interpreted as a regular expression and all
1822
 
    matching options are displayed mentioning their scope. The active value
1823
 
    that bzr will take into account is the first one displayed for each option.
1824
 
 
1825
 
    If no NAME is given, --all .* is implied.
1826
 
 
1827
 
    Setting a value is achieved by using name=value without spaces. The value
1828
 
    is set in the most relevant scope and can be checked by displaying the
1829
 
    option again.
1830
 
    """
1831
 
 
1832
 
    takes_args = ['name?']
1833
 
 
1834
 
    takes_options = [
1835
 
        'directory',
1836
 
        # FIXME: This should be a registry option so that plugins can register
1837
 
        # their own config files (or not) -- vila 20101002
1838
 
        commands.Option('scope', help='Reduce the scope to the specified'
1839
 
                        ' configuration file',
1840
 
                        type=unicode),
1841
 
        commands.Option('all',
1842
 
            help='Display all the defined values for the matching options.',
1843
 
            ),
1844
 
        commands.Option('remove', help='Remove the option from'
1845
 
                        ' the configuration file'),
1846
 
        ]
1847
 
 
1848
 
    @commands.display_command
1849
 
    def run(self, name=None, all=False, directory=None, scope=None,
1850
 
            remove=False):
1851
 
        if directory is None:
1852
 
            directory = '.'
1853
 
        directory = urlutils.normalize_url(directory)
1854
 
        if remove and all:
1855
 
            raise errors.BzrError(
1856
 
                '--all and --remove are mutually exclusive.')
1857
 
        elif remove:
1858
 
            # Delete the option in the given scope
1859
 
            self._remove_config_option(name, directory, scope)
1860
 
        elif name is None:
1861
 
            # Defaults to all options
1862
 
            self._show_matching_options('.*', directory, scope)
1863
 
        else:
1864
 
            try:
1865
 
                name, value = name.split('=', 1)
1866
 
            except ValueError:
1867
 
                # Display the option(s) value(s)
1868
 
                if all:
1869
 
                    self._show_matching_options(name, directory, scope)
1870
 
                else:
1871
 
                    self._show_value(name, directory, scope)
1872
 
            else:
1873
 
                if all:
1874
 
                    raise errors.BzrError(
1875
 
                        'Only one option can be set.')
1876
 
                # Set the option value
1877
 
                self._set_config_option(name, value, directory, scope)
1878
 
 
1879
 
    def _get_configs(self, directory, scope=None):
1880
 
        """Iterate the configurations specified by ``directory`` and ``scope``.
1881
 
 
1882
 
        :param directory: Where the configurations are derived from.
1883
 
 
1884
 
        :param scope: A specific config to start from.
1885
 
        """
1886
 
        if scope is not None:
1887
 
            if scope == 'bazaar':
1888
 
                yield GlobalConfig()
1889
 
            elif scope == 'locations':
1890
 
                yield LocationConfig(directory)
1891
 
            elif scope == 'branch':
1892
 
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
1893
 
                    directory)
1894
 
                yield br.get_config()
1895
 
        else:
1896
 
            try:
1897
 
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
1898
 
                    directory)
1899
 
                yield br.get_config()
1900
 
            except errors.NotBranchError:
1901
 
                yield LocationConfig(directory)
1902
 
                yield GlobalConfig()
1903
 
 
1904
 
    def _show_value(self, name, directory, scope):
1905
 
        displayed = False
1906
 
        for c in self._get_configs(directory, scope):
1907
 
            if displayed:
1908
 
                break
1909
 
            for (oname, value, section, conf_id, parser) in c._get_options():
1910
 
                if name == oname:
1911
 
                    # Display only the first value and exit
1912
 
 
1913
 
                    # FIXME: We need to use get_user_option to take policies
1914
 
                    # into account and we need to make sure the option exists
1915
 
                    # too (hence the two for loops), this needs a better API
1916
 
                    # -- vila 20101117
1917
 
                    value = c.get_user_option(name)
1918
 
                    # Quote the value appropriately
1919
 
                    value = parser._quote(value)
1920
 
                    self.outf.write('%s\n' % (value,))
1921
 
                    displayed = True
1922
 
                    break
1923
 
        if not displayed:
1924
 
            raise errors.NoSuchConfigOption(name)
1925
 
 
1926
 
    def _show_matching_options(self, name, directory, scope):
1927
 
        name = re.compile(name)
1928
 
        # We want any error in the regexp to be raised *now* so we need to
1929
 
        # avoid the delay introduced by the lazy regexp.
1930
 
        name._compile_and_collapse()
1931
 
        cur_conf_id = None
1932
 
        cur_section = None
1933
 
        for c in self._get_configs(directory, scope):
1934
 
            for (oname, value, section, conf_id, parser) in c._get_options():
1935
 
                if name.search(oname):
1936
 
                    if cur_conf_id != conf_id:
1937
 
                        # Explain where the options are defined
1938
 
                        self.outf.write('%s:\n' % (conf_id,))
1939
 
                        cur_conf_id = conf_id
1940
 
                        cur_section = None
1941
 
                    if (section not in (None, 'DEFAULT')
1942
 
                        and cur_section != section):
1943
 
                        # Display the section if it's not the default (or only)
1944
 
                        # one.
1945
 
                        self.outf.write('  [%s]\n' % (section,))
1946
 
                        cur_section = section
1947
 
                    self.outf.write('  %s = %s\n' % (oname, value))
1948
 
 
1949
 
    def _set_config_option(self, name, value, directory, scope):
1950
 
        for conf in self._get_configs(directory, scope):
1951
 
            conf.set_user_option(name, value)
1952
 
            break
1953
 
        else:
1954
 
            raise errors.NoSuchConfig(scope)
1955
 
 
1956
 
    def _remove_config_option(self, name, directory, scope):
1957
 
        if name is None:
1958
 
            raise errors.BzrCommandError(
1959
 
                '--remove expects an option to remove.')
1960
 
        removed = False
1961
 
        for conf in self._get_configs(directory, scope):
1962
 
            for (section_name, section, conf_id) in conf._get_sections():
1963
 
                if scope is not None and conf_id != scope:
1964
 
                    # Not the right configuration file
1965
 
                    continue
1966
 
                if name in section:
1967
 
                    if conf_id != conf.config_id():
1968
 
                        conf = self._get_configs(directory, conf_id).next()
1969
 
                    # We use the first section in the first config where the
1970
 
                    # option is defined to remove it
1971
 
                    conf.remove_user_option(name, section_name)
1972
 
                    removed = True
1973
 
                    break
1974
 
            break
1975
 
        else:
1976
 
            raise errors.NoSuchConfig(scope)
1977
 
        if not removed:
1978
 
            raise errors.NoSuchConfigOption(name)