From 02808ac42d4c29fe3c375d859168c9bb040ed88f Mon Sep 17 00:00:00 2001 From: TomIO Date: Mon, 3 Nov 2025 10:07:28 +0100 Subject: [PATCH 1/4] fix(scripts/lint-packages.sh): fix heredoc_regex for on-device use with Android 14+ Upstream changes to `regcomp()`: AOSP - https://android-review.googlesource.com/c/platform/bionic/+/2290937 NetBSD - https://github.com/NetBSD/src/commit/1ee269c3a208a14da224b6e9917e2e9798961fff FreeBSD - https://github.com/freebsd/freebsd-src/commit/18a1e2e9b9f109a78c5a9274e4cfb4777801b4fb Co-authored-by: Robert Kirkman --- scripts/lint-packages.sh | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/lint-packages.sh b/scripts/lint-packages.sh index 2f0dab26dace94..1512020f905c82 100755 --- a/scripts/lint-packages.sh +++ b/scripts/lint-packages.sh @@ -73,7 +73,7 @@ check_indentation() { local pkg_script="$1" local line='' heredoc_terminator='' in_array=0 i=0 local -a issues=('' '') bad_lines=('FAILED') - local heredoc_regex="[^\(/%#]<{2}-?\s*(['\"]?(\w*(\\\.)?)*['\"]?)" + local heredoc_regex="[^\(/%#]<{2}-?[[:space:]]*(['\"]?([[:alnum:]_]*(\\\.)?)*['\"]?)" # We don't wanna hit version constraints "(<< x.y.z)" with this, so don't match "(<<". # We also wouldn't wanna hit parameter expansions "${var/<<}", ${var%<<}, ${var#<<} @@ -94,7 +94,12 @@ check_indentation() { (( ${#heredoc_terminator} )) && continue fi - # check for mixed indentation + # Check for mixed indentation. + # We do this after the heredoc checks because space indentation + # is significant for languages like Haskell or Nim. + # Those probably shouldn't get inlined as heredocs, + # but the Haskell `cabal.project.local` overrides currently are. + # So let's not break builds for that. [[ "$line" =~ ^($'\t'+ +| +$'\t'+) ]] && { issues[0]='Mixed indentation' bad_lines[i]="${pkg_script}:${i}:$line" @@ -185,7 +190,8 @@ check_version() { "" \ "Version of '$package_name' has not been incremented." \ "Either 'TERMUX_PKG_VERSION' or 'TERMUX_PKG_REVISION'" \ - "need to be modified in the build.sh when changing a package build." + "need to be modified in the build.sh when changing a package build." \ + "You can use ./scripts/bin/revbump '$package_name' to do this automatically." # If the version decreased throw in a suggestion for how to downgrade packages dpkg --compare-versions "$version_new" lt "$version_old" && \ From 42a73a53ef94371beb5435aa16f9bca68f003716 Mon Sep 17 00:00:00 2001 From: TomIO Date: Sun, 9 Nov 2025 14:45:51 +0100 Subject: [PATCH 2/4] enhance(scripts/lint-packages.sh): optimize handling of version arrays --- scripts/lint-packages.sh | 45 +++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/scripts/lint-packages.sh b/scripts/lint-packages.sh index 1512020f905c82..ad4594bfba388a 100755 --- a/scripts/lint-packages.sh +++ b/scripts/lint-packages.sh @@ -133,6 +133,10 @@ if ! base_commit="HEAD~$(git rev-list --count FETCH_HEAD..)"; then base_commit="HEAD~$(git rev-list --count FETCH_HEAD..)" fi +# Also figure out if we have a `%ci:no-build` trailer in the commit range, +# we may skip some checks later if yes. +no_build="$(git log --fixed-strings --grep '%ci:no-build' --pretty=format:%H "$base_commit")" + check_version() { local package_dir="${1%/*}" @@ -145,12 +149,11 @@ check_version() { } >&2 # If TERMUX_PKG_VERSION is an array that changes the formatting. - local version i=-1 error=0 is_array="${TERMUX_PKG_VERSION@a}" + local version i=0 error=0 is_array="${TERMUX_PKG_VERSION@a}" printf '%s' "${is_array:+$'ARRAY\n'}" for version in "${TERMUX_PKG_VERSION[@]}"; do printf '%s' "${is_array:+$'\t'}" - (( i++ )) # Is this version valid? dpkg --validate-version "${version}" &> /dev/null || { @@ -159,34 +162,44 @@ check_version() { continue } - # Was the package modified in this branch? - git diff --exit-code "${base_commit}" -- "${package_dir}" &> /dev/null && { - printf '%s\n' "PASS - ${version} (not modified in this branch)" - continue - } - local version_new version_old version_new="${version}-${TERMUX_PKG_REVISION:-0}" version_old=$( unset TERMUX_PKG_VERSION TERMUX_PKG_REVISION # shellcheck source=/dev/null . <(git -P show "${base_commit}:${package_dir}/build.sh" 2> /dev/null) - if [[ -n "$is_array" ]]; then - echo "${TERMUX_PKG_VERSION[$i]:-0}-${TERMUX_PKG_REVISION:-0}" - else - echo "${TERMUX_PKG_VERSION:-0}-${TERMUX_PKG_REVISION:-0}" - fi + # ${TERMUX_PKG_VERSION[0]} also works fine for non-array versions. + # Since those resolve in 1 iteration, no higher index is ever attempted to be called. + echo "${TERMUX_PKG_VERSION[$i]:-0}-${TERMUX_PKG_REVISION:-0}" ) # Is ${version_old} valid? local version_old_is_bad="" dpkg --validate-version "${version_old}" &> /dev/null || version_old_is_bad="0~invalid" + # The rest of the checks aren't useful past the first index when $TERMUX_PKG_VERSION is an array + # since that is the index that determines the actual version. + if (( i++ > 0 )); then + echo "PASS - ${version_old%-0}${version_old_is_bad:+" (INVALID)"} -> ${version_new%-0}" + continue + fi + + # Was the package modified in this branch? + git diff --exit-code "${base_commit}" -- "${package_dir}" &> /dev/null && { + printf '%s\n' "PASS - ${version_new%-0} (not modified in this branch)" + return 0 + } + + [[ -n "$no_build" ]] && { + echo "SKIP - ${version_new%-0} ('%ci:no-build' trailer detected on commit ${no_build::7})" + return 0 + } + # If ${version_new} isn't greater than "$version_old" that's an issue. # If ${version_old} isn't valid this check is a no-op. if dpkg --compare-versions "$version_new" le "${version_old_is_bad:-$version_old}"; then printf '%s\n' \ - "FAILED" \ + "FAILED ${version_old_is_bad:-$version_old} -> ${version_new}" \ "" \ "Version of '$package_name' has not been incremented." \ "Either 'TERMUX_PKG_VERSION' or 'TERMUX_PKG_REVISION'" \ @@ -223,9 +236,7 @@ check_version() { continue # If that check passed the TERMUX_PKG_VERSION must have changed, # in which case TERMUX_PKG_REVISION should be reset to 0. - # This check isn't useful past the first index when $TERMUX_PKG_VERSION is an array - # since the main version of such a package may remain unchanged when another is changed. - elif [[ "${version_new%-*}" != "${version_old%-*}" && "$new_revision" != "0" && "$i" == 0 ]]; then + elif [[ "${version_new%-*}" != "${version_old%-*}" && "$new_revision" != "0" ]]; then (( error++ )) # Not reset printf '%s\n' \ "FAILED - $version_old -> $version_new" \ From 159772ebb771d39f172364486c1f57911189f7ea Mon Sep 17 00:00:00 2001 From: TomIO Date: Sun, 9 Nov 2025 14:46:16 +0100 Subject: [PATCH 3/4] fix(scripts/lint-packages): attempt not to trip over merge commits closes #27168 Co-authored-by: Robert Kirkman --- scripts/lint-packages.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/lint-packages.sh b/scripts/lint-packages.sh index ad4594bfba388a..5bed59589c3edc 100755 --- a/scripts/lint-packages.sh +++ b/scripts/lint-packages.sh @@ -128,9 +128,9 @@ check_indentation() { # We'll need the 'origin/master' as a base commit when running the version check. # So try fetching it now if it doesn't exist. -if ! base_commit="HEAD~$(git rev-list --count FETCH_HEAD..)"; then +if ! base_commit="HEAD~$(git rev-list --no-merges --count FETCH_HEAD..)"; then git fetch https://github.com/termux/termux-packages.git - base_commit="HEAD~$(git rev-list --count FETCH_HEAD..)" + base_commit="HEAD~$(git rev-list --no-merges --count FETCH_HEAD..)" fi # Also figure out if we have a `%ci:no-build` trailer in the commit range, @@ -185,7 +185,7 @@ check_version() { fi # Was the package modified in this branch? - git diff --exit-code "${base_commit}" -- "${package_dir}" &> /dev/null && { + git diff --no-merges --exit-code "${base_commit}" -- "${package_dir}" &> /dev/null && { printf '%s\n' "PASS - ${version_new%-0} (not modified in this branch)" return 0 } From 07754ad17ce5c6ceafd8a285e81db21043a76b89 Mon Sep 17 00:00:00 2001 From: TomIO Date: Tue, 11 Nov 2025 19:26:48 +0100 Subject: [PATCH 4/4] enhance(scripts/lint-packages): make the linter more talkative when starting and stopping --- scripts/lint-packages.sh | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/scripts/lint-packages.sh b/scripts/lint-packages.sh index 5bed59589c3edc..dede8924b09c81 100755 --- a/scripts/lint-packages.sh +++ b/scripts/lint-packages.sh @@ -2,6 +2,8 @@ set -e -u +start_time="$(date +%10s.%3N)" + TERMUX_SCRIPTDIR=$(realpath "$(dirname "$0")/../") . "$TERMUX_SCRIPTDIR/scripts/properties.sh" @@ -126,12 +128,15 @@ check_indentation() { return 0 } -# We'll need the 'origin/master' as a base commit when running the version check. -# So try fetching it now if it doesn't exist. -if ! base_commit="HEAD~$(git rev-list --no-merges --count FETCH_HEAD..)"; then - git fetch https://github.com/termux/termux-packages.git - base_commit="HEAD~$(git rev-list --no-merges --count FETCH_HEAD..)" -fi +{ + # We'll need the termux/termux-packages master@HEAD commit as a base commit when running the version check. + # So try fetching it now. + git fetch https://github.com/termux/termux-packages.git || { + echo "ERROR: Unable to fetch 'https://github.com/termux/termux-packages.git'" + echo "Falling back to HEAD~1" + } + base_commit="HEAD~$(git rev-list --count FETCH_HEAD.. -- || printf 1)" +} 2> /dev/null # Also figure out if we have a `%ci:no-build` trailer in the commit range, # we may skip some checks later if yes. @@ -702,6 +707,18 @@ linter_main() { return } +time_elapsed() { + local start="$1" end="$(date +%10s.%3N)" + local elapsed="$(( ${end/.} - ${start/.} ))" + echo "[INFO]: Finished linting build scripts ($(date -d "@$end" --utc '+%Y-%m-%dT%H:%M:%SZ' 2>&1))" + printf '[INFO]: Time elapsed: %s\n' \ + "$(sed 's/0m //;s/0s //' <<< "$(( elapsed % 3600000 / 60000 ))m$(( elapsed % 60000 / 1000 ))s$(( elapsed % 1000 ))ms")" +} + +echo "[INFO]: Starting build script linter ($(date -d "@$start_time" --utc '+%Y-%m-%dT%H:%M:%SZ' 2>&1))" +echo "[INFO]: $base_commit ($(git rev-parse "$base_commit"))" +trap 'time_elapsed "$start_time"' EXIT + package_counter=0 if (( $# )); then linter_main "$@"