Skip to content

Instantly share code, notes, and snippets.

@venantius
Created December 9, 2015 05:09
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save venantius/ba11dc49cc7a770a3420 to your computer and use it in GitHub Desktop.
Save venantius/ba11dc49cc7a770a3420 to your computer and use it in GitHub Desktop.
Rubocop summary stats generator
#!/usr/bin/env python3
"""
A little script to quickly identify the worst offenders. Easily extensible to
find and sort by other issues. Expects you to have results available in an
easily consumable JSON file, which you can generate by running:
rubocop --format progress --format json --out rubocop.json
"""
import json
import sys
from collections import Counter
def generate_offense_breakdown(offenses):
"""
Given a list of offenses, return a dict with keys as offenses
and values the counts of that offense.
"""
c = Counter()
for o in offenses:
c.update([o['cop_name']])
return c
def offenses_by_type(blob):
"""
Given a JSON blob, return a bunch of offenses.
"""
offending_files = []
for f in blob['files']:
r = {
"total_offenses": len(f['offenses']),
"offense_breakdown": generate_offense_breakdown(f['offenses']),
"filename": f['path']
}
offending_files.append(r)
return sorted(offending_files,
key=lambda k: k['total_offenses'],
reverse=True)
def offenses(blob):
"""
Just get the basic count of offenses.
"""
offending_files = []
for f in blob['files']:
offending_files.append([len(f['offenses']), f['path']])
offending_files.sort(reverse=True)
return offending_files
def print_offense_breakdown(offense_counter):
"""
Given an offense counter, print the individual offense counts.
"""
items = offense_counter.most_common()
for k, v in items:
if (k, v) != items[-1]:
print(' ├──', k + ":", v)
else:
print(' └──', k + ":", v)
def main():
results = json.loads(open('rubocop.json').read())
rubocop_results = offenses_by_type(results)
for r in rubocop_results:
if r['total_offenses'] >= 5:
print(r['filename'])
print(str.join("",
["└─┬ TotalOffenses: ", str(r['total_offenses'])]
))
print_offense_breakdown(r['offense_breakdown'])
print()
if __name__ == "__main__":
main()
@sasharevzin
Copy link

Example output:

spec/services/notify_researcher_service_spec.rb
└─┬ TotalOffenses: 16
  ├── RSpec/NestedGroups: 12
  ├── RSpec/ContextWording: 2
  └── RSpec/RepeatedExampleGroupDescription: 2

app/services/reports_service.rb
└─┬ TotalOffenses: 12
  ├── Metrics/AbcSize: 4
  ├── Metrics/CyclomaticComplexity: 4
  ├── Style/MultilineIfModifier: 2
  ├── Metrics/ClassLength: 1
  └── Metrics/PerceivedComplexity: 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment