Merge MrAdityaAlok's auto update feature and add neovim-nightly
Allows for auto-updates of more packages, not only the ones that are released through github. Ref: https://github.com/termux/termux-packages/pull/7977
This commit is contained in:
commit
c114f860a0
42
.github/workflows/package_updates.yml
vendored
42
.github/workflows/package_updates.yml
vendored
@ -2,26 +2,36 @@ name: Package updates
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 */6 * * *'
|
||||
- cron: "0 */6 * * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
packages:
|
||||
description: "A space-seperated list of packages to update. Defaults to all packages"
|
||||
default: "@all"
|
||||
required: false
|
||||
|
||||
jobs:
|
||||
update-packages:
|
||||
if: github.repository == 'termux/termux-packages'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GH_API_KEY }}
|
||||
- name: Process package updates
|
||||
env:
|
||||
GITHUB_API_TOKEN: ${{ secrets.GH_API_KEY }}
|
||||
BUILD_PACKAGES: "true"
|
||||
GIT_COMMIT_PACKAGES: "true"
|
||||
GIT_PUSH_PACKAGES: "true"
|
||||
run: |
|
||||
git config --global user.name "Termux Github Actions"
|
||||
git config --global user.email "contact@termux.org"
|
||||
bash ./scripts/bin/update-packages
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GH_API_KEY }}
|
||||
- name: Process package updates
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_API_KEY }}
|
||||
BUILD_PACKAGES: "true"
|
||||
GIT_COMMIT_PACKAGES: "true"
|
||||
GIT_PUSH_PACKAGES: "true"
|
||||
run: |
|
||||
git config --global user.name "Termux Github Actions"
|
||||
git config --global user.email "contact@termux.org"
|
||||
|
||||
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
|
||||
./scripts/bin/update-packages ${{ github.event.inputs.packages }}
|
||||
else
|
||||
./scripts/bin/update-packages "@all"
|
||||
fi
|
||||
|
125
packages/neovim-nightly/build.sh
Normal file
125
packages/neovim-nightly/build.sh
Normal file
@ -0,0 +1,125 @@
|
||||
TERMUX_PKG_HOMEPAGE=https://neovim.io
|
||||
TERMUX_PKG_DESCRIPTION="Ambitious Vim-fork focused on extensibility and agility (nvim-nightly)"
|
||||
TERMUX_PKG_LICENSE="Apache-2.0"
|
||||
TERMUX_PKG_MAINTAINER="Aditya Alok <dev.aditya.alok@gmail.com>"
|
||||
TERMUX_PKG_VERSION="0.7.0-dev+1341-g79dcd045d"
|
||||
TERMUX_PKG_SRCURL="https://github.com/neovim/neovim/archive/nightly.tar.gz"
|
||||
TERMUX_PKG_SHA256=d37d50c28059fde68b1ff6787bace6f4744c052cddce0bef38e4cf228da75266
|
||||
TERMUX_PKG_DEPENDS="libiconv, libuv, luv, libmsgpack, libandroid-support, libvterm, libtermkey, libluajit, libunibilium, libtreesitter"
|
||||
TERMUX_PKG_HOSTBUILD=true
|
||||
|
||||
TERMUX_PKG_EXTRA_CONFIGURE_ARGS="
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
-DENABLE_JEMALLOC=OFF
|
||||
-DGETTEXT_MSGFMT_EXECUTABLE=$(which msgfmt)
|
||||
-DGETTEXT_MSGMERGE_EXECUTABLE=$(which msgmerge)
|
||||
-DGPERF_PRG=$TERMUX_PKG_HOSTBUILD_DIR/deps/usr/bin/gperf
|
||||
-DLUA_PRG=$TERMUX_PKG_HOSTBUILD_DIR/deps/usr/bin/luajit
|
||||
-DPKG_CONFIG_EXECUTABLE=$(which pkg-config)
|
||||
-DXGETTEXT_PRG=$(which xgettext)
|
||||
-DLUAJIT_INCLUDE_DIR=$TERMUX_PREFIX/include/luajit-2.1
|
||||
"
|
||||
TERMUX_PKG_CONFFILES="share/nvim/sysinit.vim"
|
||||
TERMUX_PKG_CONFLICTS="neovim"
|
||||
|
||||
TERMUX_PKG_AUTO_UPDATE=true
|
||||
|
||||
termux_pkg_auto_update() {
|
||||
# Scrap and parse github release page to get version of nightly build.
|
||||
# Neovim just uses 'nightly' tag for release and not nightly version specific, so cannot use github api.
|
||||
local curl_response=$(
|
||||
curl \
|
||||
--silent \
|
||||
"https://github.com/neovim/neovim/releases/tag/nightly" \
|
||||
--write-out '|%{http_code}'
|
||||
)
|
||||
local http_code="${curl_response##*|}"
|
||||
|
||||
if [ "$http_code" != "200" ]; then
|
||||
echo "Error: failed to get latest neovim-nightly tag page."
|
||||
echo -e "http code: ${http_code}\ncurl response: ${curl_response}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# this outputs in the following format: "0.6.0-dev+575-g2ef9d2a66"
|
||||
local remote_nvim_version=$(
|
||||
echo "$curl_response" |
|
||||
cut -d"|" -f1 |
|
||||
grep "<pre><code>NVIM" | cut -d " " -f2 | sed "0,/v/s///"
|
||||
)
|
||||
|
||||
# since we are using a nightly build, therefore no need to check for version increment/decrement.
|
||||
if [ "${TERMUX_PKG_VERSION}" != "${remote_nvim_version}" ]; then
|
||||
termux_pkg_upgrade_version "${remote_nvim_version}" --skip-version-check
|
||||
fi
|
||||
}
|
||||
|
||||
_patch_luv() {
|
||||
# git submodule update --init deps/lua-compat-5.3 failed
|
||||
cp -r $1/build/src/lua-compat-5.3/* $1/build/src/luv/deps/lua-compat-5.3/
|
||||
cp -r $1/build/src/luajit/* $1/build/src/luv/deps/luajit/
|
||||
cp -r $1/build/src/libuv/* $1/build/src/luv/deps/libuv/
|
||||
}
|
||||
|
||||
termux_step_host_build() {
|
||||
termux_setup_cmake
|
||||
|
||||
TERMUX_ORIGINAL_CMAKE=$(which cmake)
|
||||
if [ ! -f "$TERMUX_ORIGINAL_CMAKE.orig" ]; then
|
||||
mv "$TERMUX_ORIGINAL_CMAKE" "$TERMUX_ORIGINAL_CMAKE.orig"
|
||||
fi
|
||||
cp "$TERMUX_PKG_BUILDER_DIR/custom-bin/cmake" "$TERMUX_ORIGINAL_CMAKE"
|
||||
chmod +x "$TERMUX_ORIGINAL_CMAKE"
|
||||
export TERMUX_ORIGINAL_CMAKE="$TERMUX_ORIGINAL_CMAKE.orig"
|
||||
|
||||
mkdir -p $TERMUX_PKG_HOSTBUILD_DIR/deps
|
||||
cd $TERMUX_PKG_HOSTBUILD_DIR/deps
|
||||
cmake $TERMUX_PKG_SRCDIR/third-party
|
||||
|
||||
make -j 1 ||
|
||||
(_patch_luv $TERMUX_PKG_HOSTBUILD_DIR/deps && make -j 1)
|
||||
|
||||
cd $TERMUX_PKG_SRCDIR
|
||||
|
||||
make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$TERMUX_PKG_HOSTBUILD_DIR -DUSE_BUNDLED_LUAROCKS=ON" install ||
|
||||
(_patch_luv $TERMUX_PKG_SRCDIR/.deps && make CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX=$TERMUX_PKG_HOSTBUILD_DIR -DUSE_BUNDLED_LUAROCKS=ON" install)
|
||||
|
||||
make distclean
|
||||
rm -Rf build/
|
||||
|
||||
cd $TERMUX_PKG_HOSTBUILD_DIR
|
||||
}
|
||||
|
||||
termux_step_pre_configure() {
|
||||
TERMUX_PKG_EXTRA_CONFIGURE_ARGS+=" -DLUA_MATH_LIBRARY=$TERMUX_STANDALONE_TOOLCHAIN/sysroot/usr/lib/$TERMUX_HOST_PLATFORM/$TERMUX_PKG_API_LEVEL/libm.so"
|
||||
}
|
||||
|
||||
termux_step_post_make_install() {
|
||||
local _CONFIG_DIR=$TERMUX_PREFIX/share/nvim
|
||||
mkdir -p $_CONFIG_DIR
|
||||
cp $TERMUX_PKG_BUILDER_DIR/sysinit.vim $_CONFIG_DIR/
|
||||
}
|
||||
|
||||
termux_step_create_debscripts() {
|
||||
cat <<-EOF >./postinst
|
||||
#!$TERMUX_PREFIX/bin/sh
|
||||
if [ "$TERMUX_PACKAGE_FORMAT" = "pacman" ] || [ "\$1" = "configure" ] || [ "\$1" = "abort-upgrade" ]; then
|
||||
if [ -x "$TERMUX_PREFIX/bin/update-alternatives" ]; then
|
||||
update-alternatives --install \
|
||||
$TERMUX_PREFIX/bin/editor editor $TERMUX_PREFIX/bin/nvim 40
|
||||
update-alternatives --install \
|
||||
$TERMUX_PREFIX/bin/vi vi $TERMUX_PREFIX/bin/nvim 15
|
||||
fi
|
||||
fi
|
||||
EOF
|
||||
|
||||
cat <<-EOF >./prerm
|
||||
#!$TERMUX_PREFIX/bin/sh
|
||||
if [ "$TERMUX_PACKAGE_FORMAT" = "pacman" ] || [ "\$1" != "upgrade" ]; then
|
||||
if [ -x "$TERMUX_PREFIX/bin/update-alternatives" ]; then
|
||||
update-alternatives --remove editor $TERMUX_PREFIX/bin/nvim
|
||||
update-alternatives --remove vi $TERMUX_PREFIX/bin/nvim
|
||||
fi
|
||||
fi
|
||||
EOF
|
||||
}
|
77
packages/neovim-nightly/custom-bin/cmake
Executable file
77
packages/neovim-nightly/custom-bin/cmake
Executable file
@ -0,0 +1,77 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -z $TERMUX_ORIGINAL_CMAKE ]; then
|
||||
SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
|
||||
TERMUX_ORIGINAL_CMAKE="$SCRIPTPATH/cmake.orig"
|
||||
fi
|
||||
|
||||
# Need to move --build argument to first due to following error:
|
||||
# CMake Error: Unknown argument --build
|
||||
# CMake Error: Run 'cmake --help' for all supported options.
|
||||
HAS_BUILD=false
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" == "--build" ]; then
|
||||
HAS_BUILD=true
|
||||
fi
|
||||
done
|
||||
|
||||
if ! $HAS_BUILD; then
|
||||
$TERMUX_ORIGINAL_CMAKE "$@"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
|
||||
BUILD_FLAG=false
|
||||
BUILD_VALUE=
|
||||
NEW_ARGS=()
|
||||
UPDATE_CMAKE_CACHE=()
|
||||
for arg in "$@"
|
||||
do
|
||||
if [ "$arg" == "--build" ]; then
|
||||
BUILD_FLAG=true
|
||||
else
|
||||
if $BUILD_FLAG; then
|
||||
BUILD_VALUE="$arg"
|
||||
BUILD_FLAG=false
|
||||
else
|
||||
case "$arg" in
|
||||
-D*=*)
|
||||
UPDATE_CMAKE_CACHE+=("${arg:2}")
|
||||
;;
|
||||
*)
|
||||
NEW_ARGS+=("$arg")
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -z $BUILD_VALUE ]; then
|
||||
NEW_ARGS=(--build "$BUILD_VALUE" "${NEW_ARGS[@]}")
|
||||
fi
|
||||
|
||||
function update_cmake_cache() {
|
||||
[ ${#UPDATE_CMAKE_CACHE[@]} -eq 0 ] && return
|
||||
[ -z $BUILD_VALUE ] && return
|
||||
if [ -f "$BUILD_VALUE/CMakeCache.txt" ]; then
|
||||
rm -rf "$BUILD_VALUE/.tmp-orig.CMakeCache.tmp"
|
||||
cp "$BUILD_VALUE/CMakeCache.txt" "$BUILD_VALUE/.tmp-orig.CMakeCache.tmp"
|
||||
cat "$BUILD_VALUE/.tmp-orig.CMakeCache.tmp" | sed -E "$(python3 -c 'import os, sys
|
||||
def z(x): return x.replace("/","\\/")
|
||||
for a in sys.argv[2:]: print("-e s/^"+z(a.split("=",1)[0])+":(.*)=.*$/"+z(a.split("=",1)[0])+":\\1="+z(a.split("=",1)[1])+"/g", end=" ")
|
||||
' -- "${UPDATE_CMAKE_CACHE[@]}")" > "$BUILD_VALUE/CMakeCache.txt"
|
||||
fi
|
||||
}
|
||||
|
||||
function undo_update_cmake_cache() {
|
||||
[ ${#UPDATE_CMAKE_CACHE[@]} -eq 0 ] && return
|
||||
[ -z $BUILD_VALUE ] && return
|
||||
[ ! -f "$BUILD_VALUE/.tmp-orig.CMakeCache.tmp" ] && return
|
||||
mv -f "$BUILD_VALUE/.tmp-orig.CMakeCache.tmp" "$BUILD_VALUE/CMakeCache.txt"
|
||||
}
|
||||
|
||||
update_cmake_cache
|
||||
trap undo_update_cmake_cache EXIT
|
||||
|
||||
|
||||
$TERMUX_ORIGINAL_CMAKE "${NEW_ARGS[@]}"
|
21
packages/neovim-nightly/runtime-CMakeLists.txt.patch
Normal file
21
packages/neovim-nightly/runtime-CMakeLists.txt.patch
Normal file
@ -0,0 +1,21 @@
|
||||
diff -u -r ../neovim-0.3.2/runtime/CMakeLists.txt ./runtime/CMakeLists.txt
|
||||
--- ../neovim-0.3.2/runtime/CMakeLists.txt 2018-12-31 00:06:17.000000000 +0000
|
||||
+++ ./runtime/CMakeLists.txt 2019-01-03 00:07:55.652628776 +0000
|
||||
@@ -32,7 +32,7 @@
|
||||
add_custom_target("${PACKNAME}-tags"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${PACKAGE} ${GENERATED_PACKAGE_DIR}/${PACKNAME}
|
||||
- COMMAND "${PROJECT_BINARY_DIR}/bin/nvim"
|
||||
+ COMMAND "${PROJECT_BINARY_DIR}/../host-build/bin/nvim"
|
||||
-u NONE -i NONE -e --headless -c "helptags doc" -c quit
|
||||
DEPENDS
|
||||
nvim
|
||||
@@ -71,7 +71,7 @@
|
||||
COMMAND ${CMAKE_COMMAND} -E remove doc/*
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${PROJECT_SOURCE_DIR}/runtime/doc doc
|
||||
- COMMAND "${PROJECT_BINARY_DIR}/bin/nvim"
|
||||
+ COMMAND "${PROJECT_BINARY_DIR}/../host-build/bin/nvim"
|
||||
-u NONE -i NONE -e --headless -c "helptags ++t doc" -c quit
|
||||
DEPENDS
|
||||
nvim
|
12
packages/neovim-nightly/runtime-autoload-man.vim.patch
Normal file
12
packages/neovim-nightly/runtime-autoload-man.vim.patch
Normal file
@ -0,0 +1,12 @@
|
||||
diff -u -r ../neovim-0851057a8deaa1197bd0af22babb62c1146d836c/runtime/autoload/man.vim ./runtime/autoload/man.vim
|
||||
--- ../neovim-0851057a8deaa1197bd0af22babb62c1146d836c/runtime/autoload/man.vim 2018-02-04 12:54:30.000000000 +0000
|
||||
+++ ./runtime/autoload/man.vim 2018-02-05 00:48:37.422608665 +0000
|
||||
@@ -149,7 +149,7 @@
|
||||
" Force MANPAGER=cat to ensure Vim is not recursively invoked (by man-db).
|
||||
" http://comments.gmane.org/gmane.editors.vim.devel/29085
|
||||
" Set MAN_KEEP_FORMATTING so Debian man doesn't discard backspaces.
|
||||
- let cmd = ['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'MAN_KEEP_FORMATTING=1', 'man']
|
||||
+ let cmd = ['env', 'MANPAGER=cat', 'MANWIDTH='.manwidth, 'MAN_KEEP_FORMATTING=1', 'mandoc']
|
||||
return s:system(cmd + (s:localfile_arg ? ['-l', a:path] : [a:path]))
|
||||
endfunction
|
||||
|
13
packages/neovim-nightly/src-nvim-eval-funcs.c.patch
Normal file
13
packages/neovim-nightly/src-nvim-eval-funcs.c.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
|
||||
index 801b0f9..35c54df 100644
|
||||
--- a/src/nvim/eval/funcs.c
|
||||
+++ b/src/nvim/eval/funcs.c
|
||||
@@ -4306,6 +4306,8 @@ static void f_has(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
#ifdef _WIN64
|
||||
"win64",
|
||||
#endif
|
||||
+ "android",
|
||||
+ "termux",
|
||||
#ifndef CASE_INSENSITIVE_FILENAME
|
||||
"fname_case",
|
||||
#endif
|
14
packages/neovim-nightly/src-nvim-os-stdpaths.c.patch
Normal file
14
packages/neovim-nightly/src-nvim-os-stdpaths.c.patch
Normal file
@ -0,0 +1,14 @@
|
||||
diff -u -r ../neovim-master/src/nvim/os/stdpaths.c ./src/nvim/os/stdpaths.c
|
||||
--- ../neovim-master/src/nvim/os/stdpaths.c 2015-11-01 16:16:38.000000000 -0500
|
||||
+++ ./src/nvim/os/stdpaths.c 2015-11-02 14:12:12.770172673 -0500
|
||||
@@ -34,8 +34,8 @@
|
||||
[kXDGDataHome] = "~/.local/share",
|
||||
[kXDGCacheHome] = "~/.cache",
|
||||
[kXDGRuntimeDir] = NULL,
|
||||
- [kXDGConfigDirs] = "/etc/xdg/",
|
||||
- [kXDGDataDirs] = "/usr/local/share/:/usr/share/",
|
||||
+ [kXDGConfigDirs] = "@TERMUX_PREFIX@/etc/xdg/",
|
||||
+ [kXDGDataDirs] = "@TERMUX_PREFIX@/local/share/:@TERMUX_PREFIX@/share/",
|
||||
#endif
|
||||
};
|
||||
|
6
packages/neovim-nightly/sysinit.vim
Normal file
6
packages/neovim-nightly/sysinit.vim
Normal file
@ -0,0 +1,6 @@
|
||||
" Scroll only one line for mouse wheel events to get smooth scrolling on touch screens
|
||||
set mouse=a
|
||||
map <ScrollWheelUp> <C-Y>
|
||||
imap <ScrollWheelUp> <C-X><C-Y>
|
||||
map <ScrollWheelDown> <C-E>
|
||||
imap <ScrollWheelDown> <C-X><C-E>
|
@ -1,29 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# apt-compare-versions: Simple script which takes two arguments and compares
|
||||
# their version according to apt rules. This can be used to verify the ordering
|
||||
# between two versions.
|
||||
#
|
||||
# Note that ~ (tilde) construct, which allows for beta and preview releases.
|
||||
# A version with ~ is considered earlier than one without, so 1.6~beta1 is
|
||||
# considered earlier than 1.6. If both versions contains ~ the version comparison
|
||||
# is made first on the part preceding the tilde, then the part coming after,
|
||||
# so 1.6~beta1 comes before 1.6~beta2.
|
||||
|
||||
import apt_pkg, sys
|
||||
apt_pkg.init_system()
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
sys.exit('usage: apt-compare-versions <first-version> <second-version>')
|
||||
|
||||
version1 = sys.argv[1]
|
||||
version2 = sys.argv[2]
|
||||
|
||||
comparison_result = apt_pkg.version_compare(version1, version2)
|
||||
if comparison_result > 0:
|
||||
operator = ' > '
|
||||
elif comparison_result < 0:
|
||||
operator = ' < '
|
||||
elif comparison_result == 0:
|
||||
operator = ' == '
|
||||
|
||||
print(version1 + operator + version2)
|
1
scripts/bin/apt-compare-versions
Symbolic link
1
scripts/bin/apt-compare-versions
Symbolic link
@ -0,0 +1 @@
|
||||
../updates/utils/termux_pkg_is_update_needed.sh
|
@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e -u
|
||||
BASEDIR=$(dirname "$(realpath "$0")")
|
||||
# shellcheck source-path=/data/data/com.termux/files/home/termux-packages
|
||||
set -u
|
||||
|
||||
# These variables should be set in environment outside of this script.
|
||||
# Following variables should be set in environment outside of this script.
|
||||
# Build updated packages.
|
||||
: "${BUILD_PACKAGES:=false}"
|
||||
# Commit changes to Git.
|
||||
@ -10,110 +10,184 @@ BASEDIR=$(dirname "$(realpath "$0")")
|
||||
# Push changes to remote.
|
||||
: "${GIT_PUSH_PACKAGES:=false}"
|
||||
|
||||
if [ -z "${GITHUB_API_TOKEN-}" ]; then
|
||||
echo "Error: you need a Github Personal Access Token be set in variable GITHUB_API_TOKEN."
|
||||
exit 1
|
||||
fi
|
||||
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.
|
||||
|
||||
for pkg_dir in "${BASEDIR}"/../../packages/*; do
|
||||
if [ -f "${pkg_dir}/build.sh" ]; then
|
||||
package=$(basename "$pkg_dir")
|
||||
else
|
||||
# Fail if detected a non-package directory.
|
||||
echo "Error: directory '${pkg_dir}' is not a package."
|
||||
exit 1
|
||||
fi
|
||||
export TERMUX_SCRIPTDIR
|
||||
TERMUX_SCRIPTDIR="$(realpath "$(dirname "$0")/../..")" # Script directory.
|
||||
|
||||
# Extract the package auto-update configuration.
|
||||
build_vars=$(
|
||||
set +e +u
|
||||
. "${BASEDIR}/../../packages/${package}/build.sh" 2>/dev/null
|
||||
echo "auto_update_flag=${TERMUX_PKG_AUTO_UPDATE};"
|
||||
echo "termux_version=\"${TERMUX_PKG_VERSION}\";"
|
||||
echo "srcurl=\"${TERMUX_PKG_SRCURL}\";"
|
||||
echo "version_regexp=\"${TERMUX_PKG_AUTO_UPDATE_TAG_REGEXP//\\/\\\\}\";"
|
||||
)
|
||||
auto_update_flag=""; termux_version=""; srcurl=""; version_regexp="";
|
||||
eval "$build_vars"
|
||||
# Define few more variables used by scripts.
|
||||
# shellcheck source=scripts/properties.sh
|
||||
. "${TERMUX_SCRIPTDIR}/scripts/properties.sh"
|
||||
|
||||
# Ignore packages that have auto-update disabled.
|
||||
if [ "${auto_update_flag}" != "true" ]; then
|
||||
continue
|
||||
fi
|
||||
# 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
|
||||
|
||||
# Extract github project from TERMUX_PKG_SRCURL
|
||||
project="$(echo "${srcurl}" | grep github.com | cut -d / -f4-5)"
|
||||
if [ -z "${project}" ]; then
|
||||
echo "Error: package '${package}' doesn't use GitHub archive source URL but has been configured for automatic updates."
|
||||
exit 1
|
||||
fi
|
||||
# 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
|
||||
|
||||
# Our local version of package.
|
||||
termux_epoch="$(echo "$termux_version" | cut -d: -f1)"
|
||||
termux_version=$(echo "$termux_version" | cut -d: -f2-)
|
||||
if [ "$termux_version" == "$termux_epoch" ]; then
|
||||
# No epoch set.
|
||||
termux_epoch=""
|
||||
else
|
||||
termux_epoch+=":"
|
||||
fi
|
||||
# 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
|
||||
|
||||
# Get the latest release tag.
|
||||
latest_tag=$(curl --silent --location -H "Authorization: token ${GITHUB_API_TOKEN}" "https://api.github.com/repos/${project}/releases/latest" | jq -r .tag_name)
|
||||
# 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
|
||||
|
||||
# If the github api returns error
|
||||
if [ -z "$latest_tag" ] || [ "${latest_tag}" = "null" ]; then
|
||||
echo "Error: failed to get the latest release tag for '${package}'. GitHub API returned 'null' which indicates that no releases available."
|
||||
exit 1
|
||||
fi
|
||||
# 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
|
||||
|
||||
# Remove leading 'v' which is common in version tag.
|
||||
latest_version=${latest_tag#v}
|
||||
# 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
|
||||
|
||||
# If needed, filter version numbers from tag by using regexp.
|
||||
if [ -n "$version_regexp" ]; then
|
||||
latest_version=$(grep -oP "$version_regexp" <<< "$latest_version" || true)
|
||||
fi
|
||||
if [ -z "$latest_version" ]; then
|
||||
echo "Error: failed to get latest version for '${package}'. Check whether the TERMUX_PKG_AUTO_UPDATE_TAG_REGEXP='${version_regexp}' is work right with latest_release='${latest_tag}'."
|
||||
exit 1
|
||||
fi
|
||||
# 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
|
||||
|
||||
# Translate "_" into ".": some packages use underscores to seperate
|
||||
# version numbers, but we require them to be separated by dots.
|
||||
latest_version=${latest_version//_/.}
|
||||
# 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
|
||||
|
||||
# We have no better choice for comparing versions.
|
||||
if [ "$(echo -e "${termux_version}\n${latest_version}" | sort -V | head -n 1)" != "$latest_version" ] ;then
|
||||
if [ "$BUILD_PACKAGES" = "false" ]; then
|
||||
echo "Package '${package}' needs update to '${latest_version}'."
|
||||
else
|
||||
echo "Updating '${package}' to '${latest_version}'."
|
||||
sed -i "s/^\(TERMUX_PKG_VERSION=\)\(.*\)\$/\1${termux_epoch}${latest_version}/g" "${BASEDIR}/../../packages/${package}/build.sh"
|
||||
sed -i "/TERMUX_PKG_REVISION=/d" "${BASEDIR}/../../packages/${package}/build.sh"
|
||||
echo n | "${BASEDIR}/../bin/update-checksum" "$package" || {
|
||||
echo "Warning: failed to update checksum for '${package}', skipping..."
|
||||
git checkout -- "${BASEDIR}/../../packages/${package}"
|
||||
git pull --rebase
|
||||
continue
|
||||
}
|
||||
# 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
|
||||
|
||||
echo "Trying to build package '${package}'."
|
||||
if "${BASEDIR}/../run-docker.sh" ./build-package.sh -a aarch64 -I "$package" && \
|
||||
"${BASEDIR}/../run-docker.sh" ./build-package.sh -a arm -I "$package"; then
|
||||
if [ "$GIT_COMMIT_PACKAGES" = "true" ]; then
|
||||
git add "${BASEDIR}/../../packages/${package}"
|
||||
git commit -m "$(echo -e "${package}: update to ${latest_version}\n\nThis commit has been automatically submitted by Github Actions.")"
|
||||
fi
|
||||
# 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
|
||||
|
||||
if [ "$GIT_PUSH_PACKAGES" = "true" ]; then
|
||||
git pull --rebase
|
||||
git push
|
||||
fi
|
||||
else
|
||||
echo "Warning: failed to build '${package}'."
|
||||
git checkout -- "${BASEDIR}/../../packages/${package}"
|
||||
fi
|
||||
_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
|
||||
done
|
||||
}
|
||||
|
||||
_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 "$@"
|
||||
|
92
scripts/updates/api/dump-repology-data
Executable file
92
scripts/updates/api/dump-repology-data
Executable file
@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# The MIT License (MIT)
|
||||
|
||||
# Copyright (c) 2022 Aditya Alok (aka. @MrAdityaAlok) <dev.aditya.alok+legal@gmail.com>
|
||||
|
||||
# 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.
|
||||
|
||||
|
||||
from requests import get as requests_get
|
||||
|
||||
|
||||
def get_repology_data(last_project):
|
||||
repology_data = requests_get(
|
||||
f"https://repology.org/api/v1/projects/{last_project}?inrepo=termux&outdated=True&families_newest=2-"
|
||||
).json() # NOTE: We are using 2- so that api will return a package as outdated if it is so in 2 or more
|
||||
# repo family. This helps us avoid false positives.
|
||||
|
||||
return repology_data
|
||||
|
||||
|
||||
def get_outdated_packages():
|
||||
termux_outdated_packages = {}
|
||||
last_project = ""
|
||||
|
||||
while True:
|
||||
repology_data = get_repology_data(last_project)
|
||||
last_project = sorted(repology_data.keys())[
|
||||
-1
|
||||
] # This used to query repology for next set of packages.
|
||||
# Quoting repology documentation: "You may iterate through
|
||||
# all projects by using the last project name in the next request"
|
||||
# For more info, visit https://repology.org/api
|
||||
# NOTE: next response to request will include the last_project given.
|
||||
if len(repology_data) <= 1:
|
||||
# Break the loop now. Since api returned only one package, it
|
||||
# must be the last_project, which was already included in previous iteration.
|
||||
break
|
||||
|
||||
for package_name, package_data in repology_data.items():
|
||||
if package_name in termux_outdated_packages:
|
||||
# Skip if package is already in the dict.
|
||||
continue
|
||||
newest_stable = None
|
||||
newest_devel = None
|
||||
for repo_data in package_data:
|
||||
if repo_data.get("status", "") == "newest":
|
||||
newest_stable = repo_data["version"]
|
||||
# If we found stable version, break the loop.
|
||||
break
|
||||
elif repo_data.get("status", "") == "devel":
|
||||
# Do not break the loop if we found devel version as there may be stable version later.
|
||||
newest_devel = repo_data["version"]
|
||||
|
||||
if newest_stable:
|
||||
termux_outdated_packages[package_name] = newest_stable
|
||||
elif newest_devel:
|
||||
termux_outdated_packages[package_name] = newest_devel
|
||||
else:
|
||||
# If we don't find any version, skip the package.
|
||||
continue
|
||||
|
||||
return termux_outdated_packages
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import json
|
||||
import sys
|
||||
|
||||
try:
|
||||
output_file = sys.argv[1]
|
||||
except IndexError:
|
||||
sys.exit("Please provide an output file")
|
||||
|
||||
with open(output_file, "w") as f:
|
||||
json.dump(get_outdated_packages(), f)
|
136
scripts/updates/api/termux_github_api_get_tag.sh
Normal file
136
scripts/updates/api/termux_github_api_get_tag.sh
Normal file
@ -0,0 +1,136 @@
|
||||
# shellcheck shell=bash
|
||||
termux_github_api_get_tag() {
|
||||
if [[ -z "$1" ]]; then
|
||||
termux_error_exit <<-EndOfUsage
|
||||
Usage: ${FUNCNAME[0]} PKG_SRCURL [TAG_TYPE]
|
||||
Returns the latest tag of the given package.
|
||||
EndOfUsage
|
||||
fi
|
||||
|
||||
if [[ -z "${GITHUB_TOKEN:-}" ]]; then
|
||||
# Needed to use graphql API.
|
||||
termux_error_exit "ERROR: GITHUB_TOKEN environment variable not set."
|
||||
fi
|
||||
|
||||
local PKG_SRCURL="$1"
|
||||
local TAG_TYPE="${2:-}"
|
||||
|
||||
local project
|
||||
project="$(echo "${PKG_SRCURL}" | cut -d'/' -f4-5)"
|
||||
project="${project%.git}"
|
||||
|
||||
if [[ -z "${TAG_TYPE}" ]]; then # If not set, then decide on the basis of url.
|
||||
if [[ "${PKG_SRCURL: -4}" == ".git" ]]; then
|
||||
# Get newest tag.
|
||||
TAG_TYPE="newest-tag"
|
||||
else
|
||||
# Get the latest release tag.
|
||||
TAG_TYPE="latest-release-tag"
|
||||
fi
|
||||
fi
|
||||
|
||||
local jq_filter
|
||||
local api_url="https://api.github.com"
|
||||
local -a extra_curl_opts
|
||||
|
||||
if [[ "${TAG_TYPE}" == "newest-tag" ]]; then
|
||||
api_url="${api_url}/graphql"
|
||||
jq_filter='.data.repository.refs.edges[0].node.name'
|
||||
extra_curl_opts=(
|
||||
"-X POST"
|
||||
"-d $(
|
||||
cat <<-EOF | tr '\n' ' '
|
||||
{
|
||||
"query": "query {
|
||||
repository(owner: \"${project%/*}\", name: \"${project##*/}\") {
|
||||
refs(refPrefix: \"refs/tags/\", first: 1, orderBy: {
|
||||
field: TAG_COMMIT_DATE, direction: DESC
|
||||
})
|
||||
{
|
||||
edges {
|
||||
node {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}"
|
||||
}
|
||||
EOF
|
||||
)"
|
||||
)
|
||||
|
||||
elif [[ "${TAG_TYPE}" == "latest-release-tag" ]]; then
|
||||
api_url="${api_url}/repos/${project}/releases/latest"
|
||||
jq_filter=".tag_name"
|
||||
else
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: Invalid TAG_TYPE: '${TAG_TYPE}'.
|
||||
Allowed values: 'newest-tag', 'latest-release-tag'.
|
||||
EndOfError
|
||||
fi
|
||||
|
||||
local response
|
||||
# shellcheck disable=SC2086 # we need expansion of ${extra_curl_opts[0]}
|
||||
response="$(
|
||||
curl --silent --location --retry 10 --retry-delay 1 \
|
||||
-H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
--write-out '|%{http_code}' \
|
||||
${extra_curl_opts[0]:-} \
|
||||
"${extra_curl_opts[1]:-}" \
|
||||
"${api_url}"
|
||||
)"
|
||||
|
||||
local http_code
|
||||
http_code="${response##*|}"
|
||||
# Why printf "%s\n"? Because echo interpolates control characters, which jq does not like.
|
||||
response="$(printf "%s\n" "${response%|*}")"
|
||||
|
||||
local tag_name
|
||||
if [[ "${http_code}" == "200" ]]; then
|
||||
if jq --exit-status --raw-output "${jq_filter}" <<<"${response}" >/dev/null; then
|
||||
tag_name="$(jq --exit-status --raw-output "${jq_filter}" <<<"${response}")"
|
||||
else
|
||||
termux_error_exit "ERROR: Failed to parse tag name from: '${response}'"
|
||||
fi
|
||||
elif [[ "${http_code}" == "404" ]]; then
|
||||
if jq --exit-status "has(\"message\") and .message == \"Not Found\"" <<<"${response}"; then
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: No '${TAG_TYPE}' found (${api_url}).
|
||||
Try using '$(
|
||||
if [ ${TAG_TYPE} = "newest-tag" ]; then
|
||||
echo "latest-release-tag"
|
||||
else
|
||||
echo "newest-tag"
|
||||
fi
|
||||
)'.
|
||||
EndOfError
|
||||
else
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: Failed to get '${TAG_TYPE}'(${api_url})'.
|
||||
Response:
|
||||
${response}
|
||||
EndOfError
|
||||
fi
|
||||
else
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: Failed to get '${TAG_TYPE}'(${api_url})'.
|
||||
HTTP code: ${http_code}
|
||||
Response:
|
||||
${response}
|
||||
EndOfError
|
||||
fi
|
||||
|
||||
# If program control reached here and still no tag_name, then something went wrong.
|
||||
if [[ -z "${tag_name:-}" ]] || [[ "${tag_name}" == "null" ]]; then
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: JQ could not find '${TAG_TYPE}'(${api_url})'.
|
||||
Response:
|
||||
${response}
|
||||
Please report this as bug.
|
||||
EndOfError
|
||||
fi
|
||||
|
||||
echo "${tag_name#v}" # Remove leading 'v' which is common in version tag.
|
||||
}
|
112
scripts/updates/api/termux_gitlab_api_get_tag.sh
Normal file
112
scripts/updates/api/termux_gitlab_api_get_tag.sh
Normal file
@ -0,0 +1,112 @@
|
||||
# shellcheck shell=bash
|
||||
termux_gitlab_api_get_tag() {
|
||||
if [[ -z "$1" ]]; then
|
||||
termux_error_exit <<-EndOfUsage
|
||||
Usage: ${FUNCNAME[0]} PKG_SRCURL [TAG_TYPE] [API_HOST]
|
||||
Returns the latest tag of the given package.
|
||||
EndOfUsage
|
||||
|
||||
fi
|
||||
local PKG_SRCURL="$1"
|
||||
local TAG_TYPE="${2:-}"
|
||||
local API_HOST="${3:-gitlab.com}"
|
||||
|
||||
local project
|
||||
project="$(echo "${PKG_SRCURL}" | cut -d'/' -f4-5)"
|
||||
project="${project%.git}"
|
||||
|
||||
if [[ -z "${TAG_TYPE}" ]]; then # If not set, then decide on the basis of url.
|
||||
if [[ "${PKG_SRCURL: -4}" == ".git" ]]; then
|
||||
# Get newest tag.
|
||||
TAG_TYPE="newest-tag"
|
||||
else
|
||||
# Get the latest release tag.
|
||||
TAG_TYPE="latest-release-tag"
|
||||
fi
|
||||
fi
|
||||
|
||||
local jq_filter
|
||||
local api_path
|
||||
|
||||
case "${TAG_TYPE}" in
|
||||
latest-release-tag)
|
||||
api_path="/releases"
|
||||
jq_filter=".[0].tag_name"
|
||||
;;
|
||||
newest-tag)
|
||||
api_path="/repository/tags"
|
||||
jq_filter=".[0].name"
|
||||
;;
|
||||
*)
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: Invalid TAG_TYPE: '${TAG_TYPE}'.
|
||||
Allowed values: 'newest-tag', 'latest-release-tag'.
|
||||
EndOfError
|
||||
;;
|
||||
esac
|
||||
|
||||
# Replace slash '/' with '%2F' in project name. It is required for Gitlab API.
|
||||
local api_url="https://${API_HOST}/api/v4/projects/${project//\//%2F}${api_path}"
|
||||
# Api can be accessed without authentication if the repository is publicly accessible.
|
||||
# Default rate limit for gitlab.com is 300 requests per minute for unauthenticated users
|
||||
# and non-protected paths which should be enough for most use cases.
|
||||
# see: https://docs.gitlab.com/ee/user/gitlab_com/index.html#gitlabcom-specific-rate-limits
|
||||
local response
|
||||
response="$(
|
||||
curl --silent --location --retry 10 --retry-delay 1 \
|
||||
--write-out '|%{http_code}' \
|
||||
"${api_url}"
|
||||
)"
|
||||
|
||||
local http_code
|
||||
http_code="${response##*|}"
|
||||
# Why printf "%s\n"? Because echo interpolates control characters, which jq does not like.
|
||||
response="$(printf "%s\n" "${response%|*}")"
|
||||
|
||||
local tag_name
|
||||
if [[ "${http_code}" == "200" ]]; then
|
||||
if jq --exit-status --raw-output "${jq_filter}" <<<"${response}" >/dev/null; then
|
||||
tag_name="$(jq --exit-status --raw-output "${jq_filter}" <<<"${response}")"
|
||||
else
|
||||
termux_error_exit "ERROR: Failed to parse tag name from: '${response}'"
|
||||
fi
|
||||
elif [[ "${http_code}" == "404" ]]; then
|
||||
if jq --exit-status "has(\"message\") and .message == \"Not Found\"" <<<"${response}"; then
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: No '${TAG_TYPE}' found. (${api_url})
|
||||
Try using '$(
|
||||
if [ ${TAG_TYPE} = "newest-tag" ]; then
|
||||
echo "latest-release-tag"
|
||||
else
|
||||
echo "newest-tag"
|
||||
fi
|
||||
)'.
|
||||
EndOfError
|
||||
else
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: Failed to get '${TAG_TYPE}' (${api_url}).
|
||||
Response:
|
||||
${response}
|
||||
EndOfError
|
||||
fi
|
||||
else
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: Failed to get '${TAG_TYPE}' (${api_url}).
|
||||
HTTP code: ${http_code}
|
||||
Response:
|
||||
${response}
|
||||
EndOfError
|
||||
fi
|
||||
|
||||
# If program control reached here and still no tag_name, then something is not right.
|
||||
if [[ -z "${tag_name:-}" ]] || [[ "${tag_name}" == "null" ]]; then
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: JQ could not find '${TAG_TYPE}' (${api_url}).
|
||||
Response:
|
||||
${response}
|
||||
Please report this as bug.
|
||||
EndOfError
|
||||
fi
|
||||
|
||||
echo "${tag_name#v}" # Strip leading 'v'.
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
# shellcheck shell=bash
|
||||
termux_repology_api_get_latest_version() {
|
||||
if [[ -z "$1" ]]; then
|
||||
termux_error_exit "Usage: ${FUNCNAME[0]} PKG_NAME"
|
||||
fi
|
||||
|
||||
if [[ ! -s "${TERMUX_REPOLOGY_DATA_FILE}" ]]; then
|
||||
pip3 install bs4 requests >/dev/null # Install python dependencies.
|
||||
python3 "${TERMUX_SCRIPTDIR}"/scripts/updates/api/dump-repology-data \
|
||||
"${TERMUX_REPOLOGY_DATA_FILE}" >/dev/null
|
||||
fi
|
||||
|
||||
local PKG_NAME="$1"
|
||||
local version
|
||||
# Why `--arg`? See: https://stackoverflow.com/a/54674832/15086226
|
||||
version="$(jq -r --arg packageName "$PKG_NAME" '.[$packageName]' <"${TERMUX_REPOLOGY_DATA_FILE}")"
|
||||
echo "${version#v}"
|
||||
}
|
25
scripts/updates/internal/termux_github_auto_update.sh
Normal file
25
scripts/updates/internal/termux_github_auto_update.sh
Normal file
@ -0,0 +1,25 @@
|
||||
# shellcheck shell=bash
|
||||
# Default algorithm to use for packages hosted on github.com
|
||||
termux_github_auto_update() {
|
||||
local pkg_version
|
||||
pkg_version="$(echo "${TERMUX_PKG_VERSION}" | cut -d: -f2-)"
|
||||
local pkg_epoch
|
||||
pkg_epoch="$(echo "${TERMUX_PKG_VERSION}" | cut -d: -f1)"
|
||||
|
||||
if [[ "${pkg_version}" == "${pkg_epoch}" ]]; then
|
||||
# No epoch set.
|
||||
pkg_epoch=""
|
||||
else
|
||||
pkg_epoch+=":"
|
||||
fi
|
||||
|
||||
local latest_tag
|
||||
latest_tag="$(
|
||||
termux_github_api_get_tag "${TERMUX_PKG_SRCURL}" "${TERMUX_PKG_UPDATE_TAG_TYPE}"
|
||||
)"
|
||||
|
||||
if [[ -z "${latest_tag}" ]]; then
|
||||
termux_error_exit "ERROR: Unable to get tag from ${TERMUX_PKG_SRCURL}"
|
||||
fi
|
||||
termux_pkg_upgrade_version "${pkg_epoch}${latest_tag}"
|
||||
}
|
28
scripts/updates/internal/termux_gitlab_auto_update.sh
Normal file
28
scripts/updates/internal/termux_gitlab_auto_update.sh
Normal file
@ -0,0 +1,28 @@
|
||||
# shellcheck shell=bash
|
||||
# Default algorithm to use for packages hosted on hosts using gitlab-ci.
|
||||
termux_gitlab_auto_update() {
|
||||
# Our local version of package.
|
||||
local pkg_version
|
||||
pkg_version="$(echo "${TERMUX_PKG_VERSION}" | cut -d: -f2-)"
|
||||
local pkg_epoch
|
||||
pkg_epoch="$(echo "${TERMUX_PKG_VERSION}" | cut -d: -f1)"
|
||||
|
||||
if [[ "${pkg_version}" == "${pkg_epoch}" ]]; then
|
||||
# No epoch set.
|
||||
pkg_epoch=""
|
||||
else
|
||||
pkg_epoch+=":"
|
||||
fi
|
||||
|
||||
local latest_tag
|
||||
latest_tag="$(
|
||||
termux_gitlab_api_get_tag \
|
||||
"${TERMUX_PKG_SRCURL}" "${TERMUX_PKG_UPDATE_TAG_TYPE}" "${TERMUX_GITLAB_API_HOST}"
|
||||
)"
|
||||
# No need to check for return code `2`, since gitlab api does not implement cache control.
|
||||
|
||||
if [[ -z "${latest_tag}" ]]; then
|
||||
termux_error_exit "ERROR: Unable to get tag from ${TERMUX_PKG_SRCURL}"
|
||||
fi
|
||||
termux_pkg_upgrade_version "${pkg_epoch}${latest_tag}"
|
||||
}
|
26
scripts/updates/internal/termux_repology_auto_update.sh
Normal file
26
scripts/updates/internal/termux_repology_auto_update.sh
Normal file
@ -0,0 +1,26 @@
|
||||
# shellcheck shell=bash
|
||||
termux_repology_auto_update() {
|
||||
# Our local version of package.
|
||||
local pkg_version
|
||||
pkg_version="$(echo "${TERMUX_PKG_VERSION}" | cut -d: -f2-)"
|
||||
local pkg_epoch
|
||||
pkg_epoch="$(echo "${TERMUX_PKG_VERSION}" | cut -d: -f1)"
|
||||
|
||||
if [[ "${pkg_version}" == "${pkg_epoch}" ]]; then
|
||||
# No epoch set.
|
||||
pkg_epoch=""
|
||||
else
|
||||
pkg_epoch+=":"
|
||||
fi
|
||||
|
||||
local latest_version
|
||||
latest_version="$(termux_repology_api_get_latest_version "${TERMUX_PKG_NAME}")"
|
||||
|
||||
# Repology api returns null if package is not tracked by repology or is already upto date.
|
||||
if [[ "${latest_version}" == "null" ]]; then
|
||||
echo "INFO: Already up to date." # Since we exclude unique to termux packages, this package
|
||||
# should be tracked by repology and be already up to date.
|
||||
return 0
|
||||
fi
|
||||
termux_pkg_upgrade_version "${pkg_epoch}${latest_version}"
|
||||
}
|
44
scripts/updates/termux_pkg_auto_update.sh
Normal file
44
scripts/updates/termux_pkg_auto_update.sh
Normal file
@ -0,0 +1,44 @@
|
||||
# shellcheck shell=bash
|
||||
termux_pkg_auto_update() {
|
||||
local project_host
|
||||
project_host="$(echo "${TERMUX_PKG_SRCURL}" | cut -d"/" -f3)"
|
||||
|
||||
if [[ -z "${TERMUX_PKG_UPDATE_METHOD}" ]]; then
|
||||
if [[ "${project_host}" == "github.com" ]]; then
|
||||
TERMUX_PKG_UPDATE_METHOD="github"
|
||||
elif [[ "${project_host}" == "gitlab.com" ]]; then
|
||||
TERMUX_PKG_UPDATE_METHOD="gitlab"
|
||||
else
|
||||
TERMUX_PKG_UPDATE_METHOD="repology"
|
||||
fi
|
||||
fi
|
||||
|
||||
local _err_msg="ERROR: source url's hostname is not ${TERMUX_PKG_UPDATE_METHOD}.com, but has been
|
||||
configured to use ${TERMUX_PKG_UPDATE_METHOD}'s method."
|
||||
|
||||
case "${TERMUX_PKG_UPDATE_METHOD}" in
|
||||
github)
|
||||
if [[ "${project_host}" != "${TERMUX_PKG_UPDATE_METHOD}.com" ]]; then
|
||||
termux_error_exit "${_err_msg}"
|
||||
else
|
||||
termux_github_auto_update
|
||||
fi
|
||||
;;
|
||||
gitlab)
|
||||
if [[ "${project_host}" != "${TERMUX_PKG_UPDATE_METHOD}.com" ]]; then
|
||||
termux_error_exit "${_err_msg}"
|
||||
else
|
||||
termux_gitlab_auto_update
|
||||
fi
|
||||
;;
|
||||
repology)
|
||||
termux_repology_auto_update
|
||||
;;
|
||||
*)
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: wrong value '${TERMUX_PKG_UPDATE_METHOD}' for TERMUX_PKG_UPDATE_METHOD.
|
||||
Can be 'github', 'gitlab' or 'repology'
|
||||
EndOfError
|
||||
;;
|
||||
esac
|
||||
}
|
10
scripts/updates/utils/termux_error_exit.sh
Normal file
10
scripts/updates/utils/termux_error_exit.sh
Normal file
@ -0,0 +1,10 @@
|
||||
# shellcheck shell=bash
|
||||
termux_error_exit() {
|
||||
if [ "$#" -eq 0 ]; then
|
||||
# Read from stdin.
|
||||
printf '%s\n' "$(cat)" >&2
|
||||
else
|
||||
printf '%s\n' "$*" >&2
|
||||
fi
|
||||
exit 1
|
||||
}
|
87
scripts/updates/utils/termux_pkg_is_update_needed.sh
Executable file
87
scripts/updates/utils/termux_pkg_is_update_needed.sh
Executable file
@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# NOTE: This function returns true even when CURRENT_VERSION = "1.0" and LATEST_VERSION = "1.0-1".
|
||||
# This is logically correct, but repology sometimes returns "1.0-1" as the latest version even
|
||||
# if "1.0" is latest. This happens when any of the repositories tracked by repology has specified
|
||||
# "1.0-1" as the latest.
|
||||
#
|
||||
# For example:
|
||||
# latest lua:lpeg version (as of 2021-11-20T12:21:31) is "1.0.2" but MacPorts specifies as "1.0.2-1".
|
||||
# Hence repology returns "1.0.2-1" as the latest.
|
||||
#
|
||||
# But hopefully, all this can be avoided if TERMUX_PKG_AUTO_UPDATE_TAG_REGEXP is set.
|
||||
#
|
||||
termux_pkg_is_update_needed() {
|
||||
# USAGE: termux_pkg_is_update_needed <current-version> <latest-version> [regexp]
|
||||
|
||||
if [[ -z "$1" ]] || [[ -z "$2" ]]; then
|
||||
termux_error_exit "${BASH_SOURCE[0]}: at least 2 arguments expected"
|
||||
fi
|
||||
|
||||
local CURRENT_VERSION="$1"
|
||||
local LATEST_VERSION="$2"
|
||||
local VERSION_REGEX="${3:-}"
|
||||
|
||||
# If needed, filter version numbers from tag by using regexp.
|
||||
if [[ -n "${VERSION_REGEX}" ]]; then
|
||||
LATEST_VERSION="$(grep -oP "${VERSION_REGEX}" <<<"${LATEST_VERSION}" || true)"
|
||||
|
||||
if [[ -z "${LATEST_VERSION}" ]]; then
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: failed to compare versions. Ensure whether the version regex '${VERSION_REGEX}'
|
||||
works correctly with given versions.
|
||||
EndOfError
|
||||
fi
|
||||
fi
|
||||
|
||||
# Translate "_" into ".": some packages use underscores to seperate
|
||||
# version numbers, but we require them to be separated by dots.
|
||||
LATEST_VERSION="${LATEST_VERSION//_/.}"
|
||||
|
||||
# Compare versions.
|
||||
# shellcheck disable=SC2091
|
||||
if $(
|
||||
cat <<-EOF | python3 -
|
||||
import sys
|
||||
|
||||
from pkg_resources import parse_version
|
||||
|
||||
if parse_version("${CURRENT_VERSION}") < parse_version("${LATEST_VERSION}"):
|
||||
sys.exit(0)
|
||||
else:
|
||||
sys.exit(1)
|
||||
EOF
|
||||
); then
|
||||
return 0 # true. Update needed.
|
||||
fi
|
||||
return 1 # false. Update not needed.
|
||||
}
|
||||
|
||||
show_help() {
|
||||
echo "Usage: ${BASH_SOURCE[0]} [--help] <first-version> <second-version>] [version-regex]"
|
||||
echo "--help - show this help message and exit"
|
||||
echo " <first-version> - first version to compare"
|
||||
echo " <second-version> - second version to compare"
|
||||
echo " [version-regex] - optional regular expression to filter version numbers"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Make script sourceable as well as executable.
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
declare -f termux_error_exit >/dev/null ||
|
||||
. "$(dirname "$(realpath "${BASH_SOURCE[0]}")")/termux_error_exit.sh" # realpath is used to resolve symlinks.
|
||||
|
||||
if [[ "${1}" == "--help" ]]; then
|
||||
show_help
|
||||
fi
|
||||
|
||||
# Print in human readable format.
|
||||
first_version="$1"
|
||||
second_version="$2"
|
||||
version_regexp="${3:-}"
|
||||
if termux_pkg_is_update_needed "${first_version}" "${second_version}" "${version_regexp}"; then
|
||||
echo "${first_version} < ${second_version}"
|
||||
else
|
||||
echo "${first_version} >= ${second_version}"
|
||||
fi
|
||||
fi
|
79
scripts/updates/utils/termux_pkg_upgrade_version.sh
Executable file
79
scripts/updates/utils/termux_pkg_upgrade_version.sh
Executable file
@ -0,0 +1,79 @@
|
||||
# shellcheck shell=bash
|
||||
termux_pkg_upgrade_version() {
|
||||
if [[ "$#" -lt 1 ]]; then
|
||||
# Show usage.
|
||||
termux_error_exit <<-EndUsage
|
||||
Usage: ${FUNCNAME[0]} LATEST_VERSION [--skip-version-check]
|
||||
Version should be passed with epoch, if any.
|
||||
EndUsage
|
||||
fi
|
||||
|
||||
local LATEST_VERSION="$1"
|
||||
local SKIP_VERSION_CHECK="${2:-}"
|
||||
local PKG_DIR
|
||||
PKG_DIR="${TERMUX_SCRIPTDIR}/packages/${TERMUX_PKG_NAME}"
|
||||
|
||||
if [[ "${SKIP_VERSION_CHECK}" != "--skip-version-check" ]]; then
|
||||
if ! termux_pkg_is_update_needed \
|
||||
"${TERMUX_PKG_VERSION}" "${LATEST_VERSION}" "${TERMUX_PKG_UPDATE_VERSION_REGEXP}"; then
|
||||
echo "INFO: No update needed. Already at version '${TERMUX_PKG_VERSION}'."
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${BUILD_PACKAGES}" == "false" ]]; then
|
||||
echo "INFO: package needs to be updated to $(echo "${LATEST_VERSION}" | cut -d':' -f2)."
|
||||
else
|
||||
echo "INFO: package being updated to $(echo "${LATEST_VERSION}" | cut -d':' -f2)."
|
||||
|
||||
sed -i \
|
||||
"s/^\(TERMUX_PKG_VERSION=\)\(.*\)\$/\1\"${LATEST_VERSION}\"/g" \
|
||||
"${PKG_DIR}/build.sh"
|
||||
sed -i \
|
||||
"/TERMUX_PKG_REVISION=/d" \
|
||||
"${PKG_DIR}/build.sh"
|
||||
|
||||
# Update checksum
|
||||
if [[ "${TERMUX_PKG_SHA256[*]}" != "SKIP_CHECKSUM" ]] && [[ "${TERMUX_PKG_SRCURL: -4}" != ".git" ]]; then
|
||||
echo n | "${TERMUX_SCRIPTDIR}/scripts/bin/update-checksum" "${TERMUX_PKG_NAME}" || {
|
||||
git checkout -- "${PKG_DIR}"
|
||||
git pull --rebase
|
||||
termux_error_exit "ERROR: failed to update checksum."
|
||||
}
|
||||
fi
|
||||
|
||||
echo "INFO: Trying to build package."
|
||||
if "${TERMUX_SCRIPTDIR}/scripts/run-docker.sh" ./build-package.sh -a "${TERMUX_ARCH}" -I "${TERMUX_PKG_NAME}"; then
|
||||
if [[ "${GIT_COMMIT_PACKAGES}" == "true" ]]; then
|
||||
echo "INFO: Committing package."
|
||||
stderr="$(
|
||||
git add "${PKG_DIR}" 2>&1 >/dev/null
|
||||
git commit -m "${TERMUX_PKG_NAME}: update to $(echo "${LATEST_VERSION}" | cut -d':' -f2)" \
|
||||
-m "This commit has been automatically submitted by Github Actions." 2>&1 >/dev/null
|
||||
)" || {
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: git commit failed. See below for details.
|
||||
${stderr}
|
||||
EndOfError
|
||||
}
|
||||
fi
|
||||
|
||||
if [[ "${GIT_PUSH_PACKAGES}" == "true" ]]; then
|
||||
echo "INFO: Pushing package."
|
||||
stderr="$(
|
||||
git pull --rebase 2>&1 >/dev/null
|
||||
git push 2>&1 >/dev/null
|
||||
)" || {
|
||||
termux_error_exit <<-EndOfError
|
||||
ERROR: git push failed. See below for details.
|
||||
${stderr}
|
||||
EndOfError
|
||||
}
|
||||
fi
|
||||
else
|
||||
git checkout -- "${PKG_DIR}"
|
||||
termux_error_exit "ERROR: failed to build."
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
Loading…
Reference in New Issue
Block a user