Changeset - e28d8f0b02a5
[Not reviewed]
0 1 0
Branko Majic (branko) - 4 years ago 2020-07-04 23:40:18
branko@majic.rs
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.
1 file changed with 136 insertions and 81 deletions:
0 comments (0 inline, 0 general) First comment
games/factorio_manager.sh
Show inline comments
 
@@ -225,12 +225,33 @@ else
 
    _bg_blue=""
 
    _bg_purple=""
 
    _bg_cyan=""
 
    _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
 
        echo "${_text_bold}${_text_blue}[DEBUG]${_text_reset}" "$@"
 
    fi
 
}
 
@@ -248,77 +269,123 @@ function warning() {
 
}
 

	
 
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"
 

	
 
    if [[ ${1-} =~ -.* ]]; then
 
        options="$1"
 
        shift
 
    fi
 

	
 
    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"
 

	
 
    local color="$1"
 
    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
 
}
 

	
 
#
 
# Prompts user to provide settings for a server instance.
 
#
 
# Function will go over a number of questions, providing a set of
 
@@ -1133,30 +1200,30 @@ elif [[ $command == list-backups ]]; then
 
    source "$instance_config"
 
    current_game_version="$game_version"
 
    unset game_version
 

	
 
    # 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
 

	
 
            if [[ $backup_destination =~ $backup_destination_name_pattern ]]; then
 
                backup_date=$(basename "$backup_destination")
 

	
 
                # Read instance configuration for backup.
 
                source "$backup_destination/instance.conf"
 

	
 
                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
 

	
 

	
 
            fi
 
        done
 

	
 
@@ -1249,13 +1316,13 @@ elif [[ $command == restore ]]; then
 
        if [[ -f "$restore_source/.description" ]]; then
 
            backup_description=$(<"$restore_source/.description")
 
            backup_info="$backup_name ($backup_description)"
 
        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.
 
        if [[ ${#entries_to_remove[@]} == 0 ]]; then
 
            echo "Instance directory is currently empty. No files will be removed."
 
            echo
 
@@ -1266,19 +1333,15 @@ elif [[ $command == restore ]]; then
 
                echo "  - $entry"
 
            done
 
            echo
 
        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
 
                error "Failed to remove existing instance files."
 
                exit "$ERROR_GENERAL"
 
            fi
 
@@ -1350,29 +1413,25 @@ elif [[ $command == remove-backup ]]; then
 
    else
 
        backup_info="$backup_name"
 
    fi
 

	
 
    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
 
    echo " - $removal_target"
 
    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."
 
        exit "$ERROR_GENERAL"
 
    fi
 

	
 
@@ -1429,23 +1488,23 @@ elif [[ $command == set-version ]]; then
 
    echo
 

	
 
    for candidate in "$game_installations_directory"/*; do
 
        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
 

	
 
        fi
 
    done
 
    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
 

	
 
    if [[ -z $game_version_selected ]]; then
 
        game_version_selected="$game_version"
 
    fi
 
@@ -1458,13 +1517,13 @@ elif [[ $command == set-version ]]; then
 

	
 
    # Change instance game version.
 
    if [[ $game_version_selected == $game_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
 

	
 
#======#
 
# info #
 
#======#
 
elif [[ $command == info ]]; then
 
@@ -1507,21 +1566,21 @@ elif [[ $command == info ]]; then
 
    fi
 

	
 
    # Load instance configuration.
 
    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.
 
    shopt -s nullglob
 
    mod_files=($instance_directory/mods/*.zip)
 
    mod_list="$instance_directory/mods/mod-list.json"
 
@@ -1700,24 +1759,20 @@ elif [[ $command == remove ]]; then
 
            done
 
            echo
 
        fi
 

	
 
        # 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
 
                error "Failed to remove instance files."
 
                exit "$ERROR_GENERAL"
 
            fi
 
@@ -1822,22 +1877,22 @@ elif [[ $command == copy ]]; then
 
        echo
 

	
 
        for candidate in "$game_installations_directory"/*; do
 
            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
 
            fi
 
        done
 
        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
 

	
 
        if [[ -z $game_version_selected ]]; then
 
            game_version_selected="$game_version"
 
        fi
 
@@ -1879,13 +1934,13 @@ elif [[ $command == copy ]]; then
 
        write_data="write-data=${destination_instance_directory}"
 
        find "$destination_instance_directory/" -type f -name config.ini -exec \
 
             sed -i -e "s#^write-data=.*#$write_data#" '{}' \;
 

	
 
        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"
 

	
 
#========#
 
# import #
 
#========#
 
@@ -2002,13 +2057,13 @@ elif [[ $command == import ]]; then
 
        # Copy files and directories.
 
        echo
 
        declare -a missing_import_entries=()
 
        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)."
 
                    exit "$ERROR_GENERAL"
 
                fi
 
            else
 
@@ -2030,20 +2085,20 @@ EOF
 

	
 
        if [[ ${#missing_import_entries[@]} != 0 ]]; then
 
            warning "A number of files or directories were missing from the specified source."
 
            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"
 

	
 

	
 
#===============#
 
# create-server #
 
@@ -2225,12 +2280,12 @@ EOF
 

	
 
    if ! "$factorio_bin" --config "$game_config" --create "$saves_directory/default.zip"; then
 
        error "Failed to generate default savegame/map under: $saves_directory/default.zip"
 
        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"
 

	
 
    exit "$ERROR_ARGUMENTS"
 
fi
0 comments (0 inline, 0 general) First comment
You need to be logged in to comment. Login now