~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: IWATA Hidetaka
  • Date: 2010-12-26 13:19:11 UTC
  • mto: This revision was merged to the branch mainline in revision 5593.
  • Revision ID: iwata0303@gmail.com-20101226131911-o7txs0fnji5zekq1
add icon resources tbzrcommand(w)

Show diffs side-by-side

added added

removed removed

Lines of Context:
65
65
import os
66
66
import sys
67
67
 
 
68
from bzrlib import commands
 
69
from bzrlib.decorators import needs_write_lock
68
70
from bzrlib.lazy_import import lazy_import
69
71
lazy_import(globals(), """
70
72
import errno
71
 
from fnmatch import fnmatch
 
73
import fnmatch
72
74
import re
73
75
from cStringIO import StringIO
74
76
 
75
77
import bzrlib
76
78
from bzrlib import (
 
79
    atomicfile,
 
80
    bzrdir,
77
81
    debug,
78
82
    errors,
 
83
    lockdir,
79
84
    mail_client,
80
85
    osutils,
81
86
    registry,
82
87
    symbol_versioning,
83
88
    trace,
 
89
    transport,
84
90
    ui,
85
91
    urlutils,
86
92
    win32utils,
149
155
    def __init__(self):
150
156
        super(Config, self).__init__()
151
157
 
 
158
    def config_id(self):
 
159
        """Returns a unique ID for the config."""
 
160
        raise NotImplementedError(self.config_id)
 
161
 
152
162
    def get_editor(self):
153
163
        """Get the users pop up editor."""
154
164
        raise NotImplementedError
193
203
            interpreted as a boolean. Returns True or False otherwise.
194
204
        """
195
205
        s = self._get_user_option(option_name)
196
 
        return ui.bool_from_string(s)
 
206
        if s is None:
 
207
            # The option doesn't exist
 
208
            return None
 
209
        val = ui.bool_from_string(s)
 
210
        if val is None:
 
211
            # The value can't be interpreted as a boolean
 
212
            trace.warning('Value "%s" is not a boolean for "%s"',
 
213
                          s, option_name)
 
214
        return val
197
215
 
198
216
    def get_user_option_as_list(self, option_name):
199
217
        """Get a generic option as a list - no special process, no default.
249
267
 
250
268
        Something similar to 'Martin Pool <mbp@sourcefrog.net>'
251
269
 
252
 
        $BZR_EMAIL can be set to override this (as well as the
253
 
        deprecated $BZREMAIL), then
 
270
        $BZR_EMAIL can be set to override this, then
254
271
        the concrete policy type is checked, and finally
255
272
        $EMAIL is examined.
256
 
        If none is found, a reasonable default is (hopefully)
257
 
        created.
 
273
        If no username can be found, errors.NoWhoami exception is raised.
258
274
 
259
275
        TODO: Check it's reasonably well-formed.
260
276
        """
270
286
        if v:
271
287
            return v.decode(osutils.get_user_encoding())
272
288
 
273
 
        name, email = _auto_user_id()
274
 
        if name:
275
 
            return '%s <%s>' % (name, email)
276
 
        else:
277
 
            return email
 
289
        raise errors.NoWhoami()
 
290
 
 
291
    def ensure_username(self):
 
292
        """Raise errors.NoWhoami if username is not set.
 
293
 
 
294
        This method relies on the username() function raising the error.
 
295
        """
 
296
        self.username()
278
297
 
279
298
    def signature_checking(self):
280
299
        """What is the current policy for signature checking?."""
342
361
class IniBasedConfig(Config):
343
362
    """A configuration policy that draws from ini files."""
344
363
 
345
 
    def __init__(self, get_filename):
 
364
    def __init__(self, get_filename=symbol_versioning.DEPRECATED_PARAMETER,
 
365
                 file_name=None):
 
366
        """Base class for configuration files using an ini-like syntax.
 
367
 
 
368
        :param file_name: The configuration file path.
 
369
        """
346
370
        super(IniBasedConfig, self).__init__()
347
 
        self._get_filename = get_filename
 
371
        self.file_name = file_name
 
372
        if symbol_versioning.deprecated_passed(get_filename):
 
373
            symbol_versioning.warn(
 
374
                'IniBasedConfig.__init__(get_filename) was deprecated in 2.3.'
 
375
                ' Use file_name instead.',
 
376
                DeprecationWarning,
 
377
                stacklevel=2)
 
378
            if get_filename is not None:
 
379
                self.file_name = get_filename()
 
380
        else:
 
381
            self.file_name = file_name
 
382
        self._content = None
348
383
        self._parser = None
349
384
 
350
 
    def _get_parser(self, file=None):
 
385
    @classmethod
 
386
    def from_string(cls, str_or_unicode, file_name=None, save=False):
 
387
        """Create a config object from a string.
 
388
 
 
389
        :param str_or_unicode: A string representing the file content. This will
 
390
            be utf-8 encoded.
 
391
 
 
392
        :param file_name: The configuration file path.
 
393
 
 
394
        :param _save: Whether the file should be saved upon creation.
 
395
        """
 
396
        conf = cls(file_name=file_name)
 
397
        conf._create_from_string(str_or_unicode, save)
 
398
        return conf
 
399
 
 
400
    def _create_from_string(self, str_or_unicode, save):
 
401
        self._content = StringIO(str_or_unicode.encode('utf-8'))
 
402
        # Some tests use in-memory configs, some other always need the config
 
403
        # file to exist on disk.
 
404
        if save:
 
405
            self._write_config_file()
 
406
 
 
407
    def _get_parser(self, file=symbol_versioning.DEPRECATED_PARAMETER):
351
408
        if self._parser is not None:
352
409
            return self._parser
353
 
        if file is None:
354
 
            input = self._get_filename()
 
410
        if symbol_versioning.deprecated_passed(file):
 
411
            symbol_versioning.warn(
 
412
                'IniBasedConfig._get_parser(file=xxx) was deprecated in 2.3.'
 
413
                ' Use IniBasedConfig(_content=xxx) instead.',
 
414
                DeprecationWarning,
 
415
                stacklevel=2)
 
416
        if self._content is not None:
 
417
            co_input = self._content
 
418
        elif self.file_name is None:
 
419
            raise AssertionError('We have no content to create the config')
355
420
        else:
356
 
            input = file
 
421
            co_input = self.file_name
357
422
        try:
358
 
            self._parser = ConfigObj(input, encoding='utf-8')
 
423
            self._parser = ConfigObj(co_input, encoding='utf-8')
359
424
        except configobj.ConfigObjError, e:
360
425
            raise errors.ParseConfigError(e.errors, e.config.filename)
 
426
        # Make sure self.reload() will use the right file name
 
427
        self._parser.filename = self.file_name
361
428
        return self._parser
362
429
 
 
430
    def reload(self):
 
431
        """Reload the config file from disk."""
 
432
        if self.file_name is None:
 
433
            raise AssertionError('We need a file name to reload the config')
 
434
        if self._parser is not None:
 
435
            self._parser.reload()
 
436
 
363
437
    def _get_matching_sections(self):
364
438
        """Return an ordered list of (section_name, extra_path) pairs.
365
439
 
376
450
        """Override this to define the section used by the config."""
377
451
        return "DEFAULT"
378
452
 
 
453
    def _get_sections(self, name=None):
 
454
        """Returns an iterator of the sections specified by ``name``.
 
455
 
 
456
        :param name: The section name. If None is supplied, the default
 
457
            configurations are yielded.
 
458
 
 
459
        :return: A tuple (name, section, config_id) for all sections that will
 
460
            be walked by user_get_option() in the 'right' order. The first one
 
461
            is where set_user_option() will update the value.
 
462
        """
 
463
        parser = self._get_parser()
 
464
        if name is not None:
 
465
            yield (name, parser[name], self.config_id())
 
466
        else:
 
467
            # No section name has been given so we fallback to the configobj
 
468
            # itself which holds the variables defined outside of any section.
 
469
            yield (None, parser, self.config_id())
 
470
 
 
471
    def _get_options(self, sections=None):
 
472
        """Return an ordered list of (name, value, section, config_id) tuples.
 
473
 
 
474
        All options are returned with their associated value and the section
 
475
        they appeared in. ``config_id`` is a unique identifier for the
 
476
        configuration file the option is defined in.
 
477
 
 
478
        :param sections: Default to ``_get_matching_sections`` if not
 
479
            specified. This gives a better control to daughter classes about
 
480
            which sections should be searched. This is a list of (name,
 
481
            configobj) tuples.
 
482
        """
 
483
        opts = []
 
484
        if sections is None:
 
485
            parser = self._get_parser()
 
486
            sections = []
 
487
            for (section_name, _) in self._get_matching_sections():
 
488
                try:
 
489
                    section = parser[section_name]
 
490
                except KeyError:
 
491
                    # This could happen for an empty file for which we define a
 
492
                    # DEFAULT section. FIXME: Force callers to provide sections
 
493
                    # instead ? -- vila 20100930
 
494
                    continue
 
495
                sections.append((section_name, section))
 
496
        config_id = self.config_id()
 
497
        for (section_name, section) in sections:
 
498
            for (name, value) in section.iteritems():
 
499
                yield (name, parser._quote(value), section_name,
 
500
                       config_id, parser)
 
501
 
379
502
    def _get_option_policy(self, section, option_name):
380
503
        """Return the policy for the given (section, option_name) pair."""
381
504
        return POLICY_NONE
468
591
    def _get_nickname(self):
469
592
        return self.get_user_option('nickname')
470
593
 
471
 
 
472
 
class GlobalConfig(IniBasedConfig):
 
594
    def remove_user_option(self, option_name, section_name=None):
 
595
        """Remove a user option and save the configuration file.
 
596
 
 
597
        :param option_name: The option to be removed.
 
598
 
 
599
        :param section_name: The section the option is defined in, default to
 
600
            the default section.
 
601
        """
 
602
        self.reload()
 
603
        parser = self._get_parser()
 
604
        if section_name is None:
 
605
            section = parser
 
606
        else:
 
607
            section = parser[section_name]
 
608
        try:
 
609
            del section[option_name]
 
610
        except KeyError:
 
611
            raise errors.NoSuchConfigOption(option_name)
 
612
        self._write_config_file()
 
613
 
 
614
    def _write_config_file(self):
 
615
        if self.file_name is None:
 
616
            raise AssertionError('We cannot save, self.file_name is None')
 
617
        conf_dir = os.path.dirname(self.file_name)
 
618
        ensure_config_dir_exists(conf_dir)
 
619
        atomic_file = atomicfile.AtomicFile(self.file_name)
 
620
        self._get_parser().write(atomic_file)
 
621
        atomic_file.commit()
 
622
        atomic_file.close()
 
623
        osutils.copy_ownership_from_path(self.file_name)
 
624
 
 
625
 
 
626
class LockableConfig(IniBasedConfig):
 
627
    """A configuration needing explicit locking for access.
 
628
 
 
629
    If several processes try to write the config file, the accesses need to be
 
630
    serialized.
 
631
 
 
632
    Daughter classes should decorate all methods that update a config with the
 
633
    ``@needs_write_lock`` decorator (they call, directly or indirectly, the
 
634
    ``_write_config_file()`` method. These methods (typically ``set_option()``
 
635
    and variants must reload the config file from disk before calling
 
636
    ``_write_config_file()``), this can be achieved by calling the
 
637
    ``self.reload()`` method. Note that the lock scope should cover both the
 
638
    reading and the writing of the config file which is why the decorator can't
 
639
    be applied to ``_write_config_file()`` only.
 
640
 
 
641
    This should be enough to implement the following logic:
 
642
    - lock for exclusive write access,
 
643
    - reload the config file from disk,
 
644
    - set the new value
 
645
    - unlock
 
646
 
 
647
    This logic guarantees that a writer can update a value without erasing an
 
648
    update made by another writer.
 
649
    """
 
650
 
 
651
    lock_name = 'lock'
 
652
 
 
653
    def __init__(self, file_name):
 
654
        super(LockableConfig, self).__init__(file_name=file_name)
 
655
        self.dir = osutils.dirname(osutils.safe_unicode(self.file_name))
 
656
        self.transport = transport.get_transport(self.dir)
 
657
        self._lock = lockdir.LockDir(self.transport, 'lock')
 
658
 
 
659
    def _create_from_string(self, unicode_bytes, save):
 
660
        super(LockableConfig, self)._create_from_string(unicode_bytes, False)
 
661
        if save:
 
662
            # We need to handle the saving here (as opposed to IniBasedConfig)
 
663
            # to be able to lock
 
664
            self.lock_write()
 
665
            self._write_config_file()
 
666
            self.unlock()
 
667
 
 
668
    def lock_write(self, token=None):
 
669
        """Takes a write lock in the directory containing the config file.
 
670
 
 
671
        If the directory doesn't exist it is created.
 
672
        """
 
673
        ensure_config_dir_exists(self.dir)
 
674
        return self._lock.lock_write(token)
 
675
 
 
676
    def unlock(self):
 
677
        self._lock.unlock()
 
678
 
 
679
    def break_lock(self):
 
680
        self._lock.break_lock()
 
681
 
 
682
    @needs_write_lock
 
683
    def remove_user_option(self, option_name, section_name=None):
 
684
        super(LockableConfig, self).remove_user_option(option_name,
 
685
                                                       section_name)
 
686
 
 
687
    def _write_config_file(self):
 
688
        if self._lock is None or not self._lock.is_held:
 
689
            # NB: if the following exception is raised it probably means a
 
690
            # missing @needs_write_lock decorator on one of the callers.
 
691
            raise errors.ObjectNotLocked(self)
 
692
        super(LockableConfig, self)._write_config_file()
 
693
 
 
694
 
 
695
class GlobalConfig(LockableConfig):
473
696
    """The configuration that should be used for a specific location."""
474
697
 
 
698
    def __init__(self):
 
699
        super(GlobalConfig, self).__init__(file_name=config_filename())
 
700
 
 
701
    def config_id(self):
 
702
        return 'bazaar'
 
703
 
 
704
    @classmethod
 
705
    def from_string(cls, str_or_unicode, save=False):
 
706
        """Create a config object from a string.
 
707
 
 
708
        :param str_or_unicode: A string representing the file content. This
 
709
            will be utf-8 encoded.
 
710
 
 
711
        :param save: Whether the file should be saved upon creation.
 
712
        """
 
713
        conf = cls()
 
714
        conf._create_from_string(str_or_unicode, save)
 
715
        return conf
 
716
 
475
717
    def get_editor(self):
476
718
        return self._get_user_option('editor')
477
719
 
478
 
    def __init__(self):
479
 
        super(GlobalConfig, self).__init__(config_filename)
480
 
 
 
720
    @needs_write_lock
481
721
    def set_user_option(self, option, value):
482
722
        """Save option and its value in the configuration."""
483
723
        self._set_option(option, value, 'DEFAULT')
489
729
        else:
490
730
            return {}
491
731
 
 
732
    @needs_write_lock
492
733
    def set_alias(self, alias_name, alias_command):
493
734
        """Save the alias in the configuration."""
494
735
        self._set_option(alias_name, alias_command, 'ALIASES')
495
736
 
 
737
    @needs_write_lock
496
738
    def unset_alias(self, alias_name):
497
739
        """Unset an existing alias."""
 
740
        self.reload()
498
741
        aliases = self._get_parser().get('ALIASES')
499
742
        if not aliases or alias_name not in aliases:
500
743
            raise errors.NoSuchAlias(alias_name)
502
745
        self._write_config_file()
503
746
 
504
747
    def _set_option(self, option, value, section):
505
 
        # FIXME: RBC 20051029 This should refresh the parser and also take a
506
 
        # file lock on bazaar.conf.
507
 
        conf_dir = os.path.dirname(self._get_filename())
508
 
        ensure_config_dir_exists(conf_dir)
 
748
        self.reload()
509
749
        self._get_parser().setdefault(section, {})[option] = value
510
750
        self._write_config_file()
511
751
 
512
 
    def _write_config_file(self):
513
 
        path = self._get_filename()
514
 
        f = osutils.open_with_ownership(path, 'wb')
515
 
        self._get_parser().write(f)
516
 
        f.close()
517
 
 
518
 
 
519
 
class LocationConfig(IniBasedConfig):
 
752
 
 
753
    def _get_sections(self, name=None):
 
754
        """See IniBasedConfig._get_sections()."""
 
755
        parser = self._get_parser()
 
756
        # We don't give access to options defined outside of any section, we
 
757
        # used the DEFAULT section by... default.
 
758
        if name in (None, 'DEFAULT'):
 
759
            # This could happen for an empty file where the DEFAULT section
 
760
            # doesn't exist yet. So we force DEFAULT when yielding
 
761
            name = 'DEFAULT'
 
762
            if 'DEFAULT' not in parser:
 
763
               parser['DEFAULT']= {}
 
764
        yield (name, parser[name], self.config_id())
 
765
 
 
766
    @needs_write_lock
 
767
    def remove_user_option(self, option_name, section_name=None):
 
768
        if section_name is None:
 
769
            # We need to force the default section.
 
770
            section_name = 'DEFAULT'
 
771
        # We need to avoid the LockableConfig implementation or we'll lock
 
772
        # twice
 
773
        super(LockableConfig, self).remove_user_option(option_name,
 
774
                                                       section_name)
 
775
 
 
776
 
 
777
class LocationConfig(LockableConfig):
520
778
    """A configuration object that gives the policy for a location."""
521
779
 
522
780
    def __init__(self, location):
523
 
        name_generator = locations_config_filename
524
 
        if (not os.path.exists(name_generator()) and
525
 
                os.path.exists(branches_config_filename())):
526
 
            if sys.platform == 'win32':
527
 
                trace.warning('Please rename %s to %s'
528
 
                              % (branches_config_filename(),
529
 
                                 locations_config_filename()))
530
 
            else:
531
 
                trace.warning('Please rename ~/.bazaar/branches.conf'
532
 
                              ' to ~/.bazaar/locations.conf')
533
 
            name_generator = branches_config_filename
534
 
        super(LocationConfig, self).__init__(name_generator)
 
781
        super(LocationConfig, self).__init__(
 
782
            file_name=locations_config_filename())
535
783
        # local file locations are looked up by local path, rather than
536
784
        # by file url. This is because the config file is a user
537
785
        # file, and we would rather not expose the user to file urls.
539
787
            location = urlutils.local_path_from_url(location)
540
788
        self.location = location
541
789
 
 
790
    def config_id(self):
 
791
        return 'locations'
 
792
 
 
793
    @classmethod
 
794
    def from_string(cls, str_or_unicode, location, save=False):
 
795
        """Create a config object from a string.
 
796
 
 
797
        :param str_or_unicode: A string representing the file content. This will
 
798
            be utf-8 encoded.
 
799
 
 
800
        :param location: The location url to filter the configuration.
 
801
 
 
802
        :param save: Whether the file should be saved upon creation.
 
803
        """
 
804
        conf = cls(location)
 
805
        conf._create_from_string(str_or_unicode, save)
 
806
        return conf
 
807
 
542
808
    def _get_matching_sections(self):
543
809
        """Return an ordered list of section names matching this location."""
544
810
        sections = self._get_parser()
561
827
            names = zip(location_names, section_names)
562
828
            matched = True
563
829
            for name in names:
564
 
                if not fnmatch(name[0], name[1]):
 
830
                if not fnmatch.fnmatch(name[0], name[1]):
565
831
                    matched = False
566
832
                    break
567
833
            if not matched:
572
838
                continue
573
839
            matches.append((len(section_names), section,
574
840
                            '/'.join(location_names[len(section_names):])))
 
841
        # put the longest (aka more specific) locations first
575
842
        matches.sort(reverse=True)
576
843
        sections = []
577
844
        for (length, section, extra_path) in matches:
584
851
                pass
585
852
        return sections
586
853
 
 
854
    def _get_sections(self, name=None):
 
855
        """See IniBasedConfig._get_sections()."""
 
856
        # We ignore the name here as the only sections handled are named with
 
857
        # the location path and we don't expose embedded sections either.
 
858
        parser = self._get_parser()
 
859
        for name, extra_path in self._get_matching_sections():
 
860
            yield (name, parser[name], self.config_id())
 
861
 
587
862
    def _get_option_policy(self, section, option_name):
588
863
        """Return the policy for the given (section, option_name) pair."""
589
864
        # check for the old 'recurse=False' flag
632
907
            if policy_key in self._get_parser()[section]:
633
908
                del self._get_parser()[section][policy_key]
634
909
 
 
910
    @needs_write_lock
635
911
    def set_user_option(self, option, value, store=STORE_LOCATION):
636
912
        """Save option and its value in the configuration."""
637
913
        if store not in [STORE_LOCATION,
639
915
                         STORE_LOCATION_APPENDPATH]:
640
916
            raise ValueError('bad storage policy %r for %r' %
641
917
                (store, option))
642
 
        # FIXME: RBC 20051029 This should refresh the parser and also take a
643
 
        # file lock on locations.conf.
644
 
        conf_dir = os.path.dirname(self._get_filename())
645
 
        ensure_config_dir_exists(conf_dir)
 
918
        self.reload()
646
919
        location = self.location
647
920
        if location.endswith('/'):
648
921
            location = location[:-1]
649
 
        if (not location in self._get_parser() and
650
 
            not location + '/' in self._get_parser()):
651
 
            self._get_parser()[location]={}
652
 
        elif location + '/' in self._get_parser():
 
922
        parser = self._get_parser()
 
923
        if not location in parser and not location + '/' in parser:
 
924
            parser[location] = {}
 
925
        elif location + '/' in parser:
653
926
            location = location + '/'
654
 
        self._get_parser()[location][option]=value
 
927
        parser[location][option]=value
655
928
        # the allowed values of store match the config policies
656
929
        self._set_option_policy(location, option, store)
657
 
        self._get_parser().write(file(self._get_filename(), 'wb'))
 
930
        self._write_config_file()
658
931
 
659
932
 
660
933
class BranchConfig(Config):
661
934
    """A configuration object giving the policy for a branch."""
662
935
 
 
936
    def __init__(self, branch):
 
937
        super(BranchConfig, self).__init__()
 
938
        self._location_config = None
 
939
        self._branch_data_config = None
 
940
        self._global_config = None
 
941
        self.branch = branch
 
942
        self.option_sources = (self._get_location_config,
 
943
                               self._get_branch_data_config,
 
944
                               self._get_global_config)
 
945
 
 
946
    def config_id(self):
 
947
        return 'branch'
 
948
 
663
949
    def _get_branch_data_config(self):
664
950
        if self._branch_data_config is None:
665
951
            self._branch_data_config = TreeConfig(self.branch)
 
952
            self._branch_data_config.config_id = self.config_id
666
953
        return self._branch_data_config
667
954
 
668
955
    def _get_location_config(self):
736
1023
                return value
737
1024
        return None
738
1025
 
 
1026
    def _get_sections(self, name=None):
 
1027
        """See IniBasedConfig.get_sections()."""
 
1028
        for source in self.option_sources:
 
1029
            for section in source()._get_sections(name):
 
1030
                yield section
 
1031
 
 
1032
    def _get_options(self, sections=None):
 
1033
        opts = []
 
1034
        # First the locations options
 
1035
        for option in self._get_location_config()._get_options():
 
1036
            yield option
 
1037
        # Then the branch options
 
1038
        branch_config = self._get_branch_data_config()
 
1039
        if sections is None:
 
1040
            sections = [('DEFAULT', branch_config._get_parser())]
 
1041
        # FIXME: We shouldn't have to duplicate the code in IniBasedConfig but
 
1042
        # Config itself has no notion of sections :( -- vila 20101001
 
1043
        config_id = self.config_id()
 
1044
        for (section_name, section) in sections:
 
1045
            for (name, value) in section.iteritems():
 
1046
                yield (name, value, section_name,
 
1047
                       config_id, branch_config._get_parser())
 
1048
        # Then the global options
 
1049
        for option in self._get_global_config()._get_options():
 
1050
            yield option
 
1051
 
739
1052
    def set_user_option(self, name, value, store=STORE_BRANCH,
740
1053
        warn_masked=False):
741
1054
        if store == STORE_BRANCH:
759
1072
                        trace.warning('Value "%s" is masked by "%s" from'
760
1073
                                      ' branch.conf', value, mask_value)
761
1074
 
 
1075
    def remove_user_option(self, option_name, section_name=None):
 
1076
        self._get_branch_data_config().remove_option(option_name, section_name)
 
1077
 
762
1078
    def _gpg_signing_command(self):
763
1079
        """See Config.gpg_signing_command."""
764
1080
        return self._get_safe_value('_gpg_signing_command')
765
1081
 
766
 
    def __init__(self, branch):
767
 
        super(BranchConfig, self).__init__()
768
 
        self._location_config = None
769
 
        self._branch_data_config = None
770
 
        self._global_config = None
771
 
        self.branch = branch
772
 
        self.option_sources = (self._get_location_config,
773
 
                               self._get_branch_data_config,
774
 
                               self._get_global_config)
775
 
 
776
1082
    def _post_commit(self):
777
1083
        """See Config.post_commit."""
778
1084
        return self._get_safe_value('_post_commit')
808
1114
            parent_dir = os.path.dirname(path)
809
1115
            if not os.path.isdir(parent_dir):
810
1116
                trace.mutter('creating config parent directory: %r', parent_dir)
811
 
            os.mkdir(parent_dir)
 
1117
                os.mkdir(parent_dir)
812
1118
        trace.mutter('creating config directory: %r', path)
813
 
        osutils.mkdir_with_ownership(path)
 
1119
        os.mkdir(path)
 
1120
        osutils.copy_ownership_from_path(path)
814
1121
 
815
1122
 
816
1123
def config_dir():
817
1124
    """Return per-user configuration directory.
818
1125
 
819
 
    By default this is ~/.bazaar/
 
1126
    By default this is %APPDATA%/bazaar/2.0 on Windows, ~/.bazaar on Mac OS X
 
1127
    and Linux.  On Linux, if there is a $XDG_CONFIG_HOME/bazaar directory,
 
1128
    that will be used instead.
820
1129
 
821
1130
    TODO: Global option --config-dir to override this.
822
1131
    """
830
1139
            raise errors.BzrError('You must have one of BZR_HOME, APPDATA,'
831
1140
                                  ' or HOME set')
832
1141
        return osutils.pathjoin(base, 'bazaar', '2.0')
 
1142
    elif sys.platform == 'darwin':
 
1143
        if base is None:
 
1144
            # this takes into account $HOME
 
1145
            base = os.path.expanduser("~")
 
1146
        return osutils.pathjoin(base, '.bazaar')
833
1147
    else:
834
 
        # cygwin, linux, and darwin all have a $HOME directory
835
1148
        if base is None:
 
1149
 
 
1150
            xdg_dir = os.environ.get('XDG_CONFIG_HOME', None)
 
1151
            if xdg_dir is None:
 
1152
                xdg_dir = osutils.pathjoin(os.path.expanduser("~"), ".config")
 
1153
            xdg_dir = osutils.pathjoin(xdg_dir, 'bazaar')
 
1154
            if osutils.isdir(xdg_dir):
 
1155
                trace.mutter(
 
1156
                    "Using configuration in XDG directory %s." % xdg_dir)
 
1157
                return xdg_dir
 
1158
 
836
1159
            base = os.path.expanduser("~")
837
1160
        return osutils.pathjoin(base, ".bazaar")
838
1161
 
842
1165
    return osutils.pathjoin(config_dir(), 'bazaar.conf')
843
1166
 
844
1167
 
845
 
def branches_config_filename():
846
 
    """Return per-user configuration ini file filename."""
847
 
    return osutils.pathjoin(config_dir(), 'branches.conf')
848
 
 
849
 
 
850
1168
def locations_config_filename():
851
1169
    """Return per-user configuration ini file filename."""
852
1170
    return osutils.pathjoin(config_dir(), 'locations.conf')
889
1207
        return os.path.expanduser('~/.cache')
890
1208
 
891
1209
 
892
 
def _auto_user_id():
893
 
    """Calculate automatic user identification.
894
 
 
895
 
    Returns (realname, email).
896
 
 
897
 
    Only used when none is set in the environment or the id file.
898
 
 
899
 
    This previously used the FQDN as the default domain, but that can
900
 
    be very slow on machines where DNS is broken.  So now we simply
901
 
    use the hostname.
902
 
    """
903
 
    import socket
904
 
 
905
 
    if sys.platform == 'win32':
906
 
        name = win32utils.get_user_name_unicode()
907
 
        if name is None:
908
 
            raise errors.BzrError("Cannot autodetect user name.\n"
909
 
                                  "Please, set your name with command like:\n"
910
 
                                  'bzr whoami "Your Name <name@domain.com>"')
911
 
        host = win32utils.get_host_name_unicode()
912
 
        if host is None:
913
 
            host = socket.gethostname()
914
 
        return name, (name + '@' + host)
915
 
 
916
 
    try:
917
 
        import pwd
918
 
        uid = os.getuid()
919
 
        try:
920
 
            w = pwd.getpwuid(uid)
921
 
        except KeyError:
922
 
            raise errors.BzrCommandError('Unable to determine your name.  '
923
 
                'Please use "bzr whoami" to set it.')
924
 
 
925
 
        # we try utf-8 first, because on many variants (like Linux),
926
 
        # /etc/passwd "should" be in utf-8, and because it's unlikely to give
927
 
        # false positives.  (many users will have their user encoding set to
928
 
        # latin-1, which cannot raise UnicodeError.)
929
 
        try:
930
 
            gecos = w.pw_gecos.decode('utf-8')
931
 
            encoding = 'utf-8'
932
 
        except UnicodeError:
933
 
            try:
934
 
                encoding = osutils.get_user_encoding()
935
 
                gecos = w.pw_gecos.decode(encoding)
936
 
            except UnicodeError:
937
 
                raise errors.BzrCommandError('Unable to determine your name.  '
938
 
                   'Use "bzr whoami" to set it.')
939
 
        try:
940
 
            username = w.pw_name.decode(encoding)
941
 
        except UnicodeError:
942
 
            raise errors.BzrCommandError('Unable to determine your name.  '
943
 
                'Use "bzr whoami" to set it.')
944
 
 
945
 
        comma = gecos.find(',')
946
 
        if comma == -1:
947
 
            realname = gecos
948
 
        else:
949
 
            realname = gecos[:comma]
950
 
        if not realname:
951
 
            realname = username
952
 
 
953
 
    except ImportError:
954
 
        import getpass
955
 
        try:
956
 
            user_encoding = osutils.get_user_encoding()
957
 
            realname = username = getpass.getuser().decode(user_encoding)
958
 
        except UnicodeDecodeError:
959
 
            raise errors.BzrError("Can't decode username as %s." % \
960
 
                    user_encoding)
961
 
 
962
 
    return realname, (username + '@' + socket.gethostname())
963
 
 
964
 
 
965
1210
def parse_username(username):
966
1211
    """Parse e-mail username and return a (name, address) tuple."""
967
1212
    match = re.match(r'(.*?)\s*<?([\w+.-]+@[\w+.-]+)>?', username)
1010
1255
 
1011
1256
    def set_option(self, value, name, section=None):
1012
1257
        """Set a per-branch configuration option"""
 
1258
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1259
        # higher levels providing the right lock -- vila 20101004
1013
1260
        self.branch.lock_write()
1014
1261
        try:
1015
1262
            self._config.set_option(value, name, section)
1016
1263
        finally:
1017
1264
            self.branch.unlock()
1018
1265
 
 
1266
    def remove_option(self, option_name, section_name=None):
 
1267
        # FIXME: We shouldn't need to lock explicitly here but rather rely on
 
1268
        # higher levels providing the right lock -- vila 20101004
 
1269
        self.branch.lock_write()
 
1270
        try:
 
1271
            self._config.remove_option(option_name, section_name)
 
1272
        finally:
 
1273
            self.branch.unlock()
 
1274
 
1019
1275
 
1020
1276
class AuthenticationConfig(object):
1021
1277
    """The authentication configuration file based on a ini file.
1053
1309
        """Save the config file, only tests should use it for now."""
1054
1310
        conf_dir = os.path.dirname(self._filename)
1055
1311
        ensure_config_dir_exists(conf_dir)
1056
 
        self._get_config().write(file(self._filename, 'wb'))
 
1312
        f = file(self._filename, 'wb')
 
1313
        try:
 
1314
            self._get_config().write(f)
 
1315
        finally:
 
1316
            f.close()
1057
1317
 
1058
1318
    def _set_option(self, section_name, option_name, value):
1059
1319
        """Set an authentication configuration option"""
1407
1667
 
1408
1668
 
1409
1669
class PlainTextCredentialStore(CredentialStore):
1410
 
    """Plain text credential store for the authentication.conf file."""
 
1670
    __doc__ = """Plain text credential store for the authentication.conf file"""
1411
1671
 
1412
1672
    def decode_password(self, credentials):
1413
1673
        """See CredentialStore.decode_password."""
1460
1720
    """A Config that reads/writes a config file on a Transport.
1461
1721
 
1462
1722
    It is a low-level object that considers config data to be name/value pairs
1463
 
    that may be associated with a section.  Assigning meaning to the these
1464
 
    values is done at higher levels like TreeConfig.
 
1723
    that may be associated with a section.  Assigning meaning to these values
 
1724
    is done at higher levels like TreeConfig.
1465
1725
    """
1466
1726
 
1467
1727
    def __init__(self, transport, filename):
1500
1760
            configobj.setdefault(section, {})[name] = value
1501
1761
        self._set_configobj(configobj)
1502
1762
 
 
1763
    def remove_option(self, option_name, section_name=None):
 
1764
        configobj = self._get_configobj()
 
1765
        if section_name is None:
 
1766
            del configobj[option_name]
 
1767
        else:
 
1768
            del configobj[section_name][option_name]
 
1769
        self._set_configobj(configobj)
 
1770
 
1503
1771
    def _get_config_file(self):
1504
1772
        try:
1505
1773
            return StringIO(self._transport.get_bytes(self._filename))
1507
1775
            return StringIO()
1508
1776
 
1509
1777
    def _get_configobj(self):
1510
 
        return ConfigObj(self._get_config_file(), encoding='utf-8')
 
1778
        f = self._get_config_file()
 
1779
        try:
 
1780
            return ConfigObj(f, encoding='utf-8')
 
1781
        finally:
 
1782
            f.close()
1511
1783
 
1512
1784
    def _set_configobj(self, configobj):
1513
1785
        out_file = StringIO()
1514
1786
        configobj.write(out_file)
1515
1787
        out_file.seek(0)
1516
1788
        self._transport.put_file(self._filename, out_file)
 
1789
 
 
1790
 
 
1791
class cmd_config(commands.Command):
 
1792
    __doc__ = """Display, set or remove a configuration option.
 
1793
 
 
1794
    Display the active value for a given option.
 
1795
 
 
1796
    If --all is specified, NAME is interpreted as a regular expression and all
 
1797
    matching options are displayed mentioning their scope. The active value
 
1798
    that bzr will take into account is the first one displayed for each option.
 
1799
 
 
1800
    If no NAME is given, --all .* is implied.
 
1801
 
 
1802
    Setting a value is achieved by using name=value without spaces. The value
 
1803
    is set in the most relevant scope and can be checked by displaying the
 
1804
    option again.
 
1805
    """
 
1806
 
 
1807
    takes_args = ['name?']
 
1808
 
 
1809
    takes_options = [
 
1810
        'directory',
 
1811
        # FIXME: This should be a registry option so that plugins can register
 
1812
        # their own config files (or not) -- vila 20101002
 
1813
        commands.Option('scope', help='Reduce the scope to the specified'
 
1814
                        ' configuration file',
 
1815
                        type=unicode),
 
1816
        commands.Option('all',
 
1817
            help='Display all the defined values for the matching options.',
 
1818
            ),
 
1819
        commands.Option('remove', help='Remove the option from'
 
1820
                        ' the configuration file'),
 
1821
        ]
 
1822
 
 
1823
    @commands.display_command
 
1824
    def run(self, name=None, all=False, directory=None, scope=None,
 
1825
            remove=False):
 
1826
        if directory is None:
 
1827
            directory = '.'
 
1828
        directory = urlutils.normalize_url(directory)
 
1829
        if remove and all:
 
1830
            raise errors.BzrError(
 
1831
                '--all and --remove are mutually exclusive.')
 
1832
        elif remove:
 
1833
            # Delete the option in the given scope
 
1834
            self._remove_config_option(name, directory, scope)
 
1835
        elif name is None:
 
1836
            # Defaults to all options
 
1837
            self._show_matching_options('.*', directory, scope)
 
1838
        else:
 
1839
            try:
 
1840
                name, value = name.split('=', 1)
 
1841
            except ValueError:
 
1842
                # Display the option(s) value(s)
 
1843
                if all:
 
1844
                    self._show_matching_options(name, directory, scope)
 
1845
                else:
 
1846
                    self._show_value(name, directory, scope)
 
1847
            else:
 
1848
                if all:
 
1849
                    raise errors.BzrError(
 
1850
                        'Only one option can be set.')
 
1851
                # Set the option value
 
1852
                self._set_config_option(name, value, directory, scope)
 
1853
 
 
1854
    def _get_configs(self, directory, scope=None):
 
1855
        """Iterate the configurations specified by ``directory`` and ``scope``.
 
1856
 
 
1857
        :param directory: Where the configurations are derived from.
 
1858
 
 
1859
        :param scope: A specific config to start from.
 
1860
        """
 
1861
        if scope is not None:
 
1862
            if scope == 'bazaar':
 
1863
                yield GlobalConfig()
 
1864
            elif scope == 'locations':
 
1865
                yield LocationConfig(directory)
 
1866
            elif scope == 'branch':
 
1867
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1868
                    directory)
 
1869
                yield br.get_config()
 
1870
        else:
 
1871
            try:
 
1872
                (_, br, _) = bzrdir.BzrDir.open_containing_tree_or_branch(
 
1873
                    directory)
 
1874
                yield br.get_config()
 
1875
            except errors.NotBranchError:
 
1876
                yield LocationConfig(directory)
 
1877
                yield GlobalConfig()
 
1878
 
 
1879
    def _show_value(self, name, directory, scope):
 
1880
        displayed = False
 
1881
        for c in self._get_configs(directory, scope):
 
1882
            if displayed:
 
1883
                break
 
1884
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1885
                if name == oname:
 
1886
                    # Display only the first value and exit
 
1887
 
 
1888
                    # FIXME: We need to use get_user_option to take policies
 
1889
                    # into account and we need to make sure the option exists
 
1890
                    # too (hence the two for loops), this needs a better API
 
1891
                    # -- vila 20101117
 
1892
                    value = c.get_user_option(name)
 
1893
                    # Quote the value appropriately
 
1894
                    value = parser._quote(value)
 
1895
                    self.outf.write('%s\n' % (value,))
 
1896
                    displayed = True
 
1897
                    break
 
1898
        if not displayed:
 
1899
            raise errors.NoSuchConfigOption(name)
 
1900
 
 
1901
    def _show_matching_options(self, name, directory, scope):
 
1902
        name = re.compile(name)
 
1903
        # We want any error in the regexp to be raised *now* so we need to
 
1904
        # avoid the delay introduced by the lazy regexp.
 
1905
        name._compile_and_collapse()
 
1906
        cur_conf_id = None
 
1907
        cur_section = None
 
1908
        for c in self._get_configs(directory, scope):
 
1909
            for (oname, value, section, conf_id, parser) in c._get_options():
 
1910
                if name.search(oname):
 
1911
                    if cur_conf_id != conf_id:
 
1912
                        # Explain where the options are defined
 
1913
                        self.outf.write('%s:\n' % (conf_id,))
 
1914
                        cur_conf_id = conf_id
 
1915
                        cur_section = None
 
1916
                    if (section not in (None, 'DEFAULT')
 
1917
                        and cur_section != section):
 
1918
                        # Display the section if it's not the default (or only)
 
1919
                        # one.
 
1920
                        self.outf.write('  [%s]\n' % (section,))
 
1921
                        cur_section = section
 
1922
                    self.outf.write('  %s = %s\n' % (oname, value))
 
1923
 
 
1924
    def _set_config_option(self, name, value, directory, scope):
 
1925
        for conf in self._get_configs(directory, scope):
 
1926
            conf.set_user_option(name, value)
 
1927
            break
 
1928
        else:
 
1929
            raise errors.NoSuchConfig(scope)
 
1930
 
 
1931
    def _remove_config_option(self, name, directory, scope):
 
1932
        if name is None:
 
1933
            raise errors.BzrCommandError(
 
1934
                '--remove expects an option to remove.')
 
1935
        removed = False
 
1936
        for conf in self._get_configs(directory, scope):
 
1937
            for (section_name, section, conf_id) in conf._get_sections():
 
1938
                if scope is not None and conf_id != scope:
 
1939
                    # Not the right configuration file
 
1940
                    continue
 
1941
                if name in section:
 
1942
                    if conf_id != conf.config_id():
 
1943
                        conf = self._get_configs(directory, conf_id).next()
 
1944
                    # We use the first section in the first config where the
 
1945
                    # option is defined to remove it
 
1946
                    conf.remove_user_option(name, section_name)
 
1947
                    removed = True
 
1948
                    break
 
1949
            break
 
1950
        else:
 
1951
            raise errors.NoSuchConfig(scope)
 
1952
        if not removed:
 
1953
            raise errors.NoSuchConfigOption(name)