blob: 2e4486a45fd885bcebcd929b7877d2e5b97dbfb7 [file] [log] [blame]
Copybara854996b2021-09-07 19:36:02 +00001# Copyright 2019 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style
3# license that can be found in the LICENSE file or at
4# https://developers.google.com/open-source/licenses/bsd
5
6"""Logic for storing and representing issues from external trackers."""
7
8from __future__ import print_function
9from __future__ import division
10from __future__ import absolute_import
11
12import re
13
14from framework.exceptions import InvalidExternalIssueReference
15
16
17class FederatedIssue(object):
18 """Abstract base class for holding one federated issue.
19
20 Each distinct external tracker should subclass this.
21 """
22 shortlink_re = None
23
24 def __init__(self, shortlink):
25 if not self.IsShortlinkValid(shortlink):
26 raise InvalidExternalIssueReference(
27 'Shortlink does not match any valid tracker: %s' % shortlink)
28
29 self.shortlink = shortlink
30
31 @classmethod
32 def IsShortlinkValid(cls, shortlink):
33 """Returns whether given shortlink is correctly formatted."""
34 if not cls.shortlink_re:
35 raise NotImplementedError()
36 return re.match(cls.shortlink_re, shortlink)
37
38
39class GoogleIssueTrackerIssue(FederatedIssue):
40 """Holds one Google Issue Tracker issue.
41
42 URL: https://issuetracker.google.com/
43 """
44 shortlink_re = r'^b\/\d+$'
45 url_format = 'https://issuetracker.google.com/issues/{issue_id}'
46
47 def __init__(self, shortlink):
48 super(GoogleIssueTrackerIssue, self).__init__(shortlink)
49 self.issue_id = int(self.shortlink[2:])
50
51 def ToURL(self):
52 return self.url_format.format(issue_id=self.issue_id)
53
54 def Summary(self):
55 """Returns a short string description for UI."""
56 return 'Google Issue Tracker issue %s.' % self.issue_id
57
58
59# All supported tracker classes.
60_federated_issue_classes = [GoogleIssueTrackerIssue]
61
62
63def IsShortlinkValid(shortlink):
64 """Returns whether the given string is valid for any issue tracker."""
65 return any(tracker_class.IsShortlinkValid(shortlink)
66 for tracker_class in _federated_issue_classes)
67
68
69def FromShortlink(shortlink):
70 """Returns a FederatedIssue for the first matching tracker.
71
72 If no matching tracker is found, returns None.
73 """
74 for tracker_class in _federated_issue_classes:
75 if tracker_class.IsShortlinkValid(shortlink):
76 return tracker_class(shortlink)
77
78 return None