summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbill-auger <mr.j.spam.me@gmail.com>2020-09-23 03:00:06 -0400
committerbill-auger <mr.j.spam.me@gmail.com>2021-01-05 22:24:56 -0500
commitf7878ef7b0cbcd34b604f699e93478d2358d9919 (patch)
treef1a029aa644e4629b45a4eac414bd5dc8002a3f7
parent41ca916b592b44d0855a568c3688382b46b2a5f7 (diff)
[parabola-dependents]: formatted and verbose outputwip-2020-11-20
-rwxr-xr-xsrc/maintenance-tools/parabola-dependents107
1 files changed, 78 insertions, 29 deletions
diff --git a/src/maintenance-tools/parabola-dependents b/src/maintenance-tools/parabola-dependents
index 0e0f619..f601bb3 100755
--- a/src/maintenance-tools/parabola-dependents
+++ b/src/maintenance-tools/parabola-dependents
@@ -1,9 +1,7 @@
#!/bin/bash
readonly BE_VERBOSE=$( [[ "$1" == '-v' ]] && echo 1 || echo 0 )
-readonly DB_DIR="$(su $(logname) -c 'mktemp -d -t parabola-dependents-XXXXXXXXXX')"
-readonly CFG_FILE=${DB_DIR}/pacman-all.conf
-readonly OPTS="--dbpath=${DB_DIR} --config=${CFG_FILE}"
+# readonly REPOS=( nonprism nonsystemd{-testing,} libre{-testing,}
readonly REPOS=( nonprism{-testing,} nonsystemd{-testing,} libre{-testing,}
kernels{-testing,} testing core extra community{-testing,}
pcr{-testing,} nonprism-multilib{-testing,} nonsystemd-multilib
@@ -23,17 +21,31 @@ readonly USAGE='USAGE:
List all parabola packages which are dependents of a specified package.
+ By default, only first-order dependents are listed,
+ with counts of higher-order dependents.
+
If <PACKAGE_NAME> does not exist, a dummy package will be created,
in memory, for pactree to reflect upon.
+ Note: this script can take several minutes to complete,
+ if the dependency-tree for <PACKAGE_NAME> is large.
+
Options:
-v
- Display the dependency-chain.'
+ Itemize all higher-order dependents, displaying the dependency-chain.'
readonly INVALID_ARG_MSG="no dependency package specified\n\n${USAGE}"
readonly UNPRIVILEGED_MSG="this script requires super-user privileges"
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()
+
+Ignored=() # CollectResults()
+Dependents=() # CollectResults()
+declare -A HiorderDependents # CollectResults()
Log() # (log_fmt [args]*)
@@ -41,7 +53,7 @@ Log() # (log_fmt [args]*)
local log_fmt=$1 ; shift ;
local args="$@"
- printf "${CBLUE}${log_fmt}${CEND}\n" ${args}
+ printf "${CBLUE}${log_fmt}${CEND}\n" ${args} >&2
}
LogError() # (source_file func_name line_n)
@@ -51,7 +63,7 @@ LogError() # (source_file func_name line_n)
local line_n=$3
printf "${CRED}ERROR: in ${func_name}\n${line_n}: %s${CEND}\n" \
- "$(awk "(( NR == ${line_n} )) { print }" ${source_file})"
+ "$(awk "(( NR == ${line_n} )) { print }" ${source_file})" >&2
}
Init() # (dep_pkgname)
@@ -59,11 +71,14 @@ Init() # (dep_pkgname)
local dep_pkgname=$1
local dummy_pkg=${dep_pkgname}-0.0.0-42-$(uname -m).pkg.tar.xz
+ readonly DB_DIR="$(su $(logname) -c 'mktemp -d -t parabola-dependents-XXXXXXXXXX')"
+ readonly CFG_FILE=${DB_DIR}/pacman-all.conf
+ readonly OPTS="--dbpath=${DB_DIR} --config=${CFG_FILE}"
+
printf "[options]\nArchitecture = auto\n" > ${CFG_FILE}
for repo in ${REPOS[@]}
do printf "[${repo}]\nInclude = /etc/pacman.d/mirrorlist\n" >> ${CFG_FILE}
done
- printf "[parabola-dependents]\nServer = file://${DB_DIR}\n" >> ${CFG_FILE}
Log "updating database ...."
pacman ${OPTS} -Sy &> /dev/null || true
@@ -80,8 +95,9 @@ Init() # (dep_pkgname)
repo-add --new parabola-dependents.db.tar ./${dummy_pkg} &> /dev/null
Log "dummy package '${dep_pkgname}' created"
+ printf "[parabola-dependents]\nServer = file://${DB_DIR}\n" >> ${CFG_FILE}
fi
- pacman ${OPTS} -Sy&> /dev/null
+ pacman ${OPTS} -Sy &> /dev/null
}
IsArchRepo() # (repo)
@@ -89,31 +105,63 @@ IsArchRepo() # (repo)
local repo=$1 ; [[ "${repo}" =~ ^(community|core|extra|multilib|testing)$ ]]
}
-ListParabolaDependents() # (dep_pkgname)
+CollectResults() # (dep_pkgname)
{
local dep_pkgname=$1
- local dep_chain pkg repos
+ local dep_chains dep_chain dep_pkg via_pkg repos repo
# TODO: --chain is a custom pactree feature
export PATH="/code/pacman-contrib/src:${PATH}"
- Log "searching ...." ; echo ;
- # TODO: --chain is a custom pactree feature
- pactree ${OPTS} --sync --reverse --unique --chain ${dep_pkgname} | sort | \
- while read dep_chain
- do pkg=$(sed 's|.*<- ||' <<<${dep_chain})
- repos=$(pacman ${OPTS} -Si ${pkg} | grep Repository | cut -d ':' -f 2)
-
- for repo in ${REPOS}
- do if IsArchRepo ${repo}
- then echo "${repo}/${pkg} (ignoring)" >&2
- else echo -n "${repo}/${pkg}"
- (( $BE_VERBOSE )) && echo " [ ${dep_chain} ]" || echo ''
- fi
- done
+ # query database
+ Log "searching ...."
+ mapfile -t dep_chains < <(pactree ${OPTS} --sync --reverse --unique --chain \
+ ${dep_pkgname} | sort )
+
+ # compile results
+ Log "compiling results for (${#dep_chains[@]}) dependencies ...."
+ 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 ' ')
+
+ for repo in ${repos}
+ do if IsArchRepo ${repo}
+ then Ignored+=( "${repo}/${dep_pkg}" )
+ else Dependents+=( "${repo}/${dep_pkg} ${dep_chain}" )
+ HiorderDependents[${via_pkg}]=$(( ${HiorderDependents[${via_pkg}]} + 1 ))
+ fi
+ done
done
}
+PrintReport()
+{
+ local dep_chain is_hiorder_dep via_pkg repo_pkg
+ declare -i n_hiorder_deps
+
+ echo
+ 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
+ fi
+ done | column --table --separator="${SEP_CHAR}" --table-wrap=2
+
+ echo
+ if (( BE_VERBOSE && ${#Ignored[@]} ))
+ then printf "%s${SEP_CHAR}(ignored)\n" "${Ignored[@]}" | column --table --separator="${SEP_CHAR}"
+ else echo "(${#Ignored[@]} ignored)"
+ fi
+}
+
Cleanup()
{
if [[ -d "${DB_DIR}" && "${DB_DIR}" =~ parabola-dependents ]]
@@ -128,10 +176,11 @@ trap 'LogError "${BASH_SOURCE[0]}" "${FUNCNAME[0]}" "${LINENO}"' ERR
(( $BE_VERBOSE )) && shift || true
-(( ! EUID )) || ! echo -e "${UNPRIVILEGED_MSG}" || false
-(( $# )) || ! echo -e "${INVALID_ARG_MSG}" || false
+(( ! EUID )) || ! echo -e "${UNPRIVILEGED_MSG}" || exit 1
+(( $# )) || ! echo -e "${INVALID_ARG_MSG}" || exit 1
-Init $1
-ListParabolaDependents $1
-Cleanup
+LANG=C
+Init $1
+CollectResults $1
+PrintReport