|
| 1 | +# shellcheck shell=bash |
| 2 | + |
| 3 | +# The Debian `.alternatives` format is a simple ad-hoc plain text format |
| 4 | +# to declaratively define groups for `update-alternatives`. |
| 5 | +# This function parses files of this format and returns their contents |
| 6 | +# in the associative arrays: ${LINK[@]} ${[ALTERNATIVE@]} ${DEPENDENTS[@]} ${PRIORITY[@]} |
| 7 | +termux_parse_alternatives() { |
| 8 | + local line key value |
| 9 | + local dependents=0 |
| 10 | + while IFS=$'\n' read -r line; do |
| 11 | + |
| 12 | + key="${line%%:*}" # Part before the first ':' |
| 13 | + value="${line#*:[[:blank:]]*}" # Part after the first `:`, leading whitespace stripped |
| 14 | + |
| 15 | + case "$key" in |
| 16 | + 'Name') NAME+=("$value") dependents=0 ;; |
| 17 | + 'Link') LINK[${NAME[-1]}]="$value" dependents=0 ;; |
| 18 | + 'Alternative') ALTERNATIVE[${NAME[-1]}]="$value" dependents=0 ;; |
| 19 | + 'Priority') PRIORITY[${NAME[-1]}]="$value" dependents=0 ;; |
| 20 | + 'Dependents') dependents=1; continue;; |
| 21 | + esac |
| 22 | + |
| 23 | + if (( dependents )); then |
| 24 | + read -r dep_link dep_name dep_alternative <<< "$line" |
| 25 | + if [ "${TERMUX_PACKAGE_FORMAT}" = "pacman" ]; then |
| 26 | + # Data format for pacman-switch |
| 27 | + DEPENDENTS[${NAME[-1]}]+=" ${dep_link}:${dep_alternative}" |
| 28 | + else |
| 29 | + # Data format for update-alternatives |
| 30 | + DEPENDENTS[${NAME[-1]}]+=" --slave \"${TERMUX_PREFIX}/${dep_link}\" \"${dep_name}\" \"${TERMUX_PREFIX}/${dep_alternative}\""$' \\\n' |
| 31 | + fi |
| 32 | + fi |
| 33 | + |
| 34 | + done < <(sed -e 's|\s*#.*$||g' "$1") # Strip out any comments |
| 35 | +} |
| 36 | + |
| 37 | +termux_step_setup_alternatives() { |
| 38 | + if [ "${TERMUX_PACKAGE_FORMAT}" = "pacman" ]; then |
| 39 | + printf '%s\n' "INFO: Creating switcher files for 'pacman-switch':" 1>&2 |
| 40 | + else |
| 41 | + printf '%s\n' "INFO: Processing 'update-alternatives' entries:" 1>&2 |
| 42 | + fi |
| 43 | + for alternatives_file in "${TERMUX_PKG_BUILDER_DIR}"/*.alternatives; do |
| 44 | + [[ -f "$alternatives_file" ]] || continue |
| 45 | + local -a NAME=() |
| 46 | + local -A DEPENDENTS=() LINK=() ALTERNATIVE=() PRIORITY=() |
| 47 | + termux_parse_alternatives "$alternatives_file" |
| 48 | + |
| 49 | + local name |
| 50 | + for name in "${NAME[@]}"; do |
| 51 | + # Not every entry will have dependents in its group |
| 52 | + # but we need to initialize the keys regardless |
| 53 | + : "${DEPENDENTS[$name]:=}" |
| 54 | + done |
| 55 | + |
| 56 | + if [ "${TERMUX_PACKAGE_FORMAT}" = "pacman" ]; then |
| 57 | + local name_alternatives="$(basename "${alternatives_file//.alternatives/}")" |
| 58 | + ( |
| 59 | + # Storage location of switcher files |
| 60 | + cd "$TERMUX_PKG_MASSAGEDIR/$TERMUX_PREFIX_CLASSICAL" |
| 61 | + mkdir -p ./share/pacman-switch |
| 62 | + # Log message to indicate the switcher name |
| 63 | + printf 'INFO: %s\n' "${name_alternatives}:" 1>&2 |
| 64 | + { |
| 65 | + for name in "${NAME[@]}"; do |
| 66 | + # The second part of the log messenger to |
| 67 | + # indicate the switcher group and its points |
| 68 | + printf 'INFO: %s\n' "${name}:${PRIORITY[$name]}:" 1>&2 |
| 69 | + local point |
| 70 | + for point in ${LINK[$name]}:${ALTERNATIVE[$name]} ${DEPENDENTS[$name]}; do |
| 71 | + printf 'INFO: %s\n' "${point//:/ -> }" 1>&2 |
| 72 | + done |
| 73 | + # Filling the switcher data in shell function format |
| 74 | + echo "switcher_group_${name}() {" |
| 75 | + echo " priority=${PRIORITY[$name]}" |
| 76 | + echo " points=(${LINK[$name]}:${ALTERNATIVE[$name]}${DEPENDENTS[$name]})" |
| 77 | + echo "}" |
| 78 | + done |
| 79 | + } > "./share/pacman-switch/${name_alternatives}.sw" |
| 80 | + ) |
| 81 | + else |
| 82 | + # Handle postinst script |
| 83 | + [[ -f postinst ]] && mv postinst{,.orig} |
| 84 | + |
| 85 | + { # Splice in the alternatives |
| 86 | + # Use the original shebang if there's a 'postinst.orig' |
| 87 | + [[ -f postinst.orig ]] && head -n1 postinst.orig || echo "#!${TERMUX_PREFIX}/bin/sh" |
| 88 | + # Boilerplate header comment and checks |
| 89 | + echo "# Automatically added by termux_step_setup_alternatives" |
| 90 | + echo "if [ \"\$1\" = 'configure' ] || [ \"\$1\" = 'abort-upgrade' ] || [ \"\$1\" = 'abort-deconfigure' ] || [ \"\$1\" = 'abort-remove' ]; then" |
| 91 | + echo " if [ -x \"${TERMUX_PREFIX}/bin/update-alternatives\" ]; then" |
| 92 | + # 'update-alternatives' command for each group |
| 93 | + for name in "${NAME[@]}"; do |
| 94 | + # Main alternative group |
| 95 | + printf '%b' \ |
| 96 | + " # ${name}\n" \ |
| 97 | + " update-alternatives" $' \\\n' \ |
| 98 | + " --install \"${TERMUX_PREFIX}/${LINK[$name]}\" \"${name}\" \"${TERMUX_PREFIX}/${ALTERNATIVE[$name]}\" ${PRIORITY[$name]}" |
| 99 | + # If we have dependents, add those as well |
| 100 | + if [[ -n "${DEPENDENTS[$name]}" ]]; then |
| 101 | + # We need to add a ' \<lf>' to the --install line, |
| 102 | + # and remove the last ' \<lf>' from the dependents. |
| 103 | + printf ' \\\n%s' "${DEPENDENTS[$name]%$' \\\n'}" |
| 104 | + fi |
| 105 | + echo "" |
| 106 | + done |
| 107 | + # Close up boilerplate and add end comment |
| 108 | + echo " fi" |
| 109 | + echo "fi" |
| 110 | + echo "# End automatically added section" |
| 111 | + } > postinst |
| 112 | + if [[ -f postinst.orig ]]; then |
| 113 | + tail -n+2 postinst.orig >> postinst |
| 114 | + rm postinst.orig |
| 115 | + fi |
| 116 | + |
| 117 | + # Handle prerm script |
| 118 | + [[ -f prerm ]] && mv prerm{,.orig} |
| 119 | + |
| 120 | + { # Splice in the alternatives |
| 121 | + # Use the original shebang if there's a 'prerm.orig' |
| 122 | + [[ -f prerm.orig ]] && head -n1 prerm.orig || echo "#!${TERMUX_PREFIX}/bin/sh" |
| 123 | + # Boilerplate header comment and checks |
| 124 | + echo "# Automatically added by termux_step_setup_alternatives" |
| 125 | + echo "if [ \"\$1\" = 'remove' ] || [ \"\$1\" != 'upgrade' ]; then" |
| 126 | + echo " if [ -x \"${TERMUX_PREFIX}/bin/update-alternatives\" ]; then" |
| 127 | + # Remove each group |
| 128 | + for name in "${NAME[@]}"; do |
| 129 | + # Log message for this alternative group |
| 130 | + printf 'INFO: %s\n' "${name} -> ${ALTERNATIVE[$name]} (${PRIORITY[$name]})" 1>&2 |
| 131 | + # Removal line |
| 132 | + printf '%s\n' " update-alternatives --remove \"${name}\" \"${TERMUX_PREFIX}/${ALTERNATIVE[$name]}\"" |
| 133 | + done |
| 134 | + # Close up boilerplate and add end comment |
| 135 | + echo " fi" |
| 136 | + echo "fi" |
| 137 | + echo "# End automatically added section" |
| 138 | + } > prerm |
| 139 | + if [[ -f prerm.orig ]]; then |
| 140 | + tail -n+2 prerm.orig >> prerm |
| 141 | + rm prerm.orig |
| 142 | + fi |
| 143 | + fi |
| 144 | + done |
| 145 | +} |
0 commit comments