Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

152 lines
4.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Pre-commit hook to check for external CDN and resource references.
Ensures all resources are served locally from vendor directories.
"""
import re
import sys
from pathlib import Path
from typing import List, Tuple
# Patterns that indicate external resources
EXTERNAL_PATTERNS = [
# CDN URLs (with or without protocol)
r"(https?://)?cdn\.(cloudflare|jsdelivr|unpkg|jspm|skypack)",
r"(https?://)?cdnjs\.(cloudflare\.com|com)",
r"(https?://)?unpkg\.(com|\.)",
r"(https?://)?jsdelivr\.(net|com)",
r"(https?://)?ajax\.googleapis\.",
r"(https?://)?code\.jquery\.",
r"(https?://)?maxcdn\.",
r"(https?://)?stackpath\.",
# Common external libraries
r"https?://.*\/(jquery|bootstrap|react|vue|angular|fontawesome|font-awesome)[\-\.]",
# Script/link tags with external sources (excluding vendor paths)
r'<script[^>]+src=["\']https?://(?!localhost|127\.0\.0\.1)',
r'<link[^>]+href=["\']https?://(?!localhost|127\.0\.0\.1)',
# Integrity attributes (often used with CDNs)
r'integrity=["\']sha(256|384|512)-',
r'crossorigin=["\']anonymous["\']',
]
# Allowed external resources (APIs, documentation, etc)
ALLOWED_PATTERNS = [
# API endpoints
r"https?://api\.",
r"https?://.*\.api\.",
r"openrouter\.ai/api",
# Documentation and source links
r"https?://github\.com",
r"https?://docs\.",
r"https?://.*\.readthedocs\.",
r"https?://npmjs\.com",
r"https?://pypi\.org",
# Example/placeholder URLs
r"https?://example\.",
r"https?://localhost",
r"https?://127\.0\.0\.1",
r"https?://0\.0\.0\.0",
# Common in comments or documentation
r"#.*https?://",
r"//.*https?://",
r"\*.*https?://",
]
def check_file(filepath: Path) -> List[Tuple[int, str, str]]:
"""
Check a file for external resource references.
Returns list of (line_number, line_content, pattern_matched) tuples.
"""
violations = []
try:
with open(filepath, "r", encoding="utf-8") as f:
lines = f.readlines()
except (UnicodeDecodeError, IOError):
# Skip binary files or files we can't read
return violations
for line_num, line in enumerate(lines, 1):
# Check if line contains external patterns
for pattern in EXTERNAL_PATTERNS:
if re.search(pattern, line, re.IGNORECASE):
# Check if it's an allowed exception
is_allowed = False
for allowed in ALLOWED_PATTERNS:
if re.search(allowed, line, re.IGNORECASE):
is_allowed = True
break
if not is_allowed:
violations.append((line_num, line.strip(), pattern))
break # Only report first matching pattern per line
return violations
def main():
"""Main entry point for the pre-commit hook."""
# Get list of files to check from command line arguments
files = sys.argv[1:] if len(sys.argv) > 1 else []
if not files:
# If no files specified, check all relevant files
patterns = ["**/*.html", "**/*.js", "**/*.css", "**/*.py"]
files = []
for pattern in patterns:
files.extend(Path(".").glob(pattern))
else:
files = [Path(f) for f in files]
all_violations = []
for filepath in files:
# Skip vendor directories and node_modules
if any(
part in filepath.parts
for part in [
"vendor",
"node_modules",
".venv",
"venv",
"__pycache__",
]
):
continue
violations = check_file(filepath)
if violations:
all_violations.append((filepath, violations))
if all_violations:
print("\n❌ External resource references found!\n")
print(
"All resources should be served locally from the vendor directory."
)
print("Found the following external references:\n")
for filepath, violations in all_violations:
print(f"📄 {filepath}")
for line_num, line_content, pattern in violations:
print(f" Line {line_num}: {line_content[:100]}...")
print(f" Matched pattern: {pattern}\n")
print("\nTo fix this:")
print("1. Add the library to package.json as a dependency")
print("2. Run 'npm install' to download it")
print("3. Update the reference to use the local node_modules path")
print("4. Use a build process to bundle the assets")
print(
"\nAll external libraries should be managed through npm for security and version tracking."
)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())