Skip to content

Commit d50e501

Browse files
authored
fix node/npm/pnpm detection (#316)
1 parent 69c5b5f commit d50e501

File tree

1 file changed

+80
-54
lines changed

1 file changed

+80
-54
lines changed

comfy_cli/command/install.py

Lines changed: 80 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -637,76 +637,102 @@ def find_pr_by_branch(repo_owner: str, repo_name: str, username: str, branch: st
637637
def verify_node_tools() -> bool:
638638
"""Verify that Node.js, npm, and pnpm are available for frontend building"""
639639
try:
640-
# Check Node.js
641640
node_result = subprocess.run(["node", "--version"], capture_output=True, text=True, check=False)
642-
if node_result.returncode != 0:
643-
rprint("[bold red]Node.js is not installed.[/bold red]")
644-
rprint("[yellow]To use --frontend-pr, please install Node.js first:[/yellow]")
645-
rprint(" • Download from: https://nodejs.org/")
646-
rprint(" • Or use a package manager:")
647-
rprint(" - macOS: brew install node")
648-
rprint(" - Ubuntu/Debian: sudo apt install nodejs npm")
649-
rprint(" - Windows: winget install OpenJS.NodeJS")
650-
return False
651-
652-
node_version = node_result.stdout.strip()
641+
except FileNotFoundError:
642+
rprint("[bold red]Node.js is not installed or not found in PATH.[/bold red]")
643+
rprint("[yellow]To use --frontend-pr, please install Node.js first:[/yellow]")
644+
rprint(" • Download from: https://nodejs.org/")
645+
rprint(" • Or use a package manager:")
646+
rprint(" - macOS: brew install node")
647+
rprint(" - Ubuntu/Debian: sudo apt install nodejs npm")
648+
rprint(" - Windows: winget install OpenJS.NodeJS")
649+
return False
650+
651+
if node_result.returncode != 0:
652+
rprint("[bold red]Node.js is not installed or not working correctly.[/bold red]")
653+
rprint("[yellow]To use --frontend-pr, please install Node.js first:[/yellow]")
654+
rprint(" • Download from: https://nodejs.org/")
655+
rprint(" • Or use a package manager:")
656+
rprint(" - macOS: brew install node")
657+
rprint(" - Ubuntu/Debian: sudo apt install nodejs npm")
658+
rprint(" - Windows: winget install OpenJS.NodeJS")
659+
return False
660+
661+
node_version = (node_result.stdout or node_result.stderr or "").strip()
662+
if node_version:
653663
rprint(f"[green]Found Node.js {node_version}[/green]")
664+
else:
665+
rprint("[green]Found Node.js[/green]")
654666

655-
# Check npm (needed for pnpm installation)
667+
try:
656668
npm_result = subprocess.run(["npm", "--version"], capture_output=True, text=True, check=False)
657-
if npm_result.returncode != 0:
658-
rprint("[bold red]npm is not installed.[/bold red]")
659-
rprint("[yellow]npm usually comes with Node.js. Try reinstalling Node.js.[/yellow]")
660-
return False
669+
except FileNotFoundError:
670+
rprint("[bold red]npm is not installed or not found in PATH.[/bold red]")
671+
rprint("[yellow]npm usually comes with Node.js. Try reinstalling Node.js.[/yellow]")
672+
return False
661673

662-
npm_version = npm_result.stdout.strip()
674+
if npm_result.returncode != 0:
675+
rprint("[bold red]npm is not installed or not working correctly.[/bold red]")
676+
rprint("[yellow]npm usually comes with Node.js. Try reinstalling Node.js.[/yellow]")
677+
return False
678+
679+
npm_version = npm_result.stdout.strip()
680+
if npm_version:
663681
rprint(f"[green]Found npm {npm_version}[/green]")
682+
else:
683+
rprint("[green]Found npm[/green]")
664684

665-
# Check pnpm (required for modern frontend)
685+
try:
666686
pnpm_result = subprocess.run(["pnpm", "--version"], capture_output=True, text=True, check=False)
667-
if pnpm_result.returncode != 0:
668-
rprint("[yellow]pnpm is not installed but is required for the modern frontend.[/yellow]")
669-
670-
# Ask user permission to install pnpm
671-
install_pnpm = Confirm.ask(
672-
"[bold yellow]Install pnpm automatically using npm?[/bold yellow] (This will run: npm install -g pnpm)"
673-
)
687+
if pnpm_result.returncode == 0:
688+
pnpm_version = pnpm_result.stdout.strip()
689+
if pnpm_version:
690+
rprint(f"[green]Found pnpm {pnpm_version}[/green]")
691+
else:
692+
rprint("[green]Found pnpm[/green]")
693+
return True
694+
except FileNotFoundError:
695+
pass
674696

675-
if not install_pnpm:
676-
rprint("[bold red]Cannot build frontend without pnpm.[/bold red]")
677-
rprint("[yellow]To install manually:[/yellow]")
678-
rprint(" npm install -g pnpm")
679-
return False
697+
rprint("[yellow]pnpm is not installed but is required for the modern frontend.[/yellow]")
680698

681-
# Install pnpm
682-
rprint("[yellow]Installing pnpm...[/yellow]")
683-
install_result = subprocess.run(
684-
["npm", "install", "-g", "pnpm"], capture_output=True, text=True, check=False
685-
)
699+
install_pnpm = Confirm.ask(
700+
"[bold yellow]Install pnpm automatically using npm?[/bold yellow] (This will run: npm install -g pnpm)"
701+
)
702+
if not install_pnpm:
703+
rprint("[bold red]Cannot build frontend without pnpm.[/bold red]")
704+
rprint("[yellow]To install manually:[/yellow]")
705+
rprint(" npm install -g pnpm")
706+
return False
686707

687-
if install_result.returncode != 0:
688-
rprint("[bold red]Failed to install pnpm automatically.[/bold red]")
689-
rprint(f"[red]Error: {install_result.stderr}[/red]")
690-
rprint("[yellow]Please install manually: npm install -g pnpm[/yellow]")
691-
return False
708+
rprint("[yellow]Installing pnpm...[/yellow]")
709+
install_result = subprocess.run(["npm", "install", "-g", "pnpm"], capture_output=True, text=True, check=False)
692710

693-
# Verify pnpm installation
694-
verify_result = subprocess.run(["pnpm", "--version"], capture_output=True, text=True, check=False)
695-
if verify_result.returncode != 0:
696-
rprint("[bold red]pnpm installation failed to verify.[/bold red]")
697-
return False
711+
if install_result.returncode != 0:
712+
rprint("[bold red]Failed to install pnpm automatically.[/bold red]")
713+
rprint(f"[red]Error: {install_result.stderr}[/red]")
714+
rprint("[yellow]Please install manually: npm install -g pnpm[/yellow]")
715+
return False
698716

699-
pnpm_version = verify_result.stdout.strip()
700-
rprint(f"[green]Successfully installed pnpm {pnpm_version}[/green]")
701-
else:
702-
pnpm_version = pnpm_result.stdout.strip()
703-
rprint(f"[green]Found pnpm {pnpm_version}[/green]")
717+
try:
718+
verify_result = subprocess.run(["pnpm", "--version"], capture_output=True, text=True, check=False)
719+
except FileNotFoundError:
720+
rprint("[bold red]pnpm installation succeeded but pnpm was not found on PATH.[/bold red]")
721+
rprint(
722+
"[yellow]Try restarting your shell or add npm global bin to PATH, then verify with: pnpm --version[/yellow]"
723+
)
724+
return False
704725

705-
return True
706-
except FileNotFoundError as e:
707-
rprint(f"[bold red]Error checking frontend tools: {e}[/bold red]")
726+
if verify_result.returncode != 0:
727+
rprint("[bold red]pnpm installation failed to verify.[/bold red]")
728+
if verify_result.stderr:
729+
rprint(f"[red]{verify_result.stderr.strip()}[/red]")
708730
return False
709731

732+
pnpm_version = verify_result.stdout.strip()
733+
rprint(f"[green]Successfully installed pnpm {pnpm_version}[/green]")
734+
return True
735+
710736

711737
def handle_temporary_frontend_pr(frontend_pr: str) -> Optional[str]:
712738
"""Handle temporary frontend PR for launch - returns path to built frontend"""

0 commit comments

Comments
 (0)