#!/usr/bin/env bash # shellcheck source-path=/data/data/com.termux/files/home/termux-packages set -u # Following variables should be set in environment outside of this script. # Build updated packages. : "${BUILD_PACKAGES:=false}" # Commit changes to Git. : "${GIT_COMMIT_PACKAGES:=false}" # Push changes to remote. : "${GIT_PUSH_PACKAGES:=false}" export TERMUX_PKG_UPDATE_METHOD="" # Which method to use for updating? (repology, github or gitlab) export TERMUX_PKG_UPDATE_TAG_TYPE="" # Whether to use latest-release-tag or newest-tag. export TERMUX_GITLAB_API_HOST="gitlab.com" # Default host for gitlab-ci. export TERMUX_PKG_AUTO_UPDATE=false # Whether to auto-update or not. Disabled by default. export TERMUX_PKG_UPDATE_VERSION_REGEXP="" # Regexp to extract version. export TERMUX_REPOLOGY_DATA_FILE TERMUX_REPOLOGY_DATA_FILE="$(mktemp -t termux-repology.XXXXXX)" # File to store repology data. export TERMUX_SCRIPTDIR TERMUX_SCRIPTDIR="$(realpath "$(dirname "$0")/../..")" # Script directory. # Define few more variables used by scripts. # shellcheck source=scripts/properties.sh . "${TERMUX_SCRIPTDIR}/scripts/properties.sh" # Utility function to write error message to stderr. # shellcheck source=scripts/updates/utils/termux_error_exit.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/utils/termux_error_exit.sh # Utility function to write updated version to build.sh. # shellcheck source=scripts/updates/utils/termux_pkg_upgrade_version.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/utils/termux_pkg_upgrade_version.sh # Utility function to check if package needs to be updated, based on version comparison. # shellcheck source=scripts/updates/utils/termux_pkg_is_update_needed.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/utils/termux_pkg_is_update_needed.sh # Wrapper around github api to get latest release or newest tag. # shellcheck source=scripts/updates/api/termux_github_api_get_tag.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/api/termux_github_api_get_tag.sh # Wrapper around gitlab api to get latest release or newest tag. # shellcheck source=scripts/updates/api/termux_gitlab_api_get_tag.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/api/termux_gitlab_api_get_tag.sh # Function to get latest version of a package as per repology. # shellcheck source=scripts/updates/api/termux_repology_api_get_latest_version.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/api/termux_repology_api_get_latest_version.sh # Default auto update script for packages hosted on github.com. Should not be overrided by build.sh. # To use custom algorithm, one should override termux_pkg_auto_update(). # shellcheck source=scripts/updates/internal/termux_github_auto_update.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/internal/termux_github_auto_update.sh # Default auto update script for packages hosted on hosts using gitlab-ci. Should not be overrided by build.sh. # To use custom algorithm, one should override termux_pkg_auto_update(). # shellcheck source=scripts/updates/internal/termux_gitlab_auto_update.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/internal/termux_gitlab_auto_update.sh # Default auto update script for rest packages. Should not be overrided by build.sh. # To use custom algorithm, one should override termux_pkg_auto_update(). # shellcheck source=scripts/updates/internal/termux_repology_auto_update.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/internal/termux_repology_auto_update.sh # Main script to: # - by default, decide which update method to use, # - but can be overrided by build.sh to use custom update method. # - For example: see neovim-nightly's build.sh. # shellcheck source=scripts/updates/termux_pkg_auto_update.sh . "${TERMUX_SCRIPTDIR}"/scripts/updates/termux_pkg_auto_update.sh _update() { export TERMUX_PKG_NAME TERMUX_PKG_NAME="$(basename "$1")" # Avoid: # - ending on errors such as $(which prog), where prog is not installed. # - error on unbound variable. # # Variables used by auto update script should be covered by above variables and properties.sh. set +e +u # shellcheck source=/dev/null . "${pkg_dir}"/build.sh 2>/dev/null set -e -u IFS="," read -r -a BLACKLISTED_ARCH <<<"${TERMUX_PKG_BLACKLISTED_ARCHES:-}" export TERMUX_ARCH="" # Arch to test updates. for arch in aarch64 arm i686 x86_64; do # shellcheck disable=SC2076 if [[ ! " ${BLACKLISTED_ARCH[*]} " =~ " ${arch} " ]]; then TERMUX_ARCH="${arch}" break fi done echo # Newline. echo "INFO: Updating ${TERMUX_PKG_NAME}..." # Only update if auto update is enabled. if [[ "${TERMUX_PKG_AUTO_UPDATE}" == "true" ]]; then echo "INFO: Current version: ${TERMUX_PKG_VERSION}" termux_pkg_auto_update echo # Newline. else echo "INFO: Skipping update. Auto update is disabled." fi } _test_pkg_build_file() { local pkg_dir="$1" if [[ ! -f "${pkg_dir}/build.sh" ]]; then # Fail if detected a non-package directory. termux_error_exit "ERROR: directory '${pkg_dir}' is not a package." fi } declare -a _FAILED_UPDATES=() _run_update() { local pkg_dir="$1" _test_pkg_build_file "${pkg_dir}" # Run each package update in separate process since we include their environment variables. ( set -euo pipefail _update "${pkg_dir}" ) # shellcheck disable=SC2181 if [[ $? -ne 0 ]]; then _FAILED_UPDATES+=("$(basename "${pkg_dir}")") fi } _get_unique_packages() { local -a unique_packages=() while read -r pkg; do unique_packages+=("${pkg}") done < <(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) echo "${unique_packages[@]}" } declare -a _UNIQUE_PACKAGES read -r -a _UNIQUE_PACKAGES <<<"$(_get_unique_packages)" _unique_to_termux() { local pkg_dir="$1" # shellcheck disable=2076 # We want literal match not regex. if [[ "${_UNIQUE_PACKAGES[*]}" =~ "\"$(basename "${pkg_dir}")\"" ]]; then return 0 else return 1 fi } main() { echo "INFO: Running update for: $*" if [[ "$1" == "@all" ]]; then for pkg_dir in "${TERMUX_SCRIPTDIR}"/packages/*; do # Skip update if package is unique to Termux. if _unique_to_termux "${pkg_dir}"; then echo # Newline. echo "INFO: Skipping update for unique to Termux package: $(basename "${pkg_dir}")" continue fi _run_update "${pkg_dir}" done else for pkg in "$@"; do # Skip update if package is unique to Termux. if _unique_to_termux "${TERMUX_SCRIPTDIR}"/packages/"${pkg}"; then echo # Newline. echo "INFO: Skipping update for unique to Termux package: ${pkg}" continue fi _run_update "${TERMUX_SCRIPTDIR}/packages/${pkg}" done fi if ((${#_FAILED_UPDATES[@]} > 0)); then echo # Newline. echo "===========================Failed updates===========================" for failed_update in "${_FAILED_UPDATES[@]}"; do echo "==> ${failed_update}" done exit 1 # Exit with error code, so that we know that some/all updates failed. fi } main "$@"