xref: /netbsd-src/external/gpl3/gcc.old/dist/contrib/git-fix-changelog.py (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
1*4c3eb207Smrg#!/usr/bin/env python3
2*4c3eb207Smrg
3*4c3eb207Smrg# Copyright (C) 2020 Free Software Foundation, Inc.
4*4c3eb207Smrg#
5*4c3eb207Smrg# This file is part of GCC.
6*4c3eb207Smrg#
7*4c3eb207Smrg# GCC is free software; you can redistribute it and/or modify
8*4c3eb207Smrg# it under the terms of the GNU General Public License as published by
9*4c3eb207Smrg# the Free Software Foundation; either version 3, or (at your option)
10*4c3eb207Smrg# any later version.
11*4c3eb207Smrg#
12*4c3eb207Smrg# GCC is distributed in the hope that it will be useful,
13*4c3eb207Smrg# but WITHOUT ANY WARRANTY; without even the implied warranty of
14*4c3eb207Smrg# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*4c3eb207Smrg# GNU General Public License for more details.
16*4c3eb207Smrg#
17*4c3eb207Smrg# You should have received a copy of the GNU General Public License
18*4c3eb207Smrg# along with GCC; see the file COPYING.  If not, write to
19*4c3eb207Smrg# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20*4c3eb207Smrg# Boston, MA 02110-1301, USA.
21*4c3eb207Smrg#
22*4c3eb207Smrg# The script tries to fix commit message where ChangeLog entries
23*4c3eb207Smrg# can point to .cc renamed files.
24*4c3eb207Smrg
25*4c3eb207Smrgimport argparse
26*4c3eb207Smrgimport os
27*4c3eb207Smrgimport subprocess
28*4c3eb207Smrgimport tempfile
29*4c3eb207Smrg
30*4c3eb207SmrgDESCRIPTION = 'Fix up ChangeLog of the current commit.'
31*4c3eb207Smrg
32*4c3eb207Smrgscript_folder = os.path.dirname(os.path.abspath(__file__))
33*4c3eb207Smrgverify_script = os.path.join(script_folder,
34*4c3eb207Smrg                             'gcc-changelog/git_check_commit.py')
35*4c3eb207Smrg
36*4c3eb207Smrg
37*4c3eb207Smrgdef replace_file_in_changelog(lines, filename, fixed):
38*4c3eb207Smrg    # consider all componenets of a path: gcc/ipa-icf.cc
39*4c3eb207Smrg    while filename:
40*4c3eb207Smrg        for i, line in enumerate(lines):
41*4c3eb207Smrg            if filename in line:
42*4c3eb207Smrg                lines[i] = line.replace(filename, fixed)
43*4c3eb207Smrg                return
44*4c3eb207Smrg
45*4c3eb207Smrg        parts = filename.split('/')
46*4c3eb207Smrg        if len(parts) == 1:
47*4c3eb207Smrg            return
48*4c3eb207Smrg        filename = '/'.join(parts[1:])
49*4c3eb207Smrg        fixed = '/'.join(fixed.split('/')[1:])
50*4c3eb207Smrg
51*4c3eb207Smrg
52*4c3eb207Smrgif __name__ == '__main__':
53*4c3eb207Smrg    parser = argparse.ArgumentParser(description=DESCRIPTION)
54*4c3eb207Smrg    args = parser.parse_args()
55*4c3eb207Smrg
56*4c3eb207Smrg    # Update commit message if change for a .cc file was taken
57*4c3eb207Smrg    r = subprocess.run(f'{verify_script} HEAD', shell=True, encoding='utf8',
58*4c3eb207Smrg                       stdout=subprocess.PIPE, stderr=subprocess.PIPE)
59*4c3eb207Smrg    if r.returncode != 0:
60*4c3eb207Smrg        lines = r.stdout.splitlines()
61*4c3eb207Smrg        cmd = 'git show -s --format=%B'
62*4c3eb207Smrg        commit_message = subprocess.check_output(cmd, shell=True,
63*4c3eb207Smrg                                                 encoding='utf8').strip()
64*4c3eb207Smrg        commit_message = commit_message.splitlines()
65*4c3eb207Smrg
66*4c3eb207Smrg        # Parse the following lines:
67*4c3eb207Smrg        # ERR: unchanged file mentioned in a ChangeLog \
68*4c3eb207Smrg        # (did you mean "gcc/ipa-icf.cc"?): "gcc/ipa-icf.c"
69*4c3eb207Smrg        replaced = 0
70*4c3eb207Smrg        for line in lines:
71*4c3eb207Smrg            if ('unchanged file mentioned' in line and
72*4c3eb207Smrg                    'did you mean' in line):
73*4c3eb207Smrg                filename = line.split()[-1].strip('"')
74*4c3eb207Smrg                fixed = line[line.index('did you mean'):]
75*4c3eb207Smrg                fixed = fixed[fixed.index('"') + 1:]
76*4c3eb207Smrg                fixed = fixed[:fixed.index('"')]
77*4c3eb207Smrg
78*4c3eb207Smrg                if filename.count('/') == fixed.count('/'):
79*4c3eb207Smrg                    replace_file_in_changelog(commit_message, filename, fixed)
80*4c3eb207Smrg                    replaced += 1
81*4c3eb207Smrg
82*4c3eb207Smrg        if replaced:
83*4c3eb207Smrg            with tempfile.NamedTemporaryFile('w', encoding='utf8',
84*4c3eb207Smrg                                             delete=False) as w:
85*4c3eb207Smrg                w.write('\n'.join(commit_message))
86*4c3eb207Smrg                w.close()
87*4c3eb207Smrg                subprocess.check_output(f'git commit --amend -F {w.name}',
88*4c3eb207Smrg                                        shell=True, encoding='utf8')
89*4c3eb207Smrg                os.unlink(w.name)
90*4c3eb207Smrg                print(f'Commit message updated: {replaced} file(s) renamed.')
91*4c3eb207Smrg        else:
92*4c3eb207Smrg            print('Commit message has not been updated.')
93