diff --git a/build-sbx.sh b/build-sbx.sh index f7e8258..435b479 100755 --- a/build-sbx.sh +++ b/build-sbx.sh @@ -83,6 +83,69 @@ prompt_component() { done } +select_workspaces() { + # Namerefs let this helper read and write the caller's arrays by name. + # The source array stays unchanged so the displayed menu remains useful. + local -n available_workspaces="$1" + local -n selected_workspaces="$2" + local selection selection_part index + local valid_selection + declare -A selected_indices=() + + printf 'Existing workspace directories:\n' + for index in "${!available_workspaces[@]}"; do + printf ' %d) %s\n' "$((index + 1))" "${available_workspaces[index]}" + done + + while true; do + read -r -p 'Workspaces to reuse (a for all, n for none, or numbers such as 1, 3): ' selection || exit 0 + selection="${selection//[[:space:]]/}" + + # `a` reuses every path, while `n` deliberately starts with no + # inherited paths and leaves manual additions to the next question. + if [[ "$selection" == a ]]; then + selected_workspaces=("${available_workspaces[@]}") + return 0 + fi + if [[ "$selection" == n ]]; then + selected_workspaces=() + return 0 + fi + + # Treat the numeric selection as a set so duplicate numbers are safe. + selected_indices=() + valid_selection=true + IFS=',' read -ra selection_parts <<< "$selection" + for selection_part in "${selection_parts[@]}"; do + if [[ "$selection_part" =~ ^[0-9]+$ ]]; then + index=$((10#$selection_part)) + if ((index < 1 || index > ${#available_workspaces[@]})); then + valid_selection=false + break + fi + selected_indices[$index]=1 + else + valid_selection=false + break + fi + done + + if [[ "$valid_selection" != true || ${#selected_indices[@]} -eq 0 ]]; then + printf 'Please enter a, n, or valid workspace numbers from 1 to %d.\n' \ + "${#available_workspaces[@]}" + continue + fi + + selected_workspaces=() + for ((index = 1; index <= ${#available_workspaces[@]}; index++)); do + if [[ ${selected_indices[$index]:-} == 1 ]]; then + selected_workspaces+=("${available_workspaces[index - 1]}") + fi + done + return 0 + done +} + cleanup_temporary_directory() { # EXIT traps run after `main` returns, so a variable declared local inside # `main` is no longer available. `${tmp:-}` also keeps nounset from @@ -130,6 +193,7 @@ main() { local base_sandbox_name next_version selected_sandbox local -a current_workspace_paths=() local -a workspace_paths=() + local reused_workspaces=false if [[ "$build_from_scratch" == true ]]; then # Keep the three name components separate so common combinations are @@ -162,6 +226,15 @@ main() { <<< "$sandbox_json" ) + if ((${#current_workspace_paths[@]} > 0)); then + select_workspaces current_workspace_paths workspace_paths + if ((${#workspace_paths[@]} > 0)); then + reused_workspaces=true + fi + else + printf 'The selected sandbox has no workspace directories to reuse.\n' + fi + # A name ending in -v is versioned. Strip that suffix and # increment it; an unversioned source starts at version 1. if [[ "$selected_sandbox" =~ ^(.*)-v([0-9]+)$ ]]; then @@ -181,7 +254,7 @@ main() { if [[ "$build_from_scratch" == true && ( "$sandbox_prefix" != 'finmas-gmbh' || "$sandbox_suffix" == 'private-api' ) ]]; then workspace_paths=("$HOME/docker-sbx/empty") - else + elif [[ "$build_from_scratch" == true ]]; then workspace_paths=("$HOME/Documents/git") fi @@ -196,8 +269,14 @@ main() { printf '%s\n' "${current_workspace_paths[@]}" fi - # Additional paths are appended rather than replacing the default mount. - if ask_yes_no 'Do you want to add additional workspace directories?'; then + # Additional paths are appended rather than replacing reused paths. + local additional_workspace_prompt + if [[ "$reused_workspaces" == true ]]; then + additional_workspace_prompt='Would you like other workspaces added?' + else + additional_workspace_prompt='Do you want to add additional workspace directories?' + fi + if ask_yes_no "$additional_workspace_prompt"; then local workspace_path while true; do read -r -p 'Additional workspace path (press Enter when finished): ' workspace_path || exit 0