Add source code files (detectors, generators, CLI)
This commit is contained in:
111
src/detectors/language.py
Normal file
111
src/detectors/language.py
Normal file
@@ -0,0 +1,111 @@
|
||||
"""Language detector for identifying programming languages."""
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Dict, List
|
||||
|
||||
from src.data.patterns import LANGUAGE_INDICATOR_FILES
|
||||
from src.detectors.base import BaseDetector
|
||||
|
||||
|
||||
class LanguageDetector(BaseDetector):
|
||||
"""Detects programming languages used in a project."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.indicator_files = LANGUAGE_INDICATOR_FILES
|
||||
self.priority = 100
|
||||
|
||||
def get_priority(self) -> int:
|
||||
return self.priority
|
||||
|
||||
def detect(self, project_path: Path) -> List[str]:
|
||||
"""Detect programming languages from project files.
|
||||
|
||||
Args:
|
||||
project_path: Path to the project directory.
|
||||
|
||||
Returns:
|
||||
List of detected language names.
|
||||
"""
|
||||
detected_languages = []
|
||||
|
||||
for language, indicators in self.indicator_files.items():
|
||||
if self._detect_language(project_path, language, indicators):
|
||||
detected_languages.append(language)
|
||||
|
||||
return detected_languages
|
||||
|
||||
def _detect_language(
|
||||
self, project_path: Path, language: str, indicators: List[str]
|
||||
) -> bool:
|
||||
"""Check if a language is present based on indicators.
|
||||
|
||||
Args:
|
||||
project_path: Project root directory.
|
||||
language: Language name to check.
|
||||
indicators: List of indicator files for the language.
|
||||
|
||||
Returns:
|
||||
True if language is detected, False otherwise.
|
||||
"""
|
||||
for indicator in indicators:
|
||||
matches = list(project_path.rglob(indicator))
|
||||
if matches:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def detect_from_content(self, project_path: Path) -> Dict[str, List[str]]:
|
||||
"""Detect languages from file content analysis.
|
||||
|
||||
Args:
|
||||
project_path: Path to the project directory.
|
||||
|
||||
Returns:
|
||||
Dict mapping languages to matching files.
|
||||
"""
|
||||
language_files: Dict[str, List[str]] = {}
|
||||
|
||||
extension_map: Dict[str, List[str]] = {
|
||||
".py": ["python"],
|
||||
".js": ["nodejs"],
|
||||
".jsx": ["nodejs"],
|
||||
".ts": ["nodejs"],
|
||||
".tsx": ["nodejs"],
|
||||
".go": ["go"],
|
||||
".java": ["java"],
|
||||
".rs": ["rust"],
|
||||
".cs": ["csharp"],
|
||||
".cpp": ["cpp"],
|
||||
".c": ["cpp"],
|
||||
".h": ["cpp"],
|
||||
".rb": ["ruby"],
|
||||
".php": ["php"],
|
||||
".dart": ["dart"],
|
||||
".swift": ["swift"],
|
||||
".kt": ["kotlin"],
|
||||
".kts": ["kotlin"],
|
||||
".scala": ["scala"],
|
||||
".pl": ["perl"],
|
||||
".pm": ["perl"],
|
||||
".r": ["r"],
|
||||
".R": ["r"],
|
||||
".ex": ["elixir"],
|
||||
".exs": ["elixir"],
|
||||
".clj": ["clojure"],
|
||||
".lua": ["lua"],
|
||||
".hs": ["haskell"],
|
||||
}
|
||||
|
||||
try:
|
||||
for file_path in project_path.rglob("*"):
|
||||
if file_path.is_file():
|
||||
suffix = file_path.suffix.lower()
|
||||
if suffix in extension_map:
|
||||
for lang in extension_map[suffix]:
|
||||
if lang not in language_files:
|
||||
language_files[lang] = []
|
||||
language_files[lang].append(str(file_path))
|
||||
except (PermissionError, OSError):
|
||||
pass
|
||||
|
||||
return language_files
|
||||
Reference in New Issue
Block a user