* refactor: remove dead and test-only code and the write-only prompt registry (#620) 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. * fix: network-share readers, model unload off the loop, bad save requests (#620) Every read-only SQLite open now uses one URI helper, so a library on a Windows network share works in backups, restores, moves and history reads. Unloading a model no longer blocks the server. A malformed /save body gets a 400, not a 500. * feat(library): add Recently used, Most used and Name Z-A sorting (#620) The old Dashboard's sorts the community asked for, on the Prompt library, in saved views, and with paging through the whole list. * feat(workspace): stop linking the old pages (#620) They show a removal notice since 3.5.1. System no longer links them, the load failure offers a reload and ComfyUI instead, and the README says they are going away. The pages still work at their URLs.
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())
|