xref: /Lucene/dev-tools/scripts/releasedJirasRegex.py (revision 674b66dd16f5b89b7c97ea9aedcac077e6d7f3b9)
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Licensed to the Apache Software Foundation (ASF) under one or more
4# contributor license agreements.  See the NOTICE file distributed with
5# this work for additional information regarding copyright ownership.
6# The ASF licenses this file to You under the Apache License, Version 2.0
7# (the "License"); you may not use this file except in compliance with
8# the License.  You may obtain a copy of the License at
9#
10#     http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
18import sys
19import os
20sys.path.append(os.path.dirname(__file__))
21from scriptutil import *
22import argparse
23import re
24
25# Pulls out all JIRAs mentioned at the beginning of bullet items
26# under the given version in the given CHANGES.txt file
27# and prints a regular expression that will match all of them
28#
29# Caveat: In ancient versions (Lucene v1.9 and older),
30# does not find Bugzilla bugs or JIRAs not mentioned at the beginning of
31# bullets or numbered entries.
32#
33def print_released_jiras_regex(version, filename):
34  release_boundary_re = re.compile(r'\s*====*\s+(.*)\s+===')
35  version_re = re.compile(r'%s(?:$|[^-])' % version)
36  bullet_re = re.compile(r'\s*(?:[-*]|\d+\.(?=(?:\s|(?:LUCENE)-)))(.*)')
37  jira_ptn = r'(?:LUCENE)-\d+'
38  jira_re = re.compile(jira_ptn)
39  jira_list_ptn = r'(?:[:,/()\s]*(?:%s))+' % jira_ptn
40  jira_list_re = re.compile(jira_list_ptn)
41  more_jiras_on_next_line_re = re.compile(r'%s\s*,\s*$' % jira_list_ptn) # JIRA list with trailing comma
42  under_requested_version = False
43  requested_version_found = False
44  more_jiras_on_next_line = False
45  lucene_jiras = []
46  with open(filename, 'r') as changes:
47    for line in changes:
48      version_boundary = release_boundary_re.match(line)
49      if version_boundary is not None:
50        if under_requested_version:
51          break # No longer under the requested version - stop looking for JIRAs
52        else:
53          if version_re.search(version_boundary.group(1)):
54            under_requested_version = True # Start looking for JIRAs
55            requested_version_found = True
56      else:
57        if under_requested_version:
58          bullet_match = bullet_re.match(line)
59          if more_jiras_on_next_line or bullet_match is not None:
60            content = line if bullet_match is None else bullet_match.group(1)
61            jira_list_match = jira_list_re.match(content)
62            if jira_list_match is not None:
63              jira_match = jira_re.findall(jira_list_match.group(0))
64              for jira in jira_match:
65                lucene_jiras.append(jira.rsplit('-', 1)[-1])
66            more_jiras_on_next_line = more_jiras_on_next_line_re.match(content)
67  if not requested_version_found:
68    raise Exception('Could not find %s in %s' % (version, filename))
69  print()
70  if (len(lucene_jiras) == 0):
71    print('(No JIRAs => no regex)', end='')
72  else:
73    print(r'LUCENE-(?:%s)\b' % '|'.join(lucene_jiras), end='')
74  print()
75
76def read_config():
77  parser = argparse.ArgumentParser(
78    description='Prints a regex matching JIRAs fixed in the given version by parsing the given CHANGES.txt file')
79  parser.add_argument('version', type=Version.parse, help='Version of the form X.Y.Z')
80  parser.add_argument('changes', help='CHANGES.txt file to parse')
81  return parser.parse_args()
82
83def main():
84  config = read_config()
85  print_released_jiras_regex(config.version, config.changes)
86
87if __name__ == '__main__':
88  try:
89    main()
90  except KeyboardInterrupt:
91    print('\nReceived Ctrl-C, exiting early')
92