~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/config.py

  • Committer: Robert Collins
  • Date: 2005-10-14 04:29:39 UTC
  • mto: This revision was merged to the branch mainline in revision 1456.
  • Revision ID: robertc@lifelesslap.robertcollins.net-20051014042939-d03fe7c79012279c
Create a default signature checking policy of CHECK_IF_POSSIBLE

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
 
"""Configuration that affects the behaviour of Bazaar.
19
 
 
20
 
Currently this configuration resides in ~/.bazaar/bazaar.conf
21
 
and ~/.bazaar/branches.conf, which is written to by bzr.
22
 
 
23
 
In bazaar.conf the following options may be set:
24
 
[DEFAULT]
25
 
editor=name-of-program
26
 
email=Your Name <your@email.address>
27
 
check_signatures=require|ignore|check-available(default)
28
 
create_signatures=always|never|when-required(default)
29
 
gpg_signing_command=name-of-program
30
 
 
31
 
in branches.conf, you specify the url of a branch and options for it.
32
 
Wildcards may be used - * and ? as normal in shell completion. Options
33
 
set in both bazaar.conf and branches.conf are overriden by the branches.conf
34
 
setting.
35
 
[/home/robertc/source]
36
 
recurse=False|True(default)
37
 
email= as above
38
 
check_signatures= as abive 
39
 
create_signatures= as above.
40
 
 
41
 
explanation of options
42
 
----------------------
43
 
editor - this option sets the pop up editor to use during commits.
44
 
email - this option sets the user id bzr will use when committing.
45
 
check_signatures - this option controls whether bzr will require good gpg
46
 
                   signatures, ignore them, or check them if they are 
47
 
                   present.
48
 
create_signatures - this option controls whether bzr will always create 
49
 
                    gpg signatures, never create them, or create them if the
50
 
                    branch is configured to require them.
51
 
                    NB: This option is planned, but not implemented yet.
52
 
"""
 
18
"""Configuration that affects the behaviour of Bazaar."""
53
19
 
54
20
from ConfigParser import ConfigParser
55
21
import os
73
39
        """Get the users pop up editor."""
74
40
        raise NotImplementedError
75
41
 
76
 
    def _get_signature_checking(self):
77
 
        """Template method to override signature checking policy."""
78
 
 
79
 
    def _get_user_option(self, option_name):
80
 
        """Template method to provide a user option."""
81
 
        return None
82
 
 
83
 
    def get_user_option(self, option_name):
84
 
        """Get a generic option - no special process, no default."""
85
 
        return self._get_user_option(option_name)
86
 
 
87
 
    def gpg_signing_command(self):
88
 
        """What program should be used to sign signatures?"""
89
 
        result = self._gpg_signing_command()
90
 
        if result is None:
91
 
            result = "gpg"
92
 
        return result
93
 
 
94
 
    def _gpg_signing_command(self):
95
 
        """See gpg_signing_command()."""
96
 
        return None
97
 
 
98
42
    def __init__(self):
99
43
        super(Config, self).__init__()
100
44
 
140
84
 
141
85
    def signature_checking(self):
142
86
        """What is the current policy for signature checking?."""
143
 
        policy = self._get_signature_checking()
144
 
        if policy is not None:
145
 
            return policy
146
87
        return CHECK_IF_POSSIBLE
147
88
 
148
 
    def signature_needed(self):
149
 
        """Is a signature needed when committing ?."""
150
 
        policy = self._get_signature_checking()
151
 
        if policy == CHECK_ALWAYS:
152
 
            return True
153
 
        return False
154
 
 
155
 
 
156
 
class IniBasedConfig(Config):
157
 
    """A configuration policy that draws from ini files."""
158
 
 
159
 
    def _get_parser(self, file=None):
160
 
        if self._parser is not None:
161
 
            return self._parser
 
89
class GlobalConfig(Config):
 
90
    """The configuration that should be used for a specific location."""
 
91
 
 
92
    def _get_parser(self, filename=None, file=None):
162
93
        parser = ConfigParser()
163
94
        if file is not None:
164
95
            parser.readfp(file)
165
96
        else:
166
 
            parser.read([self._get_filename()])
167
 
        self._parser = parser
 
97
            parser.read([filename])
168
98
        return parser
169
99
 
170
 
    def _get_section(self):
171
 
        """Override this to define the section used by the config."""
172
 
        return "DEFAULT"
173
 
 
174
 
    def _get_signature_checking(self):
175
 
        """See Config._get_signature_checking."""
176
 
        section = self._get_section()
177
 
        if section is None:
178
 
            return None
179
 
        if self._get_parser().has_option(section, 'check_signatures'):
180
 
            return self._string_to_signature_policy(
181
 
                self._get_parser().get(section, 'check_signatures'))
182
 
 
183
 
    def _get_user_id(self):
184
 
        """Get the user id from the 'email' key in the current section."""
185
 
        section = self._get_section()
186
 
        if section is not None:
187
 
            if self._get_parser().has_option(section, 'email'):
188
 
                return self._get_parser().get(section, 'email')
189
 
 
190
 
    def _get_user_option(self, option_name):
191
 
        """See Config._get_user_option."""
192
 
        section = self._get_section()
193
 
        if section is not None:
194
 
            if self._get_parser().has_option(section, option_name):
195
 
                return self._get_parser().get(section, option_name)
196
 
 
197
 
    def _gpg_signing_command(self):
198
 
        """See Config.gpg_signing_command."""
199
 
        section = self._get_section()
200
 
        if section is not None:
201
 
            if self._get_parser().has_option(section, 'gpg_signing_command'):
202
 
                return self._get_parser().get(section, 'gpg_signing_command')
203
 
 
204
 
    def __init__(self, get_filename):
205
 
        super(IniBasedConfig, self).__init__()
206
 
        self._get_filename = get_filename
 
100
    def _get_config_parser(self, file=None):
 
101
        if self._parser is None:
 
102
            self._parser =  self._get_parser(config_filename(), file)
 
103
        return self._parser
 
104
    
 
105
    def _get_branches_config_parser(self, file=None):
 
106
        if self._branches_parser is None:
 
107
            self._branches_parser = self._get_parser(
 
108
                branches_config_filename(), file)
 
109
        return self._branches_parser
 
110
 
 
111
    def get_editor(self):
 
112
        if self._get_config_parser().has_option('DEFAULT', 'editor'):
 
113
            return self._get_config_parser().get('DEFAULT', 'editor')
 
114
 
 
115
    def _get_user_id(self, branch=None):
 
116
        """Return the full user id from the global config file.
 
117
    
 
118
        e.g. "John Hacker <jhacker@foo.org>"
 
119
        from 
 
120
        [DEFAULT]
 
121
        email=John Hacker <jhacker@foo.org>
 
122
        """
 
123
        if self._get_config_parser().has_option('DEFAULT', 'email'):
 
124
            email = self._get_config_parser().get('DEFAULT', 'email')
 
125
            if email is not None:
 
126
                return email
 
127
    
 
128
    def __init__(self):
 
129
        super(GlobalConfig, self).__init__()
 
130
        self._branches_parser = None
207
131
        self._parser = None
208
132
 
209
 
    def _string_to_signature_policy(self, signature_string):
210
 
        """Convert a string to a signing policy."""
211
 
        if signature_string.lower() == 'check-available':
212
 
            return CHECK_IF_POSSIBLE
213
 
        if signature_string.lower() == 'ignore':
214
 
            return CHECK_NEVER
215
 
        if signature_string.lower() == 'require':
216
 
            return CHECK_ALWAYS
217
 
        raise errors.BzrError("Invalid signatures policy '%s'"
218
 
                              % signature_string)
219
 
 
220
 
 
221
 
class GlobalConfig(IniBasedConfig):
222
 
    """The configuration that should be used for a specific location."""
223
 
 
224
 
    def get_editor(self):
225
 
        if self._get_parser().has_option(self._get_section(), 'editor'):
226
 
            return self._get_parser().get(self._get_section(), 'editor')
227
 
 
228
 
    def __init__(self):
229
 
        super(GlobalConfig, self).__init__(config_filename)
230
 
 
231
 
 
232
 
class LocationConfig(IniBasedConfig):
 
133
 
 
134
class LocationConfig(Config):
233
135
    """A configuration object that gives the policy for a location."""
234
136
 
235
137
    def __init__(self, location):
236
 
        super(LocationConfig, self).__init__(branches_config_filename)
237
138
        self._global_config = None
238
139
        self.location = location
239
140
 
 
141
    def _get_branches_config_parser(self, file=None):
 
142
        return self._get_global_config()._get_branches_config_parser(file)
 
143
 
240
144
    def _get_global_config(self):
241
145
        if self._global_config is None:
242
146
            self._global_config = GlobalConfig()
249
153
        TODO: perhaps return a NullSection that thunks through to the 
250
154
              global config.
251
155
        """
252
 
        sections = self._get_parser().sections()
 
156
        parser = self._get_branches_config_parser()
 
157
        sections = parser.sections()
253
158
        location_names = self.location.split('/')
254
 
        if self.location.endswith('/'):
255
 
            del location_names[-1]
256
159
        matches=[]
257
160
        for section in sections:
258
161
            section_names = section.split('/')
272
175
                continue
273
176
            # if path is longer, and recurse is not true, no match
274
177
            if len(section_names) < len(location_names):
275
 
                if (self._get_parser().has_option(section, 'recurse')
276
 
                    and not self._get_parser().getboolean(section, 'recurse')):
 
178
                if (parser.has_option(section, 'recurse')
 
179
                    and not parser.getboolean(section, 'recurse')):
277
180
                    continue
278
181
            matches.append((len(section_names), section))
279
182
        if not len(matches):
281
184
        matches.sort(reverse=True)
282
185
        return matches[0][1]
283
186
 
284
 
    def _gpg_signing_command(self):
285
 
        """See Config.gpg_signing_command."""
286
 
        command = super(LocationConfig, self)._gpg_signing_command()
287
 
        if command is not None:
288
 
            return command
289
 
        return self._get_global_config()._gpg_signing_command()
290
 
 
291
187
    def _get_user_id(self):
292
 
        user_id = super(LocationConfig, self)._get_user_id()
293
 
        if user_id is not None:
294
 
            return user_id
 
188
        section = self._get_section()
 
189
        if section is not None:
 
190
            if self._get_branches_config_parser().has_option(section, 'email'):
 
191
                return self._get_branches_config_parser().get(section, 'email')
295
192
        return self._get_global_config()._get_user_id()
296
193
 
297
 
    def _get_user_option(self, option_name):
298
 
        """See Config._get_user_option."""
299
 
        option_value = super(LocationConfig, 
300
 
                             self)._get_user_option(option_name)
301
 
        if option_value is not None:
302
 
            return option_value
303
 
        return self._get_global_config()._get_user_option(option_name)
304
 
 
305
 
    def _get_signature_checking(self):
306
 
        """See Config._get_signature_checking."""
307
 
        check = super(LocationConfig, self)._get_signature_checking()
308
 
        if check is not None:
309
 
            return check
310
 
        return self._get_global_config()._get_signature_checking()
311
 
 
312
194
 
313
195
class BranchConfig(Config):
314
196
    """A configuration object giving the policy for a branch."""
334
216
        
335
217
        return self._get_location_config()._get_user_id()
336
218
 
337
 
    def _get_signature_checking(self):
338
 
        """See Config._get_signature_checking."""
339
 
        return self._get_location_config()._get_signature_checking()
340
 
 
341
 
    def _get_user_option(self, option_name):
342
 
        """See Config._get_user_option."""
343
 
        return self._get_location_config()._get_user_option(option_name)
344
 
 
345
 
    def _gpg_signing_command(self):
346
 
        """See Config.gpg_signing_command."""
347
 
        return self._get_location_config()._gpg_signing_command()
348
 
        
349
219
    def __init__(self, branch):
350
220
        super(BranchConfig, self).__init__()
351
221
        self._location_config = None
408
278
    return realname, (username + '@' + socket.gethostname())
409
279
 
410
280
 
411
 
def extract_email_address(e):
412
 
    """Return just the address part of an email string.
413
 
    
414
 
    That is just the user@domain part, nothing else. 
415
 
    This part is required to contain only ascii characters.
416
 
    If it can't be extracted, raises an error.
417
 
    
418
 
    >>> extract_email_address('Jane Tester <jane@test.com>')
419
 
    "jane@test.com"
420
 
    """
421
 
    m = re.search(r'[\w+.-]+@[\w+.-]+', e)
422
 
    if not m:
423
 
        raise BzrError("%r doesn't seem to contain "
424
 
                       "a reasonable email address" % e)
425
 
    return m.group(0)