118 lines
3.9 KiB
Python
Executable file
118 lines
3.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
"""
|
|
Check for unused routes in Flask application
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import re
|
|
from flask import Flask
|
|
|
|
# Add the parent directory to sys.path
|
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
|
|
|
|
|
def find_all_routes():
|
|
"""Find all route definitions in Python files"""
|
|
routes = []
|
|
route_pattern = re.compile(r'@\w+\.route\([\'"]([^\'"]+)[\'"]')
|
|
|
|
for root, _, files in os.walk("app"):
|
|
for file in files:
|
|
if file.endswith(".py"):
|
|
file_path = os.path.join(root, file)
|
|
with open(file_path, "r") as f:
|
|
content = f.read()
|
|
matches = route_pattern.findall(content)
|
|
for match in matches:
|
|
routes.append(match)
|
|
|
|
return routes
|
|
|
|
|
|
def find_template_references():
|
|
"""Find all url_for calls in template files"""
|
|
references = []
|
|
url_for_pattern = re.compile(r'url_for\([\'"]([^\'"]+)[\'"]')
|
|
|
|
# Add patterns for direct links and HTMX references
|
|
direct_href_pattern = re.compile(r'href=[\'"]([^\'"]+)[\'"]')
|
|
htmx_pattern = re.compile(r'hx-(get|post|put|delete)=[\'"]([^\'"]+)[\'"]')
|
|
|
|
# Template files scanning
|
|
for root, _, files in os.walk("app/templates"):
|
|
for file in files:
|
|
if file.endswith(".html"):
|
|
file_path = os.path.join(root, file)
|
|
with open(file_path, "r") as f:
|
|
content = f.read()
|
|
# Find url_for references
|
|
matches = url_for_pattern.findall(content)
|
|
for match in matches:
|
|
references.append(match)
|
|
|
|
# Also check for direct route references in hrefs that aren't url_for
|
|
href_matches = direct_href_pattern.findall(content)
|
|
for href in href_matches:
|
|
if href.startswith("/") and not href.startswith("//"):
|
|
references.append(href)
|
|
|
|
# Check HTMX references
|
|
htmx_matches = htmx_pattern.findall(content)
|
|
for _, url in htmx_matches:
|
|
if url.startswith("/") and not url.startswith("//"):
|
|
references.append(url)
|
|
|
|
# Also check Python files for url_for calls
|
|
for root, _, files in os.walk("app"):
|
|
for file in files:
|
|
if file.endswith(".py"):
|
|
file_path = os.path.join(root, file)
|
|
with open(file_path, "r") as f:
|
|
content = f.read()
|
|
matches = url_for_pattern.findall(content)
|
|
for match in matches:
|
|
references.append(match)
|
|
|
|
return references
|
|
|
|
|
|
def check_unused_routes():
|
|
"""Find routes that are not referenced by url_for"""
|
|
from app import create_app
|
|
|
|
app = create_app()
|
|
|
|
# Get all route endpoints from the app
|
|
all_endpoints = set()
|
|
for rule in app.url_map.iter_rules():
|
|
all_endpoints.add(rule.endpoint)
|
|
|
|
# Get all url_for references
|
|
all_references = set(find_template_references())
|
|
|
|
# Find unused endpoints
|
|
unused_endpoints = all_endpoints - all_references
|
|
|
|
if unused_endpoints:
|
|
print(
|
|
"The following routes are defined but not referenced in templates or code:"
|
|
)
|
|
for endpoint in sorted(unused_endpoints):
|
|
# Skip static routes, error handlers, etc.
|
|
if endpoint.startswith("static") or endpoint == "static":
|
|
continue
|
|
|
|
print(f" - {endpoint}")
|
|
|
|
# Find the URL for this endpoint
|
|
for rule in app.url_map.iter_rules():
|
|
if rule.endpoint == endpoint:
|
|
print(f" URL: {rule}")
|
|
break
|
|
else:
|
|
print("All routes are referenced in templates or code. Good job!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
check_unused_routes()
|