Home | History | Annotate | Line # | Download | only in sets
      1 #!/bin/sh
      2 #
      3 # syspkgdeps [-a arch] [-m machine] [-s setsdir] [-p prefix] sets
      4 #
      5 # Compute naive package dependencies based on file & directory
      6 # nesting. E.g., if pkg P contains /foo/bar and Q contains /foo,
      7 # then Q is considered a dependency of P.
      8 #
      9 # Each line of output contains two syspkg names,
     10 # where the first syspkg depends on the second syspkg.
     11 #
     12 
     13 #set -u
     14 
     15 prog="${0##*/}"
     16 rundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/"
     17 . "${rundir}/sets.subr"
     18 
     19 #
     20 # set defaults
     21 #
     22 prefix=/
     23 
     24 usage()
     25 {
     26 	cat 1>&2 <<USAGE
     27 Usage: ${0##*/} [-a arch] [-m machine] [-s setsdir] [-p prefix] setname [...]
     28 	-a arch		set arch (e.g, m68k, mips, powerpc)	[${MACHINE_ARCH}]
     29 	-m machine	set machine (e.g, amiga, i386, macppc)	[${MACHINE}]
     30 	-s setsdir	directory to find sets			[${setsdir}]
     31 	-p prefix	prefix for created plist		[${prefix}]
     32 	setname [...]	sets to find dependencies for
     33 USAGE
     34 	exit 1
     35 }
     36 
     37 # parse arguments
     38 while getopts a:m:p:s: ch; do
     39 	case ${ch} in
     40 	a)
     41 		MACHINE_ARCH="${OPTARG}"
     42 		MACHINE_CPU="$(arch_to_cpu "${OPTARG}")"
     43 		;;
     44 	m)
     45 		MACHINE="${OPTARG}"
     46 		;;
     47 	p)
     48 		prefix="${OPTARG}"
     49 		;;
     50 	s)
     51 		setsdir="${OPTARG}"
     52 		;;
     53 	*)
     54 		usage
     55 		;;
     56 	esac
     57 done
     58 shift $((${OPTIND} - 1))
     59 if [ $# -lt 1 ]; then
     60 	usage
     61 fi
     62 
     63 sets="$*"
     64 case "${sets}" in
     65 all)	sets="${nlists}" ;;
     66 esac
     67 
     68 # TBD clean up
     69 SCRATCH="$(${MKTEMP} -d "/var/tmp/${prog}.XXXXXX")"
     70 
     71 if [ $? -ne 0 ]; then
     72 	echo >&2 "${prog}: Could not create scratch directory."
     73 	exit 1
     74 fi
     75 
     76 PATH_MEMBERSHIP="${SCRATCH}/path-membership"
     77 PATH_TO_PKGNAME="${SCRATCH}/pathpkg.db"
     78 PARENT_PKGNAMES="${SCRATCH}/parent-pkgnames"
     79 PARENT_PATHNAMES="${SCRATCH}/parent-pathnames"
     80 
     81 echo >&2 "${prog}: indexing packages by pathnames"
     82 
     83 list_set_files ${sets} | ${SED} 's/^\.\///' | \
     84 ${ENV_CMD} PREFIX="${prefix}" ${AWK} '{
     85 	if ($1 == ".") {
     86 		print ENVIRON["PREFIX"] " " $2;
     87 	} else {
     88 		print ENVIRON["PREFIX"] $1 " " $2;
     89 	}
     90 }' | ${SORT} -k 1 -u > "${PATH_MEMBERSHIP}"
     91 
     92 ${DB} -q -w -f - btree "${PATH_TO_PKGNAME}" < "${PATH_MEMBERSHIP}"
     93 
     94 if [ $? -ne 0 ]; then
     95 	echo >&2 "${prog}: error creating database, aborting"
     96 	exit 1
     97 fi
     98 
     99 echo >&2 "${prog}: computing parent pathnames"
    100 
    101 while read pathname pkgname; do
    102 	# print parent pathname.
    103 	# (This uses a cheap implementation of dirname from sets.subr.)
    104 	dirname "${pathname}"
    105 done < "${PATH_MEMBERSHIP}" > "${PARENT_PATHNAMES}"
    106 
    107 echo >&2 "${prog}: selecting parent packages using parent pathnames"
    108 
    109 ${DB} -q -f - btree "${PATH_TO_PKGNAME}" < "${PARENT_PATHNAMES}" | \
    110 	${PASTE} "${PATH_MEMBERSHIP}" - | \
    111 	${AWK} '{ if ($2 != $4) print $2 " " $4; }' | \
    112 	${SORT} -u > "${SCRATCH}/alldeps"
    113 
    114 if [ $? -ne 0 ]; then
    115 	echo >&2 "${prog}: error in parent-directory lookup, aborting"
    116 	exit 1
    117 fi
    118 
    119 echo >&2 "${prog}: checking for cyclic dependencies"
    120 
    121 tsort_errors="$(${TSORT} < "${SCRATCH}/alldeps" 2>&1 >/dev/null)"
    122 
    123 if [ -n "${tsort_errors}" ]; then
    124 	# Errors from tsort are usually to do with cyclic dependencies.
    125 	# The most likely underlying cause is that /foo and /foo/bar/baz
    126 	# are in syspkg A, but /foo/bar is in syspkg B.
    127 	echo >&2 "${tsort_errors}" # this is likely to be multiple lines
    128 	echo >&2 "${prog}: Above messages probably indicate an error in the lists"
    129 	exit 1
    130 fi
    131 
    132 echo >&2 "${prog}: removing redundant dependencies"
    133 
    134 ${HOST_SH} "${rundir}/culldeps" < "${SCRATCH}/alldeps"
    135 
    136 if [ $? -ne 0 ]; then
    137 	echo >&2 "${prog}: error in culldeps, aborting"
    138 	exit 1
    139 fi
    140