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