Files
G4F/ReactDev/core/project_map.py
2025-06-02 16:43:01 +03:00

93 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
from pathlib import Path
from pathspec import PathSpec
from pathspec.patterns import GitWildMatchPattern
from ..utils.logger import log
from .file_analyzer import FileAnalyzer
class ProjectMap:
def __init__(self, project_path: str):
self.project_path = project_path
self.gitignore_rules = self._load_gitignore()
self.file_analyzer = FileAnalyzer()
def generate_map(self) -> str:
"""
Создает карту структуры проекта, игнорируя файлы из .gitignore и директорию .git/.
Добавляет информацию о функциях в файлы .ts, .tsx, .js, .jsx.
"""
log("Generating project structure map...")
structure = self._traverse_directory(self.project_path)
return structure
def _traverse_directory(self, path: str, level: int = 0) -> str:
"""
Рекурсивно обходит директории и формирует строку структуры,
игнорируя файлы и директории из .gitignore и .git/.
"""
indent = " " * level
result = ""
for entry in sorted(os.listdir(path)):
full_path = os.path.join(path, entry)
# Игнорируем директорию .git/
if entry == ".git":
continue
# Проверяем, игнорируется ли файл или директория по правилам .gitignore
relative_path = os.path.relpath(full_path, self.project_path)
if self._is_ignored(relative_path):
continue
if os.path.isdir(full_path):
result += f"{indent}- {entry}/\n"
result += self._traverse_directory(full_path, level + 1)
else:
result += f"{indent}- {entry}\n"
# Если это файл TypeScript/JavaScript, добавляем информацию о функциях
if entry.endswith((".ts", ".tsx", ".js", ".jsx")):
functions_info = self.file_analyzer.analyze_file(full_path)
if functions_info:
for func_name, details in functions_info.items():
params = ", ".join(details["params"])
return_type = details.get("return_type", "unknown")
result += f"{indent} FUNCTION {func_name}({params}): {return_type}\n"
return result
def save_map(self, output_file: str = "react_app_map.txt"):
"""
Сохраняет карту структуры в файл.
"""
map_content = self.generate_map()
with open(output_file, "w", encoding="utf-8") as f:
f.write(map_content)
log(f"Project map saved to {output_file}")
def _load_gitignore(self) -> list:
"""
Загружает правила из .gitignore, если файл существует.
"""
gitignore_path = os.path.join(self.project_path, ".gitignore")
rules = []
if os.path.exists(gitignore_path):
with open(gitignore_path, "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line and not line.startswith("#"): # Игнорируем комментарии и пустые строки
rules.append(line)
return rules
def _is_ignored(self, path: str) -> bool:
"""
Проверяет, игнорируется ли файл или директория по правилам .gitignore,
включая поддержку сложных правил (например, **/logs/*.log).
"""
# Преобразуем правила .gitignore в PathSpec
spec = PathSpec.from_lines(GitWildMatchPattern, self.gitignore_rules)
# Проверяем, соответствует ли путь правилам
return spec.match_file(path)