Make sure BranchConfig providers all required functions.
[jelmer/subvertpy.git] / config.py
1 # Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16 """Stores per-repository settings."""
17
18 from bzrlib import osutils
19 from bzrlib.config import IniBasedConfig, config_dir, ensure_config_dir_exists, GlobalConfig, LocationConfig, Config
20
21 import os
22
23 from scheme import BranchingScheme
24 import svn.core
25
26 # Settings are stored by UUID. 
27 # Data stored includes default branching scheme and locations the repository 
28 # was seen at.
29
30 def subversion_config_filename():
31     """Return per-user configuration ini file filename."""
32     return osutils.pathjoin(config_dir(), 'subversion.conf')
33
34
35 class SvnRepositoryConfig(IniBasedConfig):
36     """Per-repository settings."""
37
38     def __init__(self, uuid):
39         name_generator = subversion_config_filename
40         super(SvnRepositoryConfig, self).__init__(name_generator)
41         self.uuid = uuid
42         if not self.uuid in self._get_parser():
43             self._get_parser()[self.uuid] = {}
44
45     def set_branching_scheme(self, scheme, mandatory=False):
46         """Change the branching scheme.
47
48         :param scheme: New branching scheme.
49         """
50         self.set_user_option('branching-scheme', str(scheme))
51         self.set_user_option('branching-scheme-mandatory', str(mandatory))
52
53     def _get_user_option(self, name, use_global=True):
54         try:
55             return self._get_parser()[self.uuid][name]
56         except KeyError:
57             if not use_global:
58                 return None
59             return GlobalConfig()._get_user_option(name)
60
61     def get_branching_scheme(self):
62         """Get the branching scheme.
63
64         :return: BranchingScheme instance.
65         """
66         schemename = self._get_user_option("branching-scheme", use_global=False)
67         if schemename is not None:
68             return BranchingScheme.find_scheme(schemename.encode('ascii'))
69         return None
70
71     def get_set_revprops(self):
72         """Check whether or not bzr-svn should attempt to store Bazaar
73         revision properties in Subversion revision properties during commit."""
74         try:
75             return self._get_parser().get_bool(self.uuid, "set-revprops")
76         except KeyError:
77             return None
78
79     def get_supports_change_revprop(self):
80         """Check whether or not the repository supports changing existing 
81         revision properties."""
82         try:
83             return self._get_parser().get_bool(self.uuid, "supports-change-revprop")
84         except KeyError:
85             return None
86
87     def get_log_strip_trailing_newline(self):
88         """Check whether or not trailing newlines should be stripped in the 
89         Subversion log message (where support by the bzr<->svn mapping used)."""
90         try:
91             return self._get_parser().get_bool(self.uuid, "log-strip-trailing-newline")
92         except KeyError:
93             return False
94
95     def branching_scheme_is_mandatory(self):
96         """Check whether or not the branching scheme for this repository 
97         is mandatory.
98         """
99         try:
100             return self._get_parser().get_bool(self.uuid, "branching-scheme-mandatory")
101         except KeyError:
102             return False
103
104     def get_override_svn_revprops(self):
105         """Check whether or not bzr-svn should attempt to override Subversion revision 
106         properties after committing."""
107         def get_list(parser, section):
108             try:
109                 if parser.get_bool(section, "override-svn-revprops"):
110                     return [svn.core.SVN_PROP_REVISION_DATE, svn.core.SVN_PROP_REVISION_AUTHOR]
111                 return []
112             except ValueError:
113                 return parser.get_value(section, "override-svn-revprops").split(",")
114             except KeyError:
115                 return None
116         ret = get_list(self._get_parser(), self.uuid)
117         if ret is not None:
118             return ret
119         global_config = GlobalConfig()
120         return get_list(global_config._get_parser(), global_config._get_section())
121
122     def get_append_revisions_only(self):
123         """Check whether it is possible to remove revisions from the mainline.
124         """
125         try:
126             return self._get_parser().get_bool(self.uuid, "append_revisions_only")
127         except KeyError:
128             return None
129
130     def get_locations(self):
131         """Find the locations this repository has been seen at.
132
133         :return: Set with URLs.
134         """
135         val = self._get_user_option("locations", use_global=False)
136         if val is None:
137             return set()
138         return set(val.split(";"))
139
140     def add_location(self, location):
141         """Add a location for this repository.
142
143         :param location: URL of location to add.
144         """
145         locations = self.get_locations()
146         locations.add(location.rstrip("/"))
147         self.set_user_option('locations', ";".join(list(locations)))
148
149     def set_user_option(self, name, value):
150         """Change a user option.
151
152         :param name: Name of the option.
153         :param value: Value of the option.
154         """
155         conf_dir = os.path.dirname(self._get_filename())
156         ensure_config_dir_exists(conf_dir)
157         self._get_parser()[self.uuid][name] = value
158         f = open(self._get_filename(), 'wb')
159         self._get_parser().write(f)
160         f.close()
161
162
163 class BranchConfig(Config):
164     def __init__(self, branch):
165         super(BranchConfig, self).__init__()
166         self._location_config = None
167         self._repository_config = None
168         self.branch = branch
169         self.option_sources = (self._get_location_config, 
170                                self._get_repository_config)
171
172     def _get_location_config(self):
173         if self._location_config is None:
174             self._location_config = LocationConfig(self.branch.base)
175         return self._location_config
176
177     def _get_repository_config(self):
178         if self._repository_config is None:
179             self._repository_config = SvnRepositoryConfig(self.branch.repository.uuid)
180         return self._repository_config
181
182     def _get_user_option(self, option_name):
183         """See Config._get_user_option."""
184         for source in self.option_sources:
185             value = source()._get_user_option(option_name)
186             if value is not None:
187                 return value
188         return None
189
190     def get_append_revisions_only(self):
191         return self.get_user_option("append_revision_only")
192
193     def _get_user_id(self):
194         """Get the user id from the 'email' key in the current section."""
195         return self._get_user_option('email')