From c262c1a5c255304a8823973bc416b74cb18c364d Mon Sep 17 00:00:00 2001 From: torlando-tech Date: Thu, 18 Dec 2025 15:44:34 -0500 Subject: [PATCH] feat(install): Add uv tool installation support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Detect and handle RNS installations via `uv tool install rns`: - Add uv detection when python3 can import RNS (path contains /uv/tools/) - Add shebang-based detection when system python3 differs from tool's python - Install dependencies using `uv pip install --python` - Handle uv Python path for setcap Bluetooth permissions This fixes "Could not determine installation mode" errors for users who install Reticulum with uv instead of pip/pipx. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- install.sh | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 4 deletions(-) diff --git a/install.sh b/install.sh index 84bc9d6..ba7ca78 100755 --- a/install.sh +++ b/install.sh @@ -254,8 +254,24 @@ if command -v rnsd &> /dev/null; then if [ -n "$RNS_LOCATION" ]; then print_success "Found RNS Python package at: $RNS_LOCATION" - # Check if it's a pipx installation (most specific, check first) - if [[ "$RNS_LOCATION" == *"/pipx/venvs/"* ]]; then + # Check if it's a uv tool installation (most specific, check first) + if [[ "$RNS_LOCATION" == *"/uv/tools/"* ]]; then + print_info "RNS appears to be installed via uv tool" + + # Extract uv tools path (e.g., ~/.local/share/uv/tools/rns) + UV_RNS_PATH=$(echo "$RNS_LOCATION" | grep -oP '^.*?/uv/tools/rns') + RNS_PYTHON="$UV_RNS_PATH/bin/python" + + if [ ! -f "$RNS_PYTHON" ]; then + print_error "uv Python not found at: $RNS_PYTHON" + exit 1 + fi + + INSTALL_MODE="uv" + print_success "Detected uv tool installation at: $UV_RNS_PATH" + + # Check if it's a pipx installation + elif [[ "$RNS_LOCATION" == *"/pipx/venvs/"* ]]; then print_info "RNS appears to be installed via pipx" # Verify pipx command is available @@ -308,6 +324,55 @@ if command -v rnsd &> /dev/null; then INSTALL_MODE="system" RNS_PYTHON="python3" fi + else + # rnsd exists but python3 can't import RNS + # This happens with uv/pipx when system python3 differs from tool's python + print_warning "rnsd found but RNS not importable by system python3" + print_info "Checking rnsd shebang for isolated environment..." + + RNSD_PATH=$(which rnsd) + RNSD_SHEBANG=$(head -1 "$RNSD_PATH" 2>/dev/null) + + if [[ "$RNSD_SHEBANG" == *"/uv/tools/rns/"* ]]; then + # uv tool installation + print_info "RNS appears to be installed via uv tool" + UV_RNS_PATH=$(echo "$RNSD_SHEBANG" | grep -oP '^#!\K.*?/uv/tools/rns' || echo "$HOME/.local/share/uv/tools/rns") + RNS_PYTHON="$UV_RNS_PATH/bin/python" + + if [ -f "$RNS_PYTHON" ]; then + INSTALL_MODE="uv" + print_success "Detected uv tool installation at: $UV_RNS_PATH" + else + print_error "uv Python not found at: $RNS_PYTHON" + exit 1 + fi + + elif [[ "$RNSD_SHEBANG" == *"/pipx/venvs/rns/"* ]]; then + # pipx installation + print_info "RNS appears to be installed via pipx" + PIPX_RNS_PATH=$(echo "$RNSD_SHEBANG" | grep -oP '^#!\K.*?/pipx/venvs/rns' || echo "$HOME/.local/pipx/venvs/rns") + RNS_PYTHON="$PIPX_RNS_PATH/bin/python3" + + if [ -f "$RNS_PYTHON" ]; then + INSTALL_MODE="pipx" + print_success "Detected pipx installation at: $PIPX_RNS_PATH" + else + print_error "pipx Python not found at: $RNS_PYTHON" + exit 1 + fi + + else + print_error "Could not determine RNS installation type from rnsd shebang" + print_info "Shebang: $RNSD_SHEBANG" + echo + echo "Please ensure RNS is properly installed and accessible to python3:" + echo " pip install rns" + echo " # or" + echo " uv tool install rns" + echo " # or" + echo " pipx install rns" + exit 1 + fi fi else print_warning "Reticulum (rnsd) not found" @@ -399,7 +464,42 @@ if [[ "$ARCH" == "armhf" ]] || [[ "$(uname -m)" =~ ^(armv6l|armv7l)$ ]]; then fi fi -if [ "$INSTALL_MODE" = "pipx" ]; then +if [ "$INSTALL_MODE" = "uv" ]; then + print_info "Installing dependencies into uv tool environment..." + echo + + # uv tool environments are at ~/.local/share/uv/tools/ + # We install directly using the tool's pip + DEPS=("bleak==1.1.1" "bluezero" "dbus-python") + + for dep in "${DEPS[@]}"; do + print_info "Installing $dep into RNS environment..." + + if uv pip install --python "$RNS_PYTHON" "$dep" 2>/dev/null; then + print_success "Installed $dep" + else + print_error "Failed to install $dep" + echo + echo "Try manually:" + echo " uv pip install --python $RNS_PYTHON $dep" + exit 1 + fi + echo + done + + # Verify all modules can be imported + print_info "Verifying dependencies..." + if "$RNS_PYTHON" -c "import bleak, bluezero, dbus" 2>/dev/null; then + print_success "All dependencies verified and working" + else + print_error "Dependency verification failed" + echo + echo "Test imports manually:" + echo " $RNS_PYTHON -c 'import bleak, bluezero, dbus'" + exit 1 + fi + +elif [ "$INSTALL_MODE" = "pipx" ]; then print_info "Installing dependencies via pipx inject..." print_warning "dbus-python will be compiled from source (may take 2-3 minutes)" echo @@ -567,7 +667,10 @@ else print_info "Root user already has all required Bluetooth permissions" elif command -v setcap &> /dev/null; then # Determine correct Python path based on installation mode - if [ "$INSTALL_MODE" = "pipx" ]; then + if [ "$INSTALL_MODE" = "uv" ]; then + PYTHON_PATH="$UV_RNS_PATH/bin/python" + print_info "Using uv Python: $PYTHON_PATH" + elif [ "$INSTALL_MODE" = "pipx" ]; then PYTHON_PATH="$PIPX_RNS_PATH/bin/python3" print_info "Using pipx Python: $PYTHON_PATH" elif [ "$INSTALL_MODE" = "venv" ]; then