Files
skill-template/tests/test_release_packaging_constraints.py
chendelian f3f7a9b9e5
All checks were successful
技能自动化发布 / release (push) Successful in 5s
chore: auto release commit (2026-06-17 09:48:59)
2026-06-17 09:49:00 +08:00

166 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""发布打包守护PyArmor 单文件行数与 UTF-8 without BOM。"""
from __future__ import annotations
import os
import unittest
from _support import get_skill_root
SCRIPTS_MAX_LINES = 1000
SCRIPTS_RECOMMENDED_MAX_LINES = 900
TEXT_EXTENSIONS = frozenset(
{
".py",
".md",
".yml",
".yaml",
".json",
".toml",
".ini",
".txt",
".ps1",
".sh",
}
)
SPECIAL_TEXT_FILES = frozenset({".env.example", ".gitignore"})
SKIP_DIR_NAMES = frozenset(
{
".git",
"__pycache__",
".pytest_cache",
"rpa-artifacts",
"videos",
}
)
BINARY_EXTENSIONS = frozenset(
{
".db",
".sqlite",
".png",
".jpg",
".jpeg",
".gif",
".webp",
".mp4",
".zip",
".tar",
".gz",
}
)
def _is_text_candidate(path: str) -> bool:
basename = os.path.basename(path)
if basename in SPECIAL_TEXT_FILES:
return True
ext = os.path.splitext(basename)[1].lower()
if ext in BINARY_EXTENSIONS:
return False
return ext in TEXT_EXTENSIONS
def _iter_text_files(skill_root: str) -> list[str]:
found: list[str] = []
for root, dirnames, filenames in os.walk(skill_root):
dirnames[:] = [d for d in dirnames if d not in SKIP_DIR_NAMES]
for name in filenames:
full = os.path.join(root, name)
if _is_text_candidate(full):
found.append(full)
return sorted(found)
def _iter_scripts_py_files(skill_root: str) -> list[str]:
scripts_dir = os.path.join(skill_root, "scripts")
found: list[str] = []
if not os.path.isdir(scripts_dir):
return found
for root, dirnames, filenames in os.walk(scripts_dir):
dirnames[:] = [d for d in dirnames if d not in SKIP_DIR_NAMES]
for name in filenames:
if name.endswith(".py"):
found.append(os.path.join(root, name))
return sorted(found)
class TestReleasePackagingConstraints(unittest.TestCase):
def test_scripts_py_files_under_pyarmor_line_limit(self) -> None:
skill_root = get_skill_root()
offenders: list[str] = []
for path in _iter_scripts_py_files(skill_root):
with open(path, encoding="utf-8") as f:
line_count = sum(1 for _ in f)
if line_count >= SCRIPTS_MAX_LINES:
rel = os.path.relpath(path, skill_root).replace("\\", "/")
offenders.append(
f"{rel}: {line_count} lines (limit < {SCRIPTS_MAX_LINES})"
)
self.assertEqual(
offenders,
[],
msg=(
"PyArmor trial/free mode may fail when a single Python file reaches "
f"{SCRIPTS_MAX_LINES} lines; split this file into smaller modules. "
f"Recommended keep each file < {SCRIPTS_RECOMMENDED_MAX_LINES} lines. "
f"Offenders: {offenders}"
),
)
def test_text_files_are_utf8_without_bom(self) -> None:
skill_root = get_skill_root()
bom_failures: list[str] = []
decode_failures: list[str] = []
feff_failures: list[str] = []
for path in _iter_text_files(skill_root):
rel = os.path.relpath(path, skill_root).replace("\\", "/")
with open(path, "rb") as f:
raw = f.read()
if raw.startswith(b"\xef\xbb\xbf"):
bom_failures.append(rel)
continue
try:
text = raw.decode("utf-8")
except UnicodeDecodeError as exc:
decode_failures.append(f"{rel}: {exc}")
continue
if "\ufeff" in text:
feff_failures.append(rel)
self.assertEqual(
bom_failures,
[],
msg=(
"Files must be saved as UTF-8 without BOM (remove UTF-8 BOM prefix). "
f"Offenders: {bom_failures}"
),
)
self.assertEqual(
decode_failures,
[],
msg=(
"Files must be valid UTF-8 without BOM. "
f"Offenders: {decode_failures}"
),
)
self.assertEqual(
feff_failures,
[],
msg=(
"Files must not contain U+FEFF; save as UTF-8 without BOM. "
f"Offenders: {feff_failures}"
),
)
if __name__ == "__main__":
unittest.main()