Add source code files (detectors, generators, CLI)
This commit is contained in:
114
src/detectors/base.py
Normal file
114
src/detectors/base.py
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
"""Base detector class for project detection."""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
|
|
||||||
|
class BaseDetector(ABC):
|
||||||
|
"""Abstract base class for all detectors."""
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def detect(self, project_path: Path) -> List[str]:
|
||||||
|
"""Detect items from the project path.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
project_path: Path to the project directory.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of detected item names (e.g., language names, framework names).
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_priority(self) -> int:
|
||||||
|
"""Get the priority of this detector.
|
||||||
|
|
||||||
|
Higher priority detectors are run first.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Integer priority value.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _find_files(self, project_path: Path, patterns: List[str]) -> List[Path]:
|
||||||
|
"""Find files matching given patterns.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
project_path: Root directory to search.
|
||||||
|
patterns: List of filename patterns to match.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of matching file paths.
|
||||||
|
"""
|
||||||
|
if not project_path.exists() or not project_path.is_dir():
|
||||||
|
return []
|
||||||
|
|
||||||
|
found_files = []
|
||||||
|
try:
|
||||||
|
for pattern in patterns:
|
||||||
|
matches = list(project_path.rglob(pattern))
|
||||||
|
found_files.extend(matches)
|
||||||
|
except PermissionError:
|
||||||
|
pass
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return found_files
|
||||||
|
|
||||||
|
def _read_file_content(self, file_path: Path, max_size: int = 10240) -> Optional[str]:
|
||||||
|
"""Read file content safely.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
file_path: Path to the file.
|
||||||
|
max_size: Maximum file size to read in bytes.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
File content as string, or None if reading fails.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if file_path.stat().st_size > max_size:
|
||||||
|
return None
|
||||||
|
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
return f.read()
|
||||||
|
except (PermissionError, OSError, UnicodeDecodeError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _check_file_exists(self, project_path: Path, filenames: List[str]) -> List[str]:
|
||||||
|
"""Check if any of the given filenames exist.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
project_path: Project root directory.
|
||||||
|
filenames: List of filenames to check.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of existing filenames.
|
||||||
|
"""
|
||||||
|
existing = []
|
||||||
|
for filename in filenames:
|
||||||
|
if (project_path / filename).exists():
|
||||||
|
existing.append(filename)
|
||||||
|
return existing
|
||||||
|
|
||||||
|
def _check_content_markers(self, project_path: Path, markers: Dict[str, str]) -> List[str]:
|
||||||
|
"""Check for content markers in source files.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
project_path: Project root directory.
|
||||||
|
markers: Dict mapping marker names to search patterns.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List of found marker names.
|
||||||
|
"""
|
||||||
|
found = []
|
||||||
|
try:
|
||||||
|
for file_path in project_path.rglob("*"):
|
||||||
|
if file_path.is_file() and file_path.suffix in ['.py', '.js', '.ts', '.go', '.java', '.rb', '.php', '.rs']:
|
||||||
|
content = self._read_file_content(file_path)
|
||||||
|
if content:
|
||||||
|
for name, pattern in markers.items():
|
||||||
|
if name not in found and pattern.lower() in content.lower():
|
||||||
|
found.append(name)
|
||||||
|
except (PermissionError, OSError):
|
||||||
|
pass
|
||||||
|
return found
|
||||||
Reference in New Issue
Block a user