#!/bin/sh # # syspkgdeps [-a arch] [-m machine] [-s setsdir] [-p prefix] sets # # Compute naive package dependencies based on file & directory # nesting. E.g., if pkg P contains /foo/bar and Q contains /foo, # then Q is considered a dependency of P. # # Each line of output contains two syspkg names, # where the first syspkg depends on the second syspkg. # #set -u prog="${0##*/}" rundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/" . "${rundir}/sets.subr" # # set defaults # prefix=/ usage() { cat 1>&2 <<USAGE Usage: ${0##*/} [-a arch] [-m machine] [-s setsdir] [-p prefix] setname [...] -a arch set arch (e.g, m68k, mips, powerpc) [${MACHINE_ARCH}] -m machine set machine (e.g, amiga, i386, macppc) [${MACHINE}] -s setsdir directory to find sets [${setsdir}] -p prefix prefix for created plist [${prefix}] setname [...] sets to find dependencies for USAGE exit 1 } # parse arguments while getopts a:m:p:s: ch; do case ${ch} in a) MACHINE_ARCH="${OPTARG}" MACHINE_CPU="$(arch_to_cpu "${OPTARG}")" ;; m) MACHINE="${OPTARG}" ;; p) prefix="${OPTARG}" ;; s) setsdir="${OPTARG}" ;; *) usage ;; esac done shift $((${OPTIND} - 1)) if [ $# -lt 1 ]; then usage fi sets="$*" case "${sets}" in all) sets="${nlists}" ;; esac # TBD clean up SCRATCH="$(${MKTEMP} -d "/var/tmp/${prog}.XXXXXX")" if [ $? -ne 0 ]; then echo >&2 "${prog}: Could not create scratch directory." exit 1 fi PATH_MEMBERSHIP="${SCRATCH}/path-membership" PATH_TO_PKGNAME="${SCRATCH}/pathpkg.db" PARENT_PKGNAMES="${SCRATCH}/parent-pkgnames" PARENT_PATHNAMES="${SCRATCH}/parent-pathnames" echo >&2 "${prog}: indexing packages by pathnames" list_set_files ${sets} | ${SED} 's/^\.\///' | \ ${ENV_CMD} PREFIX="${prefix}" ${AWK} '{ if ($1 == ".") { print ENVIRON["PREFIX"] " " $2; } else { print ENVIRON["PREFIX"] $1 " " $2; } }' | ${SORT} -k 1 -u > "${PATH_MEMBERSHIP}" ${DB} -q -w -f - btree "${PATH_TO_PKGNAME}" < "${PATH_MEMBERSHIP}" if [ $? -ne 0 ]; then echo >&2 "${prog}: error creating database, aborting" exit 1 fi echo >&2 "${prog}: computing parent pathnames" while read pathname pkgname; do # print parent pathname. # (This uses a cheap implementation of dirname from sets.subr.) dirname "${pathname}" done < "${PATH_MEMBERSHIP}" > "${PARENT_PATHNAMES}" echo >&2 "${prog}: selecting parent packages using parent pathnames" ${DB} -q -f - btree "${PATH_TO_PKGNAME}" < "${PARENT_PATHNAMES}" | \ ${PASTE} "${PATH_MEMBERSHIP}" - | \ ${AWK} '{ if ($2 != $4) print $2 " " $4; }' | \ ${SORT} -u > "${SCRATCH}/alldeps" if [ $? -ne 0 ]; then echo >&2 "${prog}: error in parent-directory lookup, aborting" exit 1 fi echo >&2 "${prog}: checking for cyclic dependencies" tsort_errors="$(${TSORT} < "${SCRATCH}/alldeps" 2>&1 >/dev/null)" if [ -n "${tsort_errors}" ]; then # Errors from tsort are usually to do with cyclic dependencies. # The most likely underlying cause is that /foo and /foo/bar/baz # are in syspkg A, but /foo/bar is in syspkg B. echo >&2 "${tsort_errors}" # this is likely to be multiple lines echo >&2 "${prog}: Above messages probably indicate an error in the lists" exit 1 fi echo >&2 "${prog}: removing redundant dependencies" ${HOST_SH} "${rundir}/culldeps" < "${SCRATCH}/alldeps" if [ $? -ne 0 ]; then echo >&2 "${prog}: error in culldeps, aborting" exit 1 fi