~gagern/bzr-svn/bug242321

1119 by Jelmer Vernooij
Add reuse-revisions option to speed up looking for revids in Subversion repositories.
1
# Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org>
492 by Jelmer Vernooij
Add config objects for repositories.
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
1022 by Jelmer Vernooij
Switch license to GPLv3 or later.
5
# the Free Software Foundation; either version 3 of the License, or
492 by Jelmer Vernooij
Add config objects for repositories.
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
1086 by Jelmer Vernooij
Support set_user_option() on Subversion branch BranchConfig.
18
from bzrlib import osutils, urlutils, trace
19
from bzrlib.config import IniBasedConfig, config_dir, ensure_config_dir_exists, GlobalConfig, LocationConfig, Config, STORE_BRANCH, STORE_GLOBAL, STORE_LOCATION
493 by Jelmer Vernooij
Remember locations and branching scheme.
20
21
import os
492 by Jelmer Vernooij
Add config objects for repositories.
22
1020 by Jelmer Vernooij
Allow more granularity over what svn properties can be overridden.
23
import svn.core
531 by Jelmer Vernooij
Let config return a BranchingScheme instance rather than just a string.
24
492 by Jelmer Vernooij
Add config objects for repositories.
25
# Settings are stored by UUID. 
26
# Data stored includes default branching scheme and locations the repository 
27
# was seen at.
28
29
def subversion_config_filename():
30
    """Return per-user configuration ini file filename."""
31
    return osutils.pathjoin(config_dir(), 'subversion.conf')
32
765.1.1 by Jelmer Vernooij
Support custom user options for repository config.
33
492 by Jelmer Vernooij
Add config objects for repositories.
34
class SvnRepositoryConfig(IniBasedConfig):
35
    """Per-repository settings."""
36
37
    def __init__(self, uuid):
38
        name_generator = subversion_config_filename
39
        super(SvnRepositoryConfig, self).__init__(name_generator)
40
        self.uuid = uuid
41
        if not self.uuid in self._get_parser():
42
            self._get_parser()[self.uuid] = {}
43
856 by Jelmer Vernooij
Avoid errors about invalid branching paths unless the branching scheme was specified explicitly.
44
    def set_branching_scheme(self, scheme, mandatory=False):
639 by Jelmer Vernooij
Add more docstrings, general cleanups.
45
        """Change the branching scheme.
46
47
        :param scheme: New branching scheme.
48
        """
531 by Jelmer Vernooij
Let config return a BranchingScheme instance rather than just a string.
49
        self.set_user_option('branching-scheme', str(scheme))
856 by Jelmer Vernooij
Avoid errors about invalid branching paths unless the branching scheme was specified explicitly.
50
        self.set_user_option('branching-scheme-mandatory', str(mandatory))
492 by Jelmer Vernooij
Add config objects for repositories.
51
765.1.1 by Jelmer Vernooij
Support custom user options for repository config.
52
    def _get_user_option(self, name, use_global=True):
53
        try:
54
            return self._get_parser()[self.uuid][name]
55
        except KeyError:
56
            if not use_global:
57
                return None
58
            return GlobalConfig()._get_user_option(name)
59
1119 by Jelmer Vernooij
Add reuse-revisions option to speed up looking for revids in Subversion repositories.
60
    def get_reuse_revisions(self):
61
        ret = self._get_user_option("reuse-revisions")
62
        if ret is None:
63
            return "other-branches"
64
        assert ret in ("none", "other-branches", "removed-branches")
65
        return ret
66
492 by Jelmer Vernooij
Add config objects for repositories.
67
    def get_branching_scheme(self):
639 by Jelmer Vernooij
Add more docstrings, general cleanups.
68
        """Get the branching scheme.
69
70
        :return: BranchingScheme instance.
71
        """
974.1.18 by Jelmer Vernooij
Fix more tests.
72
        from mapping3.scheme import BranchingScheme
765.1.4 by Jelmer Vernooij
Support optionally overriding svn:author and svn:date (#140001)
73
        schemename = self._get_user_option("branching-scheme", use_global=False)
74
        if schemename is not None:
848 by Jelmer Vernooij
Make sure scheme names are ascii strings.
75
            return BranchingScheme.find_scheme(schemename.encode('ascii'))
765.1.4 by Jelmer Vernooij
Support optionally overriding svn:author and svn:date (#140001)
76
        return None
492 by Jelmer Vernooij
Add config objects for repositories.
77
579.1.15 by Jelmer Vernooij
Add function for getting set-revprops config variable.
78
    def get_set_revprops(self):
79
        """Check whether or not bzr-svn should attempt to store Bazaar
80
        revision properties in Subversion revision properties during commit."""
81
        try:
82
            return self._get_parser().get_bool(self.uuid, "set-revprops")
83
        except KeyError:
84
            return None
85
579.1.16 by Jelmer Vernooij
add two more configuration options.
86
    def get_supports_change_revprop(self):
87
        """Check whether or not the repository supports changing existing 
88
        revision properties."""
89
        try:
90
            return self._get_parser().get_bool(self.uuid, "supports-change-revprop")
91
        except KeyError:
92
            return None
93
1051 by Jelmer Vernooij
Add configuration option for disabling the cache.
94
    def get_use_cache(self):
95
        try:
96
            return self._get_parser().get_bool(self.uuid, "use-cache")
97
        except KeyError:
98
            return True
99
1018 by Jelmer Vernooij
Add log-strip-trailing-newline option.
100
    def get_log_strip_trailing_newline(self):
101
        """Check whether or not trailing newlines should be stripped in the 
102
        Subversion log message (where support by the bzr<->svn mapping used)."""
103
        try:
104
            return self._get_parser().get_bool(self.uuid, "log-strip-trailing-newline")
105
        except KeyError:
106
            return False
107
856 by Jelmer Vernooij
Avoid errors about invalid branching paths unless the branching scheme was specified explicitly.
108
    def branching_scheme_is_mandatory(self):
109
        """Check whether or not the branching scheme for this repository 
110
        is mandatory.
111
        """
868 by Jelmer Vernooij
Fix parsing of -mandatory setting.
112
        try:
113
            return self._get_parser().get_bool(self.uuid, "branching-scheme-mandatory")
114
        except KeyError:
115
            return False
856 by Jelmer Vernooij
Avoid errors about invalid branching paths unless the branching scheme was specified explicitly.
116
765.1.2 by Jelmer Vernooij
Add configuration option for override-svn-revprops.
117
    def get_override_svn_revprops(self):
118
        """Check whether or not bzr-svn should attempt to override Subversion revision 
119
        properties after committing."""
1020 by Jelmer Vernooij
Allow more granularity over what svn properties can be overridden.
120
        def get_list(parser, section):
121
            try:
122
                if parser.get_bool(section, "override-svn-revprops"):
123
                    return [svn.core.SVN_PROP_REVISION_DATE, svn.core.SVN_PROP_REVISION_AUTHOR]
124
                return []
125
            except ValueError:
1151 by Jelmer Vernooij
Fix parsing of override-svn-revprops configuration option.
126
                val = parser.get_value(section, "override-svn-revprops")
127
                if not isinstance(val, list):
128
                    return [val]
129
                return val
1020 by Jelmer Vernooij
Allow more granularity over what svn properties can be overridden.
130
            except KeyError:
131
                return None
132
        ret = get_list(self._get_parser(), self.uuid)
133
        if ret is not None:
134
            return ret
765.1.2 by Jelmer Vernooij
Add configuration option for override-svn-revprops.
135
        global_config = GlobalConfig()
1020 by Jelmer Vernooij
Allow more granularity over what svn properties can be overridden.
136
        return get_list(global_config._get_parser(), global_config._get_section())
765.1.2 by Jelmer Vernooij
Add configuration option for override-svn-revprops.
137
1025 by Jelmer Vernooij
Add new append-revisions-only'' option with similar behaviour as in standard bzr formats.
138
    def get_append_revisions_only(self):
139
        """Check whether it is possible to remove revisions from the mainline.
140
        """
141
        try:
142
            return self._get_parser().get_bool(self.uuid, "append_revisions_only")
143
        except KeyError:
144
            return None
145
492 by Jelmer Vernooij
Add config objects for repositories.
146
    def get_locations(self):
639 by Jelmer Vernooij
Add more docstrings, general cleanups.
147
        """Find the locations this repository has been seen at.
148
149
        :return: Set with URLs.
150
        """
765.1.1 by Jelmer Vernooij
Support custom user options for repository config.
151
        val = self._get_user_option("locations", use_global=False)
152
        if val is None:
492 by Jelmer Vernooij
Add config objects for repositories.
153
            return set()
765.1.1 by Jelmer Vernooij
Support custom user options for repository config.
154
        return set(val.split(";"))
492 by Jelmer Vernooij
Add config objects for repositories.
155
156
    def add_location(self, location):
639 by Jelmer Vernooij
Add more docstrings, general cleanups.
157
        """Add a location for this repository.
158
159
        :param location: URL of location to add.
160
        """
492 by Jelmer Vernooij
Add config objects for repositories.
161
        locations = self.get_locations()
555 by Jelmer Vernooij
Store urls without trailing slash.
162
        locations.add(location.rstrip("/"))
492 by Jelmer Vernooij
Add config objects for repositories.
163
        self.set_user_option('locations', ";".join(list(locations)))
164
165
    def set_user_option(self, name, value):
639 by Jelmer Vernooij
Add more docstrings, general cleanups.
166
        """Change a user option.
167
168
        :param name: Name of the option.
169
        :param value: Value of the option.
170
        """
493 by Jelmer Vernooij
Remember locations and branching scheme.
171
        conf_dir = os.path.dirname(self._get_filename())
172
        ensure_config_dir_exists(conf_dir)
492 by Jelmer Vernooij
Add config objects for repositories.
173
        self._get_parser()[self.uuid][name] = value
174
        f = open(self._get_filename(), 'wb')
175
        self._get_parser().write(f)
176
        f.close()
1025 by Jelmer Vernooij
Add new append-revisions-only'' option with similar behaviour as in standard bzr formats.
177
178
179
class BranchConfig(Config):
180
    def __init__(self, branch):
181
        super(BranchConfig, self).__init__()
182
        self._location_config = None
183
        self._repository_config = None
184
        self.branch = branch
185
        self.option_sources = (self._get_location_config, 
186
                               self._get_repository_config)
187
188
    def _get_location_config(self):
189
        if self._location_config is None:
190
            self._location_config = LocationConfig(self.branch.base)
191
        return self._location_config
192
193
    def _get_repository_config(self):
194
        if self._repository_config is None:
1026 by Jelmer Vernooij
Fix syntax error.
195
            self._repository_config = SvnRepositoryConfig(self.branch.repository.uuid)
1025 by Jelmer Vernooij
Add new append-revisions-only'' option with similar behaviour as in standard bzr formats.
196
        return self._repository_config
197
1143 by Jelmer Vernooij
Share some code for pushing revisions, use specified configuration rather than repository configuration when committing.
198
    def get_set_revprops(self):
199
        return self._get_repository_config().get_set_revprops()
200
201
    def get_log_strip_trailing_newline(self):
202
        return self._get_repository_config().get_log_strip_trailing_newline()
203
204
    def get_override_svn_revprops(self):
205
        return self._get_repository_config().get_override_svn_revprops()
206
1025 by Jelmer Vernooij
Add new append-revisions-only'' option with similar behaviour as in standard bzr formats.
207
    def _get_user_option(self, option_name):
208
        """See Config._get_user_option."""
209
        for source in self.option_sources:
210
            value = source()._get_user_option(option_name)
211
            if value is not None:
212
                return value
213
        return None
214
215
    def get_append_revisions_only(self):
216
        return self.get_user_option("append_revision_only")
1028 by Jelmer Vernooij
Make sure BranchConfig providers all required functions.
217
218
    def _get_user_id(self):
219
        """Get the user id from the 'email' key in the current section."""
220
        return self._get_user_option('email')
1035 by Jelmer Vernooij
Parse mergeWithUpstream used by svn-buildpackage.
221
222
    def get_option(self, key, section=None):
223
        if section == "BUILDDEB" and key == "merge":
224
            revnum = self.branch.get_revnum()
225
            try:
226
                props = self.branch.repository.transport.get_dir(urlutils.join(self.branch.get_branch_path(revnum), "debian"), revnum)[2]
227
                if props.has_key("mergeWithUpstream"):
228
                    return "True"
229
                else:
230
                    return "False"
231
            except svn.core.SubversionException:
232
                return None
233
        return None
1086 by Jelmer Vernooij
Support set_user_option() on Subversion branch BranchConfig.
234
235
    def set_user_option(self, name, value, store=STORE_LOCATION,
236
        warn_masked=False):
237
        if store == STORE_GLOBAL:
238
            self._get_global_config().set_user_option(name, value)
239
        elif store == STORE_BRANCH:
240
            raise NotImplementedError("Saving in branch config not supported for Subversion branches")
241
        else:
242
            self._get_location_config().set_user_option(name, value, store)
243
        if not warn_masked:
244
            return
245
        if store in (STORE_GLOBAL, STORE_BRANCH):
246
            mask_value = self._get_location_config().get_user_option(name)
247
            if mask_value is not None:
248
                trace.warning('Value "%s" is masked by "%s" from'
249
                              ' locations.conf', value, mask_value)
250
            else:
251
                if store == STORE_GLOBAL:
252
                    branch_config = self._get_branch_data_config()
253
                    mask_value = branch_config.get_user_option(name)
254
                    if mask_value is not None:
255
                        trace.warning('Value "%s" is masked by "%s" from'
256
                                      ' branch.conf', value, mask_value)