From e356ec8c9535f79a02777d61c6c8b950668dd5c4 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Thu, 25 Jul 2024 00:16:12 +0900 Subject: [PATCH 1/5] Support new ComfyUI-Manager --- comfy_cli/command/custom_nodes/cm_cli_util.py | 8 +- comfy_cli/command/custom_nodes/command.py | 126 +++++------------- comfy_cli/command/install.py | 4 +- comfy_cli/constants.py | 1 + comfy_cli/workspace_manager.py | 44 ++++-- 5 files changed, 78 insertions(+), 105 deletions(-) diff --git a/comfy_cli/command/custom_nodes/cm_cli_util.py b/comfy_cli/command/custom_nodes/cm_cli_util.py index 1fcccda3..fec0d949 100644 --- a/comfy_cli/command/custom_nodes/cm_cli_util.py +++ b/comfy_cli/command/custom_nodes/cm_cli_util.py @@ -23,12 +23,10 @@ def execute_cm_cli(args, channel=None, mode=None) -> str | None: print("\n[bold red]ComfyUI path is not resolved.[/bold red]\n", file=sys.stderr) raise typer.Exit(code=1) - cm_cli_path = os.path.join( - workspace_path, "custom_nodes", "ComfyUI-Manager", "cm-cli.py" - ) - if not os.path.exists(cm_cli_path): + cm_cli_path = workspace_manager.get_cm_cli_path() + if cm_cli_path is None: print( - f"\n[bold red]ComfyUI-Manager not found: {cm_cli_path}[/bold red]\n", + f"\n[bold red]ComfyUI-Manager not found[/bold red]\n", file=sys.stderr, ) raise typer.Exit(code=1) diff --git a/comfy_cli/command/custom_nodes/command.py b/comfy_cli/command/custom_nodes/command.py index 218b796c..8ff66e74 100644 --- a/comfy_cli/command/custom_nodes/command.py +++ b/comfy_cli/command/custom_nodes/command.py @@ -497,10 +497,15 @@ def update_node_id_cache(): config_manager = ConfigManager() workspace_path = workspace_manager.workspace_path - cm_cli_path = os.path.join( - workspace_path, "custom_nodes", "ComfyUI-Manager", "cm-cli.py" - ) + cm_cli_path = workspace_manager.get_cm_cli_path() + if cm_cli_path is None: + print( + f"\n[bold red]ComfyUI-Manager not found[/bold red]\n", + file=sys.stderr, + ) + raise typer.Exit(code=1) + tmp_path = os.path.join(config_manager.get_config_path(), "tmp") if not os.path.exists(tmp_path): os.makedirs(tmp_path) @@ -630,6 +635,35 @@ def fix( execute_cm_cli(["fix"] + nodes, channel, mode) +@app.command( + "show-versions", help="Show the list of available versions for the target custom node." +) +@tracking.track_command("node") +def show_versions( + node_name: str, + channel: Annotated[ + Optional[str], + typer.Option( + show_default=False, + help="Specify the operation mode", + autocompletion=channel_completer, + ), + ] = None, + mode: str = typer.Option( + None, + help="[remote|local|cache]", + autocompletion=mode_completer, + ), +): + validate_mode(mode) + + execute_cm_cli( + ["show-versions", node_name], + channel, + mode, + ) + + @app.command( "install-deps", help="Install dependencies from dependencies file(.json) or workflow(.png/.json)", @@ -824,92 +858,6 @@ def display_all_nodes(): ) -@app.command( - "registry-install", - help="Install a node from the registry", - hidden=True, -) -@tracking.track_command("node") -def registry_install( - node_id: str, - version: Optional[str] = None, - force_download: Annotated[ - bool, - typer.Option( - "--force-download", - help="Force download the node even if it is already installed", - ), - ] = False, -): - """ - Install a node from the registry. - Args: - node_id: The ID of the node to install. - version: The version of the node to install. If not provided, the latest version will be installed. - """ - - # If the node ID is not provided, prompt the user to enter it - if not node_id: - node_id = typer.prompt("Enter the ID of the node you want to install") - - node_version = None - try: - # Call the API to install the node - node_version = registry_api.install_node(node_id, version) - if not node_version.download_url: - logging.error("Download URL not provided from the registry.") - ui.display_error_message(f"Failed to download the custom node {node_id}.") - return - - except Exception as e: - logging.error( - f"Encountered an error while installing the node. error: {str(e)}" - ) - ui.display_error_message(f"Failed to download the custom node {node_id}.") - return - - # Download the node archive - custom_nodes_path = pathlib.Path(workspace_manager.workspace_path) / "custom_nodes" - node_specific_path = custom_nodes_path / node_id # Subdirectory for the node - if node_specific_path.exists(): - print( - f"[bold red] The node {node_id} already exists in the workspace. This migit delete any model files in the node.[/bold red]" - ) - - confirm = ui.prompt_confirm_action( - "Do you want to overwrite it?", - force_download, - ) - if not confirm: - return - node_specific_path.mkdir( - parents=True, exist_ok=True - ) # Create the directory if it doesn't exist - - local_filename = node_specific_path / f"{node_id}-{node_version.version}.zip" - logging.debug( - f"Start downloading the node {node_id} version {node_version.version} to {local_filename}" - ) - download_file(node_version.download_url, local_filename) - - # Extract the downloaded archive to the custom_node directory on the workspace. - logging.debug( - f"Start extracting the node {node_id} version {node_version.version} to {custom_nodes_path}" - ) - extract_package_as_zip(local_filename, node_specific_path) - - # TODO: temoporary solution to run requirement.txt and install script - execute_install_script(node_specific_path) - - # Delete the downloaded archive - logging.debug(f"Deleting the downloaded archive {local_filename}") - os.remove(local_filename) - - logging.info( - f"Node {node_id} version {node_version.version} has been successfully installed." - ) - - @app.command( "pack", help="Pack the current node into a zip file. Ignorining .gitignore files.", diff --git a/comfy_cli/command/install.py b/comfy_cli/command/install.py index 54592dfa..6016dddb 100644 --- a/comfy_cli/command/install.py +++ b/comfy_cli/command/install.py @@ -151,7 +151,7 @@ def install_comfyui_dependencies( # install requirements for manager def install_manager_dependencies(repo_dir): - os.chdir(os.path.join(repo_dir, "custom_nodes", "ComfyUI-Manager")) + os.chdir(workspace_manager.get_comfyui_manager_path()) subprocess.run( [sys.executable, "-m", "pip", "install", "-r", "requirements.txt"], check=True ) @@ -214,7 +214,7 @@ def execute( if skip_manager: print("Skipping installation of ComfyUI-Manager. (by --skip-manager)") else: - manager_repo_dir = os.path.join(repo_dir, "custom_nodes", "ComfyUI-Manager") + manager_repo_dir = os.path.join(repo_dir, "custom_nodes", "comfyui-manager@nightly") if os.path.exists(manager_repo_dir): if restore: diff --git a/comfy_cli/constants.py b/comfy_cli/constants.py index 11685cdf..90d6a027 100644 --- a/comfy_cli/constants.py +++ b/comfy_cli/constants.py @@ -37,6 +37,7 @@ class OS(Enum): CONFIG_KEY_USER_ID = "user_id" CONFIG_KEY_INSTALL_EVENT_TRIGGERED = "install_event_triggered" CONFIG_KEY_BACKGROUND = "background" +CONFIG_KEY_COMFYUI_MANAGER_PATH = 'comfyui_manager_path' CIVITAI_API_TOKEN_KEY = "civitai_api_token" diff --git a/comfy_cli/workspace_manager.py b/comfy_cli/workspace_manager.py index 5c8b4c17..1e4b0df4 100644 --- a/comfy_cli/workspace_manager.py +++ b/comfy_cli/workspace_manager.py @@ -281,21 +281,47 @@ def get_comfyui_manager_path(self): if self.workspace_path is None: return None - # To check more robustly, verify up to the `.git` path. - manager_path = os.path.join( - self.workspace_path, "custom_nodes", "ComfyUI-Manager" - ) + cached_manager_path = self.config_manager.get(constants.CONFIG_KEY_COMFYUI_MANAGER_PATH) + + if cached_manager_path is None or not cached_manager_path.startswith(self.workspace_path): + manager_path = os.path.join( + self.workspace_path, "custom_nodes", "comfyui-manager@nightly" + ) + else: + manager_path = cached_manager_path + + if not os.path.exists(manager_path): + manager_path = os.path.join( + self.workspace_path, "custom_nodes", "ComfyUI-Manager" + ) + + if not os.path.exists(manager_path): + custom_nodes = os.path.join( + self.workspace_path, "custom_nodes" + ) + + manager_path = None + for subdir in os.listdir(custom_nodes): + if subdir.startswith('comfyui-manager@'): + manager_path = os.path.join(custom_nodes, subdir) + break + + if manager_path is not None and manager_path != cached_manager_path: + self.config_manager.set(constants.CONFIG_KEY_COMFYUI_MANAGER_PATH, manager_path) + return manager_path def is_comfyui_manager_installed(self): if self.workspace_path is None: return False - # To check more robustly, verify up to the `.git` path. - manager_git_path = os.path.join( - self.workspace_path, "custom_nodes", "ComfyUI-Manager", ".git" - ) - return os.path.exists(manager_git_path) + return self.get_comfyui_manager_path() is not None + + def get_cm_cli_path(self): + cm_path = self.get_comfyui_manager_path() + if cm_path is not None: + return os.path.join(cm_path, 'cm-cli.py') + return None def scan_dir(self): if not self.workspace_path: From 7df56f5915c26e9519cdc539817c6c5eeb82a4f8 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Thu, 25 Jul 2024 00:35:36 +0900 Subject: [PATCH 2/5] switch to feat/cnr branch for alpha testing.. --- comfy_cli/command/install.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/comfy_cli/command/install.py b/comfy_cli/command/install.py index 6016dddb..0e0b3e8e 100644 --- a/comfy_cli/command/install.py +++ b/comfy_cli/command/install.py @@ -227,6 +227,12 @@ def execute( print("\nInstalling ComfyUI-Manager..") subprocess.run(["git", "clone", manager_url, manager_repo_dir], check=True) + + # TODO: REMOVED - Alpha Testing ----------------------------- + os.chdir(workspace_manager.get_comfyui_manager_path()) + subprocess.run(["git", "switch", 'feat/cnr'], check=True) + # ------------------------------------------------------------ + install_manager_dependencies(repo_dir) update_node_id_cache() From 0fb09d1f6ee3ffd84f30aa38e2fcf9b48df4efa0 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Thu, 25 Jul 2024 00:49:25 +0900 Subject: [PATCH 3/5] reformat --- comfy_cli/command/custom_nodes/command.py | 5 +++-- comfy_cli/command/install.py | 8 +++++--- comfy_cli/constants.py | 2 +- comfy_cli/workspace_manager.py | 20 ++++++++++++-------- 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/comfy_cli/command/custom_nodes/command.py b/comfy_cli/command/custom_nodes/command.py index 8ff66e74..b73f06ce 100644 --- a/comfy_cli/command/custom_nodes/command.py +++ b/comfy_cli/command/custom_nodes/command.py @@ -505,7 +505,7 @@ def update_node_id_cache(): file=sys.stderr, ) raise typer.Exit(code=1) - + tmp_path = os.path.join(config_manager.get_config_path(), "tmp") if not os.path.exists(tmp_path): os.makedirs(tmp_path) @@ -636,7 +636,8 @@ def fix( @app.command( - "show-versions", help="Show the list of available versions for the target custom node." + "show-versions", + help="Show the list of available versions for the target custom node.", ) @tracking.track_command("node") def show_versions( diff --git a/comfy_cli/command/install.py b/comfy_cli/command/install.py index 0e0b3e8e..1e4b5c89 100644 --- a/comfy_cli/command/install.py +++ b/comfy_cli/command/install.py @@ -214,7 +214,9 @@ def execute( if skip_manager: print("Skipping installation of ComfyUI-Manager. (by --skip-manager)") else: - manager_repo_dir = os.path.join(repo_dir, "custom_nodes", "comfyui-manager@nightly") + manager_repo_dir = os.path.join( + repo_dir, "custom_nodes", "comfyui-manager@nightly" + ) if os.path.exists(manager_repo_dir): if restore: @@ -228,9 +230,9 @@ def execute( subprocess.run(["git", "clone", manager_url, manager_repo_dir], check=True) - # TODO: REMOVED - Alpha Testing ----------------------------- + # TODO: REMOVED - Alpha Testing -----------------------------` os.chdir(workspace_manager.get_comfyui_manager_path()) - subprocess.run(["git", "switch", 'feat/cnr'], check=True) + subprocess.run(["git", "switch", "feat/cnr"], check=True) # ------------------------------------------------------------ install_manager_dependencies(repo_dir) diff --git a/comfy_cli/constants.py b/comfy_cli/constants.py index 90d6a027..8ef85ec7 100644 --- a/comfy_cli/constants.py +++ b/comfy_cli/constants.py @@ -37,7 +37,7 @@ class OS(Enum): CONFIG_KEY_USER_ID = "user_id" CONFIG_KEY_INSTALL_EVENT_TRIGGERED = "install_event_triggered" CONFIG_KEY_BACKGROUND = "background" -CONFIG_KEY_COMFYUI_MANAGER_PATH = 'comfyui_manager_path' +CONFIG_KEY_COMFYUI_MANAGER_PATH = "comfyui_manager_path" CIVITAI_API_TOKEN_KEY = "civitai_api_token" diff --git a/comfy_cli/workspace_manager.py b/comfy_cli/workspace_manager.py index 1e4b0df4..c66d076d 100644 --- a/comfy_cli/workspace_manager.py +++ b/comfy_cli/workspace_manager.py @@ -281,9 +281,13 @@ def get_comfyui_manager_path(self): if self.workspace_path is None: return None - cached_manager_path = self.config_manager.get(constants.CONFIG_KEY_COMFYUI_MANAGER_PATH) + cached_manager_path = self.config_manager.get( + constants.CONFIG_KEY_COMFYUI_MANAGER_PATH + ) - if cached_manager_path is None or not cached_manager_path.startswith(self.workspace_path): + if cached_manager_path is None or not cached_manager_path.startswith( + self.workspace_path + ): manager_path = os.path.join( self.workspace_path, "custom_nodes", "comfyui-manager@nightly" ) @@ -296,18 +300,18 @@ def get_comfyui_manager_path(self): ) if not os.path.exists(manager_path): - custom_nodes = os.path.join( - self.workspace_path, "custom_nodes" - ) + custom_nodes = os.path.join(self.workspace_path, "custom_nodes") manager_path = None for subdir in os.listdir(custom_nodes): - if subdir.startswith('comfyui-manager@'): + if subdir.startswith("comfyui-manager@"): manager_path = os.path.join(custom_nodes, subdir) break if manager_path is not None and manager_path != cached_manager_path: - self.config_manager.set(constants.CONFIG_KEY_COMFYUI_MANAGER_PATH, manager_path) + self.config_manager.set( + constants.CONFIG_KEY_COMFYUI_MANAGER_PATH, manager_path + ) return manager_path @@ -320,7 +324,7 @@ def is_comfyui_manager_installed(self): def get_cm_cli_path(self): cm_path = self.get_comfyui_manager_path() if cm_path is not None: - return os.path.join(cm_path, 'cm-cli.py') + return os.path.join(cm_path, "cm-cli.py") return None def scan_dir(self): From e6f8c86591a15f16330b55668d23611741695eb6 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Sat, 27 Jul 2024 01:47:19 +0900 Subject: [PATCH 4/5] support: comfy node show cnr --- comfy_cli/command/custom_nodes/command.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/comfy_cli/command/custom_nodes/command.py b/comfy_cli/command/custom_nodes/command.py index b73f06ce..2ff7ae4b 100644 --- a/comfy_cli/command/custom_nodes/command.py +++ b/comfy_cli/command/custom_nodes/command.py @@ -331,7 +331,7 @@ def validate_mode(mode): @tracking.track_command("node") def show( arg: str = typer.Argument( - help="[installed|enabled|not-installed|disabled|all|snapshot|snapshot-list]", + help="[installed|enabled|not-installed|disabled|all|cnr|snapshot|snapshot-list]", autocompletion=show_completer, ), channel: Annotated[ @@ -354,6 +354,7 @@ def show( "not-installed", "disabled", "all", + "cnr", "snapshot", "snapshot-list", ] From edd0e20eca96d73e56395fbbf3607bfebd11fd31 Mon Sep 17 00:00:00 2001 From: "Dr.Lt.Data" Date: Wed, 31 Jul 2024 02:22:58 +0900 Subject: [PATCH 5/5] add command: `comfy node migrate` --- comfy_cli/command/custom_nodes/command.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/comfy_cli/command/custom_nodes/command.py b/comfy_cli/command/custom_nodes/command.py index 2ff7ae4b..f8474432 100644 --- a/comfy_cli/command/custom_nodes/command.py +++ b/comfy_cli/command/custom_nodes/command.py @@ -666,6 +666,15 @@ def show_versions( ) +@app.command( + "migrate", + help="Changes the old-style custom node installation to the new-style custom node installation.", +) +@tracking.track_command("node") +def migration(): + execute_cm_cli(["migrate"]) + + @app.command( "install-deps", help="Install dependencies from dependencies file(.json) or workflow(.png/.json)",