/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/bugtracker.py

  • Committer: Richard Wilbur
  • Date: 2016-02-04 19:07:28 UTC
  • mto: This revision was merged to the branch mainline in revision 6618.
  • Revision ID: richard.wilbur@gmail.com-20160204190728-p0zvfii6zase0fw7
Update COPYING.txt from the original http://www.gnu.org/licenses/gpl-2.0.txt  (Only differences were in whitespace.)  Thanks to Petr Stodulka for pointing out the discrepancy.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
 
from . import (
18
 
    errors,
19
 
    registry,
20
 
    )
21
 
from .lazy_import import lazy_import
 
17
from __future__ import absolute_import
 
18
 
 
19
from bzrlib import registry
 
20
from bzrlib.lazy_import import lazy_import
22
21
lazy_import(globals(), """
23
 
from breezy import urlutils
 
22
from bzrlib import errors, urlutils
24
23
""")
25
24
 
26
25
 
40
39
"""
41
40
 
42
41
 
43
 
_bugs_help = """\
44
 
When making a commit, metadata about bugs fixed by that change can be
 
42
_bugs_help = \
 
43
"""When making a commit, metadata about bugs fixed by that change can be
45
44
recorded by using the ``--fixes`` option. For each bug marked as fixed, an
46
45
entry is included in the 'bugs' revision property stating '<url> <status>'.
47
46
(The only ``status`` value currently supported is ``fixed.``)
82
81
 
83
82
If you use Bugzilla or Trac, then you only need to set a configuration
84
83
variable which contains the base URL of the bug tracker. These options
85
 
can go into ``breezy.conf``, ``branch.conf`` or into a branch-specific
 
84
can go into ``bazaar.conf``, ``branch.conf`` or into a branch-specific
86
85
configuration section in ``locations.conf``.  You can set up these values
87
86
for each of the projects you work on.
88
87
 
146
145
"""
147
146
 
148
147
 
149
 
class MalformedBugIdentifier(errors.BzrError):
150
 
 
151
 
    _fmt = ('Did not understand bug identifier %(bug_id)s: %(reason)s. '
152
 
            'See "brz help bugs" for more information on this feature.')
153
 
 
154
 
    def __init__(self, bug_id, reason):
155
 
        self.bug_id = bug_id
156
 
        self.reason = reason
157
 
 
158
 
 
159
 
class InvalidBugTrackerURL(errors.BzrError):
160
 
 
161
 
    _fmt = ("The URL for bug tracker \"%(abbreviation)s\" doesn't "
162
 
            "contain {id}: %(url)s")
163
 
 
164
 
    def __init__(self, abbreviation, url):
165
 
        self.abbreviation = abbreviation
166
 
        self.url = url
167
 
 
168
 
 
169
 
class UnknownBugTrackerAbbreviation(errors.BzrError):
170
 
 
171
 
    _fmt = ("Cannot find registered bug tracker called %(abbreviation)s "
172
 
            "on %(branch)s")
173
 
 
174
 
    def __init__(self, abbreviation, branch):
175
 
        self.abbreviation = abbreviation
176
 
        self.branch = branch
177
 
 
178
 
 
179
 
class InvalidLineInBugsProperty(errors.BzrError):
180
 
 
181
 
    _fmt = ("Invalid line in bugs property: '%(line)s'")
182
 
 
183
 
    def __init__(self, line):
184
 
        self.line = line
185
 
 
186
 
 
187
 
class InvalidBugUrl(errors.BzrError):
188
 
 
189
 
    _fmt = "Invalid bug URL: %(url)s"
190
 
 
191
 
    def __init__(self, url):
192
 
        self.url = url
193
 
 
194
 
 
195
 
class InvalidBugStatus(errors.BzrError):
196
 
 
197
 
    _fmt = ("Invalid bug status: '%(status)s'")
198
 
 
199
 
    def __init__(self, status):
200
 
        self.status = status
201
 
 
202
 
 
203
148
def get_bug_url(abbreviated_bugtracker_name, branch, bug_id):
204
149
    """Return a URL pointing to the canonical web page of the bug identified by
205
150
    'bug_id'.
222
167
            tracker = tracker_type.get(abbreviated_bugtracker_name, branch)
223
168
            if tracker is not None:
224
169
                return tracker
225
 
        raise UnknownBugTrackerAbbreviation(
226
 
            abbreviated_bugtracker_name, branch)
 
170
        raise errors.UnknownBugTrackerAbbreviation(abbreviated_bugtracker_name,
 
171
                                                   branch)
227
172
 
228
173
    def help_topic(self, topic):
229
174
        return _bugs_help
258
203
        try:
259
204
            int(bug_id)
260
205
        except ValueError:
261
 
            raise MalformedBugIdentifier(bug_id, "Must be an integer")
 
206
            raise errors.MalformedBugIdentifier(bug_id, "Must be an integer")
262
207
 
263
208
 
264
209
class UniqueIntegerBugTracker(IntegerBugTracker):
274
219
        self.base_url = base_url
275
220
 
276
221
    def get(self, abbreviated_bugtracker_name, branch):
277
 
        """Returns the tracker if the abbreviation matches, otherwise ``None``.
278
 
        """
279
 
        if abbreviated_bugtracker_name != self.abbreviation:
280
 
            return None
281
 
        return self
282
 
 
283
 
    def _get_bug_url(self, bug_id):
284
 
        """Return the URL for bug_id."""
285
 
        return self.base_url + str(bug_id)
286
 
 
287
 
 
288
 
class ProjectIntegerBugTracker(IntegerBugTracker):
289
 
    """A bug tracker that exists in one place only with per-project ids.
290
 
 
291
 
    If you have one of these trackers then register an instance passing in an
292
 
    abbreviated name for the bug tracker and a base URL. The bug ids are
293
 
    appended directly to the URL.
294
 
    """
295
 
 
296
 
    def __init__(self, abbreviated_bugtracker_name, base_url):
297
 
        self.abbreviation = abbreviated_bugtracker_name
298
 
        self._base_url = base_url
299
 
 
300
 
    def get(self, abbreviated_bugtracker_name, branch):
301
 
        """Returns the tracker if the abbreviation matches, otherwise ``None``.
302
 
        """
303
 
        if abbreviated_bugtracker_name != self.abbreviation:
304
 
            return None
305
 
        return self
306
 
 
307
 
    def check_bug_id(self, bug_id):
308
 
        try:
309
 
            (project, bug_id) = bug_id.rsplit('/', 1)
310
 
        except ValueError:
311
 
            raise MalformedBugIdentifier(bug_id, "Expected format: project/id")
312
 
        try:
313
 
            int(bug_id)
314
 
        except ValueError:
315
 
            raise MalformedBugIdentifier(bug_id, "Bug id must be an integer")
316
 
 
317
 
    def _get_bug_url(self, bug_id):
318
 
        (project, bug_id) = bug_id.rsplit('/', 1)
319
 
        """Return the URL for bug_id."""
320
 
        if '{id}' not in self._base_url:
321
 
            raise InvalidBugTrackerURL(self._abbreviation, self._base_url)
322
 
        if '{project}' not in self._base_url:
323
 
            raise InvalidBugTrackerURL(self._abbreviation, self._base_url)
324
 
        return self._base_url.replace(
325
 
            '{project}', project).replace('{id}', str(bug_id))
 
222
        """Returns the tracker if the abbreviation matches. Returns None
 
223
        otherwise."""
 
224
        if abbreviated_bugtracker_name != self.abbreviation:
 
225
            return None
 
226
        return self
 
227
 
 
228
    def _get_bug_url(self, bug_id):
 
229
        """Return the URL for bug_id."""
 
230
        return self.base_url + bug_id
326
231
 
327
232
 
328
233
tracker_registry.register(
333
238
    'debian', UniqueIntegerBugTracker('deb', 'http://bugs.debian.org/'))
334
239
 
335
240
 
336
 
tracker_registry.register(
337
 
    'gnome', UniqueIntegerBugTracker(
338
 
        'gnome', 'http://bugzilla.gnome.org/show_bug.cgi?id='))
339
 
 
340
 
 
341
 
tracker_registry.register(
342
 
    'github', ProjectIntegerBugTracker(
343
 
        'github', 'https://github.com/{project}/issues/{id}'))
 
241
tracker_registry.register('gnome',
 
242
    UniqueIntegerBugTracker('gnome',
 
243
                            'http://bugzilla.gnome.org/show_bug.cgi?id='))
344
244
 
345
245
 
346
246
class URLParametrizedBugTracker(BugTracker):
383
283
    'squid' or 'apache').
384
284
    """
385
285
 
386
 
 
387
286
tracker_registry.register(
388
287
    'trac', URLParametrizedIntegerBugTracker('trac', 'ticket/'))
389
288
 
405
304
    def _get_bug_url(self, bug_id):
406
305
        """Given a validated bug_id, return the bug's web page's URL."""
407
306
        if '{id}' not in self._base_url:
408
 
            raise InvalidBugTrackerURL(self._abbreviation, self._base_url)
 
307
            raise errors.InvalidBugTrackerURL(self._abbreviation,
 
308
                                              self._base_url)
409
309
        return self._base_url.replace('{id}', str(bug_id))
410
310
 
411
311
 
413
313
 
414
314
 
415
315
FIXED = 'fixed'
416
 
RELATED = 'related'
417
316
 
418
 
ALLOWED_BUG_STATUSES = {FIXED, RELATED}
 
317
ALLOWED_BUG_STATUSES = set([FIXED])
419
318
 
420
319
 
421
320
def encode_fixes_bug_urls(bug_urls):
422
321
    """Get the revision property value for a commit that fixes bugs.
423
322
 
424
 
    :param bug_urls: An iterable of (escaped URL, tag) tuples. These normally
 
323
    :param bug_urls: An iterable of escaped URLs to bugs. These normally
425
324
        come from `get_bug_url`.
426
325
    :return: A string that will be set as the 'bugs' property of a revision
427
326
        as part of a commit.
428
327
    """
429
 
    lines = []
430
 
    for (url, tag) in bug_urls:
431
 
        if ' ' in url:
432
 
            raise InvalidBugUrl(url)
433
 
        lines.append('%s %s' % (url, tag))
434
 
    return '\n'.join(lines)
435
 
 
436
 
 
437
 
def decode_bug_urls(bug_text):
438
 
    """Decode a bug property text.
439
 
 
440
 
    :param bug_text: Contents of a bugs property
441
 
    :return: iterator over (url, status) tuples
442
 
    """
443
 
    for line in bug_text.splitlines():
444
 
        try:
445
 
            url, status = line.split(None, 2)
446
 
        except ValueError:
447
 
            raise InvalidLineInBugsProperty(line)
448
 
        if status not in ALLOWED_BUG_STATUSES:
449
 
            raise InvalidBugStatus(status)
450
 
        yield url, status
 
328
    return '\n'.join(('%s %s' % (url, FIXED)) for url in bug_urls)