14d23e6d8Sdyoung#!/bin/sh 24d23e6d8Sdyoung# 34d23e6d8Sdyoung# syspkgdeps [-a arch] [-m machine] [-s setsdir] [-p prefix] sets 44d23e6d8Sdyoung# 54d23e6d8Sdyoung# Compute naive package dependencies based on file & directory 64d23e6d8Sdyoung# nesting. E.g., if pkg P contains /foo/bar and Q contains /foo, 74d23e6d8Sdyoung# then Q is considered a dependency of P. 84d23e6d8Sdyoung# 999b7c623Sapb# Each line of output contains two syspkg names, 1099b7c623Sapb# where the first syspkg depends on the second syspkg. 1199b7c623Sapb# 124d23e6d8Sdyoung 134d23e6d8Sdyoung#set -u 144d23e6d8Sdyoung 152f132c69Sapbprog="${0##*/}" 1626d8593bSapbrundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/" 1726d8593bSapb. "${rundir}/sets.subr" 1826d8593bSapb 192f132c69Sapb# 202f132c69Sapb# set defaults 212f132c69Sapb# 222f132c69Sapbprefix=/ 234d23e6d8Sdyoung 24b852db83Slukemusage() 25b852db83Slukem{ 26b852db83Slukem cat 1>&2 <<USAGE 27b852db83SlukemUsage: ${0##*/} [-a arch] [-m machine] [-s setsdir] [-p prefix] setname [...] 280bee96eaSapb -a arch set arch (e.g, m68k, mips, powerpc) [${MACHINE_ARCH}] 290bee96eaSapb -m machine set machine (e.g, amiga, i386, macppc) [${MACHINE}] 300bee96eaSapb -s setsdir directory to find sets [${setsdir}] 310bee96eaSapb -p prefix prefix for created plist [${prefix}] 32b852db83Slukem setname [...] sets to find dependencies for 33b852db83SlukemUSAGE 344d23e6d8Sdyoung exit 1 354d23e6d8Sdyoung} 364d23e6d8Sdyoung 374d23e6d8Sdyoung# parse arguments 382f132c69Sapbwhile getopts a:m:p:s: ch; do 39b852db83Slukem case ${ch} in 40b852db83Slukem a) 410bee96eaSapb MACHINE_ARCH="${OPTARG}" 420bee96eaSapb MACHINE_CPU="$(arch_to_cpu "${OPTARG}")" 434d23e6d8Sdyoung ;; 44b852db83Slukem m) 450bee96eaSapb MACHINE="${OPTARG}" 464d23e6d8Sdyoung ;; 47b852db83Slukem p) 480bee96eaSapb prefix="${OPTARG}" 494d23e6d8Sdyoung ;; 50b852db83Slukem s) 510bee96eaSapb setsdir="${OPTARG}" 524d23e6d8Sdyoung ;; 534d23e6d8Sdyoung *) 54b852db83Slukem usage 554d23e6d8Sdyoung ;; 564d23e6d8Sdyoung esac 574d23e6d8Sdyoungdone 58b852db83Slukemshift $((${OPTIND} - 1)) 594d23e6d8Sdyoungif [ $# -lt 1 ]; then 604d23e6d8Sdyoung usage 614d23e6d8Sdyoungfi 624d23e6d8Sdyoung 630bee96eaSapbsets="$*" 642f132c69Sapbcase "${sets}" in 652f132c69Sapball) sets="${nlists}" ;; 662f132c69Sapbesac 674d23e6d8Sdyoung 684d23e6d8Sdyoung# TBD clean up 692f132c69SapbSCRATCH="$(${MKTEMP} -d "/var/tmp/${prog}.XXXXXX")" 704d23e6d8Sdyoung 71c32228d4Sapbif [ $? -ne 0 ]; then 72c32228d4Sapb echo >&2 "${prog}: Could not create scratch directory." 73c32228d4Sapb exit 1 74c32228d4Sapbfi 754d23e6d8Sdyoung 760bee96eaSapbPATH_MEMBERSHIP="${SCRATCH}/path-membership" 770bee96eaSapbPATH_TO_PKGNAME="${SCRATCH}/pathpkg.db" 780bee96eaSapbPARENT_PKGNAMES="${SCRATCH}/parent-pkgnames" 790bee96eaSapbPARENT_PATHNAMES="${SCRATCH}/parent-pathnames" 804d23e6d8Sdyoung 81c32228d4Sapbecho >&2 "${prog}: indexing packages by pathnames" 824d23e6d8Sdyoung 830bee96eaSapblist_set_files ${sets} | ${SED} 's/^\.\///' | \ 840bee96eaSapb${ENV_CMD} PREFIX="${prefix}" ${AWK} '{ 854d23e6d8Sdyoung if ($1 == ".") { 864d23e6d8Sdyoung print ENVIRON["PREFIX"] " " $2; 874d23e6d8Sdyoung } else { 884d23e6d8Sdyoung print ENVIRON["PREFIX"] $1 " " $2; 894d23e6d8Sdyoung } 900bee96eaSapb}' | ${SORT} -k 1 -u > "${PATH_MEMBERSHIP}" 914d23e6d8Sdyoung 92c32228d4Sapb${DB} -q -w -f - btree "${PATH_TO_PKGNAME}" < "${PATH_MEMBERSHIP}" 934d23e6d8Sdyoung 94c32228d4Sapbif [ $? -ne 0 ]; then 95c32228d4Sapb echo >&2 "${prog}: error creating database, aborting" 96c32228d4Sapb exit 1 97c32228d4Sapbfi 98c32228d4Sapb 99c32228d4Sapbecho >&2 "${prog}: computing parent pathnames" 1004d23e6d8Sdyoung 1014d23e6d8Sdyoungwhile read pathname pkgname; do 1022f132c69Sapb # print parent pathname. 1032f132c69Sapb # (This uses a cheap implementation of dirname from sets.subr.) 1042f132c69Sapb dirname "${pathname}" 1050bee96eaSapbdone < "${PATH_MEMBERSHIP}" > "${PARENT_PATHNAMES}" 1064d23e6d8Sdyoung 107c32228d4Sapbecho >&2 "${prog}: selecting parent packages using parent pathnames" 1084d23e6d8Sdyoung 1090bee96eaSapb${DB} -q -f - btree "${PATH_TO_PKGNAME}" < "${PARENT_PATHNAMES}" | \ 1100bee96eaSapb ${PASTE} "${PATH_MEMBERSHIP}" - | \ 1113a0b5411Sapb ${AWK} '{ if ($2 != $4) print $2 " " $4; }' | \ 1121acb45d4Sapb ${SORT} -u > "${SCRATCH}/alldeps" 1134d23e6d8Sdyoung 1144d23e6d8Sdyoungif [ $? -ne 0 ]; then 115c32228d4Sapb echo >&2 "${prog}: error in parent-directory lookup, aborting" 1164d23e6d8Sdyoung exit 1 1174d23e6d8Sdyoungfi 1181acb45d4Sapb 119*b020cbecSapbecho >&2 "${prog}: checking for cyclic dependencies" 1201acb45d4Sapb 1211acb45d4Sapbtsort_errors="$(${TSORT} < "${SCRATCH}/alldeps" 2>&1 >/dev/null)" 1221acb45d4Sapb 1231acb45d4Sapbif [ -n "${tsort_errors}" ]; then 1241acb45d4Sapb # Errors from tsort are usually to do with cyclic dependencies. 1251acb45d4Sapb # The most likely underlying cause is that /foo and /foo/bar/baz 1261acb45d4Sapb # are in syspkg A, but /foo/bar is in syspkg B. 127*b020cbecSapb echo >&2 "${tsort_errors}" # this is likely to be multiple lines 128*b020cbecSapb echo >&2 "${prog}: Above messages probably indicate an error in the lists" 1291acb45d4Sapb exit 1 1301acb45d4Sapbfi 1311acb45d4Sapb 132*b020cbecSapbecho >&2 "${prog}: removing redundant dependencies" 1331acb45d4Sapb 1341acb45d4Sapb${HOST_SH} "${rundir}/culldeps" < "${SCRATCH}/alldeps" 1351acb45d4Sapb 1361acb45d4Sapbif [ $? -ne 0 ]; then 137*b020cbecSapb echo >&2 "${prog}: error in culldeps, aborting" 1381acb45d4Sapb exit 1 1391acb45d4Sapbfi 140