##// END OF EJS Templates
issue-trackers: implemented more sophisticated ticket data extraction based on advanced regex module, and special...
marcink -
r4498:2fce90e4 stable
parent child Browse files
Show More
@@ -1816,6 +1816,17 b' self: super: {'
1816 1816 license = [ pkgs.lib.licenses.mit ];
1817 1817 };
1818 1818 };
1819 "regex" = super.buildPythonPackage {
1820 name = "regex-2020.9.27";
1821 doCheck = false;
1822 src = fetchurl {
1823 url = "https://files.pythonhosted.org/packages/93/8c/17f45cdfb39b13d4b5f909e4b4c2917abcbdef9c0036919a0399769148cf/regex-2020.9.27.tar.gz";
1824 sha256 = "179ngfzwbsjvn5vhyzdahvmg0f7acahkwwy9bpjy1pv08bm2mwx6";
1825 };
1826 meta = {
1827 license = [ pkgs.lib.licenses.psfl ];
1828 };
1829 };
1819 1830 "redis" = super.buildPythonPackage {
1820 1831 name = "redis-3.4.1";
1821 1832 doCheck = false;
@@ -1946,6 +1957,7 b' self: super: {'
1946 1957 self."tzlocal"
1947 1958 self."pyzmq"
1948 1959 self."py-gfm"
1960 self."regex"
1949 1961 self."redis"
1950 1962 self."repoze.lru"
1951 1963 self."requests"
@@ -56,6 +56,7 b' pytz==2019.3'
56 56 tzlocal==1.5.1
57 57 pyzmq==14.6.0
58 58 py-gfm==0.1.4
59 regex==2020.9.27
59 60 redis==3.4.1
60 61 repoze.lru==0.7
61 62 requests==2.22.0
@@ -474,9 +474,18 b' class AdminSettingsView(BaseAppView):'
474 474 route_name='admin_settings_issuetracker_test', request_method='POST',
475 475 renderer='string', xhr=True)
476 476 def settings_issuetracker_test(self):
477 return h.urlify_commit_message(
477 error_container = []
478
479 urlified_commit = h.urlify_commit_message(
478 480 self.request.POST.get('test_text', ''),
479 'repo_group/test_repo1')
481 'repo_group/test_repo1', error_container=error_container)
482 if error_container:
483 def converter(inp):
484 return h.html_escape(unicode(inp))
485
486 return 'ERRORS: ' + '\n'.join(map(converter, error_container))
487
488 return urlified_commit
480 489
481 490 @LoginRequired()
482 491 @HasPermissionAllDecorator('hg.admin')
@@ -113,7 +113,7 b' def _commits_as_dict(event, commit_ids, '
113 113 cs_data['permalink_url'] = RepoModel().get_commit_url(
114 114 repo, cs_data['raw_id'], request=event.request,
115 115 permalink=True)
116 urlified_message, issues_data = process_patterns(
116 urlified_message, issues_data, errors = process_patterns(
117 117 cs_data['message'], repo.repo_name)
118 118 cs_data['issues'] = issues_data
119 119 cs_data['message_html'] = urlify_commit_message(
@@ -38,6 +38,7 b' import re'
38 38 import time
39 39 import string
40 40 import hashlib
41 import regex
41 42 from collections import OrderedDict
42 43
43 44 import pygments
@@ -1653,7 +1654,7 b' def get_active_pattern_entries(repo_name'
1653 1654 return active_entries
1654 1655
1655 1656
1656 pr_pattern_re = re.compile(r'(?:(?:^!)|(?: !))(\d+)')
1657 pr_pattern_re = regex.compile(r'(?:(?:^!)|(?: !))(\d+)')
1657 1658
1658 1659 allowed_link_formats = [
1659 1660 'html', 'rst', 'markdown', 'html+hovercard', 'rst+hovercard', 'markdown+hovercard']
@@ -1670,6 +1671,7 b' def process_patterns(text_string, repo_n'
1670 1671 active_entries = get_active_pattern_entries(repo_name)
1671 1672
1672 1673 issues_data = []
1674 errors = []
1673 1675 new_text = text_string
1674 1676
1675 1677 log.debug('Got %s entries to process', len(active_entries))
@@ -1687,9 +1689,11 b' def process_patterns(text_string, repo_n'
1687 1689 pattern = entry['pat_compiled']
1688 1690 else:
1689 1691 try:
1690 pattern = re.compile(r'%s' % entry['pat'])
1691 except re.error:
1692 log.exception('issue tracker pattern: `%s` failed to compile', entry['pat'])
1692 pattern = regex.compile(r'%s' % entry['pat'])
1693 except regex.error as e:
1694 regex_err = ValueError('{}:{}'.format(entry['pat'], e))
1695 log.exception('issue tracker pattern: `%s` failed to compile', regex_err)
1696 errors.append(regex_err)
1693 1697 continue
1694 1698
1695 1699 data_func = partial(
@@ -1721,11 +1725,11 b' def process_patterns(text_string, repo_n'
1721 1725 new_text = pr_pattern_re.sub(pr_url_func, new_text)
1722 1726 log.debug('processed !pr pattern')
1723 1727
1724 return new_text, issues_data
1728 return new_text, issues_data, errors
1725 1729
1726 1730
1727 1731 def urlify_commit_message(commit_text, repository=None, active_pattern_entries=None,
1728 issues_container=None):
1732 issues_container=None, error_container=None):
1729 1733 """
1730 1734 Parses given text message and makes proper links.
1731 1735 issues are linked to given issue-server, and rest is a commit link
@@ -1745,12 +1749,15 b' def urlify_commit_message(commit_text, r'
1745 1749 new_text = urlify_commits(new_text, repository)
1746 1750
1747 1751 # process issue tracker patterns
1748 new_text, issues = process_patterns(new_text, repository or '',
1749 active_entries=active_pattern_entries)
1752 new_text, issues, errors = process_patterns(
1753 new_text, repository or '', active_entries=active_pattern_entries)
1750 1754
1751 1755 if issues_container is not None:
1752 1756 issues_container.extend(issues)
1753 1757
1758 if error_container is not None:
1759 error_container.extend(errors)
1760
1754 1761 return literal(new_text)
1755 1762
1756 1763
@@ -1805,7 +1812,7 b" def render(source, renderer='rst', menti"
1805 1812 elif renderer == 'rst':
1806 1813 if repo_name:
1807 1814 # process patterns on comments if we pass in repo name
1808 source, issues = process_patterns(
1815 source, issues, errors = process_patterns(
1809 1816 source, repo_name, link_format='rst',
1810 1817 active_entries=active_pattern_entries)
1811 1818 if issues_container is not None:
@@ -1819,7 +1826,7 b" def render(source, renderer='rst', menti"
1819 1826 elif renderer == 'markdown':
1820 1827 if repo_name:
1821 1828 # process patterns on comments if we pass in repo name
1822 source, issues = process_patterns(
1829 source, issues, errors = process_patterns(
1823 1830 source, repo_name, link_format='markdown',
1824 1831 active_entries=active_pattern_entries)
1825 1832 if issues_container is not None:
@@ -16,8 +16,8 b' examples = ['
16 16 ),
17 17
18 18 (
19 'Redmine',
20 '(^#|\s#)(?P<issue_id>\d+)',
19 'Tickets with #123 (Redmine etc)',
20 '(?<![a-zA-Z0-9_/]{1,10}-?)(#)(?P<issue_id>\d+)',
21 21 'https://myissueserver.com/${repo}/issue/${issue_id}',
22 22 ''
23 23 ),
@@ -38,14 +38,15 b' examples = ['
38 38
39 39 (
40 40 'JIRA - All tickets',
41 '(^|\s\w+-\d+)',
42 'https://myjira.com/browse/${id}',
41 # official JIRA ticket pattern
42 '(?<![a-zA-Z0-9_/#]-?)(?P<issue_id>[A-Z]{1,6}-(?:[1-9][0-9]{0,7}))',
43 'https://myjira.com/browse/${issue_id}',
43 44 ''
44 45 ),
45 46
46 47 (
47 'JIRA - Project (JRA)',
48 '(?:(^|\s)(?P<issue_id>(?:JRA-|JRA-)(?:\d+)))',
48 'JIRA - Single project (JRA-XXXXXXXX)',
49 '(?<![a-zA-Z0-9_/#]-?)(?P<issue_id>JRA-(?:[1-9][0-9]{0,7}))',
49 50 'https://myjira.com/${issue_id}',
50 51 ''
51 52 ),
@@ -275,13 +276,19 b' examples = ['
275 276 <div class='textarea-full'>
276 277 <textarea id="test_pattern_data" rows="12">
277 278 This is an example text for testing issue tracker patterns.
278 This commit fixes ticket #451 and ticket #910.
279 Following tickets will get mentioned:
279 This commit fixes ticket #451 and ticket #910, reference for JRA-401.
280 The following tickets will get mentioned:
280 281 #123
281 #456
282 JRA-123
283 JRA-456
284 Open a pull request !101 to contribute !
282 #456 and PROJ-101
283 JRA-123 and #123
284 PROJ-456
285
286 [my artifact](http://something.com/JRA-1234-build.zip)
287
288 - #1001
289 - JRA-998
290
291 Open a pull request !101 to contribute!
285 292 Added tag v1.3.0 for commit 0f3b629be725
286 293
287 294 Add a test pattern here and hit preview to see the link.
@@ -121,7 +121,7 b' def test_extract_issues(backend, text_st'
121 121
122 122 with mock.patch.object(IssueTrackerSettingsModel,
123 123 'get_settings', get_settings_mock):
124 text, issues = helpers.process_patterns(text_string, repo.repo_name)
124 text, issues, errors = helpers.process_patterns(text_string, repo.repo_name)
125 125
126 126 expected = copy.deepcopy(expected)
127 127 for item in expected:
@@ -159,7 +159,7 b' def test_process_patterns_repo(backend, '
159 159
160 160 with mock.patch.object(IssueTrackerSettingsModel,
161 161 'get_settings', get_settings_mock):
162 processed_text, issues = helpers.process_patterns(
162 processed_text, issues, error = helpers.process_patterns(
163 163 text_string, repo.repo_name, link_format)
164 164
165 165 assert processed_text == expected_text.format(repo=repo.repo_name)
@@ -186,7 +186,7 b' def test_process_patterns_no_repo(text_s'
186 186
187 187 with mock.patch.object(IssueTrackerSettingsModel,
188 188 'get_global_settings', get_settings_mock):
189 processed_text, issues = helpers.process_patterns(
189 processed_text, issues, errors = helpers.process_patterns(
190 190 text_string, '')
191 191
192 192 assert processed_text == expected_text
@@ -211,7 +211,7 b' def test_process_patterns_non_existent_r'
211 211
212 212 with mock.patch.object(IssueTrackerSettingsModel,
213 213 'get_global_settings', get_settings_mock):
214 processed_text, issues = helpers.process_patterns(
214 processed_text, issues, errors = helpers.process_patterns(
215 215 text_string, 'do-not-exist')
216 216
217 217 assert processed_text == expected_text
General Comments 0
You need to be logged in to leave comments. Login now