Initial upload of ai-code-audit-cli project
Some checks failed
Some checks failed
This commit is contained in:
133
src/core/models.py
Normal file
133
src/core/models.py
Normal file
@@ -0,0 +1,133 @@
|
||||
"""Data models for scan results and issues."""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class SeverityLevel(Enum):
|
||||
"""Severity levels for issues."""
|
||||
|
||||
LOW = "low"
|
||||
MEDIUM = "medium"
|
||||
HIGH = "high"
|
||||
CRITICAL = "critical"
|
||||
|
||||
|
||||
class IssueCategory(Enum):
|
||||
"""Categories of issues that can be detected."""
|
||||
|
||||
SECURITY = "security"
|
||||
CODE_QUALITY = "code_quality"
|
||||
ERROR_HANDLING = "error_handling"
|
||||
ANTI_PATTERN = "anti_pattern"
|
||||
COMPLEXITY = "complexity"
|
||||
STYLE = "style"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Issue:
|
||||
"""Represents a detected issue in the code."""
|
||||
|
||||
severity: SeverityLevel
|
||||
category: IssueCategory
|
||||
file_path: str
|
||||
line_number: int
|
||||
message: str
|
||||
suggestion: Optional[str] = None
|
||||
code_snippet: Optional[str] = None
|
||||
scanner_name: str = "unknown"
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
"""Convert issue to dictionary."""
|
||||
return {
|
||||
"severity": self.severity.value,
|
||||
"category": self.category.value,
|
||||
"file_path": self.file_path,
|
||||
"line_number": self.line_number,
|
||||
"message": self.message,
|
||||
"suggestion": self.suggestion,
|
||||
"code_snippet": self.code_snippet,
|
||||
"scanner_name": self.scanner_name,
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class ScanResult:
|
||||
"""Result of a code scan operation."""
|
||||
|
||||
files_scanned: int
|
||||
issues: list[Issue] = field(default_factory=list)
|
||||
warnings: list[str] = field(default_factory=list)
|
||||
scan_time: datetime = field(default_factory=datetime.now)
|
||||
target_path: str = ""
|
||||
|
||||
def add_issue(self, issue: Issue) -> None:
|
||||
"""Add an issue to the results."""
|
||||
self.issues.append(issue)
|
||||
|
||||
def add_warning(self, warning: str) -> None:
|
||||
"""Add a warning to the results."""
|
||||
self.warnings.append(warning)
|
||||
|
||||
def filter_by_severity(self, min_severity: SeverityLevel) -> "ScanResult":
|
||||
"""Filter issues by minimum severity level."""
|
||||
severity_order = [
|
||||
SeverityLevel.LOW,
|
||||
SeverityLevel.MEDIUM,
|
||||
SeverityLevel.HIGH,
|
||||
SeverityLevel.CRITICAL,
|
||||
]
|
||||
min_index = severity_order.index(min_severity)
|
||||
|
||||
filtered = ScanResult(
|
||||
files_scanned=self.files_scanned,
|
||||
target_path=self.target_path,
|
||||
)
|
||||
for issue in self.issues:
|
||||
if severity_order.index(issue.severity) >= min_index:
|
||||
filtered.add_issue(issue)
|
||||
filtered.warnings = self.warnings.copy()
|
||||
return filtered
|
||||
|
||||
def filter_by_category(self, categories: list[IssueCategory]) -> "ScanResult":
|
||||
"""Filter issues by categories."""
|
||||
filtered = ScanResult(
|
||||
files_scanned=self.files_scanned,
|
||||
target_path=self.target_path,
|
||||
)
|
||||
category_set = set(categories)
|
||||
for issue in self.issues:
|
||||
if issue.category in category_set:
|
||||
filtered.add_issue(issue)
|
||||
filtered.warnings = self.warnings.copy()
|
||||
return filtered
|
||||
|
||||
def get_summary(self) -> dict:
|
||||
"""Get a summary of the scan results."""
|
||||
summary = {
|
||||
"files_scanned": self.files_scanned,
|
||||
"total_issues": len(self.issues),
|
||||
"issues_by_severity": {},
|
||||
"issues_by_category": {},
|
||||
}
|
||||
|
||||
for issue in self.issues:
|
||||
severity = issue.severity.value
|
||||
category = issue.category.value
|
||||
summary["issues_by_severity"][severity] = summary["issues_by_severity"].get(severity, 0) + 1
|
||||
summary["issues_by_category"][category] = summary["issues_by_category"].get(category, 0) + 1
|
||||
|
||||
return summary
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
"""Convert scan result to dictionary."""
|
||||
return {
|
||||
"files_scanned": self.files_scanned,
|
||||
"issues": [issue.to_dict() for issue in self.issues],
|
||||
"warnings": self.warnings,
|
||||
"scan_time": self.scan_time.isoformat(),
|
||||
"target_path": self.target_path,
|
||||
}
|
||||
Reference in New Issue
Block a user