Skip to content

Commit 35b27d3

Browse files
authored
New dev-tools/scripts/parseContributorsFromChanges.py (#2424)
Parses a CHANGES.txt section passed in, in order to identify all contributors. Future: integrate with the release wizard, to include providing only the versioned section of CHANGES.txt to the script.
1 parent 388101f commit 35b27d3

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one or more
2+
# contributor license agreements. See the NOTICE file distributed with
3+
# this work for additional information regarding copyright ownership.
4+
# The ASF licenses this file to You under the Apache License, Version 2.0
5+
# (the "License"); you may not use this file except in compliance with
6+
# the License. You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
import sys
17+
import re
18+
from collections import defaultdict
19+
20+
# Read data from standard input
21+
data = sys.stdin.read()
22+
23+
# Replace all carriage return line feed (Windows) with line feed
24+
data = data.replace('\r\n', '\n')
25+
26+
# Replace all carriage return (Mac OS before X) with line feed
27+
data = data.replace('\r', '\n')
28+
29+
# Split data at blank lines
30+
paras = data.split('\n\n')
31+
32+
# Initialize a default dictionary to store contributors and their counts
33+
contributors = defaultdict(int)
34+
35+
# Regular expression to find the attribution in parentheses at the end of a line
36+
pattern = re.compile(r"\(([^()]*)\)$")
37+
38+
for para in paras:
39+
# Normalize whitespace (replace all whitespace with a single space)
40+
para = re.sub('\s+', ' ', para).strip()
41+
#print(f'> {para}')
42+
43+
# Find all contributors in the line
44+
match = pattern.search(para.strip())
45+
if match:
46+
attribution = match.group(1)
47+
# might have a "via" committer; we only want the author here
48+
attribution = attribution.split(" via ")[0] # keep left side
49+
# Split the contributors by comma and strip whitespace
50+
for contributor in attribution.split(','):
51+
contributor = contributor.strip()
52+
contributors[contributor] += 1
53+
54+
del contributors['solrbot']
55+
56+
sorted_contributors = sorted(contributors.items(), key=lambda item: item[1], reverse=True)
57+
58+
# Print the contributors and their counts
59+
for contributor, count in sorted_contributors:
60+
print(f'{contributor}: {count}')
61+
62+
print('\n\nThanks to all contributors!: ')
63+
print(', '.join([contributor for contributor, count in sorted_contributors]))

0 commit comments

Comments
 (0)