Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion build-package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ source "$TERMUX_SCRIPTDIR/scripts/utils/docker/docker.sh"; docker__create_docker
# Source the `termux_package` library.
source "$TERMUX_SCRIPTDIR/scripts/utils/termux/package/termux_package.sh"

# Source the `termux_alternatives` library.
source "$TERMUX_SCRIPTDIR/scripts/utils/termux/alternatives/termux_alternatives.sh"

export SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH:-$(git -c log.showSignature=false log -1 --pretty=%ct 2>/dev/null || date "+%s")}

if [ "$(uname -o)" = "Android" ] || [ -e "/system/bin/app_process" ]; then
Expand Down Expand Up @@ -331,6 +334,10 @@ termux_step_post_make_install() {
# shellcheck source=scripts/build/termux_step_install_pacman_hooks.sh
source "$TERMUX_SCRIPTDIR/scripts/build/termux_step_install_pacman_hooks.sh"

# Install switcher files that will provide alternatives for pacman package
# shellcheck source=scripts/build/termux_step_install_switcher_files.sh
source "$TERMUX_SCRIPTDIR/scripts/build/termux_step_install_switcher_files.sh"

# Add service scripts from array TERMUX_PKG_SERVICE_SCRIPT, if it is set
# shellcheck source=scripts/build/termux_step_install_service_scripts.sh
source "$TERMUX_SCRIPTDIR/scripts/build/termux_step_install_service_scripts.sh"
Expand Down Expand Up @@ -751,7 +758,10 @@ for ((i=0; i<${#PACKAGE_LIST[@]}; i++)); do
termux_run_base_and_multilib_build_step termux_step_make_install
cd "$TERMUX_PKG_BUILDDIR"
termux_step_post_make_install
termux_step_install_pacman_hooks
if [ "$TERMUX_PACKAGE_FORMAT" = "pacman" ]; then
termux_step_install_pacman_hooks
termux_step_install_switcher_files
fi
termux_step_install_service_scripts
termux_step_install_license
cd "$TERMUX_PKG_MASSAGEDIR"
Expand Down
22 changes: 12 additions & 10 deletions packages/pacman/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ TERMUX_PKG_DESCRIPTION="A library-based package manager with dependency support"
TERMUX_PKG_LICENSE="GPL-2.0"
TERMUX_PKG_MAINTAINER="@Maxython <[email protected]>"
TERMUX_PKG_VERSION=7.0.0
TERMUX_PKG_REVISION=4
TERMUX_PKG_SRCURL=https://gitlab.archlinux.org/pacman/pacman/-/releases/v${TERMUX_PKG_VERSION}/downloads/pacman-${TERMUX_PKG_VERSION}.tar.xz
TERMUX_PKG_SHA256=61cbd445d1381b4b184bc7c4e2791f07a79f0f2807b7c600399d0d08e8cd28cf
TERMUX_PKG_REVISION=5
TERMUX_PKG_SRCURL=(https://gitlab.archlinux.org/pacman/pacman/-/releases/v${TERMUX_PKG_VERSION}/downloads/pacman-${TERMUX_PKG_VERSION}.tar.xz
https://github.com/termux-pacman/pacman-switch/archive/refs/heads/main.zip)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing you made this refs/heads/main for testing.
In a final version of this that should be pinned to a specific commit or release tag.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you got it right. When pacman-switch is fully ready, I'll make a pinned release.

TERMUX_PKG_SHA256=(61cbd445d1381b4b184bc7c4e2791f07a79f0f2807b7c600399d0d08e8cd28cf
786056cd99fb2517c30e13db1834e7d16ed4650bfeb428e39b7acfd85d4abce9)
TERMUX_PKG_DEPENDS="bash, curl, gpgme, libandroid-glob, libarchive, libcurl, openssl, termux-licenses, termux-keyring"
TERMUX_PKG_BUILD_DEPENDS="doxygen, asciidoc, nettle"
TERMUX_PKG_GROUPS="base-devel"
Expand All @@ -25,6 +27,7 @@ termux_step_pre_configure() {
rm -f ./scripts/libmakepkg/executable/fakeroot.sh.in

sed -i "s/@TERMUX_ARCH@/${TERMUX_ARCH}/" ./etc/{pacman,makepkg}.conf.in
sed -i "s|_ps_prefix=.*|_ps_prefix=\"${TERMUX_PREFIX}\"|" ./pacman-switch-main/pacman-switch.sh
}

termux_step_post_configure() {
Expand All @@ -34,12 +37,11 @@ termux_step_post_configure() {
termux_step_post_make_install() {
mkdir -p $TERMUX_PREFIX/etc/pacman.d
install -m644 $TERMUX_PKG_BUILDER_DIR/serverlist $TERMUX_PREFIX/etc/pacman.d/serverlist
}
install -m755 $TERMUX_PKG_SRCDIR/pacman-switch-main/pacman-switch.sh $TERMUX_PREFIX/bin/pacman-switch

termux_step_create_debscripts() {
echo "#!$TERMUX_PREFIX/bin/bash" > postinst
echo "mkdir -p $TERMUX_PREFIX/var/lib/pacman/sync" >> postinst
echo "mkdir -p $TERMUX_PREFIX/var/lib/pacman/local" >> postinst
echo "mkdir -p $TERMUX_PREFIX/var/cache/pacman/pkg" >> postinst
chmod 755 postinst
for dir in var/lib/pacman/{sync,local,switch} var/cache/pacman/pkg share/pacman-switch; do
dir="${TERMUX_PREFIX}/${dir}"
mkdir -p ${dir}
touch ${dir}/.placeholder
done
}
10 changes: 10 additions & 0 deletions packages/pacman/pacman-switch-disable.alpm.hook
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Trigger]
Type = Path
Operation = Remove
Target = @TERMUX_PREFIX_TARGET@/share/pacman-switch/*.sw

[Action]
Description = Automatic disabling switchers...
When = PreTransaction
Exec = @TERMUX_PREFIX@/share/libalpm/scripts/run-pacman-switch disable
NeedsTargets
10 changes: 10 additions & 0 deletions packages/pacman/pacman-switch-enable.alpm.hook
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Trigger]
Type = Path
Operation = Install
Target = @TERMUX_PREFIX_TARGET@/share/pacman-switch/*.sw

[Action]
Description = Automatic enabling switchers...
When = PostTransaction
Exec = @TERMUX_PREFIX@/share/libalpm/scripts/run-pacman-switch enable
NeedsTargets
10 changes: 10 additions & 0 deletions packages/pacman/pacman-switch-update.alpm.hook
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Trigger]
Type = Path
Operation = Upgrade
Target = @TERMUX_PREFIX_TARGET@/share/pacman-switch/*.sw

[Action]
Description = Automatic updating switchers...
When = PostTransaction
Exec = @TERMUX_PREFIX@/share/libalpm/scripts/run-pacman-switch update
NeedsTargets
27 changes: 27 additions & 0 deletions packages/pacman/run-pacman-switch.alpm.script
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!@TERMUX_PREFIX@/bin/bash

set -e

sws=()
export _PS_RUN_IN_ALPM_HOOKS=true

while read -r i; do
sw="$(basename "${i//.sw/}")"
if [[ -n "${sw}" && "${sw}" != "*" ]]; then
sws+=("${sw}")
fi
done

if [[ -n "${sws}" && ("${1}" = "update" || "${1}" = "disable") ]]; then
sws=($(pacman-switch -Qs ${sws[@]}))
fi

if [ -z "${sws}" ]; then
exit 0
fi

case "${1}" in
"enable") pacman-switch -Ea ${sws[@]};;
"update") pacman-switch -Su ${sws[@]};;
"disable") pacman-switch -Da ${sws[@]};;
esac
3 changes: 0 additions & 3 deletions scripts/build/termux_step_create_pacman_package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,6 @@ termux_step_create_pacman_package() {

# Write installation hooks.
termux_step_create_debscripts
# Process `update-alternatives` entries from `.alternatives` files
# These need to be merged into the `.postinst` and `.prerm` files, so after those are created.
termux_step_update_alternatives
termux_step_create_pacman_install_hook

# ensure all elements of the package have the same mtime
Expand Down
8 changes: 3 additions & 5 deletions scripts/build/termux_step_install_pacman_hooks.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
termux_step_install_pacman_hooks() {
[[ "$TERMUX_PACKAGE_FORMAT" != "pacman" ]] && return

local sed="sed -e s|@TERMUX_PREFIX@|${TERMUX_PREFIX}|g -e s|@TERMUX_PREFIX_TARGET@|${TERMUX_PREFIX:1}|g -e s|@TERMUX_ARCH@|${TERMUX_ARCH}|g"
local sed="sed -e s|@TERMUX_PREFIX@|${TERMUX_PREFIX_CLASSICAL}|g -e s|@TERMUX_PREFIX_TARGET@|${TERMUX_PREFIX_CLASSICAL:1}|g -e s|@TERMUX_ARCH@|${TERMUX_ARCH}|g"

# Installing hooks
local hooks
Expand All @@ -10,7 +8,7 @@ termux_step_install_pacman_hooks() {
mkdir -p ${TERMUX_PREFIX}/share/libalpm/hooks
local hook
for hook in ${hooks}; do
${sed} "${hook}" > "${TERMUX_PREFIX}/share/libalpm/hooks/$(sed 's|.alpm.hook$|.hook|' <<< "${hook##*/}")"
${sed} "${hook}" > "${TERMUX_PREFIX_CLASSICAL}/share/libalpm/hooks/$(sed 's|.alpm.hook$|.hook|' <<< "${hook##*/}")"
done
fi

Expand All @@ -21,7 +19,7 @@ termux_step_install_pacman_hooks() {
mkdir -p ${TERMUX_PREFIX}/share/libalpm/scripts
local script script_alpm
for script in ${scripts}; do
script_alpm="${TERMUX_PREFIX}/share/libalpm/scripts/$(sed 's|.alpm.script$||' <<< "${script##*/}")"
script_alpm="${TERMUX_PREFIX_CLASSICAL}/share/libalpm/scripts/$(sed 's|.alpm.script$||' <<< "${script##*/}")"
${sed} "${script}" > "${script_alpm}"
chmod +x "${script_alpm}"
done
Expand Down
20 changes: 20 additions & 0 deletions scripts/build/termux_step_install_switcher_files.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
termux_step_install_switcher_files() {
local i
for i in "${TERMUX_PKG_BUILDER_DIR}"/*.alternatives; do
[[ -f "${i}" ]] || continue
local -a NAME=()
local -A DEPENDENTS=() LINK=() ALTERNATIVE=() PRIORITY=()
termux_alternatives__parse_alternatives_file "${i}"

mkdir -p "${TERMUX_PREFIX_CLASSICAL}/share/pacman-switch"
{
local name
for name in "${NAME[@]}"; do
echo "switcher_group_${name}() {"
echo " priority=${PRIORITY[$name]}"
echo " associations=(${LINK[$name]}:${ALTERNATIVE[$name]}${DEPENDENTS[$name]})"
echo "}"
done
} > "${TERMUX_PREFIX_CLASSICAL}/share/pacman-switch/$(basename "${i//.alternatives/.sw}")"
Copy link
Member

@TomJo2000 TomJo2000 Sep 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's wrong with the .alternatives file extension?
You're parsing those anyway.
Why invent your own ad-hoc plaintext format?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why invent your own ad-hoc plaintext format?

I did this to make it easier for pacman-switch to retrieve/parse data. Switcher files (.sw) are essentially shell scripts with functions that can be run to retrieve variables with data and then manipulate them immediately.

done
}
39 changes: 3 additions & 36 deletions scripts/build/termux_step_update_alternatives.sh
Original file line number Diff line number Diff line change
@@ -1,57 +1,24 @@
# shellcheck shell=bash

# The Debian `.alternatives` format is a simple ad-hoc plain text format
# to declaratively define groups for `update-alternatives`.
# This function parses files of this format and returns their contents
# in the associative arrays: ${LINK[@]} ${[ALTERNATIVE@]} ${DEPENDENTS[@]} ${PRIORITY[@]}
termux_parse_alternatives() {
local line key value
local dependents=0
while IFS=$'\n' read -r line; do

key="${line%%:*}" # Part before the first ':'
value="${line#*:[[:blank:]]*}" # Part after the first `:`, leading whitespace stripped

case "$key" in
'Name') NAME+=("$value") dependents=0 ;;
'Link') LINK[${NAME[-1]}]="$value" dependents=0 ;;
'Alternative') ALTERNATIVE[${NAME[-1]}]="$value" dependents=0 ;;
'Priority') PRIORITY[${NAME[-1]}]="$value" dependents=0 ;;
'Dependents') dependents=1; continue;;
esac

if (( dependents )); then
read -r dep_link dep_name dep_alternative <<< "$line"
DEPENDENTS[${NAME[-1]}]+=" --slave \"${TERMUX_PREFIX}/${dep_link}\" \"${dep_name}\" \"${TERMUX_PREFIX}/${dep_alternative}\""$' \\\n'
fi

done < <(sed -e 's|\s*#.*$||g' "$1") # Strip out any comments
}

termux_step_update_alternatives() {
printf '%s\n' "INFO: Processing 'update-alternatives' entries:" 1>&2
for alternatives_file in "${TERMUX_PKG_BUILDER_DIR}"/*.alternatives; do
[[ -f "$alternatives_file" ]] || continue
local -a NAME=()
local -A DEPENDENTS=() LINK=() ALTERNATIVE=() PRIORITY=()
termux_parse_alternatives "$alternatives_file"
termux_alternatives__parse_alternatives_file "$alternatives_file"

# Handle postinst script
[[ -f postinst ]] && mv postinst{,.orig}

local name
for name in "${NAME[@]}"; do
# Not every entry will have dependents in its group
# but we need to initialize the keys regardless
: "${DEPENDENTS[$name]:=}"
done
Comment on lines -43 to -47
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving this into the function is a good call since it's a concern of the function and shouldn't need to be handled at the callsite.


{ # Splice in the alternatives
# Use the original shebang if there's a 'postinst.orig'
[[ -f postinst.orig ]] && head -n1 postinst.orig || echo "#!${TERMUX_PREFIX}/bin/sh"
# Boilerplate header comment and checks
echo "# Automatically added by termux_step_update_alternatives"
echo "if [ \"\$1\" = 'configure' ] || [ \"\$1\" = 'abort-upgrade' ] || [ \"\$1\" = 'abort-deconfigure' ] || [ \"\$1\" = 'abort-remove' ] || [ \"${TERMUX_PACKAGE_FORMAT}\" = 'pacman' ]; then"
echo "if [ \"\$1\" = 'configure' ] || [ \"\$1\" = 'abort-upgrade' ] || [ \"\$1\" = 'abort-deconfigure' ] || [ \"\$1\" = 'abort-remove' ]; then"
echo " if [ -x \"${TERMUX_PREFIX}/bin/update-alternatives\" ]; then"
# 'update-alternatives' command for each group
for name in "${NAME[@]}"; do
Expand Down Expand Up @@ -86,7 +53,7 @@ termux_step_update_alternatives() {
[[ -f prerm.orig ]] && head -n1 prerm.orig || echo "#!${TERMUX_PREFIX}/bin/sh"
# Boilerplate header comment and checks
echo "# Automatically added by termux_step_update_alternatives"
echo "if [ \"\$1\" = 'remove' ] || [ \"\$1\" != 'upgrade' ] || [ \"${TERMUX_PACKAGE_FORMAT}\" = 'pacman' ]; then"
echo "if [ \"\$1\" = 'remove' ] || [ \"\$1\" != 'upgrade' ]; then"
echo " if [ -x \"${TERMUX_PREFIX}/bin/update-alternatives\" ]; then"
# Remove each group
for name in "${NAME[@]}"; do
Expand Down
56 changes: 56 additions & 0 deletions scripts/utils/termux/alternatives/termux_alternatives.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# shellcheck shell=bash

# Title: termux_alternatives
# Description: A library for working with Termux package Alternatives.



##
# Parse datas from the alternatives file and put the datas into the variables.
# .
# .
# **Parameters:**
# `path_to_alternatives_file` - The path to the package's `.alternatives` file.
# .
# **Returns:**
# returns their contents in the associative arrays:
# ${LINK[@]} ${[ALTERNATIVE[@]} ${DEPENDENTS[@]} ${PRIORITY[@]}
# .
# .
# termux_alternatives__parse_alternatives_file <path_to_alternatives_file>
##
Comment on lines +8 to +21
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the rewritten function comment is overly verbose and loses some of the original information.

I'm also not sure why this got moved to a new function (pseudo-)namespace.
termux_parse_alternatives or termux_parse_alternatives_file should be plenty descriptive.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I needed to move the function to utils so that it could be used not only in termux_step_update_alternatives but also in termux_step_install_switcher_files.

Regarding the function naming and its comments/description, this is a standard for scripts in utils (at least in scripts/utils/termux/). You can ask @agnostic-apollo for more details. Also, take a look at another script with the same standard - https://github.com/termux/termux-packages/blob/master/scripts/utils/termux/package/termux_package.sh

termux_alternatives__parse_alternatives_file() {
local line key value
local dependents=0
while IFS=$'\n' read -r line; do

key="${line%%:*}" # Part before the first ':'
value="${line#*:[[:blank:]]*}" # Part after the first `:`, leading whitespace stripped

case "$key" in
'Name') NAME+=("$value") dependents=0 ;;
'Link') LINK[${NAME[-1]}]="$value" dependents=0 ;;
'Alternative') ALTERNATIVE[${NAME[-1]}]="$value" dependents=0 ;;
'Priority') PRIORITY[${NAME[-1]}]="$value" dependents=0 ;;
'Dependents') dependents=1; continue;;
esac

if (( dependents )); then
read -r dep_link dep_name dep_alternative <<< "$line"
if [ "${TERMUX_PACKAGE_FORMAT}" = "pacman" ]; then
# Data format for pacman-switch
DEPENDENTS[${NAME[-1]}]+=" ${dep_link}:${dep_alternative}"
else
# Data format for update-alternatives
DEPENDENTS[${NAME[-1]}]+=" --slave \"${TERMUX_PREFIX_CLASSICAL}/${dep_link}\" \"${dep_name}\" \"${TERMUX_PREFIX_CLASSICAL}/${dep_alternative}\""$' \\\n'
fi
fi

done < <(sed -e 's|\s*#.*$||g' "$1") # Strip out any comments

for key in "${NAME[@]}"; do
# Not every entry will have dependents in its group
# but we need to initialize the keys regardless
: "${DEPENDENTS[$key]:=}"
done
}