diff --git a/APP-MANAGER b/APP-MANAGER index 82199d4a8..f3efc062c 100755 --- a/APP-MANAGER +++ b/APP-MANAGER @@ -1,6 +1,6 @@ #!/usr/bin/env bash -AMVERSION="10.1-4" +AMVERSION="10.1-13" # Determine main repository and branch AMREPO="https://raw.githubusercontent.com/ivan-hc/AM/main" @@ -492,10 +492,119 @@ _validate_and_download_lists_of_archived_and_obsolete_apps() { # SAFETY CHECKS +# Function to check online connections (uses github.com by default, as the database and CLI itself are stored/hosted there) +_online_check_tool() { + if command -v wget >/dev/null 2>&1; then + wget -q --tries=10 --timeout=20 --spider https://github.com + elif command -v curl >/dev/null 2>&1; then + curl --output /dev/null --silent --head --fail https://github.com 1> /dev/null + else + printf $" ${RED}💀 ERROR! MISSING ESSENTIAL COMMANDS\033[0m: %s\n\n Install the above and try again! \n" "$(echo "curl, wget")" + exit 0 + fi +} + +_online_check() { + if ! _online_check_tool; then + printf $"\n %b is offline, please check your internet connection and try again\n\n" "$AMCLI" + exit 0 + fi +} + +_checksum_on_standard_dependencies() { + if [ -f "$CACHEDIR"/AMCACHEPATH/"$name" ]; then + dep_sum256_local=$(sha256sum "$CACHEDIR"/AMCACHEPATH/"$name" 2>/dev/null | awk '{print $1}') + dep_sum256_host=$(sort "$AMCACHEDIR/$ARCH.sha256sum.txt" | grep "$name-$ARCH-static$" 2>/dev/null | awk '{print $1}') + if [ "$dep_sum256_local" != "$dep_sum256_host" ]; then + rm -Rf "$CACHEDIR"/AMCACHEPATH/"$name" + _deps_dl && chmod a+x "$CACHEDIR"/AMCACHEPATH/"$name" && printf $" - %b, downloaded from https://github.com/ivan-hc/am-utils\n" "$name" + fi + fi +} + +# Use static binaries as a fallback solution in case there are no dependencies +AM_core_dependencies="cat chmod chown curl grep sed wget" +AM_opt_dependencies="7z ar column file md5sum notify-send sha1sum sha256sum sha512sum tar unxz unzip xz xzcat" +AM_standard_dependencies="$AM_core_dependencies $AM_opt_dependencies" +_deps_dl() { + if command -v curl >/dev/null 2>&1; then + curl -Lo "$CACHEDIR"/AMCACHEPATH/"$name" "$AM_UTILS_SOURCE/$name-$ARCH-static" 2>/dev/null + elif command -v wget >/dev/null 2>&1; then + wget -q "$AM_UTILS_SOURCE/$name-$ARCH-static" -O "$CACHEDIR"/AMCACHEPATH/"$name" + fi +} + +if [ "$ARCH" = aarch64 ] || [ "$ARCH" = x86_64 ]; then + mkdir -p "$CACHEDIR"/AMCACHEPATH + # Download static binaries if commands are not available + amutils="$AM_standard_dependencies" + AM_UTILS_SOURCE="https://github.com/ivan-hc/am-utils/releases/download/continuous-$ARCH" + for name in $amutils; do + if ! command -v "$name" >/dev/null 2>&1; then + if [ -d "$CACHEDIR"/AMCACHEPATH/"$name" ] || [ -L "$CACHEDIR"/AMCACHEPATH/"$name" ] || [ ! -f "$CACHEDIR"/AMCACHEPATH/"$name" ]; then + rm -Rf "$CACHEDIR"/AMCACHEPATH/"$name" + if [ -z "$fallback_binaries_needed" ]; then + fallback_binaries_needed="$name" + else + fallback_binaries_needed=$(echo "$fallback_binaries_needed $name" | tr ' ' '\n' | sort | xargs) + fi + fi + fi + done + if [ -n "$fallback_binaries_needed" ]; then + _online_check + printf "%b\n" "$DIVIDING_LINE" + printf $"Missing commands will be temporarily downloaded as static binaries:\n\n" | _fit + for name in $fallback_binaries_needed; do + _deps_dl && chmod a+x "$CACHEDIR"/AMCACHEPATH/"$name" && printf $" - %b, downloaded from https://github.com/ivan-hc/am-utils\n" "$name" & + done + wait + printf "\n%b\n" "$DIVIDING_LINE" + fi + # Remove static binaries and other temporary utilities if related commands are already available in PATH + amutils="appimagetool $amutils" + for name in $amutils; do + if command -v "$name" >/dev/null 2>&1 && [ -f "$CACHEDIR"/AMCACHEPATH/"$name" ]; then + rm -Rf "$CACHEDIR"/AMCACHEPATH/"$name" + fi + done + # Check AMCACHEPATH integrity + am_bins_allowed=$(echo "$amutils" | tr ' ' '\n' | sed "s#^#$CACHEDIR/AMCACHEPATH/#g") + am_bins_all=$(find "$CACHEDIR"/AMCACHEPATH -mindepth 1 -maxdepth 1 \( -type d -o -type f -o -type l \)) + if [ -n "$am_bins_all" ]; then + for f in "$CACHEDIR"/AMCACHEPATH/*; do + am_bin_item=$(echo "$f" | sed 's:.*/::') + if ! echo "$am_bins_allowed" | grep -q "$am_bin_item$" 2>/dev/null; then + rm -Rf "$f" + fi + done + fi + # Check binaries integrity + if [ "$(ls -A "$CACHEDIR"/AMCACHEPATH 2>/dev/null)" ]; then + if [ ! -f "$AMCACHEDIR"/"$ARCH".sha256sum.txt ]; then + if curl --output /dev/null --silent --head --fail https://github.com 1> /dev/null; then + deps_sum256_all=$(curl -Ls "$AM_UTILS_SOURCE/$ARCH.sha256sum.txt" 2>/dev/null) + if [ -n "$deps_sum256_all" ]; then + echo "$deps_sum256_all" > "$AMCACHEDIR"/"$ARCH".sha256sum.txt + fi + fi + printf "%b\n" "$DIVIDING_LINE" + printf $"Temporary fallback binaries are in use for the commands below:\n%b%b\033[0m\nInstall them to avoid slow performance.\n" "${Green}" "$(ls "$CACHEDIR"/AMCACHEPATH/ | xargs | _fit )" | _fit + printf "%b\n" "$DIVIDING_LINE" + fi + if [ -f "$AMCACHEDIR"/"$ARCH".sha256sum.txt ]; then + for name in $AM_standard_dependencies; do + _checksum_on_standard_dependencies & + done + wait + export PATH="$CACHEDIR"/AMCACHEPATH/:"${PATH}" + fi + fi +fi + # Check for essential commands required by the application missing_deps="" -AMDEPENDENCES="cat chmod chown curl grep sed wget" -for name in $AMDEPENDENCES; do +for name in $AM_core_dependencies; do if ! command -v "$name" >/dev/null 2>&1; then missing_deps="$name $missing_deps" fi @@ -506,7 +615,7 @@ if [ -n "$missing_deps" ]; then echo "$DIVIDING_LINE" printf $" ${RED}💀 ERROR! MISSING ESSENTIAL COMMANDS\033[0m: %s\n\n Install the above and try again! \n" "${missing_deps[*]}" echo "$DIVIDING_LINE" - printf $"%bList of the %b core dependences\033[0m:\n\n%b\n" "${Green}" "$AMCLIUPPER $AMVERSION" "$AMDEPENDENCES" | _fit + printf $"%bList of the %b core dependences\033[0m:\n\n%b\n" "${Green}" "$AMCLIUPPER $AMVERSION" "$AM_core_dependencies" | _fit echo "$DIVIDING_LINE" printf $"If this message appears it is because you are missing some dependency and if its the first time its because something new has been introduced.\n\n" | _fit printf $" See %bhttps://github.com/ivan-hc/AM#installation\033[0m for more information\n" "${LightBlue}" @@ -533,21 +642,6 @@ _check_fedora_mess() { fi } -# Function to check online connections (uses github.com by default, as the database and CLI itself are stored/hosted there) -_online_check() { - if ! wget -q --tries=10 --timeout=20 --spider https://github.com; then - printf $"\n %b is offline, please check your internet connection and try again\n\n" "$AMCLI" - exit 0 - fi -} - -# Check AMCACHEPATH integrity -if [ -d "$CACHEDIR"/AMCACHEPATH ]; then - am_bins_allowed=$(echo "appimagetool" | tr ' ' '\n' | sed "s#^#$CACHEDIR/AMCACHEPATH/#g") - am_bins_all=$(find "$CACHEDIR"/AMCACHEPATH -mindepth 1 -maxdepth 1 \( -type d -o -type f -o -type l \)) - for f in $am_bins_all; do if ! echo "$am_bins_allowed" | grep -q "$f$" 2>/dev/null; then rm "$f" 2>/dev/null; fi; done -fi - # Check if appimagetool is installed, and if it is not installed, download and use it where it is needed _download_appimagetool() { _determine_args @@ -1659,7 +1753,15 @@ _update_print_updated_apps_table() { app_header=$(printf $"App") old_header=$(printf $"Previous") new_header=$(printf $"Current") - diff "$OLDVER" "$NEWVER" | grep "^>" | sed 's/^> //g' | while IFS= read -r updated_app; do + awk ' + NR==FNR { a[NR]=$0; next } + { + if ($0 != a[FNR]) { + print "< " a[FNR] + print "> " $0 + } + } + ' "$OLDVER" "$NEWVER" | grep "^>" | sed 's/^> //g' | while IFS= read -r updated_app; do arg=$(printf "%s\n" "$updated_app" | awk '{print $2}') old_app=$(grep -F " ◆ $arg " "$OLDVER" | head -1) old_version=$(printf "%s\n" "$old_app" | sed "s/^ ◆ $arg //; s/\x1b\[[0-9;]*m//g; s/[✖✓🔒]//g; s/ */ /g; s/ $//") @@ -1697,7 +1799,7 @@ _update_determine_apps_version_changes() { _update_list_updatable_apps OLDVER="$AMCACHEDIR/updatable-args-list-old" NEWVER="$AMCACHEDIR/updatable-args-list" - if cmp --silent -- "$NEWVER" "$OLDVER"; then + if [ "$(sort "$NEWVER")" = "$(sort "$OLDVER")" ]; then printf $" Nothing to do here! \n" else printf $" The following apps have been updated:\n\n" diff --git a/modules/install.am b/modules/install.am index a93daa0fa..009cb0d41 100644 --- a/modules/install.am +++ b/modules/install.am @@ -63,30 +63,18 @@ _check_argument() { } _check_if_optional_dependences_are_needed() { - # Determine generic build utils - app_deps="ar gcc glib-compile-schemas make tar unzip" # Determine if the argument is a script and not something else - if head -c10 ./"$arg" 2>/dev/null | grep -q "^#!"; then - script_content=$(cat ./"$arg") - elif head -c10 ./"$arg" 2>/dev/null | grep -qa '^.ELF....AI$'; then + if head -c10 ./"$arg" 2>/dev/null | grep -qa '^.ELF....AI$'; then printf $"💀 ERROR: this option is ment to handle installation scripts only! \n\n" | _fit printf $" If this AppImage is not in our database, open an issue or a pull request at\n https://github.com/ivan-hc/AM\n\n" | _fit _check_argument return 1 - else + elif ! head -c10 ./"$arg" 2>/dev/null | grep -q "^#!"; then printf $"💀 ERROR: \"$arg\" is not a valid file! \n\n" | _fit printf $"This option is ment to handle installation scripts only! \n\n" | _fit _check_argument return 1 fi - # Determine if this is an AppImage that can be compiled on-the-fly - if grep -qi "^wget.*.sh.*chmod.*&&" ./"$arg"; then - appimage_bulder_script=$(grep "^wget " ./"$arg" | tr '"' '\n' | grep -i "^http" | sed "s/\$APP/$arg/g") - if ! curl --output /dev/null --silent --head --fail "$appimage_bulder_script" 1> /dev/null; then - echo $" 💀 ERROR: cannot create \"$arg\", the builder does not exists" - return 1 - fi - fi # Determine if this script installs a Firefox webapp if grep -q 'ffwa-' ./"$arg"; then ffbrowser=$(find ${PATH//:/ } -maxdepth 1 -name "firefox*" | sort | head -1) @@ -97,15 +85,6 @@ _check_if_optional_dependences_are_needed() { sed -i 's#firefox --class#'"$(echo "$ffbrowser" | xargs -L 1 basename)"' --class#g' ./"$arg" fi fi - # Check missing dependency - for name in $app_deps; do - dependency_name="$name" - [ "$name" = "ar" ] && dependency_name="binutils" - if echo "$script_content" | grep -q "^$name" && ! command -v "$name" >/dev/null 2>&1; then - echo $" 💀 ERROR: cannot install \"$arg\" without \"$dependency_name\"" - return 1 - fi - done } _check_if_script_installs_a_metapackage() { @@ -298,6 +277,14 @@ _ending_the_installation() { fi } +_install_exec_installation_script() { + if [ "$(ls -A "$CACHEDIR"/AMCACHEPATH 2>/dev/null)" ] && [ -n "$SUDOCMD" ]; then + $SUDOCMD PATH="$PATH" ./"$arg" + else + $SUDOCMD ./"$arg" + fi +} + _install_script_retry() { # Determine if the installation has stopped when trying to download the app test_lastdir=$(ls -td "$APPSPATH"/* | head -1 | sed 's:.*/::') @@ -309,7 +296,7 @@ _install_script_retry() { if [ -z "$( ls -A "$test_lastdir_tmp" )" ]; then printf "\n The file was not downloaded, attempt %b of 5 will start in 5 seconds...\n\n" "$((TAKES_COUNT + 1))" sleep 5 - $SUDOCMD ./"$arg" + _install_exec_installation_script fi fi TAKES_COUNT=$((TAKES_COUNT + 1)) @@ -326,7 +313,7 @@ _install_script_retry() { printf -- "\n %b✔ Attempting to extend pages in progress...\033[0m\n\n" "${Gold}" sleep 5 sed -i 's#/releases #/releases?per\_page=100 #g' ./"$arg" - $SUDOCMD ./"$arg" || printf -- "\n %b✖ Failed! \033[0m \n" "${RED}" + _install_exec_installation_script || printf -- "\n %b✖ Failed! \033[0m \n" "${RED}" else # No patches found printf -- "\n %b✖ No patch available! \033[0m \n" "${RED}" @@ -354,7 +341,7 @@ _install_arg() { # Set trap to cleanup on interruption (Ctrl+C, kill, hangup, quit) trap _installation_cleanup INT TERM HUP QUIT # Install script - $SUDOCMD ./"$arg" || _install_script_retry + _install_exec_installation_script || _install_script_retry echo "" _post_installation_processes _ending_the_installation