summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbill-auger <mr.j.spam.me@gmail.com>2022-09-10 18:17:55 -0400
committerbill-auger <mr.j.spam.me@gmail.com>2022-09-21 06:58:47 -0400
commit97e192d6081e7e0c43ea147959323633c1c57de9 (patch)
tree85ea3ad624fdee3c4a5594518bda5513b5a959b1
parentea94c344e8f7e42da439bde0a062fb775388c988 (diff)
[maintenance-tools/parabola-dependents]: housekeeping
-rwxr-xr-xsrc/maintenance-tools/parabola-dependents157
1 files changed, 96 insertions, 61 deletions
diff --git a/src/maintenance-tools/parabola-dependents b/src/maintenance-tools/parabola-dependents
index 4b6b675..86504cb 100755
--- a/src/maintenance-tools/parabola-dependents
+++ b/src/maintenance-tools/parabola-dependents
@@ -3,7 +3,7 @@
readonly ABS_DIR=/packages/abslibre
readonly DEBUG=0
-readonly BE_VERBOSE=$( [[ "$1" == '-v' ]] && echo 1 || echo 0 )
+readonly BE_VERBOSE=$( [[ "${1}" == '-v' ]] && echo 1 || echo 0 ) ; (( $BE_VERBOSE )) && shift ;
readonly PKGBUILD_SED_RX='s|/PKGBUILD$|| ; s|([^/]*/)?([^/]+)/([^/]+)$|\2 \3|'
readonly DEP=$( sed -E "${PKGBUILD_SED_RX}" <<<${1} | cut -d ' ' -f 2 )
@@ -46,7 +46,11 @@ readonly USAGE="USAGE:
By default, only first-order dependents are listed,
with counts of higher-order dependents.
- Note: this script can take several minutes to complete, if the dependency-tree is large.
+ Note: This script makes no assumption regarding the state of the ABS trees.
+ You will need to manage them manually (eg: \`git pull && git checkout master\`).
+ It will however, ignore any PKGBUILDs which are not checked-in to the master branch.
+
+ Note: This script can take several minutes to complete, if the dependency-graph is large.
Options:
-v
@@ -57,9 +61,10 @@ readonly CBLUE='\033[0;36m'
readonly CRED='\033[0;31m'
readonly CEND='\033[0m'
readonly SEP_CHAR='='
-DB_DIR='' # Init()
-CFG_FILE='' # Init()
-OPTS='' # Init()
+DB_DIR='' # Init()
+CFG_FILE='' # Init()
+PACMAN_OPTS='' # Init()
+PACTREE_OPTS='' # Init()
Ignored=() # CollectResults()
Dependents=() # CollectResults()
@@ -67,33 +72,62 @@ Makedependents=() # CollectResults()
declare -A HiorderDependents # CollectResults()
-Log() # (log_fmt [args]*)
+## helpers ##
+
+Log() # (log_fmt [fmt_args]*)
+{
+ local log_fmt=$1
+ local fmt_args="${@:2}"
+
+ printf "${CBLUE}${log_fmt}${CEND}\n" ${fmt_args} >&2
+}
+
+LogError() # (log_fmt [fmt_args]*)
{
- local log_fmt=$1 ; shift ;
- local args="$@"
+ local log_fmt=$1
+ local fmt_args="${@:2}"
- printf "${CBLUE}${log_fmt}${CEND}\n" ${args} >&2
+ printf "${CRED}ERROR: ${log_fmt}${CEND}\n" ${fmt_args} >&2
}
-LogError() # (source_file func_name line_n)
+LogScriptError() # (source_file func_name line_n)
{
local source_file="$1"
local func_name=$2
local line_n=$3
+ local err_loc="$(awk "(( NR == ${line_n} )) { print }" ${source_file})"
+
+ LogError "in ${func_name}\n${line_n}: %s\n" "${err_loc}"
+}
- printf "${CRED}ERROR: in ${func_name}\n${line_n}: %s${CEND}\n" \
- "$(awk "(( NR == ${line_n} )) { print }" ${source_file})" >&2
+Exit() # (log_fmt [fmt_args]*)
+{
+ LogError "$@" ; exit 1 ;
+}
+
+IsArchRepo() # (repo)
+{
+ local repo=$1 ; [[ "${repo}" =~ ^(community|core|extra|multilib|testing)$ ]]
}
+
+## business ##
+
Init()
{
+ # find or create the temporary workspace
readonly DB_DIR="$( db_dir=$(ls -1 -d /tmp/${TEMP_DB_NAME}.??? 2> /dev/null | head -n 1)
[[ -d "${db_dir}" ]] &&
echo "${db_dir}" ||
su $(logname) -c "mktemp -d -p /tmp -t ${TEMP_DB_NAME}.XXX" )"
readonly CFG_FILE=${DB_DIR}/pacman-all.conf
- readonly OPTS="--config=${CFG_FILE}"
+ readonly PACMAN_OPTS="--config=${CFG_FILE}"
+ readonly PACTREE_OPTS="${PACMAN_OPTS} --sync --reverse --unique --chain"
+# TODO: `pactree --chain` is an unpublished custom feature
+export PATH="/code/pacman-contrib/src:${PATH}"
+
+ # populate or update the temporary package database
if ! (( DEBUG )) || ! (( $(ls -1 /tmp/${TEMP_DB_NAME}.??? | wc -l) ))
then Log "updating database ...."
printf "[options]\nArchitecture = auto\n" > ${CFG_FILE}
@@ -101,52 +135,45 @@ Init()
for repo in ${REPOS[@]}
do printf "[${repo}]\nInclude = /etc/pacman.d/mirrorlist\n" >> ${CFG_FILE}
done
- pacman ${OPTS} -Sy &> /dev/null
- else Log "not updating database in DEBUG mode - delete ${DB_DIR} to sync"
+ pacman ${PACMAN_OPTS} -Sy &> /dev/null
+ else Log "skipping database update in DEBUG mode - delete ${DB_DIR} to sync"
fi
# create dummy for missing dependency package or sodep
- local dep pkgbase dummy_pkg
- if ! pacman ${OPTS} -Ss ^${DEP}$ &> /dev/null
+ local log_msg dep pkgbase dummy_pkg
+ if ! pacman ${PACMAN_OPTS} -Ss ^${DEP}$ &> /dev/null
then if [[ "${DEP}" =~ (.*)\.so=? ]]
- then Log "creating dummy package for sodep: '${DEP}'"
+ then log_msg="creating dummy package for sodep: '${DEP}'"
dep=${DEP} ; pkgbase=$(sed 's|^\([0-9a-z@._+-]*\)|\1|' <<<${BASH_REMATCH[1]}) ;
- else Log "pkgbase: '${DEP}' not found - creating dummy package"
+ else log_msg="pkgbase: '${DEP}' not found - creating dummy package"
dep='' ; pkgbase=${DEP} ;
fi
+ dummy_pkg=${pkgbase}-0.0.0-42-$(uname -m).pkg.tar.xz
+
+ [[ ! -f ${DB_DIR}/${dummy_pkg} ]] && Log "${log_msg}" || break
cd ${DB_DIR}
printf "${DUMMY_PKGBUILD}\n" "${pkgbase}" "${dep}" > ./PKGBUILD
su $(logname) -c 'makepkg --force &> /dev/null'
- dummy_pkg=${pkgbase}-0.0.0-42-$(uname -m).pkg.tar.xz
- [[ -f ./${dummy_pkg} ]]
-
- repo-add ${TEMP_DB_NAME}.db.tar ./${dummy_pkg} &> /dev/null
+ if [[ -f ./${dummy_pkg} ]]
+ then repo-add ${TEMP_DB_NAME}.db.tar ./${dummy_pkg} &> /dev/null
+ printf "[${TEMP_DB_NAME}]\nServer = file://${DB_DIR}\n" >> ${CFG_FILE}
+ pacman ${PACMAN_OPTS} -Sy &> /dev/null
- Log "dummy package '${pkgbase}' created"
- printf "[${TEMP_DB_NAME}]\nServer = file://${DB_DIR}\n" >> ${CFG_FILE}
-
- pacman ${OPTS} -Sy &> /dev/null
+ Log "dummy package '${pkgbase}' created"
+ else Exit "makepkg failed"
+ fi
fi
}
-IsArchRepo() # (repo)
-{
- local repo=$1 ; [[ "${repo}" =~ ^(community|core|extra|multilib|testing)$ ]]
-}
-
CollectResults()
{
- local dep_chains dep_chain dep_pkg via_pkg repos repo pkgbase
-
-# TODO: --chain is a custom pactree feature
-export PATH="/code/pacman-contrib/src:${PATH}"
+ local dep_chains pkgbuild repo pkgbase dep_chain dep_pkg via_pkg repos
# query database for dependents
Log "querying database ...."
- mapfile -t dep_chains < <(pactree ${OPTS} --sync --reverse --unique --chain \
- ${DEP} | sort )
+ mapfile -t dep_chains < <(pactree ${PACTREE_OPTS} ${DEP} | sort)
# parse PKGBUILDs for makedepends
Log "searching abslibre ...."
@@ -161,11 +188,12 @@ export PATH="/code/pacman-contrib/src:${PATH}"
done
# compile results
- Log "compiling results for ($(( ${#Makedependents[*]} + ${#dep_chains[@]} ))) dependents ...."
+ Log "compiling results ...."
for dep_chain in "${dep_chains[@]}"
do dep_pkg=$(sed 's|.*<- ||' <<<${dep_chain})
via_pkg=$(sed 's|.*\] <- \([^ ]*\).*|\1|' <<<${dep_chain})
- repos=$(pacman ${OPTS} -Si ${dep_pkg} | grep Repository | cut -d ':' -f 2 | tr -d ' ')
+ repos="$(pacman ${PACMAN_OPTS} -Si ${dep_pkg} | grep Repository | \
+ cut -d ':' -f 2 | tr -d ' ' )"
for repo in ${repos}
do if IsArchRepo ${repo}
@@ -179,33 +207,41 @@ export PATH="/code/pacman-contrib/src:${PATH}"
PrintReport()
{
+ local log_msg="\ndirect$( ! (( BE_VERBOSE )) || echo " and transitive") parabola dependents:"
local dep_chain is_hiorder_dep via_pkg repo_pkg
declare -i n_hiorder_deps
- (( ${#Dependents[*]} )) && echo "direct and transitive dependents"
+ # report parabola abslibre packages with some degree of run-time dependency
+ # on the input package or sodep
+ (( ${#Dependents[*]} )) && Log "${log_msg}"
for dep_chain in "${Dependents[@]}"
- do if (( BE_VERBOSE ))
- then echo "${dep_chain/ /${SEP_CHAR}}"
- else is_hiorder_dep=$( (( $(tr '<' '\n' <<<${dep_chain} | wc -l) > 2 )) && echo 1 || echo 0 )
-
- if ! (( is_hiorder_dep ))
- then via_pkg=$(sed 's|.*\] <- \([^ ]*\).*|\1|' <<<${dep_chain})
- repo_pkg=${dep_chain/ *}
- n_hiorder_deps=$(( ${HiorderDependents[${via_pkg}]} - 1 ))
- echo " ${repo_pkg}${SEP_CHAR}(${n_hiorder_deps} higher-order deps)"
- fi
+ do is_hiorder_dep=$( (( $(tr '<' '\n' <<<${dep_chain} | wc -l) > 2 )) && echo 1 || echo 0 )
+
+ if (( BE_VERBOSE ))
+ then # display all transitive dependents
+ echo " ${dep_chain/ /${SEP_CHAR}}"
+ elif ! (( is_hiorder_dep ))
+ then # display only first-order dependents
+ via_pkg=$(sed 's|.*\] <- \([^ ]*\).*|\1|' <<<${dep_chain})
+ repo_pkg=${dep_chain/ *}
+ n_hiorder_deps=$(( ${HiorderDependents[${via_pkg}]} - 1 ))
+ echo " ${repo_pkg}${SEP_CHAR}(${n_hiorder_deps} higher-order deps)"
fi
done | column --table --separator="${SEP_CHAR}" --table-wrap=2
+ # report parabola abslibre packages with direct build-time dependency
+ # on the input package or sodep
if (( ${#Makedependents[*]} ))
- then Log "\nmakedepends dependents:"
+ then Log "\nbuild dependents:"
printf " %s\n" ${Makedependents[*]}
fi
- echo
+ # report arch abs packages with direct run-time dependency
+ # on the input package or sodep
if (( BE_VERBOSE && ${#Ignored[@]} ))
- then printf "%s${SEP_CHAR}(ignored)\n" "${Ignored[@]}" | column --table --separator="${SEP_CHAR}"
- else echo "(${#Ignored[@]} ignored)"
+ then Log "\narch dependents:"
+ printf " %s\n" "${Ignored[@]}"
+ else echo -e "\n(plus ${#Ignored[@]} arch dependents)"
fi
}
@@ -218,16 +254,15 @@ Cleanup()
set -o errexit -o errtrace
-trap 'Cleanup' EXIT INT TERM
-trap 'LogError "${BASH_SOURCE[0]}" "${FUNCNAME[0]}" "${LINENO}"' ERR
+trap 'Cleanup' EXIT INT TERM
+trap 'LogScriptError "${BASH_SOURCE[0]}" "${FUNCNAME[0]}" "${LINENO}"' ERR
-(( $BE_VERBOSE )) && shift || true
-(( ! EUID )) || ! echo -e "${UNPRIVILEGED_MSG}" || exit 1
-(( $# )) || ! echo -e "${INVALID_ARG_MSG}" || exit 1
+(( ! EUID )) || ! echo -e "${UNPRIVILEGED_MSG}" || exit 1
+(( $# )) || ! echo -e "${INVALID_ARG_MSG}" || exit 1
-LANG=C
+export LC_ALL=C
Init
CollectResults
PrintReport