]> git.ipfire.org Git - thirdparty/gcc.git/blob - contrib/gcc-changelog/git_email.py
2083d7b7ec9af3904b4f2ab3299ccac33b4933bf
[thirdparty/gcc.git] / contrib / gcc-changelog / git_email.py
1 #!/usr/bin/env python3
2 #
3 # This file is part of GCC.
4 #
5 # GCC is free software; you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation; either version 3, or (at your option) any later
8 # version.
9 #
10 # GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 # for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with GCC; see the file COPYING3. If not see
17 # <http://www.gnu.org/licenses/>. */
18
19 import os
20 import sys
21 from itertools import takewhile
22
23 from dateutil.parser import parse
24
25 from git_commit import GitCommit
26
27 from unidiff import PatchSet
28
29 DATE_PREFIX = 'Date: '
30 FROM_PREFIX = 'From: '
31
32
33 class GitEmail(GitCommit):
34 def __init__(self, filename, strict=False):
35 self.filename = filename
36 diff = PatchSet.from_filename(filename)
37 date = None
38 author = None
39
40 with open(self.filename, 'r') as f:
41 lines = f.read().splitlines()
42 lines = list(takewhile(lambda line: line != '---', lines))
43 for line in lines:
44 if line.startswith(DATE_PREFIX):
45 date = parse(line[len(DATE_PREFIX):])
46 elif line.startswith(FROM_PREFIX):
47 author = GitCommit.format_git_author(line[len(FROM_PREFIX):])
48 header = list(takewhile(lambda line: line != '', lines))
49 body = lines[len(header) + 1:]
50
51 modified_files = []
52 for f in diff:
53 # Strip "a/" and "b/" prefixes
54 source = f.source_file[2:]
55 target = f.target_file[2:]
56
57 if f.is_added_file:
58 t = 'A'
59 elif f.is_removed_file:
60 t = 'D'
61 elif f.is_rename:
62 # Consider that renamed files are two operations: the deletion
63 # of the original name and the addition of the new one.
64 modified_files.append((source, 'D'))
65 t = 'A'
66 else:
67 t = 'M'
68 modified_files.append((target, t))
69 super().__init__(None, date, author, body, modified_files,
70 strict=strict, commit_to_date_hook=lambda x: date)
71
72
73 # With zero arguments, process every patch file in the ./patches directory.
74 # With one argument, process the named patch file.
75 # Patch files must be in 'git format-patch' format.
76 if __name__ == '__main__':
77 if len(sys.argv) == 1:
78 allfiles = []
79 for root, _dirs, files in os.walk('patches'):
80 for f in files:
81 full = os.path.join(root, f)
82 allfiles.append(full)
83
84 success = 0
85 for full in sorted(allfiles):
86 email = GitEmail(full, False)
87 print(email.filename)
88 if email.success:
89 success += 1
90 print(' OK')
91 else:
92 for error in email.errors:
93 print(' ERR: %s' % error)
94
95 print()
96 print('Successfully parsed: %d/%d' % (success, len(allfiles)))
97 else:
98 email = GitEmail(sys.argv[1], False)
99 if email.success:
100 print('OK')
101 email.print_output()
102 else:
103 if not email.lines:
104 print('Error: patch contains no parsed lines', file=sys.stderr)
105 email.print_errors()
106 sys.exit(1)