From e28d8f0b02a5b921428275ff635df912412c0bcf 2020-07-04 23:40:18 From: Branko Majic <branko@majic.rs> Date: 2020-07-04 23:40:18 Subject: [PATCH] Noticket: Drop warning_prompt and bold_* functions: - Introduce new function that handles promting for dangerous operations and aborts if user does not confirm operation. - Replace use of bold_* functions with colorecho function. - Refactor colorecho and colorprintf to share associative array with colors, and also support bold variants. - Write documentation for the colorecho and colorprintf functions. --- diff --git a/games/factorio_manager.sh b/games/factorio_manager.sh index ae51ef7d4beb84cc160b577e53b9457b79110547..ac5156c4e9cadae074d43b7c941f085a50294c3a 100755 --- a/games/factorio_manager.sh +++ b/games/factorio_manager.sh @@ -228,6 +228,27 @@ else _bg_white="" fi +# Make the colors available via an associative array as well. +declare -A _text_colors=() + +_text_colors[black]="${_text_black}" +_text_colors[blue]="${_text_blue}" +_text_colors[cyan]="${_text_cyan}" +_text_colors[green]="${_text_green}" +_text_colors[purple]="${_text_purple}" +_text_colors[red]="${_text_red}" +_text_colors[white]="${_text_white}" +_text_colors[yellow]="${_text_yellow}" + +_text_colors[boldblack]="${_text_bold}${_text_black}" +_text_colors[boldblue]="${_text_bold}${_text_blue}" +_text_colors[boldcyan]="${_text_bold}${_text_cyan}" +_text_colors[boldgreen]="${_text_bold}${_text_green}" +_text_colors[boldpurple]="${_text_bold}${_text_purple}" +_text_colors[boldred]="${_text_bold}${_text_red}" +_text_colors[boldwhite]="${_text_bold}${_text_white}" +_text_colors[boldyellow]="${_text_bold}${_text_yellow}" + # Set-up functions for printing coloured messages. function debug() { if [[ $debug != 0 ]]; then @@ -251,6 +272,38 @@ function error() { echo "${_text_bold}${_text_red}[ERROR]${_text_reset}" "$@" >&2 } +# +# Prints text in requested color to standard output. Behaves as thin +# wrapper around the echo built-in. +# +# Two invocation variants with different arguments are +# supported. First argument is the one that will determine what the +# desired invocation is. +# +# Arguments (variant 1): +# +# $1 (echo_options) +# Additional options to pass-in to echo. Must be a single argument +# with leading dash followed by echo's own options. E.g. "-ne". +# +# $2 (color) +# Text color to use. Supported values: black, blue, cyan, green, +# purple, red, white, yellow. +# +# $3 (text) +# Text to output. +# +# +# Arguments (variant 2): +# +# $1 (color) +# Text color to use. Supported values: black, blue, cyan, green, +# purple, red, white, yellow, boldblack, boldblue, boldcyan, +# boldgreen, boldpurple, boldred, boldwhite, boldyellow. +# +# $2 (text) +# Text to output. +# function colorecho() { local options="" color text local reset="$_text_reset" @@ -263,24 +316,30 @@ function colorecho() { color="$1" text="$2" - declare -A colors=() - - colors[black]="${_text_black}" - colors[red]="${_text_red}" - colors[green]="${_text_green}" - colors[yellow]="${_text_yellow}" - colors[blue]="${_text_blue}" - colors[purple]="${_text_purple}" - colors[cyan]="${_text_cyan}" - colors[white]="${_text_white}" - if [[ -n $options ]]; then - echo "$options" "${colors[$color]}$text${reset}" + echo "$options" "${_text_colors[$color]}$text${reset}" else - echo "${colors[$color]}$text${reset}" + echo "${_text_colors[$color]}$text${reset}" fi } +# +# Prints text in requested color to standard output using printf +# format string and arguments.. Behaves as thin wrapper around the +# printf built-in. +# +# Arguments: +# +# $1 (color) +# Text color to use. Supported values: black, blue, cyan, green, +# purple, red, white, yellow. +# +# $2 (format_string) +# printf-compatible format string. +# +# $3 .. $n +# Replacement values for the the format string. +# function colorprintf() { local reset="$_text_reset" @@ -288,34 +347,42 @@ function colorprintf() { local format="$2" shift 2 - declare -A colors=() - - colors[black]="${_text_black}" - colors[red]="${_text_red}" - colors[green]="${_text_green}" - colors[yellow]="${_text_yellow}" - colors[blue]="${_text_blue}" - colors[purple]="${_text_purple}" - colors[cyan]="${_text_cyan}" - colors[white]="${_text_white}" - - printf "${colors[$color]}${format}${reset}" "$@" + printf "${_text_colors[$color]}${format}${reset}" "$@" } -function warning_prompt() { - echo -n "${_text_bold}${_text_yellow}[WARN] ${_text_reset}" "$@" -} - -function bold_green() { - echo -n "${_text_bold}${_text_green}$@${_text_reset}" -} +# +# Presents user with a warning, asks user for confirmation to +# continue, and terminates the script is confirmation is not provided +# with designated exit code. +# +# This function can be used to request confirmation for dangerous +# actions/operations (such as removal of large number of files etc). +# +# The user must type-in YES (with capital casing) to proceed. +# +# Arguments: +# +# $1 (prompt_text) +# Text to prompt the user with. +# +# $2 (abort_text) +# Text to show to user in case the operation was aborted by user. +# +# $3 (exit_code) +# Exit code when terminating the proram. +# +function critical_confirmation() { + local prompt_text="$1" + local abort_text="$2" + local exit_code="$3" -function bold_red() { - echo -n "${_text_bold}${_text_red}$@${_text_reset}" -} + echo -n "${_text_bold}${_text_yellow}[WARN] ${_text_reset}" "${prompt_text} Type YES to confirm (default is no): " + read confirm -function bold_blue() { - echo -n "${_text_bold}${_text_blue}$@${_text_reset}" + if [[ $confirm != "YES" ]]; then + error "$abort_text" + exit "$ERROR_GENERAL" + fi } # @@ -1136,9 +1203,9 @@ elif [[ $command == list-backups ]]; then # Detect and show available backups to the user. if [[ ! -d $backup_directory ]] || ! ls "$backup_directory" | grep -q -E "^$backup_destination_name_pattern\$"; then - echo "No backups are available for instance $(bold_green $instance)." + echo "No backups are available for instance $(colorecho -n green "$instance")." else - echo "Available backups for instance $(bold_green $instance) (current version $(bold_green "$current_game_version"))." + echo "Available backups for instance $(colorecho -n green "$instance") (current version $(colorecho -n green "$current_game_version"))." echo for backup_destination in "$backup_directory"/*; do @@ -1151,9 +1218,9 @@ elif [[ $command == list-backups ]]; then if [[ -f "$backup_destination/.description" ]]; then backup_description=$(<"$backup_destination/.description") - echo " - $backup_date - version $(bold_green "$game_version") ($backup_description)" + echo " - $backup_date - version $(colorecho -n green "$game_version") ($backup_description)" else - echo " - $backup_date - version $(bold_green "$game_version")" + echo " - $backup_date - version $(colorecho -n green "$game_version")" fi @@ -1252,7 +1319,7 @@ elif [[ $command == restore ]]; then else backup_info="$backup_name" fi - echo "Restore instance $(bold_green "$instance") from backup: $(bold_green "$backup_info")" + echo "Restore instance $(colorecho -n green "$instance") from backup: $(colorecho -n green "$backup_info")" echo # Show user what files will be removed. @@ -1269,13 +1336,9 @@ elif [[ $command == restore ]]; then fi # Request from user to confirm the operation. - warning_prompt "Are you sure you want to proceed? Type YES to confirm (default is no): " - read confirm - - if [[ $confirm != "YES" ]]; then - error "Aborted restore process, no changes have been made to instance files." - exit "$ERROR_GENERAL" - fi + critical_confirmation "Are you sure you want to proceed?" \ + "Aborted restore process, no changes have been made to instance files." \ + "$ERROR_GENERAL" if [[ ${#entries_to_remove[@]} != 0 ]]; then if ! rm -rf "${entries_to_remove[@]}"; then @@ -1353,9 +1416,9 @@ elif [[ $command == remove-backup ]]; then warning "You are about to remove an instance backup. All files belonging to specified backup will be removed." echo - echo "Instance: $(bold_green "$instance")" + echo "Instance: $(colorecho -n green "$instance")" echo - echo "Backup: $(bold_green "$backup_info")" + echo "Backup: $(colorecho -n green "$backup_info")" echo echo "Files and directories that will be removed:" echo @@ -1363,13 +1426,9 @@ elif [[ $command == remove-backup ]]; then echo # Request from user to confirm the operation. - warning_prompt "Are you sure you want to proceed? Type YES to confirm (default is no): " - read confirm - - if [[ $confirm != "YES" ]]; then - error "Aborted backup removal, no changes have been made to backup files." - exit "$ERROR_GENERAL" - fi + critical_confirmation "Are you sure you want to proceed?" \ + "Aborted backup removal, no changes have been made to backup files." \ + "$ERROR_GENERAL" if ! rm -rf "$removal_target"; then error "Failed to remove existing instance files." @@ -1432,7 +1491,7 @@ elif [[ $command == set-version ]]; then if [[ -f $candidate/bin/x64/factorio ]]; then candidate_version=$(basename "$candidate") if [[ $candidate_version == $game_version ]]; then - echo " - $candidate_version $(bold_green "[current]")" + echo " - $candidate_version $(colorecho -n green "[current]")" else echo " - $candidate_version" fi @@ -1442,7 +1501,7 @@ elif [[ $command == set-version ]]; then echo # Display current version. - echo "Current version used for instance $(bold_green "$instance") is $(bold_green "$game_version")." + echo "Current version used for instance $(colorecho -n green "$instance") is $(colorecho -n green "$game_version")." echo read -p "Please specify what version you would like to use (enter to keep current): " game_version_selected @@ -1461,7 +1520,7 @@ elif [[ $command == set-version ]]; then info "Current version has been kept." else sed -i -e "s/^game_version=.*/game_version=$game_version_selected/" "$instance_config" - success "Version changed to: $(bold_green "$game_version_selected")" + success "Version changed to: $(colorecho -n green "$game_version_selected")" fi #======# @@ -1510,15 +1569,15 @@ elif [[ $command == info ]]; then source "$instance_config" # Basic information. - echo "Instance name: $(bold_green "$instance")" + echo "Instance name: $(colorecho -n green "$instance")" if [[ -e "$game_installations_directory/$game_version" ]]; then - echo "Game version: $(bold_green "$game_version")" + echo "Game version: $(colorecho -n green "$game_version")" else - echo "Game version: $(bold_red "$game_version [not available locally]")" + echo "Game version: $(colorecho -n red "$game_version [not available locally]")" fi - echo "Instance path: $(bold_green "$instance_directory")" + echo "Instance path: $(colorecho -n green "$instance_directory")" echo # Mod information. @@ -1703,18 +1762,14 @@ elif [[ $command == remove ]]; then # Display instance information. source "$instance_config" - echo "Instance name: $(bold_green "$instance")" - echo "Instance version: $(bold_green "$game_version")" + echo "Instance name: $(colorecho -n green "$instance")" + echo "Instance version: $(colorecho -n green "$game_version")" echo # Request from user to confirm the operation. - warning_prompt "Are you sure you want to proceed? Type YES to confirm (default is no): " - read confirm - - if [[ $confirm != "YES" ]]; then - error "Aborted instance removal, no changes have been made to instance files." - exit "$ERROR_GENERAL" - fi + critical_confirmation "Are you sure you want to proceed?" \ + "Aborted instance removal, no changes have been made to instance files." \ + "$ERROR_GENERAL" if [[ ${#entries_to_remove[@]} != 0 ]]; then if ! rm -rf "${entries_to_remove[@]}"; then @@ -1825,7 +1880,7 @@ elif [[ $command == copy ]]; then if [[ -f $candidate/bin/x64/factorio ]]; then candidate_version=$(basename "$candidate") if [[ $candidate_version == $game_version ]]; then - echo " - $candidate_version $(bold_green "[current]")" + echo " - $candidate_version $(colorecho -n green "[current]")" else echo " - $candidate_version" fi @@ -1834,7 +1889,7 @@ elif [[ $command == copy ]]; then echo # Display current version. - echo "Current version used for instance $(bold_green "$source_instance") is $(bold_green "$game_version")." + echo "Current version used for instance $(colorecho -n green "$source_instance") is $(colorecho -n green "$game_version")." echo read -p "Please specify what version you would like to use for new instance (press enter to keep the current version): " game_version_selected @@ -1882,7 +1937,7 @@ elif [[ $command == copy ]]; then sed -i -e "s/^game_version=.*/game_version=$game_version_selected/" "$destination_instance_config" - success "Created new instance $(bold_green "$destination_instance") using version $(bold_green "$game_version_selected") as copy of instance $(bold_green "$source_instance")." + success "Created new instance $(colorecho -n green "$destination_instance") using version $(colorecho -n green "$game_version_selected") as copy of instance $(colorecho -n green "$source_instance")." ) 200>"$source_lock_file" @@ -2005,7 +2060,7 @@ elif [[ $command == import ]]; then for source_entry in "${import_entries_keys[@]}"; do source_entry_path="$source_directory/$source_entry" if [[ -e $source_entry_path ]]; then - info "Importing $(bold_blue "$source_entry")..." + info "Importing $(colorecho -n blue "$source_entry")..." if ! cp -a "$source_entry_path" "$instance_directory/"; then error "Could not import $source_entry from $source_entry_path (see above for errors)." @@ -2033,14 +2088,14 @@ EOF warning "For some of the entries this is perfectly normal, but you should verify that no critical files have been missed by mistake before switching to using this instance." echo for missing_import_entry in "${missing_import_entries[@]}"; do - echo "$(bold_blue "$missing_import_entry"), ${import_entries[$missing_import_entry]}" + echo "$(colorecho blue "$missing_import_entry"), ${import_entries[$missing_import_entry]}" echo done warning "Press any key to continue." read -n1 fi - success "Finished import of instance $(bold_green "$instance")." + success "Finished import of instance $(colorecho -n green "$instance")." ) 200>"$source_lock_file" @@ -2228,7 +2283,7 @@ EOF exit "$ERROR_GENERAL" fi - success "Created new server instance $(bold_green "$instance")" + success "Created new server instance $(colorecho -n green "$instance")" else error "Invalid command: $command"