Skip to content

Commit

Permalink
fix: potential pip environment mismatch
Browse files Browse the repository at this point in the history
- `pip` -> `sys.executable -m pip`

fix: validate environment when execute commands

remove: install to repo of current dir
- if --workspace is given, specified path should be used
- if --workspace is not given, default path should be used

improve: add --restore option to install command
  • Loading branch information
ltdrdata committed Apr 26, 2024
1 parent 5cfd242 commit 8ba3790
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 32 deletions.
29 changes: 26 additions & 3 deletions comfy_cli/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def main():
init()
app()


def init():
# TODO(yoland): after this
metadata_manager = MetadataManager()
Expand Down Expand Up @@ -58,6 +59,12 @@ def install(
show_default=False,
help="Path to ComfyUI workspace")
] = "~/comfy",
restore: Annotated[
bool,
lambda: typer.Option(
default=False,
help="Restore dependencies for installed ComfyUI if not installed")
] = False,
skip_manager: Annotated[
bool,
lambda: typer.Option(
Expand Down Expand Up @@ -87,15 +94,15 @@ def install(
if amd:
torch_mode = 'amd'

install_inner.execute(url, manager_url, workspace, skip_manager, torch_mode)
install_inner.execute(url, manager_url, workspace, restore, skip_manager, torch_mode)


def update(self):
_env_checker = EnvChecker()
print(f"Updating ComfyUI in {self.workspace}...")
os.chdir(self.workspace)
subprocess.run(["git", "pull"], check=True)
subprocess.run(["pip", "install", "-r", "requirements.txt"], check=True)
subprocess.run([sys.executable, '-m', "pip", "install", "-r", "requirements.txt"], check=True)


@app.command(help="Run workflow file")
Expand All @@ -105,6 +112,12 @@ def run(
run_inner.execute(workflow_file)


def validate_comfyui(_env_checker):
if _env_checker.comfy_repo is None:
print(f"[bold red]If ComfyUI is not installed, this feature cannot be used.[/bold red]")
raise typer.Exit(code=1)


def launch_comfyui(_env_checker, cpu):
# TODO(yoland/data): Disabled config writing for now, checking with @data
# We need to find a viable place to write config file, e.g. standard place
Expand All @@ -114,6 +127,8 @@ def launch_comfyui(_env_checker, cpu):
#_env_checker.config['DEFAULT']['recent_path'] = os.getcwd()
#_env_checker.write_config()

validate_comfyui(_env_checker)

env_path = _env_checker.get_isolated_env()
reboot_path = None

Expand Down Expand Up @@ -149,10 +164,13 @@ def launch(workspace: Annotated[
] = False,
):
_env_checker = EnvChecker()

if workspace is not None:
comfyui_path = os.path.join(workspace, 'ComfyUI')
if os.path.exists(comfyui_path):
os.chdir(comfyui_path)
_env_checker.check() # update env

print(f"\nLaunch ComfyUI from repo: {_env_checker.comfy_repo.working_dir}\n")
launch_comfyui(_env_checker, cpu)
else:
Expand All @@ -165,7 +183,10 @@ def launch(workspace: Annotated[
elif _env_checker.config['DEFAULT'].get('recent_path') is not None:
comfy_path = _env_checker.config['DEFAULT'].get('recent_path')
print(f"\nLaunch ComfyUI from recent repo: {comfy_path}\n")

os.chdir(comfy_path)
_env_checker.check() # update env

launch_comfyui(_env_checker, cpu)
else:
print("\nComfyUI is not available.\nTo install ComfyUI, you can run:\n\n\tcomfy install\n\n", file=sys.stderr)
Expand All @@ -182,10 +203,12 @@ def env():
def nodes():
print("\n[bold red] No such command, did you mean 'comfy node' instead?[/bold red]\n")


@app.command(hidden=True)
def models():
print("\n[bold red] No such command, did you mean 'comfy model' instead?[/bold red]\n")


app.add_typer(models_command.app, name="model", help="Manage models.")
app.add_typer(custom_nodes.app, name="node", help="Manage custom nodes.")
app.add_typer(custom_nodes.manager_app, name="manager", help="Manager ComfyUI-Manager.")
app.add_typer(custom_nodes.manager_app, name="manager", help="Manager ComfyUI-Manager.")
17 changes: 17 additions & 0 deletions comfy_cli/command/custom_nodes/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import subprocess
import sys
from rich import print

app = typer.Typer()
manager_app = typer.Typer()
Expand All @@ -18,6 +19,8 @@ def execute_cm_cli(args, channel=None, mode=None, workspace=None):
_env_checker = EnvChecker()
_env_checker.write_config()

validate_comfyui_manager(_env_checker)

if workspace is not None:
comfyui_path = os.path.join(workspace, 'ComfyUI')
elif _env_checker.comfy_repo is not None:
Expand Down Expand Up @@ -53,6 +56,20 @@ def execute_cm_cli(args, channel=None, mode=None, workspace=None):
subprocess.run(cmd, env=new_env)


def validate_comfyui_manager(_env_checker):
manager_path = _env_checker.get_comfyui_manager_path()

if manager_path is None:
print(f"[bold red]If ComfyUI is not installed, this feature cannot be used.[/bold red]")
raise typer.Exit(code=1)
elif not os.path.exists(manager_path):
print(f"[bold red]If ComfyUI-Manager is not installed, this feature cannot be used.[/bold red] \\[{manager_path}]")
raise typer.Exit(code=1)
elif not os.path.exists(os.path.join(manager_path, '.git')):
print(f"[bold red]The ComfyUI-Manager installation is invalid. This feature cannot be used.[/bold red] \\[{manager_path}]")
raise typer.Exit(code=1)


@app.command('save-snapshot', help="Save a snapshot of the current ComfyUI environment")
def save_snapshot():
execute_cm_cli(['save-snapshot'])
Expand Down
73 changes: 45 additions & 28 deletions comfy_cli/command/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,55 @@
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich import print
from comfy_cli import env_checker
import sys


def execute(url: str, manager_url: str, comfy_workspace: str, skip_manager: bool, torch_mode=None, *args, **kwargs):
def install_comfyui_dependencies(repo_dir, torch_mode):
os.chdir(repo_dir)

# install torch
if torch_mode == 'amd':
pip_url = ['--extra-index-url', 'https://download.pytorch.org/whl/rocm5.7']
else:
pip_url = ['--extra-index-url', 'https://download.pytorch.org/whl/cu121']
subprocess.run([sys.executable, '-m', "pip", "install", "torch", "torchvision", "torchaudio"] + pip_url)

# install other requirements
subprocess.run([sys.executable, '-m', "pip", "install", "-r", "requirements.txt"])


# install requirements for manager
def install_manager_dependencies(repo_dir):
os.chdir(os.path.join(repo_dir, 'custom_nodes', 'ComfyUI-Manager'))
subprocess.run([sys.executable, '-m', "pip", "install", "-r", "requirements.txt"])


def execute(url: str, manager_url: str, comfy_workspace: str, restore: bool, skip_manager: bool, torch_mode=None, *args, **kwargs):
print(f"Installing from {url}")

checker = env_checker.EnvChecker()

# install ComfyUI
if checker.currently_in_comfy_repo:
print(f"Already in comfy repo. Skipping installation.")
repo_dir = os.getcwd()
else:
working_dir = os.path.expanduser(comfy_workspace)
repo_dir = os.path.join(working_dir, os.path.basename(url).replace(".git", ""))
working_dir = os.path.expanduser(comfy_workspace)
repo_dir = os.path.join(working_dir, os.path.basename(url).replace(".git", ""))
repo_dir = os.path.abspath(repo_dir)

if os.path.exists(os.path.join(repo_dir, '.git')):
print("ComfyUI is installed already. Skipping installation.")
if os.path.exists(os.path.join(repo_dir, '.git')):
if restore:
install_comfyui_dependencies(repo_dir, torch_mode)
else:
print("\nInstalling ComfyUI..")
os.makedirs(working_dir, exist_ok=True)
print("ComfyUI is installed already. Skipping installation.\nIf you want to restore dependencies, add the '--restore' option.")
else:
print("\nInstalling ComfyUI..")
os.makedirs(working_dir, exist_ok=True)

repo_dir = os.path.join(working_dir, os.path.basename(url).replace(".git", ""))
subprocess.run(["git", "clone", url, repo_dir])
repo_dir = os.path.join(working_dir, os.path.basename(url).replace(".git", ""))
repo_dir = os.path.abspath(repo_dir)
subprocess.run(["git", "clone", url, repo_dir])

os.chdir(repo_dir)
# install torch
if torch_mode == 'amd':
pip_url = ['--extra-index-url', 'https://download.pytorch.org/whl/rocm5.7']
else:
pip_url = ['--extra-index-url', 'https://download.pytorch.org/whl/cu121']
subprocess.run(["pip", "install", "torch", "torchvision", "torchaudio"] + pip_url)
install_comfyui_dependencies(repo_dir, torch_mode)

# install other requirements
subprocess.run(["pip", "install", "-r", "requirements.txt"])
print("")

# install ComfyUI-Manager
if skip_manager:
Expand All @@ -45,17 +60,19 @@ def execute(url: str, manager_url: str, comfy_workspace: str, skip_manager: bool
manager_repo_dir = os.path.join(repo_dir, 'custom_nodes', 'ComfyUI-Manager')

if os.path.exists(manager_repo_dir):
print(f"Directory {manager_repo_dir} already exists. Skipping installation of ComfyUI-Manager.")
if restore:
install_manager_dependencies(repo_dir)
else:
print(f"Directory {manager_repo_dir} already exists. Skipping installation of ComfyUI-Manager.\nIf you want to restore dependencies, add the '--restore' option.")
else:
print("\nInstalling ComfyUI-Manager..")

subprocess.run(["git", "clone", manager_url, manager_repo_dir])
os.chdir(os.path.join(repo_dir, 'custom_nodes', 'ComfyUI-Manager'))
install_manager_dependencies(repo_dir)

os.chdir(repo_dir)

subprocess.run(["pip", "install", "-r", "requirements.txt"])
os.chdir(os.path.join('..', '..'))
print("")

checker.config['DEFAULT']['recent_path'] = repo_dir
checker.write_config()


16 changes: 16 additions & 0 deletions comfy_cli/env_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,22 @@ def __init__(self):
self.config = configparser.ConfigParser()
self.check()

def get_comfyui_manager_path(self):
if self.comfy_repo is None:
return None

# To check more robustly, verify up to the `.git` path.
manager_path = os.path.join(self.comfy_repo.working_dir, 'custom_nodes', 'ComfyUI-Manager')
return manager_path

def is_comfyui_manager_installed(self):
if self.comfy_repo is None:
return False

# To check more robustly, verify up to the `.git` path.
manager_git_path = os.path.join(self.comfy_repo.working_dir, 'custom_nodes', 'ComfyUI-Manager', '.git')
return os.path.exists(manager_git_path)

def is_isolated_env(self):
return self.virtualenv_path or self.conda_env

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "comfy-cli"
license = {file = "LICENSE"}
version = "2024.4.25"
version = "2024.4.26"
requires-python = ">= 3.8"
description = "A CLI tool for installing and using ComfyUI."
readme = "README.md"
Expand Down

0 comments on commit 8ba3790

Please sign in to comment.