diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py +++ b/rhodecode/lib/helpers.py @@ -1543,11 +1543,14 @@ def process_patterns(text_string, repo_n log.debug('issue tracker entry: uid: `%s` PAT:%s URL:%s PREFIX:%s', uid, entry['pat'], entry['url'], entry['pref']) - try: - pattern = re.compile(r'%s' % entry['pat']) - except re.error: - log.exception('issue tracker pattern: `%s` failed to compile', entry['pat']) - continue + if entry.get('pat_compiled'): + pattern = entry['pat_compiled'] + else: + try: + pattern = re.compile(r'%s' % entry['pat']) + except re.error: + log.exception('issue tracker pattern: `%s` failed to compile', entry['pat']) + continue data_func = partial( _process_url_func, repo_name=repo_name, entry=entry, uid=uid, diff --git a/rhodecode/model/settings.py b/rhodecode/model/settings.py --- a/rhodecode/model/settings.py +++ b/rhodecode/model/settings.py @@ -21,6 +21,7 @@ import os import hashlib import logging +import re from collections import namedtuple from functools import wraps import bleach @@ -372,9 +373,15 @@ class IssueTrackerSettingsModel(object): for uid in issuetracker_entries: url_data = qs.get(self._get_keyname('url', uid, 'rhodecode_')) + pat = qs.get(self._get_keyname('pat', uid, 'rhodecode_')) + try: + pat_compiled = re.compile(r'%s' % pat) + except re.error: + pat_compiled = None + issuetracker_entries[uid] = AttributeDict({ - 'pat': qs.get( - self._get_keyname('pat', uid, 'rhodecode_')), + 'pat': pat, + 'pat_compiled': pat_compiled, 'url': url_cleaner( qs.get(self._get_keyname('url', uid, 'rhodecode_')) or ''), 'pref': bleach.clean( diff --git a/rhodecode/tests/models/settings/test_issue_tracker.py b/rhodecode/tests/models/settings/test_issue_tracker.py --- a/rhodecode/tests/models/settings/test_issue_tracker.py +++ b/rhodecode/tests/models/settings/test_issue_tracker.py @@ -43,6 +43,9 @@ class TestIssueTrackerSettingsModel(obje settings_mock.return_value = input_settings result = model.get_global_settings(cache=True) get_settings.assert_called_once_with(cache=True) + for k, v in result.items(): + v.pop('pat_compiled', None) + assert expected_result == result def test_get_repo_settings_raise_exception_when_repo_is_not_set(self): @@ -68,6 +71,8 @@ class TestIssueTrackerSettingsModel(obje settings_mock.return_value = input_settings result = model.get_repo_settings(cache=True) get_settings.assert_called_once_with(cache=True) + for k, v in result.items(): + v.pop('pat_compiled', None) assert expected_result == result @pytest.mark.parametrize("inherit_settings, method", [