Skip to content

Commit

Permalink
Output JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
robvanderleek committed Nov 6, 2022
1 parent 90f5510 commit 2a6f8c8
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
build/
dist/
clim.spec
clim.json
.coverage
coverage.xml
12 changes: 8 additions & 4 deletions clim
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#!/usr/bin/env python3

from codelimit.common.Report import Report
from codelimit.common.Scanner import scan
from codelimit.version import version, release_date

print('Code Limit')
print(f'Version: {version}, released on: {release_date}')

report = scan('.')
print(f'Total lines of code: {report.total_lines_of_code}')
measurements = scan('.')
print(f'Total lines of code: {measurements.total_loc()}')
report = Report(measurements)
print(f'Average length (LOC): {report.get_average()}')
print(f'90th percentile: {report.ninetieth_percentile()}')
report.display_risk_category_plot()
report.display_risk_category_plot()
with open('clim.json', 'w') as outfile:
outfile.write(measurements.to_json(True))
print('Output written to clim.json')
8 changes: 8 additions & 0 deletions codelimit/common/Measurement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from dataclasses import dataclass


@dataclass
class Measurement:
filename: str
line: int
length: int
36 changes: 36 additions & 0 deletions codelimit/common/Measurements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import dataclasses
import json

from codelimit.common.Measurement import Measurement


class Measurements:
def __init__(self):
self._measurements = []

def add(self, measurement: Measurement):
self._measurements.append(measurement)

def all(self) -> list[Measurement]:
return self._measurements

def total_loc(self) -> int:
result = 0
for m in self._measurements:
result += m.length
return result

def sorted_by_length(self):
return sorted(self._measurements, key=lambda m: m.length)

def to_json(self, pretty_print=False) -> str:
class EnhancedJSONEncoder(json.JSONEncoder):
def default(self, o):
if dataclasses.is_dataclass(o):
return dataclasses.asdict(o)
return super().default(o)

if pretty_print:
return json.dumps(self._measurements, cls=EnhancedJSONEncoder, indent=2)
else:
return json.dumps(self._measurements, cls=EnhancedJSONEncoder)
31 changes: 10 additions & 21 deletions codelimit/common/Report.py
Original file line number Diff line number Diff line change
@@ -1,40 +1,29 @@
from dataclasses import dataclass
from math import floor, ceil

import plotext


@dataclass
class Measurement:
filename: str
line: int
length: int
from codelimit.common.Measurements import Measurements


class Report:
def __init__(self):
self.measurements: list[Measurement] = []
self.total_lines_of_code = 0

def add_measurement(self, measurement: Measurement):
self.measurements.append(measurement)
self.total_lines_of_code += measurement.length
def __init__(self, measurements: Measurements):
self.measurements = measurements

def get_average(self):
return ceil(self.total_lines_of_code / len(self.measurements))
return ceil(self.measurements.total_loc() / len(self.measurements.all()))

def ninetieth_percentile(self):
self.measurements.sort(key=lambda m: m.length)
lines_of_code_90_percent = floor(self.total_lines_of_code * 0.9)
sorted_measurements = self.measurements.sorted_by_length()
lines_of_code_90_percent = floor(self.measurements.total_loc() * 0.9)
smallest_units_loc = 0
for index, m in enumerate(self.measurements):
for index, m in enumerate(sorted_measurements):
smallest_units_loc += m.length
if smallest_units_loc > lines_of_code_90_percent:
return self.measurements[index].length
return sorted_measurements[index].length

def risk_categories(self):
result = [0, 0, 0, 0]
for m in self.measurements:
for m in self.measurements.all():
if m.length <= 10:
result[0] += m.length
elif m.length <= 20:
Expand All @@ -53,5 +42,5 @@ def display_risk_category_plot(self):
plotext.show()

def display(self):
for m in self.measurements:
for m in self.measurements.all():
print(f'{m.filename}#{m.line}: {m.length}')
13 changes: 7 additions & 6 deletions codelimit/common/Scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

from halo import Halo

from codelimit.languages.python.Python import get_headers, get_blocks
from codelimit.common.Report import Report, Measurement
from codelimit.common.Measurement import Measurement
from codelimit.common.Measurements import Measurements
from codelimit.common.Scope import build_scopes
from codelimit.languages.python.Python import get_headers, get_blocks


def is_hidden(root, file):
Expand All @@ -13,8 +14,8 @@ def is_hidden(root, file):
return len([d for d in root.split(os.sep)[1:] if d.startswith('.')]) > 0


def scan(path: str) -> Report:
report = Report()
def scan(path: str) -> Measurements:
result = Measurements()
spinner = Halo(text='Scanning', spinner='dots')
spinner.start()
scanned = 0
Expand All @@ -31,8 +32,8 @@ def scan(path: str) -> Report:
for scope in scopes:
length = scope.block.end.line - scope.block.start.line + 1
measurement = Measurement(file, scope.header.start.line, length)
report.add_measurement(measurement)
result.add(measurement)
scanned += 1
spinner.text = f'Scanned {scanned} file(s)'
spinner.succeed()
return report
return result
21 changes: 21 additions & 0 deletions tests/common/test_Measurements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from codelimit.common.Measurement import Measurement
from codelimit.common.Measurements import Measurements


def test_to_json():
measurements = Measurements()
m = Measurement('foo.py', 10, 10)
measurements.add(m)

assert measurements.to_json() == '[{"filename": "foo.py", "line": 10, "length": 10}]'


def test_to_json_multiple():
measurements = Measurements()
m = Measurement('foo.py', 10, 10)
measurements.add(m)
m = Measurement('bar.py', 20, 10)
measurements.add(m)

assert measurements.to_json() == '[{"filename": "foo.py", "line": 10, "length": 10}' + \
', {"filename": "bar.py", "line": 20, "length": 10}]'

0 comments on commit 2a6f8c8

Please sign in to comment.