|
1 | 1 | import os |
2 | 2 | import pathlib |
3 | 3 | import platform |
| 4 | +import shutil |
4 | 5 | import subprocess |
5 | 6 | import sys |
6 | 7 | import uuid |
|
11 | 12 | from rich import print |
12 | 13 | from rich.console import Console |
13 | 14 |
|
14 | | -from comfy_cli import logging, tracking, ui, utils |
| 15 | +from comfy_cli import constants, logging, tracking, ui, utils |
15 | 16 | from comfy_cli.command.custom_nodes.bisect_custom_nodes import bisect_app |
16 | | -from comfy_cli.command.custom_nodes.cm_cli_util import execute_cm_cli |
| 17 | +from comfy_cli.command.custom_nodes.cm_cli_util import execute_cm_cli, find_cm_cli |
17 | 18 | from comfy_cli.config_manager import ConfigManager |
18 | 19 | from comfy_cli.constants import NODE_ZIP_FILENAME |
19 | 20 | from comfy_cli.file_utils import ( |
@@ -48,21 +49,9 @@ class ShowTarget(str, Enum): |
48 | 49 | SNAPSHOT_LIST = "snapshot-list" |
49 | 50 |
|
50 | 51 |
|
51 | | -def validate_comfyui_manager(_env_checker): |
52 | | - manager_path = _env_checker.get_comfyui_manager_path() |
53 | | - |
54 | | - if manager_path is None: |
55 | | - print("[bold red]If ComfyUI is not installed, this feature cannot be used.[/bold red]") |
56 | | - raise typer.Exit(code=1) |
57 | | - elif not os.path.exists(manager_path): |
58 | | - print( |
59 | | - f"[bold red]If ComfyUI-Manager is not installed, this feature cannot be used.[/bold red] \\[{manager_path}]" |
60 | | - ) |
61 | | - raise typer.Exit(code=1) |
62 | | - elif not os.path.exists(os.path.join(manager_path, ".git")): |
63 | | - print( |
64 | | - f"[bold red]The ComfyUI-Manager installation is invalid. This feature cannot be used.[/bold red] \\[{manager_path}]" |
65 | | - ) |
| 52 | +def validate_comfyui_manager(_env_checker=None): |
| 53 | + if not find_cm_cli(): |
| 54 | + print("[bold red]ComfyUI-Manager is not installed. 'cm-cli' command is not available.[/bold red]") |
66 | 55 | raise typer.Exit(code=1) |
67 | 56 |
|
68 | 57 |
|
@@ -234,16 +223,168 @@ def restore_dependencies(): |
234 | 223 | execute_cm_cli(["restore-dependencies"]) |
235 | 224 |
|
236 | 225 |
|
237 | | -@manager_app.command("disable-gui", help="Disable GUI mode of ComfyUI-Manager") |
| 226 | +@manager_app.command("disable", help="Disable ComfyUI-Manager completely") |
238 | 227 | @tracking.track_command("node") |
239 | | -def disable_gui(): |
240 | | - execute_cm_cli(["cli-only-mode", "enable"]) |
| 228 | +def disable_manager(): |
| 229 | + """Disable ComfyUI-Manager. No manager flags will be passed to ComfyUI.""" |
| 230 | + config_manager = ConfigManager() |
| 231 | + config_manager.set(constants.CONFIG_KEY_MANAGER_GUI_MODE, "disable") |
| 232 | + print("[bold yellow]ComfyUI-Manager has been disabled.[/bold yellow]") |
| 233 | + print("No manager flags will be passed to ComfyUI on next launch.") |
241 | 234 |
|
242 | 235 |
|
243 | | -@manager_app.command("enable-gui", help="Enable GUI mode of ComfyUI-Manager") |
| 236 | +@manager_app.command("enable-gui", help="Enable ComfyUI-Manager with new GUI") |
244 | 237 | @tracking.track_command("node") |
245 | 238 | def enable_gui(): |
246 | | - execute_cm_cli(["cli-only-mode", "disable"]) |
| 239 | + """Enable ComfyUI-Manager with new GUI.""" |
| 240 | + config_manager = ConfigManager() |
| 241 | + config_manager.set(constants.CONFIG_KEY_MANAGER_GUI_MODE, "enable-gui") |
| 242 | + print("[bold green]ComfyUI-Manager GUI has been enabled.[/bold green]") |
| 243 | + print("[dim]ComfyUI will launch with: --enable-manager[/dim]") |
| 244 | + |
| 245 | + |
| 246 | +@manager_app.command("disable-gui", help="Enable ComfyUI-Manager without GUI") |
| 247 | +@tracking.track_command("node") |
| 248 | +def disable_gui(): |
| 249 | + """Enable ComfyUI-Manager but disable its GUI.""" |
| 250 | + config_manager = ConfigManager() |
| 251 | + config_manager.set(constants.CONFIG_KEY_MANAGER_GUI_MODE, "disable-gui") |
| 252 | + print("[bold green]ComfyUI-Manager enabled with GUI disabled.[/bold green]") |
| 253 | + print("[dim]ComfyUI will launch with: --enable-manager --disable-manager-ui[/dim]") |
| 254 | + |
| 255 | + |
| 256 | +@manager_app.command("enable-legacy-gui", help="Enable ComfyUI-Manager with legacy GUI") |
| 257 | +@tracking.track_command("node") |
| 258 | +def enable_legacy_gui(): |
| 259 | + """Enable ComfyUI-Manager with legacy GUI.""" |
| 260 | + config_manager = ConfigManager() |
| 261 | + config_manager.set(constants.CONFIG_KEY_MANAGER_GUI_MODE, "enable-legacy-gui") |
| 262 | + print("[bold green]ComfyUI-Manager legacy GUI has been enabled.[/bold green]") |
| 263 | + print("[dim]ComfyUI will launch with: --enable-manager --enable-manager-legacy-ui[/dim]") |
| 264 | + |
| 265 | + |
| 266 | +@manager_app.command("migrate-legacy", help="Migrate legacy git-cloned ComfyUI-Manager to .disabled") |
| 267 | +@tracking.track_command("node") |
| 268 | +def migrate_legacy( |
| 269 | + yes: Annotated[ |
| 270 | + bool, |
| 271 | + typer.Option("--yes", "-y", help="Skip confirmation prompt"), |
| 272 | + ] = False, |
| 273 | +): |
| 274 | + """ |
| 275 | + Migrate legacy ComfyUI-Manager from custom_nodes/ to custom_nodes/.disabled/ |
| 276 | +
|
| 277 | + Detects .enable-cli-only-mode file to set appropriate mode: |
| 278 | + - If .enable-cli-only-mode exists → mode = disable |
| 279 | + - Otherwise → mode = enable-gui |
| 280 | + """ |
| 281 | + if not workspace_manager.workspace_path: |
| 282 | + print("[bold red]ComfyUI workspace is not set.[/bold red]") |
| 283 | + print("[dim]Use --workspace or run from a ComfyUI directory.[/dim]") |
| 284 | + raise typer.Exit(code=1) |
| 285 | + |
| 286 | + custom_nodes_path = pathlib.Path(workspace_manager.workspace_path) / "custom_nodes" |
| 287 | + |
| 288 | + # Find legacy manager with case-insensitive matching (must be a real directory, not symlink) |
| 289 | + legacy_manager_path = None |
| 290 | + if custom_nodes_path.exists(): |
| 291 | + for item in custom_nodes_path.iterdir(): |
| 292 | + if item.is_dir() and not item.is_symlink() and item.name.lower() == "comfyui-manager": |
| 293 | + legacy_manager_path = item |
| 294 | + break |
| 295 | + |
| 296 | + # Check if legacy manager exists |
| 297 | + if legacy_manager_path is None: |
| 298 | + print("[bold yellow]No legacy ComfyUI-Manager found in custom_nodes/[/bold yellow]") |
| 299 | + print("Nothing to migrate.") |
| 300 | + return |
| 301 | + |
| 302 | + # Verify it's a git-cloned repository |
| 303 | + git_dir = legacy_manager_path / ".git" |
| 304 | + if not git_dir.exists(): |
| 305 | + print(f"[bold yellow]Warning: {legacy_manager_path.name} does not appear to be a git repository.[/bold yellow]") |
| 306 | + print("[dim]Expected a git-cloned ComfyUI-Manager. Skipping migration.[/dim]") |
| 307 | + return |
| 308 | + |
| 309 | + # Detect CLI-only mode before any changes |
| 310 | + cli_only_mode_file = legacy_manager_path / ".enable-cli-only-mode" |
| 311 | + cli_only_mode = cli_only_mode_file.exists() |
| 312 | + |
| 313 | + # Show what will happen and ask for confirmation |
| 314 | + print(f"[bold]Found legacy ComfyUI-Manager:[/bold] {legacy_manager_path}") |
| 315 | + print(f"[dim]CLI-only mode: {cli_only_mode}[/dim]") |
| 316 | + print() |
| 317 | + print("[bold]This will:[/bold]") |
| 318 | + print(f" 1. Move {legacy_manager_path.name} to custom_nodes/.disabled/") |
| 319 | + print(f" 2. Set manager mode to: {'disable' if cli_only_mode else 'enable-gui'}") |
| 320 | + print(" 3. Install manager_requirements.txt (if present)") |
| 321 | + print() |
| 322 | + |
| 323 | + if not yes: |
| 324 | + confirm = ui.prompt_confirm_action("Proceed with migration?", False) |
| 325 | + if not confirm: |
| 326 | + print("[dim]Migration cancelled.[/dim]") |
| 327 | + return |
| 328 | + |
| 329 | + # Create .disabled directory |
| 330 | + disabled_path = custom_nodes_path / ".disabled" |
| 331 | + disabled_path.mkdir(exist_ok=True) |
| 332 | + |
| 333 | + # Check if target already exists (case-insensitive) |
| 334 | + existing_target = None |
| 335 | + for item in disabled_path.iterdir(): |
| 336 | + if item.is_dir() and item.name.lower() == "comfyui-manager": |
| 337 | + existing_target = item |
| 338 | + break |
| 339 | + |
| 340 | + if existing_target is not None: |
| 341 | + print(f"[bold red]Target path already exists: {existing_target}[/bold red]") |
| 342 | + print("Please remove it manually and try again.") |
| 343 | + raise typer.Exit(code=1) |
| 344 | + |
| 345 | + # Move legacy manager (preserve original directory name) |
| 346 | + target_path = disabled_path / legacy_manager_path.name |
| 347 | + try: |
| 348 | + shutil.move(str(legacy_manager_path), str(target_path)) |
| 349 | + except OSError as e: |
| 350 | + print(f"[bold red]Failed to move legacy manager: {e}[/bold red]") |
| 351 | + raise typer.Exit(code=1) |
| 352 | + |
| 353 | + # Install manager_requirements.txt if present |
| 354 | + workspace_path = pathlib.Path(workspace_manager.workspace_path) |
| 355 | + manager_req_path = workspace_path / constants.MANAGER_REQUIREMENTS_FILE |
| 356 | + install_success = False # Default to failure, set True only on success |
| 357 | + if manager_req_path.exists(): |
| 358 | + print("[dim]Installing ComfyUI-Manager dependencies...[/dim]") |
| 359 | + result = subprocess.run( |
| 360 | + [sys.executable, "-m", "pip", "install", "-r", str(manager_req_path)], |
| 361 | + check=False, |
| 362 | + ) |
| 363 | + if result.returncode != 0: |
| 364 | + print("[bold yellow]Warning: Failed to install ComfyUI-Manager dependencies.[/bold yellow]") |
| 365 | + print("[dim]You may need to run: pip install -r manager_requirements.txt[/dim]") |
| 366 | + else: |
| 367 | + install_success = True |
| 368 | + else: |
| 369 | + print("[bold yellow]Warning: manager_requirements.txt not found (older ComfyUI version?).[/bold yellow]") |
| 370 | + print("[dim]ComfyUI-Manager pip package not installed.[/dim]") |
| 371 | + |
| 372 | + # Set config mode |
| 373 | + config_manager = ConfigManager() |
| 374 | + if cli_only_mode or not install_success: |
| 375 | + config_manager.set(constants.CONFIG_KEY_MANAGER_GUI_MODE, "disable") |
| 376 | + print("[bold green]Legacy ComfyUI-Manager migrated to .disabled/[/bold green]") |
| 377 | + if cli_only_mode: |
| 378 | + print("[dim]Detected .enable-cli-only-mode → Manager set to: disable[/dim]") |
| 379 | + else: |
| 380 | + print("[dim]Manager installation failed → Manager set to: disable[/dim]") |
| 381 | + print("[dim]After fixing installation, run: comfy manager enable-gui[/dim]") |
| 382 | + else: |
| 383 | + config_manager.set(constants.CONFIG_KEY_MANAGER_GUI_MODE, "enable-gui") |
| 384 | + print("[bold green]Legacy ComfyUI-Manager migrated to .disabled/[/bold green]") |
| 385 | + print("[dim]Manager set to: enable-gui (new GUI)[/dim]") |
| 386 | + |
| 387 | + print("\n[bold]The new pip-installed ComfyUI-Manager will be used on next launch.[/bold]") |
247 | 388 |
|
248 | 389 |
|
249 | 390 | @manager_app.command(help="Clear reserved startup action in ComfyUI-Manager") |
@@ -479,14 +620,15 @@ def update_node_id_cache(): |
479 | 620 | config_manager = ConfigManager() |
480 | 621 | workspace_path = workspace_manager.workspace_path |
481 | 622 |
|
482 | | - cm_cli_path = os.path.join(workspace_path, "custom_nodes", "ComfyUI-Manager", "cm-cli.py") |
| 623 | + if not find_cm_cli(): |
| 624 | + raise FileNotFoundError("cm-cli not found") |
483 | 625 |
|
484 | 626 | tmp_path = os.path.join(config_manager.get_config_path(), "tmp") |
485 | 627 | if not os.path.exists(tmp_path): |
486 | 628 | os.makedirs(tmp_path) |
487 | 629 |
|
488 | 630 | cache_path = os.path.join(tmp_path, "node-cache.list") |
489 | | - cmd = [sys.executable, cm_cli_path, "export-custom-node-ids", cache_path] |
| 631 | + cmd = [sys.executable, "-m", "cm_cli", "export-custom-node-ids", cache_path] |
490 | 632 |
|
491 | 633 | new_env = os.environ.copy() |
492 | 634 | new_env["COMFYUI_PATH"] = workspace_path |
|
0 commit comments