Guest User

Untitled

a guest
Nov 4th, 2017
529
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.69 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. """
  3. Analyze Segwit2x contributors via git history.
  4.  
  5. To use:
  6.  
  7. git clone git@github.com:bitcoin/bitcoin.git
  8. cd bitcoin
  9. git remote add 2x git@github.com:btc1/bitcoin.git
  10. git fetch 2x
  11. [wget $THIS_URL, chmod +x, whatever]
  12. git log origin/master..2x/segwit2x-dev --shortstat --pretty="%cE" | ./analyze2x.py
  13.  
  14. """
  15. import fileinput
  16. import re
  17. from collections import namedtuple, defaultdict
  18.  
  19. Stat = namedtuple('Stat', 'adds rms files')
  20.  
  21. changeline_regexp = (
  22. r'(?P<files>\d+) file.? changed, '
  23. r'((?P<adds>\d+) insertion.*)?'
  24. r'((?P<rms>\d+) delet.*)?')
  25.  
  26.  
  27. definitely_not_a_2x_dev = {
  28. 'pieter.wuille@gmail.com',
  29. 'practicalswift@users.noreply.github.com',
  30. 'laanwj@gmail.com',
  31. 'noreply@github.com',
  32. 'sdaftuar@gmail.com',
  33. 'dev@jonasschnelli.ch',
  34. 'practicalswift@users.noreply.github.com',
  35. 'russ@yanofsky.org',
  36. 'morcos@chaincode.com',
  37. 'luke-jr+git@utopios.org',
  38. 'sdaftuar@chaincode.com',
  39. 'git@bluematt.me',
  40. 'cory-nospam-@coryfields.com',
  41. 'falke.marco@gmail.com',
  42. 'greg@xiph.org',
  43. 'dev@jonasschnelli.ch',
  44. 'sdaftuar@gmail.com',
  45. }
  46.  
  47.  
  48. def main():
  49. authors_to_stats = defaultdict(list)
  50. authors_per_line = set()
  51. lines = fileinput.input()
  52.  
  53. for line in lines:
  54. line = line.strip()
  55.  
  56. m = re.search(changeline_regexp, line)
  57. if m:
  58. stat = Stat(**m.groupdict())
  59. for author in authors_per_line:
  60. authors_to_stats[author].append(stat)
  61. authors_per_line = set()
  62. elif line:
  63. if line not in definitely_not_a_2x_dev:
  64. authors_per_line.add(line)
  65.  
  66. total_stat = aggregate_stat(
  67. stat for stats in authors_to_stats.values() for stat in stats)
  68.  
  69. prettyprint(aggregate(authors_to_stats), total_stat)
  70.  
  71.  
  72. def aggregate(authors_to_stats):
  73. out = {}
  74.  
  75. for author, stats in authors_to_stats.items():
  76. out[author] = aggregate_stat(stats)
  77.  
  78. return list(reversed(sorted(
  79. out.items(), key=lambda i: i[1].adds + i[1].rms)))
  80.  
  81.  
  82. def aggregate_stat(stats):
  83. def to_int(a):
  84. return int(a) if a else 0
  85.  
  86. return Stat(
  87. adds=sum(to_int(s.adds) for s in stats),
  88. rms=sum(to_int(s.rms) for s in stats),
  89. files=sum(to_int(s.files) for s in stats),
  90. )
  91.  
  92.  
  93. def prettyprint(author_stats, total_stat):
  94. total_changes = total_stat.rms + total_stat.adds
  95.  
  96. for author, stat in author_stats:
  97. perc = (stat.adds + stat.rms) / total_changes
  98. print("{:>6} {:<40} {:>8} {:>8} {:>20}".format(
  99. f'{int(perc * 100)}%',
  100. author,
  101. f'+{stat.adds}',
  102. f'-{stat.rms}',
  103. f'(over {stat.files} files)',
  104. ))
  105.  
  106.  
  107. if __name__ == '__main__':
  108. main()
Add Comment
Please, Sign In to add comment