#!/bin/bash # ============================================================================ # Make sure .venv exists and has this project installed in it. # # run.sh used to answer a missing venv with a message telling you to type # "uv venv .venv && uv pip install -e '.[dev]'" yourself, and tool/tagger.py # did not even do that -- it failed with ModuleNotFoundError: fastapi. Both # are the same rule broken: a script owns its dependencies. # # Sourced or executed. Idempotent: the common case is two file tests and no # subprocess at all, so entry points can call it unconditionally. # ============================================================================ set -euo pipefail ensure_venv() { local repo_root="$1" local venv="${repo_root}/.venv" local python="${venv}/bin/python" # Already good: the interpreter exists and the project imports from it. if [[ -x "$python" ]] && "$python" -c 'import fastapi, signal_bot' 2>/dev/null; then return 0 fi echo "== setting up ${venv} (one-off)" >&2 if [[ ! -x "$python" ]]; then if command -v uv >/dev/null; then uv venv "$venv" elif ! python3 -m venv "$venv"; then echo "Error: could not create a virtualenv at ${venv}" >&2 echo " python3 -m venv failed; on Arch: sudo pacman -S python" >&2 return 1 fi fi # Editable, so a later git pull updates what the tagger actually runs. if command -v uv >/dev/null; then VIRTUAL_ENV="$venv" uv pip install -e "${repo_root}[dev]" else "$python" -m pip install -e "${repo_root}[dev]" fi } # Executed rather than sourced: do the thing, for callers that are not bash. if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then ensure_venv "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" fi