From 289042f896d838e0a7d1fcc12ef2ef9b3a8475e8 Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Wed, 4 Nov 2026 22:12:06 -0800 Subject: [PATCH 1/3] op: setup and venv as a member of a uv workspace, find its checkout from outside In a uv workspace like xx, where openpilot is a member, uv sync uses the workspace's venv: setup then failed at source .venv/bin/activate, after its exact sync had already uninstalled every package openpilot doesn't need from the workspace's venv. Sync without removing packages there, activate the venv uv used, and have op check and activate that venv too. The fallback for running op.sh from outside a checkout still looked two levels up from tools/, a leftover from when op.sh was in openpilot/tools. --- tools/op.sh | 31 ++++++++++++++++++++++++------- tools/setup_dependencies.sh | 10 ++++++++-- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/tools/op.sh b/tools/op.sh index c46b37fc2b19fe..e9170e69977767 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -63,7 +63,7 @@ function op_get_openpilot_dir() { # Fallback to hardcoded directories if not found SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" - for dir in "$(readlink -f "$SCRIPT_DIR/../..")" "$HOME/openpilot" "/data/openpilot"; do + for dir in "$(readlink -f "$SCRIPT_DIR/..")" "$HOME/openpilot" "/data/openpilot"; do if [[ -f "$dir/launch_openpilot.sh" ]]; then OPENPILOT_ROOT="$dir" return 0 @@ -147,9 +147,22 @@ function op_check_os() { fi } +# the venv uv syncs: openpilot's own, or as a member of a uv workspace (like in xx) the workspace's +function op_venv_dir() { + local dir="$OPENPILOT_ROOT" + while [[ ! -d "$OPENPILOT_ROOT/.venv" && "$dir" != / ]]; do + dir="$(dirname "$dir")" + if grep -qs '^\[tool\.uv\.workspace\]' "$dir/pyproject.toml"; then + echo "$dir/.venv" + return + fi + done + echo "$OPENPILOT_ROOT/.venv" +} + function op_check_venv() { echo "Checking for venv..." - if [[ -f "$OPENPILOT_ROOT/.venv/bin/activate" ]]; then + if [[ -f "$(op_venv_dir)/bin/activate" ]]; then echo -e " ↳ [${GREEN}✔${NC}] venv detected." else echo -e " ↳ [${RED}✗${NC}] Can't activate venv in '$OPENPILOT_ROOT'. Assuming global env!" @@ -237,21 +250,25 @@ function op_auth() { } function op_activate_venv() { + local venv + venv="$(op_venv_dir)" # bash 3.2 can't handle this without the 'set +e' set +e - source "$OPENPILOT_ROOT/.venv/bin/activate" &> /dev/null || true + source "$venv/bin/activate" &> /dev/null || true set -e # persist venv on PATH across GitHub Actions steps if [ -n "$GITHUB_PATH" ]; then - echo "$OPENPILOT_ROOT/.venv/bin" >> "$GITHUB_PATH" + echo "$venv/bin" >> "$GITHUB_PATH" fi } function op_venv() { op_before_cmd - if [[ ! -f "$OPENPILOT_ROOT/.venv/bin/activate" ]]; then + local venv + venv="$(op_venv_dir)" + if [[ ! -f "$venv/bin/activate" ]]; then echo -e "No venv found in '$OPENPILOT_ROOT'" return 1 fi @@ -259,10 +276,10 @@ function op_venv() { case $SHELL_NAME in "zsh") ZSHRC_DIR=$(mktemp -d 2>/dev/null || mktemp -d -t 'tmp_zsh') - echo "source \"$RC_FILE\"; source \"$OPENPILOT_ROOT/.venv/bin/activate\"" >> "$ZSHRC_DIR/.zshrc" + echo "source \"$RC_FILE\"; source \"$venv/bin/activate\"" >> "$ZSHRC_DIR/.zshrc" ZDOTDIR=$ZSHRC_DIR zsh ;; *) - bash --rcfile <(echo "source \"$RC_FILE\"; source \"$OPENPILOT_ROOT/.venv/bin/activate\"") ;; + bash --rcfile <(echo "source \"$RC_FILE\"; source \"$venv/bin/activate\"") ;; esac } diff --git a/tools/setup_dependencies.sh b/tools/setup_dependencies.sh index 6f023f7b53d529..bdb957c1706e15 100755 --- a/tools/setup_dependencies.sh +++ b/tools/setup_dependencies.sh @@ -123,8 +123,14 @@ function install_python_deps() { uv self update || true echo "installing python packages..." - uv sync --frozen --all-extras - source .venv/bin/activate + # as a member of a uv workspace (like in xx), the venv is the workspace's: only add to it + VENV="$(uv run --no-sync python -c 'import sys; print(sys.prefix)')" + if [[ "$VENV" -ef .venv ]]; then + uv sync --frozen --all-extras + else + uv sync --frozen --all-extras --inexact + fi + source "$VENV/bin/activate" } # --- Main --- From 45da863d3dcf01dd3ae2f9cf2b1aa7d900fb20db Mon Sep 17 00:00:00 2001 From: Bruce Wayne Date: Wed, 4 Nov 2026 22:34:45 -0800 Subject: [PATCH 2/3] Sync openpilot's own venv instead of finding the workspace's UV_PROJECT_ENVIRONMENT keeps setup on openpilot's .venv also as a member of a uv workspace, so op's .venv assumptions hold and the workspace's venv is never touched. For a standalone checkout that's uv's default. --- tools/op.sh | 29 ++++++----------------------- tools/setup_dependencies.sh | 11 +++-------- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/tools/op.sh b/tools/op.sh index e9170e69977767..f0691e10d1e06f 100755 --- a/tools/op.sh +++ b/tools/op.sh @@ -147,22 +147,9 @@ function op_check_os() { fi } -# the venv uv syncs: openpilot's own, or as a member of a uv workspace (like in xx) the workspace's -function op_venv_dir() { - local dir="$OPENPILOT_ROOT" - while [[ ! -d "$OPENPILOT_ROOT/.venv" && "$dir" != / ]]; do - dir="$(dirname "$dir")" - if grep -qs '^\[tool\.uv\.workspace\]' "$dir/pyproject.toml"; then - echo "$dir/.venv" - return - fi - done - echo "$OPENPILOT_ROOT/.venv" -} - function op_check_venv() { echo "Checking for venv..." - if [[ -f "$(op_venv_dir)/bin/activate" ]]; then + if [[ -f "$OPENPILOT_ROOT/.venv/bin/activate" ]]; then echo -e " ↳ [${GREEN}✔${NC}] venv detected." else echo -e " ↳ [${RED}✗${NC}] Can't activate venv in '$OPENPILOT_ROOT'. Assuming global env!" @@ -250,25 +237,21 @@ function op_auth() { } function op_activate_venv() { - local venv - venv="$(op_venv_dir)" # bash 3.2 can't handle this without the 'set +e' set +e - source "$venv/bin/activate" &> /dev/null || true + source "$OPENPILOT_ROOT/.venv/bin/activate" &> /dev/null || true set -e # persist venv on PATH across GitHub Actions steps if [ -n "$GITHUB_PATH" ]; then - echo "$venv/bin" >> "$GITHUB_PATH" + echo "$OPENPILOT_ROOT/.venv/bin" >> "$GITHUB_PATH" fi } function op_venv() { op_before_cmd - local venv - venv="$(op_venv_dir)" - if [[ ! -f "$venv/bin/activate" ]]; then + if [[ ! -f "$OPENPILOT_ROOT/.venv/bin/activate" ]]; then echo -e "No venv found in '$OPENPILOT_ROOT'" return 1 fi @@ -276,10 +259,10 @@ function op_venv() { case $SHELL_NAME in "zsh") ZSHRC_DIR=$(mktemp -d 2>/dev/null || mktemp -d -t 'tmp_zsh') - echo "source \"$RC_FILE\"; source \"$venv/bin/activate\"" >> "$ZSHRC_DIR/.zshrc" + echo "source \"$RC_FILE\"; source \"$OPENPILOT_ROOT/.venv/bin/activate\"" >> "$ZSHRC_DIR/.zshrc" ZDOTDIR=$ZSHRC_DIR zsh ;; *) - bash --rcfile <(echo "source \"$RC_FILE\"; source \"$venv/bin/activate\"") ;; + bash --rcfile <(echo "source \"$RC_FILE\"; source \"$OPENPILOT_ROOT/.venv/bin/activate\"") ;; esac } diff --git a/tools/setup_dependencies.sh b/tools/setup_dependencies.sh index bdb957c1706e15..4bead10c16a8a8 100755 --- a/tools/setup_dependencies.sh +++ b/tools/setup_dependencies.sh @@ -123,14 +123,9 @@ function install_python_deps() { uv self update || true echo "installing python packages..." - # as a member of a uv workspace (like in xx), the venv is the workspace's: only add to it - VENV="$(uv run --no-sync python -c 'import sys; print(sys.prefix)')" - if [[ "$VENV" -ef .venv ]]; then - uv sync --frozen --all-extras - else - uv sync --frozen --all-extras --inexact - fi - source "$VENV/bin/activate" + # openpilot's own venv, also as a uv workspace member (like in xx), where uv would strip the workspace's venv + UV_PROJECT_ENVIRONMENT="$ROOT/.venv" uv sync --frozen --all-extras + source .venv/bin/activate } # --- Main --- From 9d257a210982f04aacdbdeed12b4aec52273263a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Sch=C3=A4fer?= Date: Fri, 6 Nov 2026 09:29:05 -0800 Subject: [PATCH 3/3] Update setup_dependencies.sh --- tools/setup_dependencies.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/setup_dependencies.sh b/tools/setup_dependencies.sh index 4bead10c16a8a8..1b8a597dcdd943 100755 --- a/tools/setup_dependencies.sh +++ b/tools/setup_dependencies.sh @@ -123,7 +123,6 @@ function install_python_deps() { uv self update || true echo "installing python packages..." - # openpilot's own venv, also as a uv workspace member (like in xx), where uv would strip the workspace's venv UV_PROJECT_ENVIRONMENT="$ROOT/.venv" uv sync --frozen --all-extras source .venv/bin/activate }