mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2025-12-16 18:02:58 +08:00
Remove package-level caching in cnr_utils and node_package modules to enable proper dynamic custom node installation and version switching without ComfyUI server restarts. Key Changes: - Remove @lru_cache decorators from version-sensitive functions - Remove cached_property from NodePackage for dynamic state updates - Add comprehensive test suite with parallel execution support - Implement version switching tests (CNR ↔ Nightly) - Add case sensitivity integration tests - Improve error handling and logging API Priority Rules (manager_core.py:1801): - Enabled-Priority: Show only enabled version when both exist - CNR-Priority: Show only CNR when both CNR and Nightly are disabled - Prevents duplicate package entries in /v2/customnode/installed API - Cross-match using cnr_id and aux_id for CNR ↔ Nightly detection Test Infrastructure: - 8 test files with 59 comprehensive test cases - Parallel test execution across 5 isolated environments - Automated test scripts with environment setup - Configurable timeout (60 minutes default) - Support for both master and dr-support-pip-cm branches Bug Fixes: - Fix COMFYUI_CUSTOM_NODES_PATH environment variable export - Resolve test fixture regression with module-level variables - Fix import timing issues in test configuration - Register pytest integration marker to eliminate warnings - Fix POSIX compliance in shell scripts (((var++)) → $((var + 1))) Documentation: - CNR_VERSION_MANAGEMENT_DESIGN.md v1.0 → v1.1 with API priority rules - Add test guides and execution documentation (TESTING_PROMPT.md) - Add security-enhanced installation guide - Create CLI migration guides and references - Document package version management 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
95 lines
2.6 KiB
Python
95 lines
2.6 KiB
Python
import os
|
|
import configparser
|
|
|
|
|
|
GITHUB_ENDPOINT = os.getenv('GITHUB_ENDPOINT')
|
|
|
|
|
|
def is_git_repo(path: str) -> bool:
|
|
""" Check if the path is a git repository. """
|
|
# NOTE: Checking it through `git.Repo` must be avoided.
|
|
# It locks the file, causing issues on Windows.
|
|
return os.path.exists(os.path.join(path, '.git'))
|
|
|
|
|
|
def get_commit_hash(fullpath):
|
|
git_head = os.path.join(fullpath, '.git', 'HEAD')
|
|
if os.path.exists(git_head):
|
|
with open(git_head) as f:
|
|
line = f.readline()
|
|
|
|
if line.startswith("ref: "):
|
|
ref = os.path.join(fullpath, '.git', line[5:].strip())
|
|
if os.path.exists(ref):
|
|
with open(ref) as f2:
|
|
return f2.readline().strip()
|
|
else:
|
|
return "unknown"
|
|
else:
|
|
return line
|
|
|
|
return "unknown"
|
|
|
|
|
|
def git_url(fullpath):
|
|
"""
|
|
resolve version of unclassified custom node based on remote url in .git/config
|
|
"""
|
|
git_config_path = os.path.join(fullpath, '.git', 'config')
|
|
|
|
if not os.path.exists(git_config_path):
|
|
return None
|
|
|
|
# Set `strict=False` to allow duplicate `vscode-merge-base` sections, addressing <https://github.com/ltdrdata/ComfyUI-Manager/issues/1529>
|
|
config = configparser.ConfigParser(strict=False)
|
|
config.read(git_config_path)
|
|
|
|
for k, v in config.items():
|
|
if k.startswith('remote ') and 'url' in v:
|
|
if 'Comfy-Org/ComfyUI-Manager' in v['url']:
|
|
return "https://github.com/ltdrdata/ComfyUI-Manager"
|
|
return v['url']
|
|
|
|
return None
|
|
|
|
|
|
def normalize_url(url) -> str:
|
|
github_id = normalize_to_github_id(url)
|
|
if github_id is not None:
|
|
url = f"https://github.com/{github_id}"
|
|
|
|
return url
|
|
|
|
|
|
def normalize_to_github_id(url) -> str:
|
|
if 'github' in url or (GITHUB_ENDPOINT is not None and GITHUB_ENDPOINT in url):
|
|
author = os.path.basename(os.path.dirname(url))
|
|
|
|
if author.startswith('git@github.com:'):
|
|
author = author.split(':')[1]
|
|
|
|
repo_name = os.path.basename(url)
|
|
if repo_name.endswith('.git'):
|
|
repo_name = repo_name[:-4]
|
|
|
|
return f"{author}/{repo_name}"
|
|
|
|
return None
|
|
|
|
|
|
def compact_url(url):
|
|
github_id = normalize_to_github_id(url)
|
|
if github_id is not None:
|
|
return github_id
|
|
|
|
return url
|
|
|
|
|
|
def get_url_for_clone(url):
|
|
url = normalize_url(url)
|
|
|
|
if GITHUB_ENDPOINT is not None and url.startswith('https://github.com/'):
|
|
url = GITHUB_ENDPOINT + url[18:] # url[18:] -> remove `https://github.com`
|
|
|
|
return url
|
|
|