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