minions-ai-agents/antigravity_brain_export/tools/route_scanner.py

107 lines
4.3 KiB
Python

import os
import re
import json
import pathspec
def scan_routes(start_path='.', doc_output='docs/manual_desenvolvimento/06_Rotas_E_Telas.md', json_output='qa_routes.json', gitignore_file='.gitignore'):
"""
Escaneia o projeto em busca de rotas e gera documentação + config de QA.
"""
# 1. Configuração de Ignorados
ignore_patterns = ['.git', '.agent', 'node_modules', 'venv', 'dist', 'build', 'test-results']
if os.path.exists(gitignore_file):
with open(gitignore_file, 'r', encoding='utf-8') as f:
ignore_patterns.extend(f.read().splitlines())
spec = pathspec.PathSpec.from_lines('gitwildmatch', ignore_patterns)
# 2. Padrões de Detecção (Regex) - ADAPTAR CONFORME SEU FRAMEWORK
# Captura: path: "/login", path: '/login', route("/login"), href="/login"
route_regexes = [
r"path:\s*['\"](\/[\w\-\/]*)['\"]", # Ex: path: "/clientes"
r"route\(\s*['\"](\/[\w\-\/]*)['\"]", # Ex: route('/dashboard')
r"\.get\(\s*['\"](\/[\w\-\/]*)['\"]", # Ex: app.get('/api/...')
r"href=['\"](\/[\w\-\/]*)['\"]" # Ex: <a href="/perfil"> (Simples)
]
routes_found = set()
files_with_routes = {}
print("🛰️ Iniciando varredura de rotas...")
for root, dirs, files in os.walk(start_path):
dirs[:] = [d for d in dirs if not spec.match_file(os.path.join(root, d))]
for file in files:
file_path = os.path.join(root, file)
if spec.match_file(file_path): continue
# Estratégia A: Arquivos HTML são rotas por si só (se for estático)
if file.endswith('.html'):
relative_path = os.path.relpath(file_path, start_path).replace('\\', '/')
# Se estiver na raiz, a rota é /nome.html ou /nome
route_name = f"/{relative_path}"
routes_found.add(route_name)
files_with_routes[route_name] = file_path
continue
# Estratégia B: Varrer JS/TS buscando definições
if file.endswith(('.js', '.ts', '.jsx', '.vue', '.php')):
try:
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
for pattern in route_regexes:
matches = re.finditer(pattern, content)
for match in matches:
route = match.group(1)
# Ignora rotas muito curtas ou genéricas demais se necessário
if len(route) > 1:
routes_found.add(route)
files_with_routes[route] = file_path
except Exception:
pass
# 3. Ordenação e Limpeza
sorted_routes = sorted(list(routes_found))
# 4. Gerar JSON para QA (qa_snapshot_spree.py)
qa_config = []
for route in sorted_routes:
qa_config.append({
"name": route.strip('/').capitalize() or "Home",
"path": route,
# Adiciona espera inteligente se for dashboard
"wait_for": "body"
})
with open(json_output, 'w', encoding='utf-8') as f:
json.dump(qa_config, f, indent=2)
# 5. Gerar Markdown (Documentação)
os.makedirs(os.path.dirname(doc_output), exist_ok=True)
md_content = [
"# 🗺️ Mapa de Rotas e Telas",
f"> Gerado automaticamente via `route_scanner.py`. Total: **{len(sorted_routes)}**",
"",
"| Rota (URL) | Arquivo Fonte Detectado | Nome Sugerido |",
"| :--- | :--- | :--- |"
]
for route in sorted_routes:
source = files_with_routes.get(route, "Auto-detected")
name = route.strip('/').capitalize() or "Home"
md_content.append(f"| `{route}` | `{source}` | {name} |")
md_content.append("")
md_content.append("## 🤖 Integração QA")
md_content.append(f"Este mapeamento atualizou automaticamente o arquivo `{json_output}` usado pelos testes automatizados.")
with open(doc_output, 'w', encoding='utf-8') as f:
f.write('\n'.join(md_content))
return f"✅ Rotas mapeadas!\n 📄 Docs: {doc_output}\n ⚙️ Config QA: {json_output}"
if __name__ == "__main__":
print(scan_routes())