diff --git a/aurora/aurora.sh b/aurora/aurora.sh index f5b56e3..b1e6268 100644 --- a/aurora/aurora.sh +++ b/aurora/aurora.sh @@ -1,5 +1,5 @@ #!/bin/sh - +# Version: 1.1.0 # Exit immediately if a command exits with a non-zero status. set -e diff --git a/backup/backup.sh b/backup/backup.sh index 178cf0a..fb3e788 100644 --- a/backup/backup.sh +++ b/backup/backup.sh @@ -1,5 +1,5 @@ #!/bin/bash - +# Version: 1.0.0 # ============================================================================== # SAP HANA Backup Script # diff --git a/clean.sh b/clean.sh index 4caf937..52b2b2a 100644 --- a/clean.sh +++ b/clean.sh @@ -1,4 +1,5 @@ #!/bin/bash +# Version: 1.1.0 # Check if any arguments were provided if [ "$#" -eq 0 ]; then diff --git a/hdb_keymanager.sh b/hdb_keymanager.sh index 7907908..ebcf77a 100644 --- a/hdb_keymanager.sh +++ b/hdb_keymanager.sh @@ -1,4 +1,5 @@ #!/bin/bash +# Version: 1.2.1 # A script to interactively manage SAP HANA hdbuserstore keys, with testing. diff --git a/install.sh b/install.sh index ed103c8..a3cca23 100644 --- a/install.sh +++ b/install.sh @@ -6,6 +6,7 @@ # 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. +# It can also check for updates to already-installed scripts. # --- Functions --- @@ -14,18 +15,41 @@ log() { echo "[$1] $2" } +# New function to get the version from a local script file. +# It reads the first 5 lines and extracts the version number. +get_local_version() { + local file_path="$1" + if [[ -f "${file_path}" ]]; then + # Grep for the version line, then use awk to get the last field. + head -n 5 "${file_path}" | grep -m 1 "^# Version:" | awk '{print $NF}' + else + echo "0.0.0" # Return a base version if file doesn't exist. + fi +} + +# New function to compare two version strings (e.g., "1.2.0" vs "1.10.0"). +# Returns 0 if v1 is newer, 1 if they are the same or v2 is newer. +is_version_greater() { + local v1=$1 + local v2=$2 + # Use sort's version sorting capability to find the "highest" version. + # If the highest version is v1, then v1 > v2. + if [[ "$(printf '%s\n' "$v1" "$v2" | sort -V | head -n 1)" != "$v1" ]]; then + return 0 # v1 is greater + else + return 1 # v1 is not greater (equal or less) + fi +} + # --- 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. This ensures that -# no matter how the script exits (normally, with an error, or via Ctrl+C), -# the temporary file is cleaned up. +# Set up a trap to delete the temporary file on exit. trap 'rm -f "${conf_file}"' EXIT -# Download the configuration file before sourcing it. +# Download the configuration file. log "🔄" "Downloading configuration file..." if ! curl -fsSL -o "${conf_file}" "https://git.technopunk.space/tomi/Scripts/raw/branch/main/packages.conf"; then log "❌" "Error: Failed to download packages.conf. Exiting." @@ -34,26 +58,55 @@ fi log "✅" "Configuration file downloaded successfully." # 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}" -# --- User Interface --- +# --- Update Check & User Interface --- echo "-------------------------------------" echo " Script Downloader " echo "-------------------------------------" -# Create an array of options from the package names (the keys of our map). -options=("${!SCRIPT_PACKAGES[@]}") +# Create an array of options from the package names. +# We will modify this array to show installation and update status. +declare -a options +package_keys=("${!SCRIPT_PACKAGES[@]}") + +log "🔎" "Checking for updates..." +for key in "${package_keys[@]}"; do + # The config format is now "VERSION|URL1 URL2..." + config_value="${SCRIPT_PACKAGES[$key]}" + remote_version=$(echo "${config_value}" | cut -d'|' -f1) + + # Get just the URLs and assume the first URL is the main script to check. + urls=$(echo "${config_value}" | cut -d'|' -f2-) + read -r -a url_array <<< "$urls" + main_script_filename=$(basename "${url_array[0]}") + + # Get the local version of the main script file. + local_version=$(get_local_version "${main_script_filename}") + + status="" + if [[ -f "${main_script_filename}" ]]; then + status=" (Installed: v${local_version})" + # Compare versions + if is_version_greater "$remote_version" "$local_version"; then + status+=" [Update available: v${remote_version}]" + fi + fi + options+=("${key}${status}") +done +echo + options+=("Quit") # Add a Quit option to the menu. # Set the prompt for the select menu. -PS3="Please enter the number of the script/package you want to download: " +PS3="Please enter your choice: " -# 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 +# Display the menu and handle user input. +select choice_with_status in "${options[@]}"; do + # Strip the status message from the choice for key lookup + choice=$(echo "${choice_with_status}" | sed 's/ (.*//') + case "${choice}" in "Quit") log "👋" "Exiting." @@ -63,38 +116,35 @@ select choice in "${options[@]}"; do # Check if the user's choice is a valid package name. if [[ -n "${SCRIPT_PACKAGES[$choice]}" ]]; then echo - log "⬇️" "Downloading package: '${choice}'..." + log "⬇️" "Processing package: '${choice}'..." + + # Get the config value and split it into version and URLs + config_value="${SCRIPT_PACKAGES[$choice]}" + remote_version=$(echo "${config_value}" | cut -d'|' -f1) + urls_to_download=$(echo "${config_value}" | cut -d'|' -f2-) - # Get the space-separated list of URLs for the chosen package. - urls_to_download="${SCRIPT_PACKAGES[$choice]}" - - # Read the URLs into an array for safer handling. read -r -a urls_to_download_array <<< "$urls_to_download" - # 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) - # 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}" + # Attempt to use diff's color option, which is common. + diff --color=always -u "${filename}" "${tmp_file}" 2>/dev/null || diff -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. + echo if [[ $REPLY =~ ^[Yy]$ ]]; then mv "${tmp_file}" "${filename}" @@ -105,15 +155,13 @@ select choice in "${options[@]}"; do 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). + # Original download logic for all other 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." @@ -124,10 +172,9 @@ select choice in "${options[@]}"; do fi done echo - log "📦" "Package download complete." - break # Exit the select loop after a successful operation. + log "📦" "Package processing complete." + break else - # The user entered an invalid number. echo "Invalid selection. Please try again." fi ;; diff --git a/packages.conf b/packages.conf index bf7a8e3..092569a 100644 --- a/packages.conf +++ b/packages.conf @@ -2,13 +2,14 @@ # # This file contains the configuration for the script downloader. # The `SCRIPT_PACKAGES` associative array maps a package name to a -# space-separated list of URLs to download. +# pipe-separated string: "|". declare -A SCRIPT_PACKAGES -SCRIPT_PACKAGES["Aurora Suite"]="https://git.technopunk.space/tomi/Scripts/raw/branch/main/aurora/aurora.sh https://git.technopunk.space/tomi/Scripts/raw/branch/main/aurora/aurora.conf" -SCRIPT_PACKAGES["Backup Suite"]="https://git.technopunk.space/tomi/Scripts/raw/branch/main/backup/backup.sh https://git.technopunk.space/tomi/Scripts/raw/branch/main/backup/backup.conf" -SCRIPT_PACKAGES["Key Manager"]="https://git.technopunk.space/tomi/Scripts/raw/branch/main/hdb_keymanager.sh" -SCRIPT_PACKAGES["File Cleaner"]="https://git.technopunk.space/tomi/Scripts/raw/branch/main/clean.sh" -# Example: To add another single script later, just add a new line: -# SCRIPT_PACKAGES["My Other Script"]="https://path/to/my-other-script.sh" +# The version should match the "# Version: x.x.x" line in the main script file. +SCRIPT_PACKAGES["Aurora Suite"]="1.1.0|https://git.technopunk.space/tomi/Scripts/raw/branch/main/aurora/aurora.sh https://git.technopunk.space/tomi/Scripts/raw/branch/main/aurora/aurora.conf" +SCRIPT_PACKAGES["Backup Suite"]="1.0.0|https://git.technopunk.space/tomi/Scripts/raw/branch/main/backup/backup.sh https://git.technopunk.space/tomi/Scripts/raw/branch/main/backup/backup.conf" +SCRIPT_PACKAGES["Key Manager"]="1.2.1|https://git.technopunk.space/tomi/Scripts/raw/branch/main/hdb_keymanager.sh" +SCRIPT_PACKAGES["File Cleaner"]="1.1.0|https://git.technopunk.space/tomi/Scripts/raw/branch/main/clean.sh" +# Example: Add a new script with its version. +# SCRIPT_PACKAGES["My Other Script"]="1.0.0|https://path/to/my-other-script.sh"