diff --git a/install.sh b/install.sh index 4d1db1d..ed103c8 100644 --- a/install.sh +++ b/install.sh @@ -2,110 +2,134 @@ # --- Main Script --- -# Generate a unique temporary filename with a timestamp +# This script presents a menu of software packages defined in a remote +# configuration file. The user can select a package, and the script +# will download the corresponding files. It includes a feature to show +# a diff and ask for confirmation before overwriting existing config files. + +# --- Functions --- + +# A simple function to log messages with a consistent format. +log() { + echo "[$1] $2" +} + +# --- Main Logic --- + +# Generate a unique temporary filename with a timestamp. +# This file will hold the package definitions downloaded from the remote source. conf_file="packages.conf.$(date +%Y%m%d%H%M%S)" -# Set up a trap to delete the temporary file on exit, regardless of how the script ends +# Set up a trap to delete the temporary file on exit. This ensures that +# no matter how the script exits (normally, with an error, or via Ctrl+C), +# the temporary file is cleaned up. trap 'rm -f "${conf_file}"' EXIT # Download the configuration file before sourcing it. -echo "🔄 Downloading configuration file '${conf_file}'..." +log "🔄" "Downloading configuration file..." if ! curl -fsSL -o "${conf_file}" "https://git.technopunk.space/tomi/Scripts/raw/branch/main/packages.conf"; then - echo "❌ Error: Failed to download packages.conf. Exiting." + log "❌" "Error: Failed to download packages.conf. Exiting." exit 1 fi -echo "✅ Configuration file downloaded successfully." +log "✅" "Configuration file downloaded successfully." -# Source the configuration file to load the SCRIPT_PACKAGES array. +# Source the configuration file to load the SCRIPT_PACKAGES associative array. +# The file is expected to contain a declaration like: +# declare -A SCRIPT_PACKAGES=( [key1]="url1 url2" [key2]="url3" ) source "${conf_file}" -# Welcome message +# --- User Interface --- + echo "-------------------------------------" -echo "        Script Downloader            " +echo " Script Downloader " echo "-------------------------------------" -# Create an array of options from the package names (the keys of our map) +# Create an array of options from the package names (the keys of our map). options=("${!SCRIPT_PACKAGES[@]}") -options+=("Quit") # Add a Quit option +options+=("Quit") # Add a Quit option to the menu. -# Set the prompt for the select menu +# Set the prompt for the select menu. PS3="Please enter the number of the script/package you want to download: " -# Display the menu and handle user input +# Display the menu and handle user input. The `select` statement is a +# convenient way to create interactive menus in shell scripts. select choice in "${options[@]}"; do -    case "${choice}" in -        "Quit") -            echo "👋 Exiting." -            break -            ;; -        *) -            # Check if the user's choice is a valid package name -            if [[ -n "${SCRIPT_PACKAGES[$choice]}" ]]; then -                echo -                echo "⬇️  Downloading package: '${choice}'..." -                 -                # Get the space-separated list of URLs for the chosen package -                urls_to_download="${SCRIPT_PACKAGES[$choice]}" + case "${choice}" in + "Quit") + log "👋" "Exiting." + break # Exit the select loop. + ;; + *) + # Check if the user's choice is a valid package name. + if [[ -n "${SCRIPT_PACKAGES[$choice]}" ]]; then + echo + log "⬇️" "Downloading package: '${choice}'..." + + # Get the space-separated list of URLs for the chosen package. + urls_to_download="${SCRIPT_PACKAGES[$choice]}" -                # Loop through each URL in the list and download the file -                for url in $urls_to_download; do -                    filename=$(basename "${url}") -                    # If it's a .conf file AND it already exists, ask to overwrite. -                    if [[ "${filename}" == *.conf && -f "${filename}" ]]; then -                        echo "   -> Found existing config file: '${filename}'." -                        # Create a temporary file to download the new version for comparison -                        tmp_file=$(mktemp) + # Read the URLs into an array for safer handling. + read -r -a urls_to_download_array <<< "$urls_to_download" -                        # Download the new version silently to the temp file -                        if curl -fsSL -o "${tmp_file}" "${url}"; then -                            echo "   🔎 Comparing versions..." -                            echo "-------------------- DIFF START --------------------" -                            # Show a colorized diff if 'colordiff' is available, otherwise use regular 'diff' -                            if command -v colordiff &> /dev/null; then -                                colordiff -u "${filename}" "${tmp_file}" -                            else -                                diff --color=always -u "${filename}" "${tmp_file}" -                            fi -                            echo "--------------------- DIFF END ---------------------" -                             -                            # Ask the user for confirmation before overwriting -                            read -p "Do you want to overwrite '${filename}'? (y/N) " -n 1 -r REPLY -                            echo # Move to a new line for cleaner output + # Loop through each URL in the list and download the file. + for url in "${urls_to_download_array[@]}"; do + filename=$(basename "${url}") + # If it's a .conf file AND it already exists, ask to overwrite. + if [[ "${filename}" == *.conf && -f "${filename}" ]]; then + log "->" "Found existing config file: '${filename}'." + # Create a temporary file to download the new version for comparison. + tmp_file=$(mktemp) -                            if [[ $REPLY =~ ^[Yy]$ ]]; then -                                mv "${tmp_file}" "${filename}" -                                echo "   ✅ Updated '${filename}'." -                            else -                                rm "${tmp_file}" -                                echo "   🤷 Kept existing version of '${filename}'." -                            fi -                        else -                            echo "   ❌ Error: Failed to download new version of '${filename}' for comparison." -                            # Clean up the temp file on failure -                            rm -f "${tmp_file}" -                        fi -                    else -                        # Original download logic for all other files (or new .conf files) -                        echo "   -> Downloading '${filename}'..." -                        if curl -fsSL -o "${filename}" "${url}"; then -                            echo "   ✅ Successfully downloaded '${filename}'." -                            # If the downloaded file is a shell script, make it executable -                            if [[ "${filename}" == *.sh ]]; then -                                chmod +x "${filename}" -                                echo "   🤖 Made '${filename}' executable." -                            fi -                        else -                            echo "   ❌ Error: Failed to download '${filename}'." -                        fi -                    fi -                done -                echo -                echo "📦 Package download complete." -                break -            else -                # The user entered an invalid number -                echo "Invalid selection. Please try again." -            fi -            ;; -    esac + # Download the new version silently to the temp file. + if curl -fsSL -o "${tmp_file}" "${url}"; then + log "🔎" "Comparing versions..." + echo "-------------------- DIFF START --------------------" + # Show a colorized diff if 'colordiff' is available, otherwise use regular 'diff'. + if command -v colordiff &> /dev/null; then + colordiff -u "${filename}" "${tmp_file}" + else + diff --color=always -u "${filename}" "${tmp_file}" + fi + echo "--------------------- DIFF END ---------------------" + + # Ask the user for confirmation before overwriting. + read -p "Do you want to overwrite '${filename}'? (y/N) " -n 1 -r REPLY + echo # Move to a new line for cleaner output. + + if [[ $REPLY =~ ^[Yy]$ ]]; then + mv "${tmp_file}" "${filename}" + log "✅" "Updated '${filename}'." + else + rm "${tmp_file}" + log "🤷" "Kept existing version of '${filename}'." + fi + else + log "❌" "Error: Failed to download new version of '${filename}' for comparison." + # Clean up the temp file on failure. + rm -f "${tmp_file}" + fi + else + # Original download logic for all other files (or new .conf files). + log "->" "Downloading '${filename}'..." + if curl -fsSL -o "${filename}" "${url}"; then + log "✅" "Successfully downloaded '${filename}'." + # If the downloaded file is a shell script, make it executable. + if [[ "${filename}" == *.sh ]]; then + chmod +x "${filename}" + log "🤖" "Made '${filename}' executable." + fi + else + log "❌" "Error: Failed to download '${filename}'." + fi + fi + done + echo + log "📦" "Package download complete." + break # Exit the select loop after a successful operation. + else + # The user entered an invalid number. + echo "Invalid selection. Please try again." + fi + ;; + esac done