Files
2026-06-12 19:01:12 +02:00

175 lines
5.4 KiB
Bash
Executable File

#!/bin/bash
# 1. Define your strings
BASE_FOLDER="/sf/bernina/applications/python"
ENVS_DIR="${BASE_FOLDER}/environments"
DEFAULT_ENV="bpy-default"
ENV_NAME=$1
# 2. Gather available environments into an array using the -L fix
ENVS=()
if [ -d "$ENVS_DIR" ]; then
while read -r bin_dir; do
name=$(basename "$(dirname "$bin_dir")")
ENVS+=("$name")
done < <(find -L "$ENVS_DIR" -maxdepth 2 -mindepth 2 -type d -name "bin" 2>/dev/null | sort)
fi
# 3. Interactive selection logic if no argument is passed (or if invalid)
VALID_ENV=false
if [ -n "$ENV_NAME" ]; then
for e in "${ENVS[@]}"; do
if [ "$e" == "$ENV_NAME" ]; then
VALID_ENV=true
break
fi
done
fi
if [ -z "$ENV_NAME" ] || [ "$VALID_ENV" = false ]; then
if [ -n "$ENV_NAME" ]; then
echo "Error: Could not find an environment folder for '${ENV_NAME}'"
echo ""
fi
if [ ${#ENVS[@]} -eq 0 ]; then
echo "Error: No environments found in $ENVS_DIR"
return 1 2>/dev/null || exit 1
fi
# Display usage hint and menu instructions
echo "💡 Pro-Tip: Skip this menu by passing the name directly: bpy-select <env_name>"
echo "Use ↑/↓ arrow keys to choose an environment. Press ENTER to select."
echo ""
# Menu settings
selected=0
timeout_duration=5
start_time=$(date +%s)
countdown_active=true
# Render menu function
draw_menu() {
local idx=0
for e in "${ENVS[@]}"; do
if [ $idx -eq $selected ]; then
printf "\r\033[K\033[1;36m > %s\033[0m\n" "$e" # Cyan highlight
else
printf "\r\033[K %s\n" "$e"
fi
((idx++))
done
# Calculate precise countdown remaining or handle frozen timer state
if [ "$countdown_active" = true ]; then
local current_time=$(date +%s)
local elapsed=$((current_time - start_time))
local remaining=$((timeout_duration - elapsed))
if [ $remaining -le 0 ]; then
remaining=0
fi
printf "\r\033[K\033[1;33mTimeout defaulting to '$DEFAULT_ENV' in %ss...\033[0m\n" "$remaining"
else
printf "\r\033[K\033[1;32mSelection active. Countdown stopped.\033[0m\n"
fi
# Move cursor back up to the top of the menu list (number of envs + 1 for timer line)
local total_lines=$((${#ENVS[@]} + 1))
printf "\033[%dA" "$total_lines"
}
# Hide cursor and draw the baseline menu
printf "\033[?25l"
draw_menu
while true; do
# Non-blocking 1-second interval read to allow real-time timer updates
if read -s -n 1 -t 1 key 2>/dev/null; then
# Handle arrow keys
if [[ $key == $'\033' ]]; then
read -s -n 2 -t 0.1 next_chars
if [[ $next_chars == "[A" ]]; then # Up arrow
countdown_active=false # Stop countdown instantly
if [ $selected -gt 0 ]; then
((selected--))
fi
elif [[ $next_chars == "[B" ]]; then # Down arrow
countdown_active=false # Stop countdown instantly
if [ $selected -lt $((${#ENVS[@]} - 1)) ]; then
((selected++))
fi
fi
elif [[ $key == "" ]]; then # Enter key pressed
ENV_NAME="${ENVS[$selected]}"
break
fi
fi
# Check if total countdown duration has passed (only if countdown hasn't been disabled)
if [ "$countdown_active" = true ]; then
current_time=$(date +%s)
elapsed=$((current_time - start_time))
if [ $elapsed -ge $timeout_duration ]; then
ENV_NAME="$DEFAULT_ENV"
break
fi
fi
# Redraw layout with updated status
draw_menu
done
# --- CLEANUP ARTIFACTS ROUTINE ---
local total_lines=$((${#ENVS[@]} + 1))
for ((i=0; i<total_lines; i++)); do
printf "\r\033[K"
printf "\033[1B"
done
printf "\033[%dA" "$total_lines"
printf "\033[J\033[?25h"
fi
# 4. Build exact absolute paths for the chosen environment
ENV_PATH="${ENVS_DIR}/${ENV_NAME}"
BIN_PATH="${ENV_PATH}/bin"
# Double check final path safety
if [ ! -d "$BIN_PATH" ]; then
echo "Error: Chosen environment path does not exist: $BIN_PATH"
return 1 2>/dev/null || exit 1
fi
# 5. Clean up the PATH (strips out any prior environments from ENVS_DIR)
NEW_PATH=""
IFS=':' read -ra PATH_ARRAY <<< "$PATH"
for segment in "${PATH_ARRAY[@]}"; do
if [[ "$segment" != *"${ENVS_DIR}"* ]]; then
if [ -z "$NEW_PATH" ]; then
NEW_PATH="$segment"
else
NEW_PATH="$NEW_PATH:$segment"
fi
fi
done
# 6. Rebuild PATH and export environment variables
#export PATH="${BIN_PATH}:${NEW_PATH}"
echo $BIN_PATH
export PATH="${BIN_PATH}:${ENV_PATH}/bin:${NEW_PATH}"
export CONDA_PREFIX="${ENV_PATH}"
export CONDA_DEFAULT_ENV="${ENV_NAME}"
export PIXI_ENVIRONMENT_NAME="${ENV_NAME}"
# Optional: Source package-specific startup scripts if they exist
if [ -d "${ENV_PATH}/etc/conda/activate.d" ]; then
for f in "${ENV_PATH}/etc/conda/activate.d"/*.sh; do
[ -r "$f" ] && source "$f"
done
fi
echo "Activated '${ENV_NAME}' successfully (Raw Path Mode)."