fix: resolve nvm when not in path
This commit is contained in:
parent
5ee5ae294a
commit
5fe6a17cfd
3 changed files with 101 additions and 41 deletions
|
|
@ -11,6 +11,24 @@ from cognee.shared.logging_utils import get_logger
|
||||||
logger = get_logger()
|
logger = get_logger()
|
||||||
|
|
||||||
|
|
||||||
|
def get_nvm_dir() -> Path:
|
||||||
|
"""
|
||||||
|
Get the nvm directory path following standard nvm installation logic.
|
||||||
|
Uses XDG_CONFIG_HOME if set, otherwise falls back to ~/.nvm.
|
||||||
|
"""
|
||||||
|
xdg_config_home = os.environ.get("XDG_CONFIG_HOME")
|
||||||
|
if xdg_config_home:
|
||||||
|
return Path(xdg_config_home) / "nvm"
|
||||||
|
return Path.home() / ".nvm"
|
||||||
|
|
||||||
|
|
||||||
|
def get_nvm_sh_path() -> Path:
|
||||||
|
"""
|
||||||
|
Get the path to nvm.sh following standard nvm installation logic.
|
||||||
|
"""
|
||||||
|
return get_nvm_dir() / "nvm.sh"
|
||||||
|
|
||||||
|
|
||||||
def check_nvm_installed() -> bool:
|
def check_nvm_installed() -> bool:
|
||||||
"""
|
"""
|
||||||
Check if nvm (Node Version Manager) is installed.
|
Check if nvm (Node Version Manager) is installed.
|
||||||
|
|
@ -29,14 +47,29 @@ def check_nvm_installed() -> bool:
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# On Unix-like systems, nvm is a shell function, so we need to source it
|
# On Unix-like systems, nvm is a shell function, so we need to source it
|
||||||
|
# First check if nvm.sh exists
|
||||||
|
nvm_path = get_nvm_sh_path()
|
||||||
|
if not nvm_path.exists():
|
||||||
|
logger.debug(f"nvm.sh not found at {nvm_path}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Try to source nvm and check version, capturing errors
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["bash", "-c", "source ~/.nvm/nvm.sh 2>/dev/null && nvm --version"],
|
["bash", "-c", f"source {nvm_path} && nvm --version"],
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=10,
|
timeout=10,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if result.returncode != 0:
|
||||||
|
# Log the error to help diagnose configuration issues
|
||||||
|
if result.stderr:
|
||||||
|
logger.debug(f"nvm check failed: {result.stderr.strip()}")
|
||||||
|
return False
|
||||||
|
|
||||||
return result.returncode == 0
|
return result.returncode == 0
|
||||||
except Exception:
|
except Exception as e:
|
||||||
|
logger.debug(f"Exception checking nvm: {str(e)}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -79,11 +112,13 @@ def install_nvm() -> bool:
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
logger.info("✓ nvm installed successfully")
|
logger.info("✓ nvm installed successfully")
|
||||||
# Source nvm in current shell session
|
# Source nvm in current shell session
|
||||||
nvm_dir = Path.home() / ".nvm"
|
nvm_dir = get_nvm_dir()
|
||||||
if nvm_dir.exists():
|
if nvm_dir.exists():
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logger.warning("nvm installation completed but .nvm directory not found")
|
logger.warning(
|
||||||
|
f"nvm installation completed but nvm directory not found at {nvm_dir}"
|
||||||
|
)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
logger.error(f"nvm installation failed: {result.stderr}")
|
logger.error(f"nvm installation failed: {result.stderr}")
|
||||||
|
|
@ -117,7 +152,12 @@ def install_node_with_nvm() -> bool:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Source nvm and install latest Node.js
|
# Source nvm and install latest Node.js
|
||||||
nvm_source_cmd = "source ~/.nvm/nvm.sh"
|
nvm_path = get_nvm_sh_path()
|
||||||
|
if not nvm_path.exists():
|
||||||
|
logger.error(f"nvm.sh not found at {nvm_path}. nvm may not be properly installed.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
nvm_source_cmd = f"source {nvm_path}"
|
||||||
install_cmd = f"{nvm_source_cmd} && nvm install node"
|
install_cmd = f"{nvm_source_cmd} && nvm install node"
|
||||||
|
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
|
|
@ -141,7 +181,7 @@ def install_node_with_nvm() -> bool:
|
||||||
|
|
||||||
# Add nvm to PATH for current session
|
# Add nvm to PATH for current session
|
||||||
# This ensures node/npm are available in subsequent commands
|
# This ensures node/npm are available in subsequent commands
|
||||||
nvm_dir = Path.home() / ".nvm"
|
nvm_dir = get_nvm_dir()
|
||||||
if nvm_dir.exists():
|
if nvm_dir.exists():
|
||||||
# Update PATH for current process
|
# Update PATH for current process
|
||||||
nvm_bin = nvm_dir / "versions" / "node"
|
nvm_bin = nvm_dir / "versions" / "node"
|
||||||
|
|
@ -178,14 +218,16 @@ def check_node_npm() -> tuple[bool, str]: # (is_available, error_message)
|
||||||
result = subprocess.run(["node", "--version"], capture_output=True, text=True, timeout=10)
|
result = subprocess.run(["node", "--version"], capture_output=True, text=True, timeout=10)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
# If direct command fails, try with nvm sourced (in case nvm is installed but not in PATH)
|
# If direct command fails, try with nvm sourced (in case nvm is installed but not in PATH)
|
||||||
nvm_path = Path.home() / ".nvm" / "nvm.sh"
|
nvm_path = get_nvm_sh_path()
|
||||||
if nvm_path.exists():
|
if nvm_path.exists():
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["bash", "-c", "source ~/.nvm/nvm.sh 2>/dev/null && node --version"],
|
["bash", "-c", f"source {nvm_path} && node --version"],
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=10,
|
timeout=10,
|
||||||
)
|
)
|
||||||
|
if result.returncode != 0 and result.stderr:
|
||||||
|
logger.debug(f"Failed to source nvm or run node: {result.stderr.strip()}")
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
# Node.js is not installed, try to install it
|
# Node.js is not installed, try to install it
|
||||||
logger.info("Node.js is not installed. Attempting to install automatically...")
|
logger.info("Node.js is not installed. Attempting to install automatically...")
|
||||||
|
|
@ -208,22 +250,27 @@ def check_node_npm() -> tuple[bool, str]: # (is_available, error_message)
|
||||||
|
|
||||||
# Verify installation after automatic setup
|
# Verify installation after automatic setup
|
||||||
# Try with nvm sourced first
|
# Try with nvm sourced first
|
||||||
nvm_path = Path.home() / ".nvm" / "nvm.sh"
|
nvm_path = get_nvm_sh_path()
|
||||||
if nvm_path.exists():
|
if nvm_path.exists():
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["bash", "-c", "source ~/.nvm/nvm.sh 2>/dev/null && node --version"],
|
["bash", "-c", f"source {nvm_path} && node --version"],
|
||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
timeout=10,
|
timeout=10,
|
||||||
)
|
)
|
||||||
|
if result.returncode != 0 and result.stderr:
|
||||||
|
logger.debug(
|
||||||
|
f"Failed to verify node after installation: {result.stderr.strip()}"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["node", "--version"], capture_output=True, text=True, timeout=10
|
["node", "--version"], capture_output=True, text=True, timeout=10
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
|
nvm_path = get_nvm_sh_path()
|
||||||
return (
|
return (
|
||||||
False,
|
False,
|
||||||
"Node.js installation completed but node command is not available. Please restart your terminal or source ~/.nvm/nvm.sh",
|
f"Node.js installation completed but node command is not available. Please restart your terminal or source {nvm_path}",
|
||||||
)
|
)
|
||||||
|
|
||||||
node_version = result.stdout.strip()
|
node_version = result.stdout.strip()
|
||||||
|
|
@ -243,12 +290,16 @@ def check_node_npm() -> tuple[bool, str]: # (is_available, error_message)
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
# Try with nvm sourced
|
# Try with nvm sourced
|
||||||
result = subprocess.run(
|
nvm_path = get_nvm_sh_path()
|
||||||
["bash", "-c", "source ~/.nvm/nvm.sh 2>/dev/null && npm --version"],
|
if nvm_path.exists():
|
||||||
capture_output=True,
|
result = subprocess.run(
|
||||||
text=True,
|
["bash", "-c", f"source {nvm_path} && npm --version"],
|
||||||
timeout=10,
|
capture_output=True,
|
||||||
)
|
text=True,
|
||||||
|
timeout=10,
|
||||||
|
)
|
||||||
|
if result.returncode != 0 and result.stderr:
|
||||||
|
logger.debug(f"Failed to source nvm or run npm: {result.stderr.strip()}")
|
||||||
|
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
return False, "npm is not installed or not in PATH"
|
return False, "npm is not installed or not in PATH"
|
||||||
|
|
@ -288,17 +339,21 @@ def check_node_npm() -> tuple[bool, str]: # (is_available, error_message)
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
node_version = result.stdout.strip()
|
node_version = result.stdout.strip()
|
||||||
# Check npm
|
# Check npm
|
||||||
result = subprocess.run(
|
nvm_path = get_nvm_sh_path()
|
||||||
["bash", "-c", "source ~/.nvm/nvm.sh 2>/dev/null && npm --version"],
|
if nvm_path.exists():
|
||||||
capture_output=True,
|
result = subprocess.run(
|
||||||
text=True,
|
["bash", "-c", f"source {nvm_path} && npm --version"],
|
||||||
timeout=10,
|
capture_output=True,
|
||||||
)
|
text=True,
|
||||||
if result.returncode == 0:
|
timeout=10,
|
||||||
npm_version = result.stdout.strip()
|
)
|
||||||
return True, f"Node.js {node_version}, npm {npm_version}"
|
if result.returncode == 0:
|
||||||
except Exception:
|
npm_version = result.stdout.strip()
|
||||||
pass
|
return True, f"Node.js {node_version}, npm {npm_version}"
|
||||||
|
elif result.stderr:
|
||||||
|
logger.debug(f"Failed to source nvm or run npm: {result.stderr.strip()}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.debug(f"Exception retrying node/npm check: {str(e)}")
|
||||||
|
|
||||||
return False, "Node.js/npm not found. Please install Node.js from https://nodejs.org/"
|
return False, "Node.js/npm not found. Please install Node.js from https://nodejs.org/"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from cognee.shared.logging_utils import get_logger
|
from cognee.shared.logging_utils import get_logger
|
||||||
|
from .node_setup import get_nvm_sh_path
|
||||||
|
|
||||||
logger = get_logger()
|
logger = get_logger()
|
||||||
|
|
||||||
|
|
@ -33,13 +34,17 @@ def run_npm_command(cmd: List[str], cwd: Path, timeout: int = 300) -> subprocess
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
)
|
)
|
||||||
# If it fails and nvm might be installed, try with nvm sourced
|
# If it fails and nvm might be installed, try with nvm sourced
|
||||||
if result.returncode != 0 and (Path.home() / ".nvm" / "nvm.sh").exists():
|
if result.returncode != 0:
|
||||||
nvm_cmd = f"source ~/.nvm/nvm.sh 2>/dev/null && {' '.join(cmd)}"
|
nvm_path = get_nvm_sh_path()
|
||||||
result = subprocess.run(
|
if nvm_path.exists():
|
||||||
["bash", "-c", nvm_cmd],
|
nvm_cmd = f"source {nvm_path} && {' '.join(cmd)}"
|
||||||
cwd=cwd,
|
result = subprocess.run(
|
||||||
capture_output=True,
|
["bash", "-c", nvm_cmd],
|
||||||
text=True,
|
cwd=cwd,
|
||||||
timeout=timeout,
|
capture_output=True,
|
||||||
)
|
text=True,
|
||||||
|
timeout=timeout,
|
||||||
|
)
|
||||||
|
if result.returncode != 0 and result.stderr:
|
||||||
|
logger.debug(f"npm command failed with nvm: {result.stderr.strip()}")
|
||||||
return result
|
return result
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import shutil
|
||||||
|
|
||||||
from cognee.shared.logging_utils import get_logger
|
from cognee.shared.logging_utils import get_logger
|
||||||
from cognee.version import get_cognee_version
|
from cognee.version import get_cognee_version
|
||||||
from .node_setup import check_node_npm
|
from .node_setup import check_node_npm, get_nvm_dir, get_nvm_sh_path
|
||||||
from .npm_utils import run_npm_command
|
from .npm_utils import run_npm_command
|
||||||
|
|
||||||
logger = get_logger()
|
logger = get_logger()
|
||||||
|
|
@ -586,10 +586,10 @@ def start_ui(
|
||||||
env["PORT"] = str(port)
|
env["PORT"] = str(port)
|
||||||
|
|
||||||
# If nvm is installed, ensure it's available in the environment
|
# If nvm is installed, ensure it's available in the environment
|
||||||
nvm_path = Path.home() / ".nvm" / "nvm.sh"
|
nvm_path = get_nvm_sh_path()
|
||||||
if platform.system() != "Windows" and nvm_path.exists():
|
if platform.system() != "Windows" and nvm_path.exists():
|
||||||
# Add nvm to PATH for the subprocess
|
# Add nvm to PATH for the subprocess
|
||||||
nvm_dir = Path.home() / ".nvm"
|
nvm_dir = get_nvm_dir()
|
||||||
# Find the latest Node.js version installed via nvm
|
# Find the latest Node.js version installed via nvm
|
||||||
nvm_versions = nvm_dir / "versions" / "node"
|
nvm_versions = nvm_dir / "versions" / "node"
|
||||||
if nvm_versions.exists():
|
if nvm_versions.exists():
|
||||||
|
|
@ -621,7 +621,7 @@ def start_ui(
|
||||||
if nvm_path.exists():
|
if nvm_path.exists():
|
||||||
# Use bash to source nvm and run npm
|
# Use bash to source nvm and run npm
|
||||||
process = subprocess.Popen(
|
process = subprocess.Popen(
|
||||||
["bash", "-c", "source ~/.nvm/nvm.sh 2>/dev/null && npm run dev"],
|
["bash", "-c", f"source {nvm_path} && npm run dev"],
|
||||||
cwd=frontend_path,
|
cwd=frontend_path,
|
||||||
env=env,
|
env=env,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue