~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Jelmer Vernooij
  • Date: 2011-02-20 00:53:24 UTC
  • mto: This revision was merged to the branch mainline in revision 5673.
  • Revision ID: jelmer@samba.org-20110220005324-xnb1ifis5bfkrl51
Lazy load gzip (we don't use it when doing 2a), remove some unused imports.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2011 Canonical Ltd
2
2
#   Authors: Robert Collins <robert.collins@canonical.com>
3
3
#            and others
4
4
#
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
                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
 
349
379
 
350
380
class IniBasedConfig(Config):
351
381
    """A configuration policy that draws from ini files."""
352
382
 
353
 
    def __init__(self, get_filename):
 
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
        """
354
389
        super(IniBasedConfig, self).__init__()
355
 
        self._get_filename = get_filename
 
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
356
402
        self._parser = None
357
403
 
358
 
    def _get_parser(self, file=None):
 
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):
359
427
        if self._parser is not None:
360
428
            return self._parser
361
 
        if file is None:
362
 
            input = self._get_filename()
 
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')
363
439
        else:
364
 
            input = file
 
440
            co_input = self.file_name
365
441
        try:
366
 
            self._parser = ConfigObj(input, encoding='utf-8')
 
442
            self._parser = ConfigObj(co_input, encoding='utf-8')
367
443
        except configobj.ConfigObjError, e:
368
444
            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
369
447
        return self._parser
370
448
 
 
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
 
371
456
    def _get_matching_sections(self):
372
457
        """Return an ordered list of (section_name, extra_path) pairs.
373
458
 
384
469
        """Override this to define the section used by the config."""
385
470
        return "DEFAULT"
386
471
 
 
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
 
387
521
    def _get_option_policy(self, section, option_name):
388
522
        """Return the policy for the given (section, option_name) pair."""
389
523
        return POLICY_NONE
476
610
    def _get_nickname(self):
477
611
        return self.get_user_option('nickname')
478
612
 
479
 
 
480
 
class GlobalConfig(IniBasedConfig):
 
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):
481
715
    """The configuration that should be used for a specific location."""
482
716
 
 
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
 
483
736
    def get_editor(self):
484
737
        return self._get_user_option('editor')
485
738
 
486
 
    def __init__(self):
487
 
        super(GlobalConfig, self).__init__(config_filename)
488
 
 
 
739
    @needs_write_lock
489
740
    def set_user_option(self, option, value):
490
741
        """Save option and its value in the configuration."""
491
742
        self._set_option(option, value, 'DEFAULT')
497
748
        else:
498
749
            return {}
499
750
 
 
751
    @needs_write_lock
500
752
    def set_alias(self, alias_name, alias_command):
501
753
        """Save the alias in the configuration."""
502
754
        self._set_option(alias_name, alias_command, 'ALIASES')
503
755
 
 
756
    @needs_write_lock
504
757
    def unset_alias(self, alias_name):
505
758
        """Unset an existing alias."""
 
759
        self.reload()
506
760
        aliases = self._get_parser().get('ALIASES')
507
761
        if not aliases or alias_name not in aliases:
508
762
            raise errors.NoSuchAlias(alias_name)
510
764
        self._write_config_file()
511
765
 
512
766
    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)
 
767
        self.reload()
517
768
        self._get_parser().setdefault(section, {})[option] = value
518
769
        self._write_config_file()
519
770
 
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):
 
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):
529
797
    """A configuration object that gives the policy for a location."""
530
798
 
531
799
    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)
 
800
        super(LocationConfig, self).__init__(
 
801
            file_name=locations_config_filename())
544
802
        # local file locations are looked up by local path, rather than
545
803
        # by file url. This is because the config file is a user
546
804
        # file, and we would rather not expose the user to file urls.
548
806
            location = urlutils.local_path_from_url(location)
549
807
        self.location = location
550
808
 
 
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
 
551
827
    def _get_matching_sections(self):
552
828
        """Return an ordered list of section names matching this location."""
553
829
        sections = self._get_parser()
570
846
            names = zip(location_names, section_names)
571
847
            matched = True
572
848
            for name in names:
573
 
                if not fnmatch(name[0], name[1]):
 
849
                if not fnmatch.fnmatch(name[0], name[1]):
574
850
                    matched = False
575
851
                    break
576
852
            if not matched:
581
857
                continue
582
858
            matches.append((len(section_names), section,
583
859
                            '/'.join(location_names[len(section_names):])))
 
860
        # put the longest (aka more specific) locations first
584
861
        matches.sort(reverse=True)
585
862
        sections = []
586
863
        for (length, section, extra_path) in matches:
593
870
                pass
594
871
        return sections
595
872
 
 
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
 
596
881
    def _get_option_policy(self, section, option_name):
597
882
        """Return the policy for the given (section, option_name) pair."""
598
883
        # check for the old 'recurse=False' flag
641
926
            if policy_key in self._get_parser()[section]:
642
927
                del self._get_parser()[section][policy_key]
643
928
 
 
929
    @needs_write_lock
644
930
    def set_user_option(self, option, value, store=STORE_LOCATION):
645
931
        """Save option and its value in the configuration."""
646
932
        if store not in [STORE_LOCATION,
648
934
                         STORE_LOCATION_APPENDPATH]:
649
935
            raise ValueError('bad storage policy %r for %r' %
650
936
                (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)
 
937
        self.reload()
655
938
        location = self.location
656
939
        if location.endswith('/'):
657
940
            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():
 
941
        parser = self._get_parser()
 
942
        if not location in parser and not location + '/' in parser:
 
943
            parser[location] = {}
 
944
        elif location + '/' in parser:
662
945
            location = location + '/'
663
 
        self._get_parser()[location][option]=value
 
946
        parser[location][option]=value
664
947
        # the allowed values of store match the config policies
665
948
        self._set_option_policy(location, option, store)
666
 
        self._get_parser().write(file(self._get_filename(), 'wb'))
 
949
        self._write_config_file()
667
950
 
668
951
 
669
952
class BranchConfig(Config):
670
953
    """A configuration object giving the policy for a branch."""
671
954
 
 
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
 
672
968
    def _get_branch_data_config(self):
673
969
        if self._branch_data_config is None:
674
970
            self._branch_data_config = TreeConfig(self.branch)
 
971
            self._branch_data_config.config_id = self.config_id
675
972
        return self._branch_data_config
676
973
 
677
974
    def _get_location_config(self):
745
1042
                return value
746
1043
        return None
747
1044
 
 
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
 
748
1071
    def set_user_option(self, name, value, store=STORE_BRANCH,
749
1072
        warn_masked=False):
750
1073
        if store == STORE_BRANCH:
768
1091
                        trace.warning('Value "%s" is masked by "%s" from'
769
1092
                                      ' branch.conf', value, mask_value)
770
1093
 
 
1094
    def remove_user_option(self, option_name, section_name=None):
 
1095
        self._get_branch_data_config().remove_option(option_name, section_name)
 
1096
 
771
1097
    def _gpg_signing_command(self):
772
1098
        """See Config.gpg_signing_command."""
773
1099
        return self._get_safe_value('_gpg_signing_command')
774
1100
 
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
1101
    def _post_commit(self):
786
1102
        """See Config.post_commit."""
787
1103
        return self._get_safe_value('_post_commit')
817
1133
            parent_dir = os.path.dirname(path)
818
1134
            if not os.path.isdir(parent_dir):
819
1135
                trace.mutter('creating config parent directory: %r', parent_dir)
820
 
            os.mkdir(parent_dir)
 
1136
                os.mkdir(parent_dir)
821
1137
        trace.mutter('creating config directory: %r', path)
822
1138
        os.mkdir(path)
823
1139
        osutils.copy_ownership_from_path(path)
826
1142
def config_dir():
827
1143
    """Return per-user configuration directory.
828
1144
 
829
 
    By default this is ~/.bazaar/
 
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.
830
1148
 
831
1149
    TODO: Global option --config-dir to override this.
832
1150
    """
833
1151
    base = os.environ.get('BZR_HOME', None)
834
1152
    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')
835
1157
        if base is None:
836
1158
            base = win32utils.get_appdata_location_unicode()
837
1159
        if base is None:
838
1160
            base = os.environ.get('HOME', None)
 
1161
            if base is not None:
 
1162
                base = base.decode('mbcs')
839
1163
        if base is None:
840
1164
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
841
1165
                                  ' or HOME set')
842
1166
        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')
843
1172
    else:
844
 
        # cygwin, linux, and darwin all have a $HOME directory
845
1173
        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
 
846
1184
            base = os.path.expanduser("~")
847
1185
        return osutils.pathjoin(base, ".bazaar")
848
1186
 
852
1190
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
853
1191
 
854
1192
 
855
 
def branches_config_filename():
856
 
    """Return per-user configuration ini file filename."""
857
 
    return osutils.pathjoin(config_dir(), 'branches.conf')
858
 
 
859
 
 
860
1193
def locations_config_filename():
861
1194
    """Return per-user configuration ini file filename."""
862
1195
    return osutils.pathjoin(config_dir(), 'locations.conf')
899
1232
        return os.path.expanduser('~/.cache')
900
1233
 
901
1234
 
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
1235
def parse_username(username):
976
1236
    """Parse e-mail username and return a (name, address) tuple."""
977
1237
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1020
1280
 
1021
1281
    def set_option(self, value, name, section=None):
1022
1282
        """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
1023
1285
        self.branch.lock_write()
1024
1286
        try:
1025
1287
            self._config.set_option(value, name, section)
1026
1288
        finally:
1027
1289
            self.branch.unlock()
1028
1290
 
 
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
 
1029
1300
 
1030
1301
class AuthenticationConfig(object):
1031
1302
    """The authentication configuration file based on a ini file.
1063
1334
        """Save the config file, only tests should use it for now."""
1064
1335
        conf_dir = os.path.dirname(self._filename)
1065
1336
        ensure_config_dir_exists(conf_dir)
1066
 
        self._get_config().write(file(self._filename, 'wb'))
 
1337
        f = file(self._filename, 'wb')
 
1338
        try:
 
1339
            self._get_config().write(f)
 
1340
        finally:
 
1341
            f.close()
1067
1342
 
1068
1343
    def _set_option(self, section_name, option_name, value):
1069
1344
        """Set an authentication configuration option"""
1470
1745
    """A Config that reads/writes a config file on a Transport.
1471
1746
 
1472
1747
    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.
 
1748
    that may be associated with a section.  Assigning meaning to these values
 
1749
    is done at higher levels like TreeConfig.
1475
1750
    """
1476
1751
 
1477
1752
    def __init__(self, transport, filename):
1510
1785
            configobj.setdefault(section, {})[name] = value
1511
1786
        self._set_configobj(configobj)
1512
1787
 
 
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
 
1513
1796
    def _get_config_file(self):
1514
1797
        try:
1515
1798
            return StringIO(self._transport.get_bytes(self._filename))
1517
1800
            return StringIO()
1518
1801
 
1519
1802
    def _get_configobj(self):
1520
 
        return ConfigObj(self._get_config_file(), encoding='utf-8')
 
1803
        f = self._get_config_file()
 
1804
        try:
 
1805
            return ConfigObj(f, encoding='utf-8')
 
1806
        finally:
 
1807
            f.close()
1521
1808
 
1522
1809
    def _set_configobj(self, configobj):
1523
1810
        out_file = StringIO()
1524
1811
        configobj.write(out_file)
1525
1812
        out_file.seek(0)
1526
1813
        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)