Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ✨ Setup regression test #53

Merged
merged 10 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
name: 'analyze'
name: 'regression'

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
analyze:
runs-on: self-hosted
Expand All @@ -24,8 +26,5 @@ jobs:
- name: 'Install dependencies'
run: poetry install --no-interaction --no-root

- name: 'Checkout pl-snakebattle'
run: git clone https://github.com/getcodelimit/pl-battlesnake.git

- name: 'Run codelimit'
run: poetry run codelimit scan pl-battlesnake
- name: 'Run regression runner'
run: poetry run poe regression
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@
.build/
dist/
main.spec
codelimit.json
.coverage
coverage.xml
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
[![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Linting: Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Checked with Code Limit](https://codelimit.vercel.app/api/badge/getcodelimit/codelimit)](https://github.com/getcodelimit/codelimit)
[![codelimit](https://github.com/getcodelimit/codelimit/blob/_codelimit_reports/main/badge.svg?raw=true)](https://github.com/getcodelimit/codelimit/blob/_codelimit_reports/main/codelimit.md)

</div>

Expand Down
4 changes: 2 additions & 2 deletions codelimit/commands/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ def _report_functions_text(root, units, report_units, full) -> Text:
result.append(format_measurement(str(file_path), unit.measurement).append("\n"))
if not full and len(units) > REPORT_LENGTH:
result.append(
f"[bold]{len(units) - REPORT_LENGTH} more rows, use --full option to get all rows[/bold]\n"
f"{len(units) - REPORT_LENGTH} more rows, use --full option to get all rows\n", style="bold"
)
return result


def _report_functions_markdown(
root: Path | None, report_units: list[ReportUnit]
root: Path | None, report_units: list[ReportUnit]
) -> str:
result = ""
result += "| **File** | **Line** | **Column** | **Length** | **Function** |\n"
Expand Down
12 changes: 12 additions & 0 deletions codelimit/common/LanguageTotals.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from codelimit.common.SourceFileEntry import SourceFileEntry
from codelimit.common.utils import make_count_profile

Expand All @@ -18,3 +20,13 @@ def add(self, entry: SourceFileEntry):
self.functions += len(entry.measurements())
self.hard_to_maintain += profile[2]
self.unmaintainable += profile[3]

def is_equal(self, other: LanguageTotals) -> bool:
return (
self.language == other.language and
self.files == other.files and
self.loc == other.loc and
self.functions == other.functions and
self.hard_to_maintain == other.hard_to_maintain and
self.unmaintainable == other.unmaintainable
)
40 changes: 21 additions & 19 deletions codelimit/common/Scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@


def scan_codebase(path: Path, cached_report: Union[Report, None] = None) -> Codebase:
codebase = Codebase(str(path.resolve().absolute()))
print_header(cached_report, path)
scan_totals = ScanTotals()
with Live(refresh_per_second=2) as live:
Expand All @@ -45,7 +44,7 @@ def add_file_entry(entry: SourceFileEntry):
table = ScanResultTable(scan_totals)
live.update(table)

_scan_folder(codebase, path, cached_report, add_file_entry)
codebase = scan_path(path, cached_report, add_file_entry)
live.stop()
live.refresh()
print()
Expand Down Expand Up @@ -80,23 +79,16 @@ def print_refactor_candidates(scan_totals: ScanTotals):
)


def _scan_folder(
codebase: Codebase,
folder: Path,
cached_report: Union[Report, None] = None,
add_file_entry: Union[Callable[[SourceFileEntry], None], None] = None,
):
excludes = DEFAULT_EXCLUDES.copy()
excludes.extend(Configuration.excludes)
gitignore_excludes = _read_gitignore(folder)
if gitignore_excludes:
excludes.extend(gitignore_excludes)
excludes_spec = PathSpec.from_lines("gitignore", excludes)
for root, dirs, files in os.walk(folder.absolute()):
def scan_path(path: Path, cached_report: Union[Report, None] = None,
add_file_entry_callback: Union[Callable[[SourceFileEntry], None], None] = None,
) -> Codebase:
result = Codebase(str(path.resolve().absolute()))
excludes_spec = _generate_exclude_spec(path)
for root, dirs, files in os.walk(path.absolute()):
files = [f for f in files if not f[0] == "."]
dirs[:] = [d for d in dirs if not d[0] == "."]
for file in files:
rel_path = Path(os.path.join(root, file)).relative_to(folder.absolute())
rel_path = Path(os.path.join(root, file)).relative_to(path.absolute())
if is_excluded(rel_path, excludes_spec):
continue
try:
Expand All @@ -106,12 +98,13 @@ def _scan_folder(
languages = Languages.by_name.keys()
if lexer_name in languages:
file_entry = _scan_file(
codebase, lexer, folder, file_path, cached_report
result, lexer, path, file_path, cached_report
)
if add_file_entry:
add_file_entry(file_entry)
if add_file_entry_callback:
add_file_entry_callback(file_entry)
except ClassNotFound:
pass
return result


def _scan_file(
Expand Down Expand Up @@ -181,6 +174,15 @@ def scan_file(tokens: list[Token], language: Language) -> list[Measurement]:
return measurements


def _generate_exclude_spec(root: Path) -> PathSpec:
excludes = DEFAULT_EXCLUDES.copy()
excludes.extend(Configuration.excludes)
gitignore_excludes = _read_gitignore(root)
if gitignore_excludes:
excludes.extend(gitignore_excludes)
return PathSpec.from_lines("gitignore", excludes)


def _read_gitignore(path: Path) -> list[str] | None:
gitignore_path = path.joinpath(".gitignore")
if gitignore_path.exists():
Expand Down
188 changes: 188 additions & 0 deletions examples/getcodelimit_battlesnake-challenge_20241209/codelimit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
{
"version": "0.13.0",
"uuid": "0608c551-d2c2-4ceb-bde7-209c254b9826",
"root": "/private/var/folders/t2/s_70szzn7qn22cp4d2nmrjbc0000gn/T/tmpegttzdoq/battlesnake-challenge",
"codebase": {
"totals": {
"Python": {
"files": 1,
"lines_of_code": 91,
"functions": 13,
"hard_to_maintain": 0,
"unmaintainable": 0
},
"Java": {
"files": 1,
"lines_of_code": 217,
"functions": 19,
"hard_to_maintain": 0,
"unmaintainable": 0
},
"C++": {
"files": 1,
"lines_of_code": 4,
"functions": 1,
"hard_to_maintain": 0,
"unmaintainable": 0
},
"JavaScript": {
"files": 1,
"lines_of_code": 92,
"functions": 9,
"hard_to_maintain": 0,
"unmaintainable": 0
},
"C": {
"files": 1,
"lines_of_code": 260,
"functions": 18,
"hard_to_maintain": 1,
"unmaintainable": 0
}
},
"tree": {
"./": {
"entries": [
"python/",
"java/",
"cpp/",
"javascript/",
"c/"
],
"profile": [393, 168, 38, 0]
},
"python/": {
"entries": [
"snake.py"
],
"profile": [81, 0, 0, 0]
},
"java/": {
"entries": [
"Snake.java"
],
"profile": [130, 39, 0, 0]
},
"cpp/": {
"entries": [
"snake.cpp"
],
"profile": [4, 0, 0, 0]
},
"javascript/": {
"entries": [
"snake.js"
],
"profile": [69, 16, 0, 0]
},
"c/": {
"entries": [
"snake.c"
],
"profile": [109, 113, 38, 0]
}
},
"files": {
"python/snake.py": {
"checksum": "a13856efeb57941dce9ee56e64825761",
"language": "Python",
"loc": 91,
"profile": [81, 0, 0, 0],
"measurements": [
{"unit_name": "do_GET", "start": {"line": 8, "column": 5}, "end": {"line": 9, "column": 35}, "value": 2},
{"unit_name": "do_POST", "start": {"line": 11, "column": 5}, "end": {"line": 17, "column": 29}, "value": 7},
{"unit_name": "handle_get_meta_data", "start": {"line": 19, "column": 1}, "end": {"line": 30, "column": 57}, "value": 12},
{"unit_name": "handle_start", "start": {"line": 32, "column": 1}, "end": {"line": 37, "column": 34}, "value": 6},
{"unit_name": "handle_end", "start": {"line": 39, "column": 1}, "end": {"line": 41, "column": 34}, "value": 3},
{"unit_name": "get_body", "start": {"line": 43, "column": 1}, "end": {"line": 46, "column": 49}, "value": 4},
{"unit_name": "handle_move", "start": {"line": 48, "column": 1}, "end": {"line": 57, "column": 78}, "value": 10},
{"unit_name": "get_direction", "start": {"line": 59, "column": 1}, "end": {"line": 62, "column": 53}, "value": 4},
{"unit_name": "preferred_directions", "start": {"line": 64, "column": 1}, "end": {"line": 74, "column": 18}, "value": 11},
{"unit_name": "nearest_food", "start": {"line": 76, "column": 1}, "end": {"line": 78, "column": 19}, "value": 3},
{"unit_name": "distance", "start": {"line": 80, "column": 1}, "end": {"line": 81, "column": 76}, "value": 2},
{"unit_name": "select_direction", "start": {"line": 83, "column": 1}, "end": {"line": 94, "column": 62}, "value": 12},
{"unit_name": "free_cell", "start": {"line": 96, "column": 1}, "end": {"line": 100, "column": 76}, "value": 5}
]
},
"java/Snake.java": {
"checksum": "1e1e0c05b9dc5dda9b0f1107462e97c9",
"language": "Java",
"loc": 217,
"profile": [130, 39, 0, 0],
"measurements": [
{"unit_name": "getField", "start": {"line": 18, "column": 20}, "end": {"line": 21, "column": 6}, "value": 4},
{"unit_name": "getBalanced", "start": {"line": 23, "column": 20}, "end": {"line": 36, "column": 6}, "value": 14},
{"unit_name": "getObject", "start": {"line": 38, "column": 20}, "end": {"line": 40, "column": 6}, "value": 3},
{"unit_name": "getArray", "start": {"line": 42, "column": 20}, "end": {"line": 44, "column": 6}, "value": 3},
{"unit_name": "getNumber", "start": {"line": 46, "column": 17}, "end": {"line": 55, "column": 6}, "value": 10},
{"unit_name": "getText", "start": {"line": 57, "column": 20}, "end": {"line": 66, "column": 6}, "value": 10},
{"unit_name": "getBody", "start": {"line": 68, "column": 20}, "end": {"line": 80, "column": 6}, "value": 13},
{"unit_name": "Coordinate", "start": {"line": 86, "column": 16}, "end": {"line": 89, "column": 10}, "value": 4},
{"unit_name": "equals", "start": {"line": 91, "column": 24}, "end": {"line": 94, "column": 10}, "value": 4},
{"unit_name": "hashCode", "start": {"line": 96, "column": 26}, "end": {"line": 98, "column": 10}, "value": 3},
{"unit_name": "getCoordinates", "start": {"line": 101, "column": 29}, "end": {"line": 110, "column": 6}, "value": 10},
{"unit_name": "nearestFood", "start": {"line": 112, "column": 24}, "end": {"line": 127, "column": 6}, "value": 16},
{"unit_name": "getPreferredDirections", "start": {"line": 129, "column": 22}, "end": {"line": 143, "column": 6}, "value": 15},
{"unit_name": "freeCell", "start": {"line": 145, "column": 21}, "end": {"line": 154, "column": 6}, "value": 10},
{"unit_name": "selectDirection", "start": {"line": 156, "column": 20}, "end": {"line": 178, "column": 6}, "value": 23},
{"unit_name": "getDirection", "start": {"line": 180, "column": 20}, "end": {"line": 183, "column": 6}, "value": 4},
{"unit_name": "sendResponse", "start": {"line": 185, "column": 18}, "end": {"line": 191, "column": 6}, "value": 7},
{"unit_name": "startServer", "start": {"line": 226, "column": 18}, "end": {"line": 236, "column": 6}, "value": 11},
{"unit_name": "main", "start": {"line": 238, "column": 24}, "end": {"line": 242, "column": 6}, "value": 5}
]
},
"cpp/snake.cpp": {
"checksum": "6871bc888c689ee297fbf9269141b44b",
"language": "C++",
"loc": 4,
"profile": [4, 0, 0, 0],
"measurements": [
{"unit_name": "main", "start": {"line": 3, "column": 5}, "end": {"line": 6, "column": 2}, "value": 4}
]
},
"javascript/snake.js": {
"checksum": "9ab69b846197b00b0b75350a48bfd731",
"language": "JavaScript",
"loc": 92,
"profile": [69, 16, 0, 0],
"measurements": [
{"unit_name": "requestHandler", "start": {"line": 3, "column": 1}, "end": {"line": 15, "column": 2}, "value": 13},
{"unit_name": "handleGetMetaData", "start": {"line": 17, "column": 1}, "end": {"line": 27, "column": 2}, "value": 11},
{"unit_name": "handleWithBody", "start": {"line": 29, "column": 1}, "end": {"line": 37, "column": 2}, "value": 9},
{"unit_name": "handleGameStart", "start": {"line": 39, "column": 1}, "end": {"line": 43, "column": 2}, "value": 5},
{"unit_name": "handleMove", "start": {"line": 45, "column": 1}, "end": {"line": 52, "column": 2}, "value": 8},
{"unit_name": "getDirection", "start": {"line": 54, "column": 1}, "end": {"line": 57, "column": 2}, "value": 4},
{"unit_name": "preferredDirections", "start": {"line": 59, "column": 1}, "end": {"line": 70, "column": 2}, "value": 12},
{"unit_name": "selectDirection", "start": {"line": 76, "column": 1}, "end": {"line": 91, "column": 2}, "value": 16},
{"unit_name": "freeCell", "start": {"line": 93, "column": 1}, "end": {"line": 99, "column": 2}, "value": 7}
]
},
"c/snake.c": {
"checksum": "e563a9d9b198de59ceb3b14f9d5c15c3",
"language": "C",
"loc": 260,
"profile": [109, 113, 38, 0],
"measurements": [
{"unit_name": "get_field", "start": {"line": 16, "column": 8}, "end": {"line": 23, "column": 2}, "value": 8},
{"unit_name": "get_object", "start": {"line": 25, "column": 8}, "end": {"line": 37, "column": 2}, "value": 13},
{"unit_name": "get_array", "start": {"line": 39, "column": 8}, "end": {"line": 51, "column": 2}, "value": 13},
{"unit_name": "get_number", "start": {"line": 53, "column": 5}, "end": {"line": 56, "column": 2}, "value": 4},
{"unit_name": "get_text", "start": {"line": 58, "column": 8}, "end": {"line": 67, "column": 2}, "value": 10},
{"unit_name": "handle_get_meta_data", "start": {"line": 69, "column": 6}, "end": {"line": 82, "column": 2}, "value": 14},
{"unit_name": "handle_start", "start": {"line": 84, "column": 6}, "end": {"line": 92, "column": 2}, "value": 9},
{"unit_name": "filter_non_coordinate_digits", "start": {"line": 94, "column": 6}, "end": {"line": 108, "column": 2}, "value": 15},
{"unit_name": "nearest_food", "start": {"line": 110, "column": 6}, "end": {"line": 132, "column": 2}, "value": 23},
{"unit_name": "preferred_directions", "start": {"line": 134, "column": 6}, "end": {"line": 162, "column": 2}, "value": 29},
{"unit_name": "free_cell", "start": {"line": 164, "column": 5}, "end": {"line": 190, "column": 2}, "value": 27},
{"unit_name": "select_direction", "start": {"line": 192, "column": 7}, "end": {"line": 209, "column": 2}, "value": 18},
{"unit_name": "get_direction", "start": {"line": 211, "column": 7}, "end": {"line": 215, "column": 2}, "value": 5},
{"unit_name": "handle_move", "start": {"line": 217, "column": 6}, "end": {"line": 232, "column": 2}, "value": 16},
{"unit_name": "handle_end", "start": {"line": 234, "column": 6}, "end": {"line": 237, "column": 2}, "value": 4},
{"unit_name": "get_content_length", "start": {"line": 239, "column": 5}, "end": {"line": 242, "column": 2}, "value": 4},
{"unit_name": "get_body", "start": {"line": 244, "column": 7}, "end": {"line": 253, "column": 2}, "value": 10},
{"unit_name": "main", "start": {"line": 255, "column": 5}, "end": {"line": 292, "column": 2}, "value": 38}
]
}
}
}
}
Loading
Loading