gitlog2changelog.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #!/usr/bin/env python3
  2. # Copyright 2008 Marcus D. Hanwell <marcus@cryos.org>
  3. # Adapted for Claws Mail - Copyright 2013 Colin Leroy <colin@colino.net>
  4. # Distributed under the terms of the GNU General Public License v2 or later
  5. import string, re, os, sys
  6. curRev = ""
  7. prevVer = ""
  8. if len(sys.argv) == 3:
  9. curRev = sys.argv[2]
  10. prevVer = sys.argv[1]
  11. else:
  12. curRevCmd = os.popen("git describe")
  13. curRev = curRevCmd.read()
  14. curRev = curRev[0:len(curRev)-1]
  15. curRevCmd.close()
  16. if len(sys.argv) == 2:
  17. prevVer = sys.argv[1]
  18. else:
  19. prevVer = re.split('-', curRev, 1)[0]
  20. # Execute git log with the desired command line options.
  21. fin = os.popen('git log ' + prevVer + '..' + curRev +' --summary --stat --no-merges --date=short', 'r')
  22. # Create a ChangeLog file in the current directory.
  23. fout = sys.stdout
  24. # Set up the loop variables in order to locate the blocks we want
  25. authorFound = False
  26. dateFound = False
  27. messageFound = False
  28. filesFound = False
  29. message = ""
  30. commit = ""
  31. messageNL = False
  32. files = ""
  33. prevAuthorLine = ""
  34. # The main part of the loop
  35. for line in fin:
  36. # The commit line marks the start of a new commit object.
  37. if re.match('^commit', line):
  38. # Start all over again...
  39. authorFound = False
  40. dateFound = False
  41. messageFound = False
  42. messageNL = False
  43. message = ""
  44. filesFound = False
  45. files = ""
  46. commitCmd = os.popen("git describe "+re.split(' ', line, 1)[1])
  47. commit = commitCmd.read()
  48. commitCmd.close()
  49. commit = commit[0:len(commit)-1]
  50. continue
  51. # Match the author line and extract the part we want
  52. elif re.match('^Author:', line):
  53. authorList = re.split(': ', line, 1)
  54. author = re.split('<', authorList[1], 1)[0]
  55. author = "[" + author[0:len(author)-1]+"]"
  56. authorFound = True
  57. continue
  58. # Match the date line
  59. elif re.match('^Date:', line):
  60. dateList = re.split(': ', line, 1)
  61. date = dateList[1]
  62. date = date[0:len(date)-1]
  63. dateFound = True
  64. continue
  65. # The svn-id lines are ignored
  66. elif re.match(' git-svn-id:', line):
  67. continue
  68. # The sign off line is ignored too
  69. elif re.search('Signed-off-by', line) != None:
  70. continue
  71. # Extract the actual commit message for this commit
  72. elif authorFound & dateFound & messageFound == False:
  73. # Find the commit message if we can
  74. if len(line) == 1:
  75. if messageNL:
  76. messageFound = True
  77. else:
  78. messageNL = True
  79. elif len(line) == 4:
  80. messageFound = True
  81. else:
  82. if len(message) == 0:
  83. message = message + line.strip()
  84. else:
  85. message = message + " " + line.strip()
  86. # If this line is hit all of the files have been stored for this commit
  87. elif re.search('file(s)? changed', line) != None:
  88. filesFound = True
  89. continue
  90. # Collect the files for this commit. FIXME: Still need to add +/- to files
  91. elif authorFound & dateFound & messageFound:
  92. fileList = re.split(' \| ', line, 2)
  93. if len(fileList) > 1:
  94. if len(files) > 0:
  95. files = files + "\n\t* " + fileList[0].strip()
  96. else:
  97. files = "\t* " + fileList[0].strip()
  98. # All of the parts of the commit have been found - write out the entry
  99. if authorFound & dateFound & messageFound & filesFound:
  100. # First the author line, only outputted if it is the first for that
  101. # author on this day
  102. authorLine = date + " " + author
  103. if len(prevAuthorLine) != 0:
  104. fout.write("\n");
  105. fout.write(authorLine + " " + commit + "\n\n")
  106. # Assemble the actual commit message line(s) and limit the line length
  107. # to 80 characters.
  108. commitLine = message
  109. i = 0
  110. commit = ""
  111. while i < len(commitLine):
  112. if len(commitLine) < i + 70:
  113. commit = commit + "\n\t\t" + commitLine[i:len(commitLine)]
  114. break
  115. index = commitLine.rfind(' ', i, i+70)
  116. if index > i:
  117. commit = commit + "\n\t\t" + commitLine[i:index]
  118. i = index+1
  119. else:
  120. commit = commit + "\n\t\t" + commitLine[i:70]
  121. i = i+71
  122. # Write out the commit line
  123. fout.write(files + "\t\t" + commit + "\n")
  124. #Now reset all the variables ready for a new commit block.
  125. authorFound = False
  126. dateFound = False
  127. messageFound = False
  128. messageNL = False
  129. message = ""
  130. filesFound = False
  131. files = ""
  132. prevAuthorLine = authorLine
  133. # Close the input and output lines now that we are finished.
  134. fin.close()
  135. fout.close()