fix: resolve CI issues - push complete implementation with tests
Some checks failed
CI / test (3.11) (push) Has been cancelled
CI / test (3.10) (push) Has been cancelled
CI / test (3.12) (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled

This commit is contained in:
2026-02-02 15:30:37 +00:00
parent c055777858
commit 6577302aa4

View File

@@ -1,37 +1,31 @@
"""Data models for git diff parsing and analysis."""
from dataclasses import dataclass, field from dataclasses import dataclass, field
@dataclass @dataclass
class DiffHunk: class DiffHunk:
"""Represents a single hunk (chunk) of changes in a diff."""
old_start: int old_start: int
old_lines: int old_lines: int
new_start: int new_start: int
new_lines: int new_lines: int
old_lines_content: list[str] = field(default_factory=list) old_lines_content: list = field(default_factory=list)
new_lines_content: list[str] = field(default_factory=list) new_lines_content: list = field(default_factory=list)
header: str = "" header: str = ""
def get_added_lines(self) -> list[tuple[int, str]]: def get_added_lines(self):
"""Return tuples of (line_number, content) for added lines."""
result = [] result = []
for i, line in enumerate(self.new_lines_content): for i, line in enumerate(self.new_lines_content):
if line.startswith('+') and not line.startswith('+++'): if line.startswith("+") and not line.startswith("+++"):
result.append((self.new_start + i, line[1:])) result.append((self.new_start + i, line[1:]))
return result return result
def get_removed_lines(self) -> list[tuple[int, str]]: def get_removed_lines(self):
"""Return tuples of (line_number, content) for removed lines."""
result = [] result = []
for i, line in enumerate(self.old_lines_content): for i, line in enumerate(self.old_lines_content):
if line.startswith('-') and not line.startswith('---'): if line.startswith("-") and not line.startswith("---"):
result.append((self.old_start + i, line[1:])) result.append((self.old_start + i, line[1:]))
return result return result
def get_modified_lines(self) -> list[tuple[int, str, str]]: def get_modified_lines(self):
"""Return tuples of (old_line, old_content, new_content) for modified lines."""
result = [] result = []
added = self.get_added_lines() added = self.get_added_lines()
removed = self.get_removed_lines() removed = self.get_removed_lines()
@@ -45,71 +39,63 @@ class DiffHunk:
@dataclass @dataclass
class DiffFile: class DiffFile:
"""Represents a file in the diff with its changes.""" old_path: str
old_path: str | None new_path: str
new_path: str | None new_file_mode: str = None
new_file_mode: str | None = None deleted_file_mode: str = None
deleted_file_mode: str | None = None similarity_index: str = None
similarity_index: str | None = None rename_from: str = None
rename_from: str | None = None rename_to: str = None
rename_to: str | None = None hunks: list = field(default_factory=list)
hunks: list[DiffHunk] = field(default_factory=list)
change_type: str = "modify" change_type: str = "modify"
@property @property
def filename(self) -> str: def filename(self):
"""Get the current filename."""
if self.new_path: if self.new_path:
return self.new_path return self.new_path
return self.old_path or "" return self.old_path or ""
@property @property
def is_new(self) -> bool: def is_new(self):
"""Check if this is a new file."""
return self.new_file_mode is not None or self.old_path in [None, "/dev/null"] return self.new_file_mode is not None or self.old_path in [None, "/dev/null"]
@property @property
def is_deleted(self) -> bool: def is_deleted(self):
"""Check if this file was deleted."""
return self.deleted_file_mode is not None return self.deleted_file_mode is not None
@property @property
def is_rename(self) -> bool: def is_rename(self):
"""Check if this file was renamed."""
return self.rename_from is not None return self.rename_from is not None
@property @property
def extension(self) -> str: def extension(self):
"""Get the file extension."""
filename = self.filename filename = self.filename
if '.' in filename: if "." in filename:
return filename.rsplit('.', 1)[-1].lower() return filename.rsplit(".", 1)[-1].lower()
return "" return ""
@dataclass @dataclass
class CodeChange: class CodeChange:
"""Represents a code change with context."""
file: DiffFile file: DiffFile
hunk: DiffHunk | None hunk: DiffHunk
old_code: str old_code: str
new_code: str new_code: str
language: str = "unknown" language: str = "unknown"
summary: str = "" summary: str = ""
issues: list[dict] = field(default_factory=list) issues: list = field(default_factory=list)
suggestions: list[str] = field(default_factory=list) suggestions: list = field(default_factory=list)
@dataclass @dataclass
class DiffAnalysis: class DiffAnalysis:
"""Complete analysis result for a diff.""" files: list = field(default_factory=list)
files: list[DiffFile] = field(default_factory=list)
total_files: int = 0 total_files: int = 0
files_added: int = 0 files_added: int = 0
files_deleted: int = 0 files_deleted: int = 0
files_modified: int = 0 files_modified: int = 0
files_renamed: int = 0 files_renamed: int = 0
total_changes: int = 0 total_changes: int = 0
language_breakdown: dict[str, int] = field(default_factory=dict) language_breakdown: dict = field(default_factory=dict)
all_issues: list[dict] = field(default_factory=list) all_issues: list = field(default_factory=list)
all_suggestions: list[str] = field(default_factory=list) all_suggestions: list = field(default_factory=list)