xref: /netbsd-src/distrib/sets/syspkgdeps (revision d6b37f8359738988ad2becd56747597dc922b426)
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