Skip to content

Commit ab4e78a

Browse files
committed
Feat. temporary install script using functions in cm-cli
This should be moved to cm-cli to handle everything there.
1 parent 47a7422 commit ab4e78a

File tree

7 files changed

+160
-9
lines changed

7 files changed

+160
-9
lines changed

comfy_cli/cmdline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def install(
280280
raise typer.Exit(code=1)
281281
if intel_arc is None:
282282
confirm_result = ui.prompt_confirm_action(
283-
"Are you sure you want to try beta install feature on Intel ARC?"
283+
"Are you sure you want to try beta install feature on Intel ARC?", True
284284
)
285285
if not confirm_result:
286286
raise typer.Exit(code=0)

comfy_cli/command/custom_nodes/command.py

Lines changed: 151 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import os
22
import pathlib
3+
import platform
4+
import re
35
import subprocess
46
import sys
57
import 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")
105226
def 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)

comfy_cli/command/install.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ def execute(
157157
):
158158

159159
if not workspace_manager.skip_prompting:
160-
res = ui.prompt_confirm_action(f"Install from {url} to {comfy_path}?")
160+
res = ui.prompt_confirm_action(f"Install from {url} to {comfy_path}?", True)
161161

162162
if not res:
163163
print("Aborting...")

comfy_cli/command/models/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def remove(
309309

310310
# Confirm deletion
311311
if to_delete and ui.prompt_confirm_action(
312-
"Are you sure you want to delete the selected files?"
312+
"Are you sure you want to delete the selected files?", False
313313
):
314314
for model_path in to_delete:
315315
model_path.unlink()

comfy_cli/file_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def parse_json(input_data):
4141
elif status_code == 403:
4242
return f"Forbidden url ({status_code}), you might need to manually log into browser to download one"
4343
elif status_code == 404:
44-
return "Sorry, your model is in another castle (404)"
44+
return "Sorry, your file is in another castle (404)"
4545
return f"Unknown error occurred (status code: {status_code})"
4646

4747

@@ -69,7 +69,7 @@ def download_file(
6969
f.write(data)
7070
except KeyboardInterrupt:
7171
delete_eh = ui.prompt_confirm_action(
72-
"Download interrupted, cleanup files?"
72+
"Download interrupted, cleanup files?", True
7373
)
7474
if delete_eh:
7575
local_filepath.unlink()

comfy_cli/tracking.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ def prompt_tracking_consent(skip_prompt: bool = False, default_value: bool = Fal
101101
init_tracking(default_value)
102102
else:
103103
enable_tracking = ui.prompt_confirm_action(
104-
"Do you agree to enable tracking to improve the application?"
104+
"Do you agree to enable tracking to improve the application?", True
105105
)
106106
init_tracking(enable_tracking)
107107

comfy_cli/ui.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def prompt_multi_select(prompt: str, choices: List[str]) -> List[str]:
110110
return selections if selections else []
111111

112112

113-
def prompt_confirm_action(prompt: str) -> bool:
113+
def prompt_confirm_action(prompt: str, default: bool) -> bool:
114114
"""
115115
Prompts the user for confirmation before proceeding with an action.
116116
@@ -120,6 +120,8 @@ def prompt_confirm_action(prompt: str) -> bool:
120120
Returns:
121121
bool: True if the user confirms, False otherwise.
122122
"""
123+
if workspace_manager.skip_prompting:
124+
return default
123125

124126
return typer.confirm(prompt)
125127

0 commit comments

Comments
 (0)