glitchcraft/lint-references.py

147 lines
4.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
Reference validator for GlitchCraft
Checks that all file references in HTML and manifest actually exist
"""
import json
import os
import re
import sys
from pathlib import Path
def check_file_exists(file_path, base_dir):
"""Check if a file exists relative to base directory."""
full_path = base_dir / file_path
return full_path.exists()
def extract_html_references(html_content):
"""Extract file references from HTML content."""
references = []
# Link href attributes
for match in re.finditer(r'<link[^>]+href=["\']([^"\']+)["\']', html_content):
href = match.group(1)
if not href.startswith(('http://', 'https://', '//', 'data:', '#')):
references.append(href)
# Script src attributes
for match in re.finditer(r'<script[^>]+src=["\']([^"\']+)["\']', html_content):
src = match.group(1)
if not src.startswith(('http://', 'https://', '//', 'data:')):
references.append(src)
# Image src attributes
for match in re.finditer(r'<img[^>]+src=["\']([^"\']+)["\']', html_content):
src = match.group(1)
if not src.startswith(('http://', 'https://', '//', 'data:')):
references.append(src)
return references
def extract_manifest_references(manifest_data):
"""Extract file references from manifest JSON."""
references = []
# Icon sources
if 'icons' in manifest_data:
for icon in manifest_data['icons']:
if 'src' in icon:
references.append(icon['src'])
# Screenshot sources
if 'screenshots' in manifest_data:
for screenshot in manifest_data['screenshots']:
if 'src' in screenshot:
references.append(screenshot['src'])
return references
def check_html_file(file_path, base_dir):
"""Check all references in an HTML file."""
errors = []
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
references = extract_html_references(content)
for ref in references:
if not check_file_exists(ref, base_dir):
errors.append(f"Missing file: {ref}")
except Exception as e:
errors.append(f"Error reading {file_path}: {e}")
return errors
def check_manifest_file(file_path, base_dir):
"""Check all references in a manifest file."""
errors = []
try:
with open(file_path, 'r', encoding='utf-8') as f:
manifest_data = json.load(f)
references = extract_manifest_references(manifest_data)
for ref in references:
if not check_file_exists(ref, base_dir):
errors.append(f"Missing file: {ref}")
except Exception as e:
errors.append(f"Error reading {file_path}: {e}")
return errors
def main():
"""Main function to check all references."""
script_dir = Path(__file__).parent
app_dir = script_dir / 'app'
print("🔍 Checking file references...")
total_errors = 0
# Check HTML files
html_files = list(app_dir.glob('*.html'))
for html_file in html_files:
errors = check_html_file(html_file, app_dir)
if errors:
print(f"\n{html_file.name}:")
for error in errors:
print(f"{error}")
total_errors += 1
else:
print(f"{html_file.name}")
# Check manifest file
manifest_file = app_dir / 'manifest.json'
if manifest_file.exists():
errors = check_manifest_file(manifest_file, app_dir)
if errors:
print(f"\n❌ manifest.json:")
for error in errors:
print(f"{error}")
total_errors += 1
else:
print("✅ manifest.json")
# Summary
if total_errors == 0:
print(f"\n🎉 All file references are valid!")
return 0
else:
print(f"\n💥 Found {total_errors} reference error(s)")
return 1
if __name__ == '__main__':
sys.exit(main())