Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / tools / generate_authors.py
blobf6114bbcddd55d9514003ab055777f264b2a1812
1 #!/usr/bin/env python3
4 # Generate the AUTHORS file combining existing AUTHORS file with
5 # git commit log.
7 # Usage: generate_authors.py AUTHORS.src
9 # Copyright 2022 Moshe Kaplan
10 # Based on generate_authors.pl by Michael Mann
12 # Wireshark - Network traffic analyzer
13 # By Gerald Combs <gerald@wireshark.org>
14 # Copyright 1998 Gerald Combs
16 # SPDX-License-Identifier: GPL-2.0-or-later
18 import argparse
19 import re
20 import subprocess
22 have_pyuca = False
23 try:
24 from pyuca import Collator
25 have_pyuca = True
26 except ModuleNotFoundError:
27 import sys
28 sys.stderr.write('pyuca module not found. Sorting names using the built-in locale module.\n')
29 import locale
31 def get_git_authors():
32 '''
33 Sample line:
34 # 4321 Navin R. Johnson <nrjohnson@example.com>
35 '''
36 GIT_LINE_REGEX = r"^\s*\d+\s+([^<]*)\s*<([^>]*)>"
37 cmd = "git --no-pager shortlog --email --summary HEAD".split(' ')
38 # check_output is used for Python 3.4 compatibility
39 git_cmd_output = subprocess.check_output(cmd, universal_newlines=True, encoding='utf-8')
41 git_authors = []
42 for line in git_cmd_output.splitlines():
43 # Check if this is needed:
44 line = line.strip()
45 match = re.match(GIT_LINE_REGEX, line)
46 name = match.group(1).strip()
47 email = match.group(2).strip()
48 # Try to lower how much spam people get:
49 email = email.replace('@', '[AT]')
50 git_authors.append((name, email))
51 if have_pyuca:
52 c = Collator()
53 return sorted(git_authors, key=lambda x: c.sort_key(x[0]))
54 return sorted(git_authors, key=lambda x: locale.strxfrm(x[0].casefold()))
57 def extract_contributors(authors_content):
58 # Extract names and email addresses from the AUTHORS file Contributors
59 contributors_content = authors_content.split("= Contributors =", 1)[1]
60 CONTRIBUTOR_LINE_REGEX = r"^([\w\.\-\'\x80-\xff]+(\s*[\w+\.\-\'\x80-\xff])*)\s+<([^>]*)>"
61 contributors = []
62 state = ""
63 for line in contributors_content.splitlines():
64 contributor_match = re.match(CONTRIBUTOR_LINE_REGEX, line)
65 if re.search(r'([^\{]*)\{', line):
66 if contributor_match:
67 name = contributor_match.group(1)
68 email = contributor_match.group(3)
69 contributors.append((name, email))
70 state = "s_in_bracket"
71 elif state == "s_in_bracket":
72 if re.search(r'([^\}]*)\}', line):
73 state = ""
74 elif re.search('<', line):
75 if contributor_match:
76 name = contributor_match.group(1)
77 email = contributor_match.group(3)
78 contributors.append((name, email))
79 elif re.search(r"(e-mail address removed at contributor's request)", line):
80 if contributor_match:
81 name = contributor_match.group(1)
82 email = contributor_match.group(3)
83 contributors.append((name, email))
84 else:
85 pass
86 return contributors
89 def generate_git_contributors_text(contributors_emails, git_authors_emails):
90 # Track the email addresses seen to avoid including the same email address twice
91 emails_addresses_seen = set()
92 for name, email in contributors_emails:
93 emails_addresses_seen.add(email.lower())
95 output_lines = []
96 for name, email in git_authors_emails:
97 if email.lower() in emails_addresses_seen:
98 continue
100 # Skip Gerald, since he's part of the header:
101 if email == "gerald[AT]wireshark.org":
102 continue
104 ntab = 3
105 if len(name) >= 8*ntab:
106 line = "{name} <{email}>".format(name=name, email=email)
107 else:
108 ntab -= len(name)/8
109 if len(name) % 8:
110 ntab += 1
111 tabs = '\t'*int(ntab)
112 line = "{name}{tabs}<{email}>".format(name=name, tabs=tabs, email=email)
114 emails_addresses_seen.add(email.lower())
115 output_lines += [line]
116 return "\n".join(output_lines)
119 # Read authors file until we find gitlog entries, then stop
120 def read_authors(parsed_args):
121 lines = []
122 with open(parsed_args.authors[0], 'r', encoding='utf-8') as fh:
123 for line in fh.readlines():
124 if '= From git log =' in line:
125 break
126 lines.append(line)
127 return ''.join(lines)
130 def main():
131 parser = argparse.ArgumentParser(description="Generate the AUTHORS file combining existing AUTHORS file with git commit log.")
132 parser.add_argument("authors", metavar='authors', nargs=1, help="path to AUTHORS file")
133 parsed_args = parser.parse_args()
135 author_content = read_authors(parsed_args)
137 # Collect the listed contributors emails so that we don't duplicate them
138 # in the listing of git contributors
139 contributors_emails = extract_contributors(author_content)
140 git_authors_emails = get_git_authors()
141 # Then generate the text output for git contributors
142 git_contributors_text = generate_git_contributors_text(contributors_emails, git_authors_emails)
144 # Now we can write our output:
145 git_contributor_header = '= From git log =\n\n'
146 output = author_content + git_contributor_header + git_contributors_text + '\n'
148 with open(parsed_args.authors[0], 'w', encoding='utf-8') as fh:
149 fh.write(output)
152 if __name__ == '__main__':
153 main()