* bump requires-python * model patcher now implements everything it needs for comfyui * index * Support LTS and Vanilla ComfyUI * Fix version string when installed as package (not material) * style: make linter happy * update init.py * Update nunchaku index * Bump dependencies, include config and workflows when installed using pip/uv * Update installation instructions to include ComfyUI LTS * Update requirements for nunchaku>=1.0.1 * Fix torch210 key * Fix pep 508 spec * Improve tests (still more to go) * Fix comfyui_controlnet_aux flaws * Update tests (all should pass) * Organize the tests in this runner * Update contribution guide * Install uv * Dependencies now resolve with correct conflicts with uv's most stringent resolution * Mediapipe hasn't been built for 3.13 yet, so we can't use it here * Remove controlnet-aux dep * make linter happy * make the linter happy * optimize the loading * update installation * update * update contribution guide * update qwenimage * need to figure out why the toml parsing doesn't owk * update * update * update * style: make linter happy * update * add pulid requirement * update docs * update * update * update * update * update * organize the pyproject.toml * update * update * update * passing all tests * update * update * update * update * update * remove a useless class * update * update * fix a typo --------- Co-authored-by: doctorpangloss <@hiddenswitch.com> Co-authored-by: doctorpangloss <2229300+doctorpangloss@users.noreply.github.com>
147 lines
4.7 KiB
Python
Executable File
147 lines
4.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Script to clone custom nodes from test_data/custom_nodes.yaml,
|
|
checkout to specified commits, and install dependencies.
|
|
"""
|
|
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
|
|
def run_command(cmd, cwd=None, check=True):
|
|
"""Run a shell command and return the result."""
|
|
print(f"Running: {' '.join(cmd)}")
|
|
result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, check=check)
|
|
if result.stdout:
|
|
print(result.stdout)
|
|
if result.stderr:
|
|
print(result.stderr, file=sys.stderr)
|
|
return result
|
|
|
|
|
|
def clone_and_setup_node(node_info, custom_nodes_dir, dependencies_dir):
|
|
"""Clone a node repository, checkout to specified commit, and install dependencies."""
|
|
name = node_info["name"]
|
|
url = node_info["url"]
|
|
branch = node_info.get("branch", "main")
|
|
|
|
node_path = custom_nodes_dir / name
|
|
|
|
print(f"\n{'='*60}")
|
|
print(f"Setting up: {name}")
|
|
print(f"{'='*60}")
|
|
|
|
# Clone repository if it doesn't exist
|
|
if not node_path.exists():
|
|
print(f"Cloning {name} from {url}...")
|
|
try:
|
|
run_command(["git", "clone", url, str(node_path)])
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error cloning {name}: {e}", file=sys.stderr)
|
|
return False
|
|
else:
|
|
print(f"{name} already exists at {node_path}")
|
|
|
|
# Checkout to specified commit/branch
|
|
print(f"Checking out to {branch}...")
|
|
try:
|
|
run_command(["git", "fetch", "--all"], cwd=node_path)
|
|
run_command(["git", "checkout", branch], cwd=node_path)
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error checking out {branch} for {name}: {e}", file=sys.stderr)
|
|
return False
|
|
|
|
# Install dependencies
|
|
print(f"Installing dependencies for {name}...")
|
|
|
|
# Check if custom dependency file exists in test_data/dependencies
|
|
custom_deps_file = dependencies_dir / f"{name}.txt"
|
|
|
|
if custom_deps_file.exists():
|
|
print(f"Using custom dependencies from {custom_deps_file}")
|
|
try:
|
|
run_command(["uv", "pip", "install", "-r", str(custom_deps_file)])
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error installing dependencies from {custom_deps_file}: {e}", file=sys.stderr)
|
|
return False
|
|
else:
|
|
# Fall back to requirements.txt in the repository
|
|
requirements_file = node_path / "requirements.txt"
|
|
if requirements_file.exists():
|
|
print(f"Using requirements.txt from repository: {requirements_file}")
|
|
try:
|
|
run_command(["uv", "pip", "install", "-r", str(requirements_file)])
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error installing dependencies from {requirements_file}: {e}", file=sys.stderr)
|
|
return False
|
|
else:
|
|
print(f"No requirements.txt found for {name}, skipping dependency installation")
|
|
|
|
print(f"✓ Successfully set up {name}")
|
|
return True
|
|
|
|
|
|
def main():
|
|
# Get project root directory (parent of scripts/)
|
|
script_dir = Path(__file__).parent
|
|
project_root = script_dir.parent
|
|
|
|
# Define paths
|
|
custom_nodes_yaml = project_root / "test_data" / "custom_nodes.yaml"
|
|
dependencies_dir = project_root / "test_data" / "dependencies"
|
|
custom_nodes_dir = Path("custom_nodes")
|
|
|
|
# Verify required files exist
|
|
if not custom_nodes_yaml.exists():
|
|
print(f"Error: {custom_nodes_yaml} not found!", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
# Create custom_nodes directory if it doesn't exist
|
|
custom_nodes_dir.mkdir(exist_ok=True)
|
|
|
|
# Load custom nodes configuration
|
|
print(f"Loading configuration from {custom_nodes_yaml}...")
|
|
with open(custom_nodes_yaml, "r") as f:
|
|
config = yaml.safe_load(f)
|
|
|
|
nodes = config.get("nodes", [])
|
|
if not nodes:
|
|
print("No nodes found in configuration")
|
|
sys.exit(0)
|
|
|
|
print(f"Found {len(nodes)} node(s) to set up")
|
|
|
|
# Process each node
|
|
success_count = 0
|
|
failed_nodes = []
|
|
|
|
for node_info in nodes:
|
|
success = clone_and_setup_node(node_info, custom_nodes_dir, dependencies_dir)
|
|
if success:
|
|
success_count += 1
|
|
else:
|
|
failed_nodes.append(node_info["name"])
|
|
|
|
# Print summary
|
|
print(f"\n{'='*60}")
|
|
print("SUMMARY")
|
|
print(f"{'='*60}")
|
|
print(f"Total nodes: {len(nodes)}")
|
|
print(f"Successfully set up: {success_count}")
|
|
print(f"Failed: {len(failed_nodes)}")
|
|
|
|
if failed_nodes:
|
|
print("\nFailed nodes:")
|
|
for name in failed_nodes:
|
|
print(f" - {name}")
|
|
sys.exit(1)
|
|
else:
|
|
print("\n✓ All nodes set up successfully!")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|