11import os
22import pathlib
3+ import platform
4+ import re
35import subprocess
46import sys
57import uuid
@@ -100,6 +102,125 @@ def validate_comfyui_manager(_env_checker):
100102 raise typer .Exit (code = 1 )
101103
102104
105+ def run_script (cmd , cwd = "." ):
106+ if len (cmd ) > 0 and cmd [0 ].startswith ("#" ):
107+ print (f"[ComfyUI-Manager] Unexpected behavior: `{ cmd } `" )
108+ return 0
109+
110+ subprocess .check_call (cmd , cwd = cwd )
111+
112+ return 0
113+
114+
115+ pip_map = None
116+
117+
118+ def get_installed_packages ():
119+ global pip_map
120+
121+ if pip_map is None :
122+ try :
123+ result = subprocess .check_output (
124+ [sys .executable , "-m" , "pip" , "list" ], universal_newlines = True
125+ )
126+
127+ pip_map = {}
128+ for line in result .split ("\n " ):
129+ x = line .strip ()
130+ if x :
131+ y = line .split ()
132+ if y [0 ] == "Package" or y [0 ].startswith ("-" ):
133+ continue
134+
135+ pip_map [y [0 ]] = y [1 ]
136+ except subprocess .CalledProcessError as e :
137+ print (
138+ f"[ComfyUI-Manager] Failed to retrieve the information of installed pip packages."
139+ )
140+ return set ()
141+
142+ return pip_map
143+
144+
145+ def try_install_script (repo_path , install_cmd , instant_execution = False ):
146+ startup_script_path = os .path .join (
147+ workspace_manager .workspace_path , "startup-scripts"
148+ )
149+ if not instant_execution and (
150+ (len (install_cmd ) > 0 and install_cmd [0 ].startswith ("#" ))
151+ or (
152+ platform .system ()
153+ == "Windows"
154+ # From Yoland: disable commit compare
155+ # and comfy_ui_commit_datetime.date()
156+ # >= comfy_ui_required_commit_datetime.date()
157+ )
158+ ):
159+ if not os .path .exists (startup_script_path ):
160+ os .makedirs (startup_script_path )
161+
162+ script_path = os .path .join (startup_script_path , "install-scripts.txt" )
163+ with open (script_path , "a" , encoding = "utf-8" ) as file :
164+ obj = [repo_path ] + install_cmd
165+ file .write (f"{ obj } \n " )
166+
167+ return True
168+ else :
169+ # From Yoland: Disable blacklisting
170+ # if len(install_cmd) == 5 and install_cmd[2:4] == ['pip', 'install']:
171+ # if is_blacklisted(install_cmd[4]):
172+ # print(f"[ComfyUI-Manager] skip black listed pip installation: '{install_cmd[4]}'")
173+ # return True
174+
175+ print (f"\n ## ComfyUI-Manager: EXECUTE => { install_cmd } " )
176+ code = run_script (install_cmd , cwd = repo_path )
177+
178+ # From Yoland: Disable warning
179+ # if platform.system() != "Windows":
180+ # try:
181+ # if comfy_ui_commit_datetime.date() < comfy_ui_required_commit_datetime.date():
182+ # print("\n\n###################################################################")
183+ # print(f"[WARN] ComfyUI-Manager: Your ComfyUI version ({comfy_ui_revision})[{comfy_ui_commit_datetime.date()}] is too old. Please update to the latest version.")
184+ # print(f"[WARN] The extension installation feature may not work properly in the current installed ComfyUI version on Windows environment.")
185+ # print("###################################################################\n\n")
186+ # except:
187+ # pass
188+
189+ if code != 0 :
190+ print ("install script failed" )
191+ return False
192+
193+
194+ def execute_install_script (repo_path ):
195+ install_script_path = os .path .join (repo_path , "install.py" )
196+ requirements_path = os .path .join (repo_path , "requirements.txt" )
197+
198+ # From Yoland: disable lazy mode
199+ # if lazy_mode:
200+ # install_cmd = ["#LAZY-INSTALL-SCRIPT", sys.executable]
201+ # try_install_script(repo_path, install_cmd)
202+ # else:
203+
204+ if os .path .exists (requirements_path ):
205+ # import pdb
206+ # pdb.set_trace()
207+ print ("Install: pip packages" )
208+ with open (requirements_path , "r" , encoding = "utf-8" ) as requirements_file :
209+ for line in requirements_file :
210+ # From Yoland: disable pip override
211+ # package_name = remap_pip_package(line.strip())
212+ package_name = line .strip ()
213+ if package_name and not package_name .startswith ("#" ):
214+ install_cmd = [sys .executable , "-m" , "pip" , "install" , package_name ]
215+ if package_name .strip () != "" :
216+ try_install_script (repo_path , install_cmd )
217+
218+ if os .path .exists (install_script_path ):
219+ print ("Install: install script" )
220+ install_cmd = [sys .executable , "install.py" ]
221+ try_install_script (repo_path , install_cmd )
222+
223+
103224@app .command ("save-snapshot" , help = "Save a snapshot of the current ComfyUI environment" )
104225@tracking .track_command ("node" )
105226def save_snapshot (
@@ -745,9 +866,23 @@ def display_all_nodes():
745866 )
746867
747868
748- @app .command ("registry-install" , help = "Install a node from the registry" , hidden = True )
869+ @app .command (
870+ "registry-install" ,
871+ help = "Install a node from the registry" ,
872+ hidden = True ,
873+ )
749874@tracking .track_command ("node" )
750- def registry_install (node_id : str , version : Optional [str ] = None ):
875+ def registry_install (
876+ node_id : str ,
877+ version : Optional [str ] = None ,
878+ force_download : Annotated [
879+ bool ,
880+ typer .Option (
881+ "--force-download" ,
882+ help = "Force download the node even if it is already installed" ,
883+ ),
884+ ] = False ,
885+ ):
751886 """
752887 Install a node from the registry.
753888 Args:
@@ -778,6 +913,17 @@ def registry_install(node_id: str, version: Optional[str] = None):
778913 # Download the node archive
779914 custom_nodes_path = pathlib .Path (workspace_manager .workspace_path ) / "custom_nodes"
780915 node_specific_path = custom_nodes_path / node_id # Subdirectory for the node
916+ if node_specific_path .exists ():
917+ print (
918+ f"[bold red] The node { node_id } already exists in the workspace. This migit delete any model files in the node.[/bold red]"
919+ )
920+
921+ confirm = ui .prompt_confirm_action (
922+ "Do you want to overwrite it?" ,
923+ force_download ,
924+ )
925+ if not confirm :
926+ return
781927 node_specific_path .mkdir (
782928 parents = True , exist_ok = True
783929 ) # Create the directory if it doesn't exist
@@ -794,6 +940,9 @@ def registry_install(node_id: str, version: Optional[str] = None):
794940 )
795941 extract_package_as_zip (local_filename , node_specific_path )
796942
943+ # TODO: temoporary solution to run requirement.txt and install script
944+ execute_install_script (node_specific_path )
945+
797946 # Delete the downloaded archive
798947 logging .debug (f"Deleting the downloaded archive { local_filename } " )
799948 os .remove (local_filename )
0 commit comments