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