121 lines
3.5 KiB
Python
121 lines
3.5 KiB
Python
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
from pathlib import Path
|
|
|
|
__version__ = "1.0.11"
|
|
|
|
_PLUGIN_DIR = Path(__file__).resolve().parent
|
|
_CUSTOM_NODES_DIR = _PLUGIN_DIR.parent
|
|
|
|
_VERSION_RE = re.compile(r'__version__\s*=\s*["\']([^"\']+)["\']')
|
|
_PYPROJECT_VERSION_RE = re.compile(r'^\s*version\s*=\s*["\']([^"\']+)["\']', re.MULTILINE)
|
|
|
|
|
|
def _version_from_init_py(init_path: Path) -> str | None:
|
|
if not init_path.is_file():
|
|
return None
|
|
try:
|
|
text = init_path.read_text(encoding="utf-8", errors="replace")
|
|
m = _VERSION_RE.search(text)
|
|
return m.group(1).strip() if m else None
|
|
except Exception:
|
|
return None
|
|
|
|
|
|
def _version_from_metadata(package_name: str) -> str | None:
|
|
try:
|
|
from importlib.metadata import version
|
|
for name in (package_name, package_name.replace("_", "-"), package_name.replace("-", "_")):
|
|
try:
|
|
return version(name)
|
|
except Exception:
|
|
continue
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
|
|
def _version_from_pyproject_toml(package_dir: Path) -> str | None:
|
|
path = package_dir / "pyproject.toml"
|
|
if not path.is_file():
|
|
return None
|
|
try:
|
|
text = path.read_text(encoding="utf-8", errors="replace")
|
|
for m in _PYPROJECT_VERSION_RE.finditer(text):
|
|
return m.group(1).strip()
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
|
|
def _version_from_package_json(package_dir: Path) -> str | None:
|
|
path = package_dir / "package.json"
|
|
if not path.is_file():
|
|
return None
|
|
try:
|
|
data = json.loads(path.read_text(encoding="utf-8", errors="replace"))
|
|
if isinstance(data.get("version"), str) and data["version"].strip():
|
|
return data["version"].strip()
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
|
|
def _version_from_version_file(package_dir: Path) -> str | None:
|
|
for name in ("version.py", "version.json"):
|
|
path = package_dir / name
|
|
if not path.is_file():
|
|
continue
|
|
try:
|
|
text = path.read_text(encoding="utf-8", errors="replace")
|
|
if name.endswith(".json"):
|
|
data = json.loads(text)
|
|
if isinstance(data.get("version"), str) and data["version"].strip():
|
|
return data["version"].strip()
|
|
else:
|
|
m = _VERSION_RE.search(text)
|
|
if m:
|
|
return m.group(1).strip()
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
|
|
def _is_git_repo(package_dir: Path) -> bool:
|
|
return (package_dir / ".git").exists()
|
|
|
|
|
|
def get_installed_modules() -> list[dict]:
|
|
result: list[dict] = []
|
|
if not _CUSTOM_NODES_DIR.is_dir():
|
|
return result
|
|
|
|
for path in sorted(_CUSTOM_NODES_DIR.iterdir()):
|
|
if not path.is_dir():
|
|
continue
|
|
init_py = path / "__init__.py"
|
|
if not init_py.is_file():
|
|
continue
|
|
name = path.name
|
|
version = (
|
|
_version_from_init_py(init_py)
|
|
or _version_from_metadata(name)
|
|
or _version_from_pyproject_toml(path)
|
|
or _version_from_package_json(path)
|
|
or _version_from_version_file(path)
|
|
)
|
|
if version is None and _is_git_repo(path):
|
|
version = "nightly"
|
|
result.append({"name": name, "version": version})
|
|
|
|
return result
|
|
|
|
|
|
def get_version_info_payload() -> dict:
|
|
return {
|
|
"workflowui_plugin_version": __version__,
|
|
"installed_custom_nodes": get_installed_modules(),
|
|
}
|