175 lines
5.4 KiB
Bash
Executable File
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)."
|
|
|