/
liquid-g
/
liquid-code
Обзор
Документация
Войти
/
liquid-g
/
liquid-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop-0.4
src/liquidcode/commands/make/controller.py
190 строк
7 KB
User
fix: add missing extract_routes_from_file function and remove OtherController
07 июл 2026, 00:07
07 июл 2026, 00:07
675c503
Код
Авторство
О чём код?
"""Генератор контроллеров для LiquidCode. Команда: lcc make:controller <name> [--route ROUTE] [--directory DIR] [--force] [--no-view] [--no-interactive] [--prefix PREFIX] """ import argparse import os import re from ..base import ( generate_from_template, TemplateError, normalize_class_name, normalize_route, ) from ..core import CONTROLLER_SUFFIX def extract_routes_from_file(filepath: str) -> list: """ Извлекает маршруты из файла контроллера. Args: filepath: Путь к файлу контроллера. Returns: Список маршрутов (строк). """ routes = [] try: with open(filepath, 'r', encoding='utf-8') as f: content = f.read() # Ищем все декораторы @route(...) route_pattern = r'@route\(["\']([^"\']+)["\']\)' matches = re.findall(route_pattern, content) for match in matches: routes.append(match) except Exception: pass return routes def configure_parser(subparser: argparse.ArgumentParser) -> None: """ Добавляет аргументы для команды make:controller. Args: subparser: Объект ArgumentParser для команды. """ subparser.add_argument( 'name', nargs='?', help='Имя контроллера (например, User)' ) subparser.add_argument( '--route', help='Префикс маршрута (по умолчанию: имя в нижнем регистре)' ) subparser.add_argument( '--prefix', help='Префикс для всех маршрутов контроллера (например, /api)' ) subparser.add_argument( '--directory', default='src/Controller', help='Целевая директория (по умолчанию: src/Controller)' ) subparser.add_argument( '--force', action='store_true', help='Перезаписать файл, если он существует' ) subparser.add_argument( '--no-view', action='store_true', help='Не создавать HTML-шаблон (по умолчанию создаётся)' ) subparser.add_argument( '--no-interactive', action='store_true', help='Отключить интерактивный режим (имя должно быть передано через аргумент)' ) def _check_route_conflict(normalized_route: str, force: bool) -> bool: """ Проверяет, не занят ли маршрут другим контроллером. Возвращает True, если можно создавать (нет конфликта или force=True). """ controller_dir = 'src/Controller' if not os.path.exists(controller_dir): return True # папки нет – конфликта быть не может existing_routes = [] for root, _, files in os.walk(controller_dir): for file in files: if file.endswith('.py') and not file.startswith('__'): filepath = os.path.join(root, file) routes = extract_routes_from_file(filepath) existing_routes.extend(routes) if normalized_route in existing_routes: if force: print(f"[WARN] Маршрут '{normalized_route}' уже используется, но --force задан, перезаписываем.") return True else: print(f"[ERROR] Маршрут '{normalized_route}' уже занят другим контроллером.") print(" Используйте другой маршрут или добавьте --force для принудительной перезаписи.") return False return True def run(args: argparse.Namespace) -> None: """ Выполняет команду make:controller. Args: args: Объект аргументов командной строки. """ try: # 1. Если имя не передано и не отключен интерактив — запрашиваем name = args.name if not name and not args.no_interactive: name = input("Введите имя контроллера (например, User): ").strip() if not name: print("[ERROR] Имя не может быть пустым") return # 2. Нормализуем имя (убираем дублирующий суффикс Controller) normalized_name = normalize_class_name(name, suffix=CONTROLLER_SUFFIX) # 3. Нормализуем маршрут route = args.route or normalized_name.lower() normalized_route = normalize_route(route) # 4. Проверяем конфликт маршрутов if not _check_route_conflict(normalized_route, args.force): return # 5. Генерируем контроллер prefix = args.prefix or '' if prefix and not prefix.startswith('/'): prefix = '/' + prefix extra = { 'route': normalized_route, 'with_view': not args.no_view, 'prefix': prefix, } created = generate_from_template( template_name='controller', args=args, extra_kwargs=extra, default_filename='{name}Controller.py', default_dir='src/Controller', ) if created: print(f"[OK] Создан контроллер: {normalized_name}{CONTROLLER_SUFFIX}") print(f" Маршрут: {normalized_route}") if prefix: print(f" Префикс класса: {prefix}") else: print(f"[WARN] Файл контроллера уже существует. Используйте --force для перезаписи.") # Если контроллер не создан, шаблон тоже не создаём (если не force) if not args.force: return # 6. Создаём шаблон, если не указан --no-view if not args.no_view: view_args = argparse.Namespace( name=normalized_name, directory='templates', force=args.force, ) view_created = generate_from_template( template_name='view', args=view_args, extra_kwargs={'name': normalized_name}, default_filename='{name}.html.j2', default_dir='templates', template_extension='.html.j2', ) if view_created: print(f"[OK] Создан шаблон: templates/{normalized_name}.html.j2") else: print("[WARN] Шаблон уже существует. Используйте --force для перезаписи.") except (TypeError, ValueError, TemplateError, IOError) as e: print(f"[ERROR] Ошибка: {e}")