diff --git a/pyproject.toml b/pyproject.toml index 2b43732d6..3ab29a7e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,7 +23,7 @@ dependencies = [ "numpy>=1.0.0", "msgpack>=1.0.7", "imageio>=2.0.0", - "pyliblzfse>=0.4.1", + "pyliblzfse>=0.4.1; platform_system!='Windows'", "scikit-image>=0.18.0", "scipy>=1.7.3", "tqdm>=4.0.0", diff --git a/src/viser/_client_autobuild.py b/src/viser/_client_autobuild.py index b27ef30f0..84e17ebcc 100644 --- a/src/viser/_client_autobuild.py +++ b/src/viser/_client_autobuild.py @@ -1,3 +1,4 @@ +import os import subprocess import sys from pathlib import Path @@ -57,16 +58,26 @@ def ensure_client_is_built() -> None: # Install nodejs and build if necessary. We assume bash is installed. if build: - env_dir = _install_sandboxed_node() - npx_path = env_dir / "bin" / "npx" + node_bin_dir = _install_sandboxed_node() + npx_path = node_bin_dir / "npx" + + subprocess_env = os.environ.copy() + subprocess_env["NODE_VIRTUAL_ENV"] = str(node_bin_dir.parent) + subprocess_env["PATH"] = ( + str(node_bin_dir) + + (";" if sys.platform == "win32" else ":") + + subprocess_env["PATH"] + ) + subprocess.run( + args=f"{npx_path} --yes yarn install", + env=subprocess_env, + cwd=client_dir, + shell=True, + check=False, + ) subprocess.run( - args=( - "bash -c '" - f"source {env_dir / 'bin' / 'activate'};" - f"{npx_path} yarn install;" - f"{npx_path} yarn run build;" - "'" - ), + args=f"{npx_path} --yes yarn run build", + env=subprocess_env, cwd=client_dir, shell=True, check=False, @@ -75,22 +86,31 @@ def ensure_client_is_built() -> None: def _install_sandboxed_node() -> Path: """Install a sandboxed copy of nodejs using nodeenv, and return a path to the - environment root.""" - env_dir = client_dir / ".nodeenv" - if (env_dir / "bin" / "npx").exists(): + environment's bin directory (`.nodeenv/bin` or `.nodeenv/Scripts`). + + On Windows, the `.nodeenv/bin` does not exist. Instead, executables are + installed to `.nodeenv/Scripts`.""" + + def get_node_bin_dir() -> Path: + env_dir = client_dir / ".nodeenv" + node_bin_dir = env_dir / "bin" + if not node_bin_dir.exists(): + node_bin_dir = env_dir / "Scripts" + return node_bin_dir + + node_bin_dir = get_node_bin_dir() + if (node_bin_dir / "npx").exists(): rich.print("[bold](viser)[/bold] nodejs is set up!") - return env_dir + return node_bin_dir + env_dir = client_dir / ".nodeenv" subprocess.run( [sys.executable, "-m", "nodeenv", "--node=20.4.0", env_dir], check=False ) - subprocess.run( - args=[env_dir / "bin" / "npm", "install", "yarn"], - input="y\n".encode(), - check=False, - ) - assert (env_dir / "bin" / "npx").exists() - return env_dir + + node_bin_dir = get_node_bin_dir() + assert (node_bin_dir / "npx").exists() + return node_bin_dir def _modified_time_recursive(dir: Path) -> float: diff --git a/src/viser/client/src/ControlPanel/ControlPanel.tsx b/src/viser/client/src/ControlPanel/ControlPanel.tsx index b444fc1a3..d6e4a8984 100644 --- a/src/viser/client/src/ControlPanel/ControlPanel.tsx +++ b/src/viser/client/src/ControlPanel/ControlPanel.tsx @@ -1,4 +1,4 @@ -import { useDisclosure, useMediaQuery, useToggle } from "@mantine/hooks"; +import { useDisclosure, useMediaQuery } from "@mantine/hooks"; import GeneratedGuiContainer from "./Generated"; import { ViewerContext } from "../App";