git-fix-changelog.py 3.4 KB

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