Files
EverOS/scripts/check_repo_assets.py
Elliot Chen ab23e40b28 ci: block repository media assets (#256)
* ci: block repository media assets

* test: stabilize cascade scanner loop test
2026-06-06 11:44:45 +08:00

123 lines
2.6 KiB
Python

"""Block committed image/video files and asset-style directories."""
from __future__ import annotations
import subprocess
import sys
from dataclasses import dataclass
from pathlib import PurePosixPath
from typing import Iterable
BLOCKED_DIR_NAMES = frozenset(
{
"asset",
"assets",
"image",
"images",
"img",
"media",
"video",
"videos",
}
)
IMAGE_EXTENSIONS = frozenset(
{
".avif",
".bmp",
".gif",
".heic",
".heif",
".icns",
".ico",
".jpeg",
".jpg",
".png",
".svg",
".tif",
".tiff",
".webp",
}
)
VIDEO_EXTENSIONS = frozenset(
{
".avi",
".flv",
".m4v",
".mkv",
".mov",
".mp4",
".mpeg",
".mpg",
".webm",
".wmv",
}
)
@dataclass(frozen=True)
class Violation:
path: str
reason: str
def _normalise_path(path: str) -> PurePosixPath:
return PurePosixPath(path.replace("\\", "/"))
def _violation_reason(path: str) -> str | None:
posix_path = _normalise_path(path)
lower_parts = tuple(part.lower() for part in posix_path.parts)
if any(part in BLOCKED_DIR_NAMES for part in lower_parts):
return "asset/media directory"
suffix = posix_path.suffix.lower()
if suffix in IMAGE_EXTENSIONS:
return "image file"
if suffix in VIDEO_EXTENSIONS:
return "video file"
return None
def find_violations(paths: Iterable[str]) -> list[Violation]:
violations: list[Violation] = []
for path in paths:
reason = _violation_reason(path)
if reason is not None:
violations.append(Violation(path=path, reason=reason))
return violations
def _tracked_paths() -> list[str]:
result = subprocess.run(
["git", "ls-files", "-z"],
check=True,
stdout=subprocess.PIPE,
text=False,
)
return [
raw.decode("utf-8")
for raw in result.stdout.split(b"\0")
if raw
]
def main() -> int:
violations = find_violations(_tracked_paths())
if not violations:
print("Repository asset/media check passed.")
return 0
print(
"Repository asset/media check failed.\n"
"Do not commit images, videos, or asset/media directories. "
"Host visual media externally, in release artifacts, or another "
"approved storage location, then link to it from docs.\n"
)
for violation in violations:
print(f"- {violation.path}: {violation.reason}")
return 1
if __name__ == "__main__":
raise SystemExit(main())