From a43f6b8eba504b1fd12c301abfea2af95aa55c7d Mon Sep 17 00:00:00 2001 From: Aditya Alok Date: Fri, 29 Apr 2022 14:36:24 +0530 Subject: [PATCH] feat(scripts/check-auto-update): improve script, minor clean up - add checks for 'newest-tag' as fallback, if 'latest-release-tag' is not found - adhere to DRY principle Signed-off-by: Aditya Alok --- scripts/bin/check-auto-update | 269 ++++++++++++++++++---------------- 1 file changed, 142 insertions(+), 127 deletions(-) diff --git a/scripts/bin/check-auto-update b/scripts/bin/check-auto-update index 00c62a0c9..c1cd8f93d 100755 --- a/scripts/bin/check-auto-update +++ b/scripts/bin/check-auto-update @@ -2,12 +2,12 @@ # This script is used to check if given package can be auto-updated and optionally enable if it can be. # NOTE: You should not trust this script if package uses commit hashes for versioning(eg. 'tsu') or -# TERMUX_PKG_VERSION is defined by us and not upstream(i.e we use some arbitrary version. For eg. when only +# TERMUX_PKG_VERSION is defined by us and not upstream(i.e we use some arbitrary version. For eg. when # getting source files based on commit hash). # The MIT License (MIT) -# Copyright (c) 2022 Aditya Alok +# Copyright (c) 2022 Aditya Alok # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -30,7 +30,6 @@ set -e TERMUX_SCRIPTDIR="$(realpath "$(dirname "$(readlink -f "$0")")/../..")" -declare -a UNIQUE_PACKAGES _RESET_COLOR="\033[0m" _BLUE="\033[1;34m" @@ -39,107 +38,105 @@ _RED="\033[0;31m" _YELLOW="\033[0;33m" _TEAL="\033[0;36m" -warn() { - [[ "${SILENT}" == "true" ]] && return - local warn_color="\033[1;33m" - echo -e "${_BLUE}[${warn_color}*${_BLUE}]${_YELLOW} $*${_RESET_COLOR}" >&2 -} - -error() { - [[ "${SILENT}" == "true" ]] && exit 1 - local error_color="\033[1;31m" - echo -e "${_BLUE}[${error_color}!${_BLUE}]${_RED} $*${_RESET_COLOR}" >&2 - exit 1 -} - -info() { - [[ "${SILENT}" == "true" ]] && return - local info_color="\033[1;32m" - echo -e "${_BLUE}[${info_color}+${_BLUE}]${_TEAL} $*${_RESET_COLOR}" -} - usage() { - echo -e "${_BLUE}Usage:${_RESET_COLOR} $(basename "$0")" \ - "${_GREEN}[-h|--help]${_RESET_COLOR}" \ - "${_GREEN}[-s|--silent]${_RESET_COLOR}" \ - "${_GREEN}[--enable]${_RESET_COLOR}" \ - "${_GREEN}PACKAGE [PACKAGE...]${_RESET_COLOR}" echo - echo -e "${_TEAL}Check if packages can be auto-updated and optionally enable if so.${_RESET_COLOR}" + echo -e "${_BLUE}Usage:${_RESET_COLOR} $(basename "$0")" \ + "${_GREEN}[-h|--help]" \ + "[-s|--silent]" \ + "[--enable]" \ + "PACKAGE_DIR [PACKAGE_DIR...]" + echo + echo -e "${_TEAL}Check if packages can be auto-updated and optionally enable if so." echo echo -e "${_RED}NOTE: ${_YELLOW}You should not trust this script if\n" \ "\t${_BLUE}- ${_YELLOW}package uses commit hashes for versioning (eg. 'tsu') or\n" \ "\t${_BLUE}- ${_GREEN}TERMUX_PKG_VERSION ${_YELLOW}is defined by us and not upstream, i.e we use some arbitrary version.\n" \ "\t For eg. when only getting source files based on commit hash." echo - echo -e "${_BLUE}Options:${_RESET_COLOR}" - echo -e "${_GREEN}-h --help${_TEAL} Show this help message.${_RESET_COLOR}" - echo -e "${_GREEN}--enable${_TEAL} Enable auto-updates for packages if it can be." \ - "Writes ${_YELLOW}TERMUX_PKG_AUTO_UPDATE=true${_TEAL} to build.sh${_RESET_COLOR}" + echo -e "${_BLUE}Options:" + echo -e "${_GREEN}-h --help${_TEAL} Show this help message." + echo -e "${_GREEN}--enable${_TEAL} Enable auto-updates for packages if it can be" \ + "(Writes ${_YELLOW}TERMUX_PKG_AUTO_UPDATE=true${_TEAL} to build.sh)." + echo -e "${_GREEN}-s --silent${_TEAL} Do not print anything to stdout." + echo + echo -e "${_BLUE}Example:${_RESET_COLOR} $(basename "$0") packages/cppcheck x11-packages/xorg-server" + echo } -can_be_updated_from_github() { - local url="$1" - if grep -Eq "^https?://github.com" <<<"$url"; then - local stderr - stderr="$( - set -euo pipefail - . "${TERMUX_SCRIPTDIR}/scripts/updates/api/termux_github_api_get_tag.sh" - . "${TERMUX_SCRIPTDIR}/scripts/updates/utils/termux_error_exit.sh" - termux_github_api_get_tag "$url" 2>&1 >/dev/null - )" || { - if grep -q "HTTP code:" <<<"${stderr}"; then - local http_code - http_code="$(grep "HTTP code:" <<<"${stderr}" | cut -d ':' -f 2 | tr -d ' ')" - if [[ "$http_code" == "000" ]]; then - error "Could not connect to GitHub API. Please check your internet connection." - fi - warn "Failed to get tag from github api [HTTP code: $http_code]." - return 1 - elif grep -q "ERROR:" <<<"${stderr}"; then - error "$(grep "ERROR:" <<<"${stderr}" | cut -d ':' -f 2 | sed 's/^[[:space:]]*//')" - return 1 - fi - } - return 0 +color_print() { + [[ "${SILENT}" == "true" ]] && return 0 + echo -e "$1${_RESET_COLOR}" +} + +warn() { + color_print "${_BLUE}[${_YELLOW}*${_BLUE}]${_YELLOW} $*" >&2 +} + +error() { + color_print "${_BLUE}[${_RED}!${_BLUE}]${_RED} $*" >&2 + exit 1 +} + +info() { + color_print "${_BLUE}[${_GREEN}+${_BLUE}]${_TEAL} $*" +} + +_check_stderr() { + local stderr="$1" + + local http_code + http_code="$(grep "HTTP code:" <<<"${stderr}" | cut -d ':' -f2 | tr -d ' ')" + + if [[ -n "${http_code}" ]]; then + [[ ${http_code} == 000 ]] && error "Could not connect to server. Please check your connection." + warn "Failed to get tag. [HTTP code: $http_code]" + return "$http_code" + elif grep -qE "ERROR: No '(latest-release-tag|newest-tag)'" <<<"${stderr}"; then + return 2 + elif grep -q "ERROR: GITHUB_TOKEN" <<<"$stderr"; then + error "GITHUB_TOKEN is not set." # exit script on this error. else - warn "Not a github url: $url" + warn "$stderr" return 1 fi } -can_be_updated_from_gitlab() { - local url="$1" - if grep -Eq "^https?://gitlab.com" <<<"$url"; then - stderr="$( - set -euo pipefail - . "${TERMUX_SCRIPTDIR}/scripts/updates/api/termux_gitlab_api_get_tag.sh" - . "${TERMUX_SCRIPTDIR}/scripts/updates/utils/termux_error_exit.sh" - termux_gitlab_api_get_tag "$url" 2>&1 >/dev/null - )" || { - if grep -q "HTTP code:" <<<"${stderr}"; then - local http_code - http_code="$(grep "HTTP code:" <<<"${stderr}" | cut -d ':' -f 2 | tr -d ' ')" - if [[ "$http_code" == "000" ]]; then - error "Could not connect to GitLab API. Please check your internet connection." - fi - warn "Failed to get tag from gitlab api [HTTP code: $http_code]." - return 1 - elif grep -q "ERROR:" <<<"${stderr}"; then - warn "$(grep "ERROR:" <<<"${stderr}" | cut -d ':' -f 2 | sed 's/^[[:space:]]*//')" - return 1 - fi - } - return 0 - else - warn "Not a gitlab url: $url" - return 1 - fi +_check() { + local from_where="$1" # Which api service to use? + shift + local stderr + stderr="$( + set -euo pipefail + # shellcheck source=/dev/null + . "${TERMUX_SCRIPTDIR}/scripts/updates/api/termux_${from_where}_api_get_tag.sh" + . "${TERMUX_SCRIPTDIR}/scripts/updates/utils/termux_error_exit.sh" + termux_"${from_where}"_api_get_tag "$@" 2>&1 >/dev/null + )" || _check_stderr "${stderr}" } -is_unique_package() { - local package="$1" - if [[ -z "${UNIQUE_PACKAGES[1]}" ]]; then +check() { + local from_where="$1" # Can be either 'github' or 'gitlab'. + local url="$2" + local return_code=0 + + _check "$from_where" "$url" || return_code="$?" + + if [[ "${url: -4}" != ".git" ]] && [[ "$return_code" == "2" ]]; then + warn "No 'latest-release-tag' found. Checking for 'newest-tag'..." + return_code=3 # Set return code to 3 to indicate that TERMUX_PKG_UPDATE_TAG_TYPE='newest-tag' + # should also be written to build.sh if we find 'newest-tag' in next line. + _check "$from_where" "$url" "newest-tag" || return_code="$?" + fi + + return "$return_code" +} + +declare -a UNIQUE_PACKAGES +# NOTE: This function ignores Termux own packages like 'termux-api','termux-exec', etc. +# It should be manually checked. +repology() { + local pkg_name="$1" + if [[ -z "${UNIQUE_PACKAGES[*]}" ]]; then # NOTE: mapfile requires bash 4+ mapfile -t UNIQUE_PACKAGES < <( curl --silent --location --retry 5 --retry-delay 5 --retry-max-time 60 \ @@ -147,67 +144,83 @@ is_unique_package() { jq -r 'keys[]' ) - [[ -z "${UNIQUE_PACKAGES[1]}" ]] && error "Failed to get unique packages from repology.org" + [[ -z "${UNIQUE_PACKAGES[*]}" ]] && error "Failed to get unique packages from repology.org" fi # shellcheck disable=SC2076 - if [[ ! " ${UNIQUE_PACKAGES[*]} " =~ " ${package} " ]]; then - return 0 # Package is not unique, hence can be updated. + if [[ ! " ${UNIQUE_PACKAGES[*]} " =~ " ${pkg_name} " ]]; then + return 0 # Package is not unique, can be updated. else - error "Package '$package' is unique, hence cannot be auto-updated." + warn "Package '$pkg_name' is unique to Termux, cannot be auto-updated." fi } write_to_first_empty_line() { local -r file="$1" local -r line="$2" - - if ! grep -q "^$line$" "$file"; then - # Find first empty line from top of file: - local -r first_empty_line=$(sed -n '/^$/=' "$file" | head -n 1) + # Find first empty line from top of file: + local -r first_empty_line=$(sed -n '/^$/=' "$file" | head -n 1) + if [[ -n "$first_empty_line" ]]; then sed -i "${first_empty_line}i$line" "$file" else - warn "$line already exists in $(basename "$file"). Skipping." + echo "$line" >>"$file" fi } -check() { - PKG_NAME="$1" - [[ "${SILENT}" == "true" ]] || echo -e "${_BLUE}==>${_YELLOW} ${PKG_NAME}${_RESET_COLOR}" - local build_sh= +test_pkg() { + local pkg_dir="$1" + local pkg_name + pkg_name="$(basename "${pkg_dir}")" - if [ -d "${PKG_NAME}" ] && [ -f "${PKG_NAME}/build.sh" ]; then - build_sh="${PKG_NAME}/build.sh" - else - for repo_dir in $(jq --raw-output 'keys | .[]' $TERMUX_SCRIPTDIR/repo.json); do - if [ -f $TERMUX_SCRIPTDIR/$repo_dir/$PKG_NAME/build.sh ]; then - build_sh=$TERMUX_SCRIPTDIR/$repo_dir/$PKG_NAME/build.sh - fi - done + if [[ ! -f "${pkg_dir}/build.sh" ]]; then + error "Package '$pkg_name' does not exist." fi - if [ -z "$build_sh" ]; then - error "No package $PKG_NAME found in any of the repository" - fi - SRC_URL="$( + + local vars + vars="$( + set +eu # shellcheck source=/dev/null - . $build_sh >/dev/null 2>&1 - echo "${TERMUX_PKG_SRCURL}" + . "$pkg_dir/build.sh" >/dev/null + echo "src_url=\"${TERMUX_PKG_SRCURL}\";" + echo "auto_update=\"${TERMUX_PKG_AUTO_UPDATE}\";" )" + local src_url="" + local auto_update="" + eval "$vars" - if [[ -z "${SRC_URL}" ]]; then + color_print "${_BLUE}==>${_YELLOW} $pkg_name" + + # Check if auto_update is not empty, then package has been already checked. + if [[ -n "${auto_update}" ]]; then + warn "Auto-update is already set to ${_BLUE}'${auto_update}'${_YELLOW} in build.sh." + return 0 + elif [[ -z "${src_url}" ]]; then error "Could not find TERMUX_PKG_SRCURL." fi - checks=( - "can_be_updated_from_github" - "can_be_updated_from_gitlab" - "is_unique_package" + local checks=( + "github" + "gitlab" + "repology" ) - can_be_updated=false + local can_be_updated=false + local tag_type="" for check in "${checks[@]}"; do - info "Checking if package ${check//_/ }..." - if $check "${SRC_URL}"; then + info "Checking if package can be updated from $check..." + local return_code=0 + + if [[ "$check" != "repology" ]]; then + check "$check" "$src_url" || return_code="$?" + else + repology "$pkg_name" || return_code="$?" + fi + + if [[ "$return_code" == "0" ]]; then can_be_updated=true break + elif [[ "$return_code" == "3" ]]; then + can_be_updated=true + tag_type="newest-tag" + break fi done @@ -216,23 +229,25 @@ check() { if [[ "${ENABLE}" == "--enable" ]]; then info "Enabling auto-update..." write_to_first_empty_line \ - $build_sh "TERMUX_PKG_AUTO_UPDATE=true" + "$pkg_dir/build.sh" "TERMUX_PKG_AUTO_UPDATE=true" + [[ -n "${tag_type}" ]] && write_to_first_empty_line \ + "$pkg_dir/build.sh" \ + "TERMUX_PKG_UPDATE_TAG_TYPE=\"${tag_type}\"" info "Done." - return fi else error "Package cannot be auto-updated." fi } -if [[ $# -lt 1 ]] || [[ $# -gt 2 ]]; then +if [[ $# -lt 1 ]]; then error "Invalid number of arguments. See --help for usage." fi while [[ $# -gt 0 ]]; do case "$1" in --enable) - ENABLE="--enable" + ENABLE="$1" ;; -s | --silent) SILENT=true @@ -241,7 +256,7 @@ while [[ $# -gt 0 ]]; do usage ;; *) - check "$1" + test_pkg "$1" [[ "${SILENT}" == "true" ]] || echo # Newline. ;; esac