gather_git_credits.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #!/usr/bin/env python3
  2. import subprocess
  3. import re
  4. from collections import defaultdict
  5. codefiles = r"(\.[ch](pp)?|\.lua|\.md|\.cmake|\.java|\.gradle|Makefile|CMakeLists\.txt)$"
  6. # two minor versions back, for "Active Contributors"
  7. REVS_ACTIVE = "5.7.0..HEAD"
  8. # all time, for "Previous Contributors"
  9. REVS_PREVIOUS = "HEAD"
  10. CUTOFF_ACTIVE = 3
  11. CUTOFF_PREVIOUS = 21
  12. # For a description of the points system see:
  13. # https://github.com/minetest/minetest/pull/9593#issue-398677198
  14. def load(revs):
  15. points = defaultdict(int)
  16. p = subprocess.Popen(["git", "log", "--mailmap", "--pretty=format:%h %aN <%aE>", revs],
  17. stdout=subprocess.PIPE, universal_newlines=True)
  18. for line in p.stdout:
  19. hash, author = line.strip().split(" ", 1)
  20. n = 0
  21. p2 = subprocess.Popen(["git", "show", "--numstat", "--pretty=format:", hash],
  22. stdout=subprocess.PIPE, universal_newlines=True)
  23. for line in p2.stdout:
  24. added, deleted, filename = re.split(r"\s+", line.strip(), 2)
  25. if re.search(codefiles, filename) and added != "-":
  26. n += int(added)
  27. p2.wait()
  28. if n == 0:
  29. continue
  30. if n > 1200:
  31. n = 8
  32. elif n > 700:
  33. n = 4
  34. elif n > 100:
  35. n = 2
  36. else:
  37. n = 1
  38. points[author] += n
  39. p.wait()
  40. # Some authors duplicate? Don't add manual workarounds here, edit the .mailmap!
  41. for author in ("updatepo.sh <script@mt>", "Weblate <42@minetest.ru>",
  42. "import <script@mt>", "minetest <minetest@minetest.net>"):
  43. points.pop(author, None)
  44. return points
  45. points_active = load(REVS_ACTIVE)
  46. points_prev = load(REVS_PREVIOUS)
  47. with open("results.txt", "w") as f:
  48. for author, points in sorted(points_active.items(), key=(lambda e: e[1]), reverse=True):
  49. if points < CUTOFF_ACTIVE: break
  50. points_prev.pop(author, None) # active authors don't appear in previous
  51. f.write("%d\t%s\n" % (points, author))
  52. f.write('\n---------\n\n')
  53. once = True
  54. for author, points in sorted(points_prev.items(), key=(lambda e: e[1]), reverse=True):
  55. if points < CUTOFF_PREVIOUS and once:
  56. f.write('\n---------\n\n')
  57. once = False
  58. f.write("%d\t%s\n" % (points, author))