From e97d9693d0c31cc41dd04d426983ff64805acc93 Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Sun, 1 Feb 2026 20:15:29 +0000 Subject: [PATCH] Add source code files (detectors, generators, CLI) --- src/detectors/language.py | 111 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 src/detectors/language.py diff --git a/src/detectors/language.py b/src/detectors/language.py new file mode 100644 index 0000000..5748e6e --- /dev/null +++ b/src/detectors/language.py @@ -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