diff options
author | bill-auger <mr.j.spam.me@gmail.com> | 2023-12-14 13:18:14 -0500 |
---|---|---|
committer | bill-auger <mr.j.spam.me@gmail.com> | 2023-12-14 17:13:11 -0500 |
commit | 8f4653db34f8ac8181e830325ea3a04e502fa785 (patch) | |
tree | e5ca480ea3b48aee1f991416fd7f9d154343657c | |
parent | f7f59d0afad879dd7b4eda91619c1f8df54067b7 (diff) |
[parabola-dependents]: wip
-rwxr-xr-x | parabola-dependents | 133 |
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 |