summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbill-auger <mr.j.spam.me@gmail.com>2023-12-14 13:18:14 -0500
committerbill-auger <mr.j.spam.me@gmail.com>2023-12-14 17:13:11 -0500
commit8f4653db34f8ac8181e830325ea3a04e502fa785 (patch)
treee5ca480ea3b48aee1f991416fd7f9d154343657c
parentf7f59d0afad879dd7b4eda91619c1f8df54067b7 (diff)
[parabola-dependents]: wip
-rwxr-xr-xparabola-dependents133
1 files changed, 75 insertions, 58 deletions
diff --git a/parabola-dependents b/parabola-dependents
index 4b2503e..996a1f4 100755
--- a/parabola-dependents
+++ b/parabola-dependents
@@ -15,7 +15,12 @@ readonly REPOS=( nonprism{-testing,} nonsystemd{-testing,} libre{-testing,}
pcr{-testing,} nonprism-multilib{-testing,} nonsystemd-multilib
libre-multilib{-testing,} multilib{-testing,} pcr-multilib{-testing,} )
readonly TEMP_DB_NAME=parabola-dependents
-readonly DUMMY_PKGBUILD='pkgname=%s
+readonly CBLUE='\033[0;36m'
+readonly CRED='\033[0;31m'
+readonly CYELLOW='\033[0;33m'
+readonly CEND='\033[0m'
+readonly JOIN_CHAR='='
+readonly DUMMY_PKGBUILD_FMT='pkgname=%s
pkgver=0.0.0
pkgrel=42
pkgdesc="dummy PKGBUILD for experimentation"
@@ -56,18 +61,16 @@ readonly USAGE="USAGE:
Options:
-v
- 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 CYELLOW='\033[0;33m'
-readonly CEND='\033[0m'
-readonly SEP_CHAR='='
+ Itemize all higher-order dependents, displaying the dependency-chain."
+readonly ENVIRONMENT_ERR_FMT="could not find \`'%s\` in the environment"
+readonly INVALID_CFG_ERR_MSG="space chars in ${TEMP_DB_NAME}\n"
+readonly INVALID_ARG_ERR_MSG="no dependency package specified${CEND}\n\n${USAGE}"
+readonly UNPRIVILEGED_ERR_MSG="this script requires super-user privileges"
DB_DIR='' # Init()
CFG_FILE='' # Init()
PACMAN_OPTS='' # Init()
PACTREE_OPTS='' # Init()
+PKGBASE='' # Init()
ParabolaDependents=() # CollectResults()
ArchDependents=() # CollectResults()
@@ -117,11 +120,13 @@ LogScriptError() # (source_file func_name line_n)
LogError "in ${func_name}\n${line_n}: ${err_loc=}\n"
}
+DummyPkg() { echo ${PKGBASE}-0.0.0-42-$(uname -m).pkg.tar.xz ; }
+
ParsePkgbuilds() # ("abs_dir" "dep_chains")
(
local abs_dir="$1"
local dep_chains=( "${@:2}" )
- local pkgbuild repo pkgbase
+ local pkgbuild
# DBG "ParsePkgbuilds() (${#dep_chains[@]}) dep_chains=${dep_chains[@]}" # ; return ;
# for ea in "${dep_chains[@]}" ; do DBG "=$ea" ; done ; return ;
set +o errexit +o errtrace ; trap '' EXIT INT TERM ERR ; # reset debug traps
@@ -131,25 +136,26 @@ ParsePkgbuilds() # ("abs_dir" "dep_chains")
do git ls-tree master ${pkgbuild} | grep -E '/PKGBUILD$' > /dev/null || continue
# DBG "ParsePkgbuilds() pkgbuild=${pkgbuild}"
-
- source ${pkgbuild}
+ (
+ local repo pkgbase ; source ${pkgbuild} ;
# continue
- if grep ^${DEP}$ <<<${makedepends[*]} > /dev/null || false
- then # parse direct makedepends
- repo=$( sed -E "${PKGBUILD_SED_RX}" <<<${pkgbuild} | cut -d ' ' -f 1)
- pkgbase=$(sed -E "${PKGBUILD_SED_RX}" <<<${pkgbuild} | cut -d ' ' -f 2)
- echo ${repo}/${pkgbase}
- else # collect transitive makedepends
- for makedepend in ${makedepends[*]}
- do
+ if grep ^${DEP}$ <<<${makedepends[*]} > /dev/null || false
+ then # parse direct makedepends
+ repo=$( sed -E "${PKGBUILD_SED_RX}" <<<${pkgbuild} | cut -d ' ' -f 1)
+ pkgbase=$(sed -E "${PKGBUILD_SED_RX}" <<<${pkgbuild} | cut -d ' ' -f 2)
+ echo ${repo}/${pkgbase}
+ else # collect transitive makedepends
+ for makedepend in ${makedepends[*]}
+ do
: # TODO:
- if grep " ${makedepend} " <<<${dep_chains[@]} > /dev/null
- then
+ if grep " ${makedepend} " <<<${dep_chains[@]} > /dev/null
+ then
DBG "ParsePkgbuilds() pkgbuild=${pkgbuild} makedepend=${makedepend} in-chain" >&2
# else echo "ParsePkgbuilds() pkgbuild=${pkgbuild} makedepend=${makedepend} not in-chain" >&2
- fi
- done
- fi
+ fi
+ done
+ fi
+ )
done
)
@@ -173,15 +179,16 @@ PrintDependent() # ("dep_chain")
if (( BE_VERBOSE ))
then # display all transitive dependents
- echo " ${dep_chain/ /${SEP_CHAR}}"
+ echo " ${dep_chain/ /${JOIN_CHAR}}"
elif IsFirstOrderDep "${dep_chain}"
then # display only first-order dependents
dep_pkg=$(sed 's|.*<- ||' <<<${dep_chain})
via_pkg=$(sed 's|.*\] <- \([^ ]*\).*|\1|' <<<${dep_chain})
n_hiorder_deps=$( awk '{print NF}' <<<${HiorderDependents[${via_pkg}]} )
- echo -n " ${dep_pkg}${SEP_CHAR}"
+ echo -n " ${dep_pkg}${JOIN_CHAR}"
(( n_hiorder_deps )) && echo "(plus ${n_hiorder_deps} higher-order deps)" || echo
+
# DBG "PrintDependent() via_pkg=$via_pkg HiorderDependents='${HiorderDependents[${via_pkg}]}'"
fi
}
@@ -196,13 +203,10 @@ Init()
echo "${db_dir}" ||
su $(logname) -c "mktemp -d -p /tmp -t ${TEMP_DB_NAME}.XXX" )"
readonly CFG_FILE=${DB_DIR}/pacman-all.conf
+ readonly LOG_FILE=${DB_DIR}/parabola-dependents.log
readonly PACMAN_OPTS="--dbpath=${DB_DIR} --config=${CFG_FILE}"
readonly PACTREE_OPTS="${PACMAN_OPTS} --sync --reverse --chain"
-# TODO: `pactree --chain` is an unpublished custom feature
-# git.parabola.nu/~git/pacman-contrib.git (parabola branch)
-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 ...."
@@ -210,35 +214,33 @@ export PATH="/code/pacman-contrib/src:${PATH}"
for repo in ${REPOS[@]}
do printf "[${repo}]\nInclude = /etc/pacman.d/mirrorlist\n" >> ${CFG_FILE}
done
- pacman ${PACMAN_OPTS} -Sy &> /dev/null
+ pacman ${PACMAN_OPTS} -Sy &> ${LOG_FILE} || Exit "$(cat ${LOG_FILE})"
else Log "skipping database update in DEBUG mode - delete ${DB_DIR} to sync"
fi
# create dummy for missing dependency package or sodep
- local log_msg dep pkgbase dummy_pkg
- if ! pacman ${PACMAN_OPTS} -Ss ^${DEP}$ &> /dev/null
+ local log_msg dep dummy_pkg
+ if ! pacman ${PACMAN_OPTS} -Ss ^${DEP}$ &> ${LOG_FILE}
then if [[ "${DEP}" =~ (.*)\.so=? ]]
then log_msg="creating dummy package for sodep: '${DEP}'"
- dep=${DEP} ; pkgbase=$(sed 's|^\([0-9a-z@._+-]*\)|\1|' <<<${BASH_REMATCH[1]}) ;
- else log_msg="pkgbase: '${DEP}' not found - creating dummy package"
- dep='' ; pkgbase=${DEP} ;
+ dep=${DEP} ; PKGBASE=$(sed 's|^\([0-9a-z@._+-]*\)|\1|' <<<${BASH_REMATCH[1]}) ;
+ else log_msg="package: '${DEP}' not found - creating dummy package"
+ dep='' ; PKGBASE=${DEP} ;
fi
- dummy_pkg=${pkgbase}-0.0.0-42-$(uname -m).pkg.tar.xz
+ readonly PKGBASE ; dummy_pkg=$(DummyPkg) ;
- if [[ ! -f ${DB_DIR}/${dummy_pkg} ]]
- then Log "${log_msg}"
- cd ${DB_DIR}
- printf "${DUMMY_PKGBUILD}\n" "${pkgbase}" "${dep}" > ./PKGBUILD
- su $(logname) -c 'makepkg --force &> /dev/null'
+ cd ${DB_DIR}
+ Log "${log_msg}" ; rm -f ./${dummy_pkg} ;
+ printf "${DUMMY_PKGBUILD_FMT}\n" "${PKGBASE}" "${dep}" > ./PKGBUILD
+ su $(logname) -c 'makepkg --force &> /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
+ if [[ -f ./${dummy_pkg} ]]
+ then repo-add ${TEMP_DB_NAME}.db.tar ./${dummy_pkg} &> ${LOG_FILE}
+ printf "[${TEMP_DB_NAME}]\nServer = file://${DB_DIR}\n" >> ${CFG_FILE}
+ pacman ${PACMAN_OPTS} -Sy &> ${LOG_FILE}
- Log "dummy package '${pkgbase}' created"
- else Exit "makepkg failed"
- fi
+ Log "dummy package '${PKGBASE}' created"
+ else Exit "makepkg failed"
fi
fi
}
@@ -249,7 +251,8 @@ CollectResults()
# query database for dependents
Log "querying database ...."
- mapfile -t dep_chains < <(pactree ${PACTREE_OPTS} ${DEP} | sort)
+# mapfile -t dep_chains < <(pactree ${PACTREE_OPTS} ${DEP} | sort)
+ mapfile -t dep_chains < <(pactree ${PACTREE_OPTS} ${DEP})
DBG "CollectResults() n_results=${#dep_chains[@]} + ${#ParabolaMakedependents[*]} + ${#ArchMakedependents[*]}"
DBG "CollectResults() dep_chains=%s" "${dep_chains[@]}"
@@ -268,6 +271,7 @@ DBG "CollectResults() ArchMakedependents=${ArchMakedependents[*]}"
via_pkg=$(sed 's|.*\] <- \([^ ]*\).*|\1|' <<<${dep_chain})
repos="$(pacman ${PACMAN_OPTS} -Si ${dep_pkg} | grep Repository | \
cut -d ':' -f 2 | tr -d ' ' )"
+
for repo in ${repos}
do if IsArchRepo ${repo}
then ArchDependents+=( "${dep_chain}" )
@@ -306,7 +310,8 @@ PrintReport()
# DBG "PrintReport() ${ParabolaDependents[*]}"
for dep_chain in "${ParabolaDependents[@]}"
do PrintDependent "${dep_chain}"
- done | column --table --separator="${SEP_CHAR}" --table-wrap=2
+ done | column --table --separator="${JOIN_CHAR}"
+ else echo -e "\n(0) parabola dependents"
fi
# report arch abs packages with some degree of run-time dependency
@@ -315,8 +320,8 @@ PrintReport()
then Log "\ndirect$( ! (( BE_VERBOSE )) || echo " and transitive") arch dependents:"
for dep_chain in "${ArchDependents[@]}"
do PrintDependent "${dep_chain}"
- done | column --table --separator="${SEP_CHAR}" --table-wrap=2
- else echo -e "\n(${#ArchDependents[@]} arch dependents)"
+ done | column --table --separator="${JOIN_CHAR}"
+ else echo -e "\n(${#ArchDependents[@]}) arch dependents"
fi
# report parabola abslibre packages with some degree of build-time dependency
@@ -336,8 +341,12 @@ PrintReport()
Cleanup()
{
- if [[ -d "${DB_DIR}" && "${DB_DIR}" =~ ^${TEMP_DB_NAME}\....$ ]] && ! (( DEBUG ))
- then rm --force --recursive ${DB_DIR}
+ if ! (( DEBUG ))
+ then [[ "${DB_DIR}" =~ ${TEMP_DB_NAME}\....$ ]] && rm -rf ${DB_DIR} || :
+ elif [[ -d "${DB_DIR}" ]]
+ then cd ${DB_DIR}
+ rm -f ./$(DummyPkg)
+ repo-remove ${TEMP_DB_NAME}.db.tar ${PKGBASE} &> ${LOG_FILE}
fi
}
@@ -347,8 +356,16 @@ trap 'Cleanup' EXIT INT
trap 'LogScriptError "${BASH_SOURCE[0]}" "${FUNCNAME[0]}" "${LINENO}"' ERR
-(( ! EUID )) || ! echo -e "${UNPRIVILEGED_MSG}" || exit 1
-(( $# )) || ! echo -e "${INVALID_ARG_MSG}" || exit 1
+# TODO: `pactree --chain` is an un-packaged custom feature
+# https://git.parabola.nu/pacman-contrib.git (parabola branch)
+export PATH="/code/pacman-contrib/src:${PATH}"
+[[ -x /code/pacman-contrib/src/pactree ]] || Exit "${ENVIRONMENT_ERR_FMT}" pactree
+
+which git &> /dev/null || Exit "${ENVIRONMENT_ERR_FMT}" git
+which pactree &> /dev/null || Exit "${ENVIRONMENT_ERR_FMT}" pactree
+[[ ! "${TEMP_DB_NAME}" =~ ' ' ]] || Exit "${INVALID_CFG_ERR_MSG}"
+(( ! EUID )) || Exit "${UNPRIVILEGED_ERR_MSG}"
+(( $# )) || Exit "${INVALID_ARG_ERR_MSG}"
export LC_ALL=C