From 18af77ba26d98d6925b8f3b5d95086fcc22d2edb Mon Sep 17 00:00:00 2001 From: jutty Date: Thu, 18 Jul 2024 09:13:18 -0300 Subject: [PATCH 1/6] Use echo over printf on logging function --- src/utility.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/utility.sh b/src/utility.sh index 868ed91..99746a7 100644 --- a/src/utility.sh +++ b/src/utility.sh @@ -4,12 +4,12 @@ log() { local level="$1" local message="$2" - if [ $level = fatal ]; then - printf "[tori] $(date "+%H:%M:%S"): $message\n" 1>&2 - elif [ $level = user ]; then - printf "[tori] $(date "+%H:%M:%S"): $message\n" 1>&2 - elif [ -n "$DEBUG" ] && [ $level = debug ]; then - printf "$(date "+%H:%M:%N") $message\n" 1>&2 + if [ "$level" = fatal ]; then + echo "[tori] $(date "+%H:%M:%S"): $message" 1>&2 + elif [ "$level" = user ]; then + echo "[tori] $(date "+%H:%M:%S"): $message" 1>&2 + elif [ -n "$DEBUG" ] && [ "$level" = debug ]; then + echo "$(date "+%H:%M:%N") $message" 1>&2 fi } From 456695544011212ce780c3c5f9fd10720f6a935a Mon Sep 17 00:00:00 2001 From: jutty Date: Thu, 18 Jul 2024 10:10:18 -0300 Subject: [PATCH 2/6] Check for shell option support before setting --- src/utility.sh | 18 +++++++++++++++--- tori | 15 +++++++-------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/utility.sh b/src/utility.sh index 99746a7..dacb48a 100644 --- a/src/utility.sh +++ b/src/utility.sh @@ -16,9 +16,21 @@ log() { set_opts() { sign="$1" - set "${sign}o" errexit - set "${sign}o" nounset - set "${sign}o" pipefail + set_opt() { + local opt="$1" + + if set -o | grep -q "^$opt[[:space:]]"; then + set "${sign}o" "$opt" + log debug "[set_opts] Set: $(set -o | grep -q "^$opt[[:space:]]")" + else + log fatal "Unsupported shell: no $opt option support" + return 1 + fi + } + + set_opt errexit + set_opt nounset + set_opt pipefail } prepare_directories() { diff --git a/tori b/tori index 261c82b..29a5efd 100755 --- a/tori +++ b/tori @@ -2,17 +2,13 @@ main() { # paths - VERSION="0.4.1 2024-07-14" + VERSION="0.5.0 2024-07-18" TORI_ROOT="$HOME/.local/share/tori" CONFIG_ROOT="$HOME/.config/tori" TMP_DIR="/tmp/tori" CACHE_DIR="$HOME/.cache/tori" - check_core_paths - - . "$TORI_ROOT/src/index.sh" - - # state + # os-independent state DEBUG=$DEBUG @@ -20,13 +16,16 @@ main() { argument="$1" parameter="$2" + # import source + + check_core_paths + . "$TORI_ROOT/src/index.sh" set_opts - - ## global constants + ## os-dependent state OS="$(get_operating_system)" PACKAGE_CACHE="$CACHE_DIR/${OS}_packages.cache" - ## global state base_files= bkp_files= user_packages= From ae206ccc3e7305d2f3bb9754cae5ecc2f73bc620 Mon Sep 17 00:00:00 2001 From: jutty Date: Thu, 18 Jul 2024 11:23:24 -0300 Subject: [PATCH 3/6] Add numerical debug levels --- CHANGELOG | 10 +++++++--- src/configuration.sh | 6 +----- src/utility.sh | 44 +++++++++++++++++++++++++++++++++++++------- tori | 1 + 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 9c917a9..759fd6f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,9 +1,13 @@ -0.4.1 2024-07-14: Fixes "Cancel" option not exiting on package resolution - Fixes whitespace preventing package list matches on "remove all" +0.5.0 2024-07-18: "Decide in editor" package conflict resolution strategy + Drop pipefail shell option for dash compatibility + Add numerical debug levels to the log utility function + Check for shell option support before setting +0.4.1 2024-07-14: Fix "Cancel" option not exiting on package resolution + Fix whitespace preventing package list matches on "remove all" 0.4.0 2024-07-14: "Add/remove all from configuration" resolution strategy 0.3.1 2024-07-13: Refactor, new docs page, make cache refresh lazier 0.3.0 2024-07-11: "Enter packages to install/uninstall" resolution strategy 0.2.1 2024-07-10: Rename package_resolution.sh, document package conflicts 0.2.0 2024-07-10: Implement "uninstall/instal all" package resolution strategies 0.1.1 2024-07-07: Handle missing tori.conf and invalid installation root path -0.1.0 2024-07-07: Added configuration parsing +0.1.0 2024-07-07: Add configuration parsing diff --git a/src/configuration.sh b/src/configuration.sh index a50086f..71a3d5a 100644 --- a/src/configuration.sh +++ b/src/configuration.sh @@ -29,12 +29,8 @@ scan_packages() { user_packages="$(get_user_packages)" if [ "$system_packages" = "$user_packages" ]; then - log debug "packages match" + log debug "Packages match" else - log debug "packages mismatch" - log debug "system:\n$system_packages" - log debug "user:\n$user_packages" - log user "System and configuration packages differ" resolve_packages fi diff --git a/src/utility.sh b/src/utility.sh index dacb48a..81ae419 100644 --- a/src/utility.sh +++ b/src/utility.sh @@ -4,12 +4,42 @@ log() { local level="$1" local message="$2" - if [ "$level" = fatal ]; then - echo "[tori] $(date "+%H:%M:%S"): $message" 1>&2 - elif [ "$level" = user ]; then - echo "[tori] $(date "+%H:%M:%S"): $message" 1>&2 - elif [ -n "$DEBUG" ] && [ "$level" = debug ]; then - echo "$(date "+%H:%M:%N") $message" 1>&2 + print_user_message() { + echo "[tori] $(date "+%H:%M:%S"): $1" 1>&2 + } + + print_debug_message() { + echo "$(date "+%H:%M:%N") $1" 1>&2 + } + + if [ -z "$DEBUG" ]; then + DEBUG=3 + elif ! echo "$DEBUG" | grep -q '^[[:number:]]$'; then + echo "[log] Warning: DEBUG should always be set to a number. Assuming DEBUG=3 (warn)" + DEBUG=3 + fi + + if [ -z "$DEBUG_DISABLED_WARNING" ] && [ "$DEBUG" -eq 0 ]; then + echo "[log] Warning: Setting DEBUG=0 disables all logging except for user messages" + echo " Use a value beween 1 (fatal) and 5 (debug). The default level is 3 (warn)" + DEBUG_DISABLED_WARNING=1 + elif [ "$DEBUG" -gt 5 ]; then + echo "[log] Warning: Assuming DEBUG maximum level of 5 (debug) over provided level $DEBUG" + DEBUG=5 + fi + + if [ "$level" = user ]; then + print_user_message "$message" + elif [ "$DEBUG" -ge 1 ] && [ "$level" = fatal ]; then + print_user_message "$message" + elif [ "$DEBUG" -ge 2 ] && [ "$level" = error ]; then + print_user_message "$message" + elif [ "$DEBUG" -ge 3 ] && [ "$level" = warn ]; then + print_user_message "$message" + elif [ "$DEBUG" -ge 4 ] && [ "$level" = info ]; then + print_debug_message "$message" + elif [ "$DEBUG" -ge 5 ] && [ "$level" = debug ]; then + print_debug_message "$message" fi } @@ -21,7 +51,7 @@ set_opts() { if set -o | grep -q "^$opt[[:space:]]"; then set "${sign}o" "$opt" - log debug "[set_opts] Set: $(set -o | grep -q "^$opt[[:space:]]")" + log debug "[set_opts] Set: $(set -o | grep "^$opt[[:space:]]")" else log fatal "Unsupported shell: no $opt option support" return 1 diff --git a/tori b/tori index 29a5efd..ac5c3ee 100755 --- a/tori +++ b/tori @@ -11,6 +11,7 @@ main() { # os-independent state DEBUG=$DEBUG + DEBUG_DISABLED_WARNING= ## user input argument="$1" From a6142163af0de1708e54b1bf971ed1d09b398193 Mon Sep 17 00:00:00 2001 From: jutty Date: Thu, 18 Jul 2024 16:58:19 -0300 Subject: [PATCH 4/6] Rename set_opts arguments to on/off --- src/package/package_manager.sh | 4 ++-- src/package/update_package_cache.sh | 4 ++-- src/utility.sh | 12 +++++++++++- tori | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/package/package_manager.sh b/src/package/package_manager.sh index 10930ca..f96f132 100644 --- a/src/package/package_manager.sh +++ b/src/package/package_manager.sh @@ -8,9 +8,9 @@ package_manager() { local args__get_manually_installed local args__get_available - set_opts + + set_opts off local args__user_args="$2" - set_opts - + set_opts on if [ "$OS" = "FreeBSD" ]; then manager="pkg" diff --git a/src/package/update_package_cache.sh b/src/package/update_package_cache.sh index 1169508..c01b750 100644 --- a/src/package/update_package_cache.sh +++ b/src/package/update_package_cache.sh @@ -1,7 +1,7 @@ update_package_cache() { - set_opts + + set_opts off local argument="$1" - set_opts - + set_opts on if [ -f "$PACKAGE_CACHE" ]; then local last_update="$(date -r "$PACKAGE_CACHE" +%Y-%m-%d)" diff --git a/src/utility.sh b/src/utility.sh index 81ae419..441ed38 100644 --- a/src/utility.sh +++ b/src/utility.sh @@ -44,7 +44,17 @@ log() { } set_opts() { - sign="$1" + local target="$1" + local sign= + + if [ "$target" = on ]; then + sign='-' + elif [ "$target" = off ]; then + sign='+' + else + log fatal "Invalid set_opts target: $target. Expected on or off" + return 1 + fi set_opt() { local opt="$1" diff --git a/tori b/tori index ac5c3ee..0f59126 100755 --- a/tori +++ b/tori @@ -21,7 +21,7 @@ main() { check_core_paths . "$TORI_ROOT/src/index.sh" - set_opts - + set_opts on ## os-dependent state OS="$(get_operating_system)" From 00d1fa3ff04afa6ab6598918ae1c4ee779fb4da1 Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 20 Jul 2024 15:54:32 -0300 Subject: [PATCH 5/6] Setup resolve-on-editor resolution logic --- src/index.sh | 1 + src/package/package_conflict_input_parser.sh | 77 ++++++++++++++++++++ src/package/package_conflict_resolution.sh | 4 + 3 files changed, 82 insertions(+) create mode 100644 src/package/package_conflict_input_parser.sh diff --git a/src/index.sh b/src/index.sh index 17e9813..f168b74 100644 --- a/src/index.sh +++ b/src/index.sh @@ -7,4 +7,5 @@ . "$TORI_ROOT/src/package/package_conflict_resolution.sh" . "$TORI_ROOT/src/package/package_tracking.sh" . "$TORI_ROOT/src/package/validate_input_packages.sh" +. "$TORI_ROOT/src/package/package_conflict_input_parser.sh" . "$TORI_ROOT/src/package/update_package_cache.sh" diff --git a/src/package/package_conflict_input_parser.sh b/src/package/package_conflict_input_parser.sh new file mode 100644 index 0000000..555f914 --- /dev/null +++ b/src/package/package_conflict_input_parser.sh @@ -0,0 +1,77 @@ +package_conflict_input_parser() { + local packages="$1" + local conflict_type="$2" + local input="$TMP_DIR/package_conflict_input" + local input_choices="$TMP_DIR/package_conflict_input_choices" + local choices= + local packages_to_install= + local packages_to_uninstall= + local packages_to_track= + local packages_to_untrack= + + help_text_generator "$conflict_type" > "$input" + + echo "$packages" | sed 's/ /\n/g' | while read -r package; do + echo "skip $package" >> "$input" + done + + $EDITOR "$input" + + choices="$(cat "$input" | grep -v '^#' | grep '.')" > "$input_choices" + + # validation + while read -r action package; do + + validate_input_packages "$package" + + if [ "$action" = install ] || [ "$action" = i ]; then + packages_to_install="$packages_to_install $package" + elif [ "$action" = uninstall ] || [ "$action" = u ]; then + packages_to_uninstall="$packages_to_uninstall $package" + elif [ "$action" = add ] || [ "$action" = a ]; then + packages_to_track="$packages_to_track $package" + elif [ "$action" = remove ] || [ "$action" = r ]; then + packages_to_untrack="$packages_to_untrack $package" + elif [ "$action" = skip ] || [ "$action" = s ]; then + log debug "[package_conflict_input_parser] Skipped: $package" + else + log user "Invalid action provided: $action" + fi + done < "$input_choices" + + # actual system or configuration change + echo "$choices" | while read -r action package; do + if [ "$action" = install ] || [ "$action" = i ]; then + package_manager install "$packages_to_install" + elif [ "$action" = uninstall ] || [ "$action" = u ]; then + debug info "Calling package manager to uninstall $packages_to_uninstall" + package_manager uninstall "$packages_to_uninstall" + elif [ "$action" = add ] || [ "$action" = a ]; then + track_packages "$package" + elif [ "$action" = remove ] || [ "$action" = r ]; then + untrack_packages "$package" + fi + done +} + + +help_text_generator() { + local conflict_type="$1" + + echo "# Options:" + + if [ "$conflict_type" == not_installed ]; then + echo "# [i]nstall Install package to system" + echo "# [r]emove Remove from configuration" + elif [ "$conflict_type" == not_on_configuration ]; then + echo "# [u]ninstall Uninstall package from system" + echo "# [a]dd Add to configuration" + else + debug fatal "Invalid conflict type provided: $conflict_type" + return 1 + fi + + echo "# [s]kip Do not take any action" + echo -e "\n# Providing just the value between brackets is sufficient" + echo -e "# Replace 'skip' below with the desired option\n" +} diff --git a/src/package/package_conflict_resolution.sh b/src/package/package_conflict_resolution.sh index e73a8d6..f2ba8dd 100644 --- a/src/package/package_conflict_resolution.sh +++ b/src/package/package_conflict_resolution.sh @@ -57,6 +57,8 @@ not_on_configuration_dialog() { if validate_input_packages "$input_packages"; then track_packages "$input_packages" fi + elif [ "$strategy" = 5 ]; then + package_conflict_input_parser "$conflicted_packages" 'not_on_configuration' else log debug "[resolve_packages] Unexpected input: $strategy" not_on_configuration_dialog "$conflicted_packages" @@ -97,6 +99,8 @@ not_installed_dialog() { read -r -p "Enter space-separated packages to remove from the configuation: " input_packages log debug "Input: input_packages = $input_packages" untrack_packages "$input_packages" + elif [ "$strategy" = 5 ]; then + package_conflict_input_parser "$conflicted_packages" 'not_installed' else log debug "[resolve_packages] Unexpected input: $strategy" not_installed_dialog "$conflicted_packages" From 7868149bbfd7ab7027b5cc4bcb44ec35d677111b Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 20 Jul 2024 16:32:36 -0300 Subject: [PATCH 6/6] Allow multiple strategies on editor resolution --- src/package/package_conflict_input_parser.sh | 33 +++++++++++--------- src/package/package_tracking.sh | 4 +-- tori | 1 - 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/package/package_conflict_input_parser.sh b/src/package/package_conflict_input_parser.sh index 555f914..6c5d9e7 100644 --- a/src/package/package_conflict_input_parser.sh +++ b/src/package/package_conflict_input_parser.sh @@ -17,7 +17,8 @@ package_conflict_input_parser() { $EDITOR "$input" - choices="$(cat "$input" | grep -v '^#' | grep '.')" > "$input_choices" + choices="$(cat "$input" | grep -v '^#' | grep '.')" + echo "$choices" > "$input_choices" # validation while read -r action package; do @@ -35,25 +36,27 @@ package_conflict_input_parser() { elif [ "$action" = skip ] || [ "$action" = s ]; then log debug "[package_conflict_input_parser] Skipped: $package" else - log user "Invalid action provided: $action" + log user "Invalid action provided for $package: $action" fi done < "$input_choices" # actual system or configuration change - echo "$choices" | while read -r action package; do - if [ "$action" = install ] || [ "$action" = i ]; then - package_manager install "$packages_to_install" - elif [ "$action" = uninstall ] || [ "$action" = u ]; then - debug info "Calling package manager to uninstall $packages_to_uninstall" - package_manager uninstall "$packages_to_uninstall" - elif [ "$action" = add ] || [ "$action" = a ]; then - track_packages "$package" - elif [ "$action" = remove ] || [ "$action" = r ]; then - untrack_packages "$package" - fi - done -} + if [ -n "$packages_to_install" ]; then + package_manager install "$packages_to_install" + fi + if [ -n "$packages_to_uninstall" ]; then + package_manager uninstall "$packages_to_uninstall" + fi + + if [ -n "$packages_to_track" ]; then + track_packages "$packages_to_track" + fi + + if [ -n "$packages_to_untrack" ]; then + untrack_packages "$packages_to_untrack" + fi +} help_text_generator() { local conflict_type="$1" diff --git a/src/package/package_tracking.sh b/src/package/package_tracking.sh index f8eeb06..9567efc 100644 --- a/src/package/package_tracking.sh +++ b/src/package/package_tracking.sh @@ -9,10 +9,10 @@ track_packages() { untrack_packages() { local packages="$1" - log debug "[untrack_packages] Removing packages: $packages" + log info "[untrack_packages] Removing packages: $packages" echo "$packages" | xargs | sed 's/ /\n/g' | while read -r package; do sed -i '' "/^[[:space:]]*$package[[:space:]]*$/d" "$CONFIG_ROOT/packages" - log debug "[untrack_packages] Executed removal for $package with exit code $?" + log info "[untrack_packages] Executed removal for $package with exit code $?" done } diff --git a/tori b/tori index 0f59126..6009659 100755 --- a/tori +++ b/tori @@ -69,7 +69,6 @@ check_core_paths() { exit 1 fi - [ -n "$DEBUG" ] && echo "TORI_ROOT: $TORI_ROOT" } main "$1" "$2"