Removes helpers nothing calls, test-only wrappers and their tests, the unused config writer, three unused images, and the prompt registry the nodes wrote to but nothing read, which grew with every run.
103 lines
3.4 KiB
Python
103 lines
3.4 KiB
Python
"""What the Registry package leaves out (#615).
|
|
|
|
``comfy node publish`` zips the tracked files minus ``.comfyignore``. The checks
|
|
here hold the two ways that can go wrong: a development folder creeping back
|
|
into the download, or a rule that drops something ComfyUI needs at run time.
|
|
"""
|
|
|
|
import ast
|
|
import fnmatch
|
|
import re
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
RUNTIME_DIRS = ("py", "database", "utils", "web")
|
|
DEVELOPMENT = (
|
|
"tests/test_package_contents.py",
|
|
"tools/vendor/package.json",
|
|
"docs/application-redesign.md",
|
|
".github/workflows/publish.yml",
|
|
"images/x.png",
|
|
"TESTING.md",
|
|
"requirements-dev.txt",
|
|
)
|
|
KEPT = (
|
|
"__init__.py",
|
|
"prompt_manager.py",
|
|
"pyproject.toml",
|
|
"requirements.txt",
|
|
"LICENSE",
|
|
"README.md",
|
|
"README-legacy.md",
|
|
"assets/readme/hero.webp",
|
|
)
|
|
|
|
|
|
def _patterns():
|
|
lines = (ROOT / ".comfyignore").read_text(encoding="utf-8").splitlines()
|
|
return [line.strip() for line in lines if line.strip() and line[0] != "#"]
|
|
|
|
|
|
def _ignored(path):
|
|
"""The rules this file allows: ``folder/`` from the root, or a root file."""
|
|
for pattern in _patterns():
|
|
if pattern.endswith("/"):
|
|
if path.startswith(pattern.lstrip("/")):
|
|
return True
|
|
elif fnmatch.fnmatchcase(path, pattern.lstrip("/")):
|
|
return True
|
|
return False
|
|
|
|
|
|
class TestPackageContents(unittest.TestCase):
|
|
def test_every_rule_is_anchored_to_the_root(self):
|
|
# An unanchored "tests/" would also drop web/js/tests, and "images/" a
|
|
# runtime folder of that name deeper down.
|
|
for pattern in _patterns():
|
|
self.assertTrue(pattern.startswith("/"), pattern)
|
|
self.assertNotIn("!", pattern)
|
|
|
|
def test_development_files_are_left_out(self):
|
|
for path in DEVELOPMENT:
|
|
self.assertTrue(_ignored(path), path)
|
|
|
|
def test_what_comfyui_needs_stays(self):
|
|
for path in KEPT:
|
|
self.assertFalse(_ignored(path), path)
|
|
for folder in RUNTIME_DIRS:
|
|
for file in (ROOT / folder).rglob("*"):
|
|
if file.is_file():
|
|
relative = file.relative_to(ROOT).as_posix()
|
|
self.assertFalse(_ignored(relative), relative)
|
|
|
|
def test_runtime_code_imports_nothing_left_out(self):
|
|
sources = list(ROOT.glob("*.py"))
|
|
for folder in ("py", "database", "utils"):
|
|
sources.extend((ROOT / folder).rglob("*.py"))
|
|
for source in sources:
|
|
tree = ast.parse(source.read_text(encoding="utf-8"))
|
|
for node in ast.walk(tree):
|
|
names = []
|
|
if isinstance(node, ast.Import):
|
|
names = [alias.name for alias in node.names]
|
|
elif isinstance(node, ast.ImportFrom) and not node.level:
|
|
names = [node.module or ""]
|
|
for name in names:
|
|
self.assertNotIn(name.split(".")[0], ("tests", "tools"), source)
|
|
|
|
def test_the_old_pages_name_their_replacement(self):
|
|
for page, section in (
|
|
("admin", "library"),
|
|
("gallery", "images"),
|
|
("metadata", "inspect"),
|
|
):
|
|
html = (ROOT / "web" / f"{page}.html").read_text(encoding="utf-8")
|
|
self.assertRegex(html, r'id="legacy-removal-notice"')
|
|
self.assertRegex(html, re.escape(f'href="workspace#/{section}"'))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(unittest.main())
|