#!/bin/bash # 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 # getting source files based on commit hash). # The MIT License (MIT) # 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 # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. set -e TERMUX_SCRIPTDIR="$(realpath "$(dirname "$(readlink -f "$0")")/../..")" declare -a UNIQUE_PACKAGES _RESET_COLOR="\033[0m" _BLUE="\033[1;34m" _GREEN="\033[0;32m" _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 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}" } 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 else warn "Not a github url: $url" 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 } is_unique_package() { local package="$1" if [[ -z "${UNIQUE_PACKAGES[1]}" ]]; then # NOTE: mapfile requires bash 4+ mapfile -t UNIQUE_PACKAGES < <( curl --silent --location --retry 5 --retry-delay 5 --retry-max-time 60 \ "https://repology.org/api/v1/projects/?inrepo=termux&&repos=1" | jq -r 'keys[]' ) [[ -z "${UNIQUE_PACKAGES[1]}" ]] && 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. else error "Package '$package' is unique, hence 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) sed -i "${first_empty_line}i$line" "$file" else warn "$line already exists in $(basename "$file"). Skipping." fi } check() { PKG_NAME="$1" [[ "${SILENT}" == "true" ]] || echo -e "${_BLUE}==>${_YELLOW} ${PKG_NAME}${_RESET_COLOR}" local build_sh= 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 fi if [ -z "$build_sh" ]; then error "No package $PKG_NAME found in any of the repository" fi SRC_URL="$( # shellcheck source=/dev/null . $build_sh >/dev/null 2>&1 echo "${TERMUX_PKG_SRCURL}" )" if [[ -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" ) can_be_updated=false for check in "${checks[@]}"; do info "Checking if package ${check//_/ }..." if $check "${SRC_URL}"; then can_be_updated=true break fi done if [[ "${can_be_updated}" == "true" ]]; then info "Package can be auto-updated." if [[ "${ENABLE}" == "--enable" ]]; then info "Enabling auto-update..." write_to_first_empty_line \ $build_sh "TERMUX_PKG_AUTO_UPDATE=true" info "Done." return fi else error "Package cannot be auto-updated." fi } if [[ $# -lt 1 ]] || [[ $# -gt 2 ]]; then error "Invalid number of arguments. See --help for usage." fi while [[ $# -gt 0 ]]; do case "$1" in --enable) ENABLE="--enable" ;; -s | --silent) SILENT=true ;; -h | --help) usage ;; *) check "$1" [[ "${SILENT}" == "true" ]] || echo # Newline. ;; esac shift done