xref: /netbsd/distrib/sets/syspkgdeps (revision 6550d01e)
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
15prog="${0##*/}"
16rundir="$(dirname "$0")" # ${0%/*} isn't good enough when there's no "/"
17. "${rundir}/sets.subr"
18
19#
20# set defaults
21#
22prefix=/
23
24usage()
25{
26	cat 1>&2 <<USAGE
27Usage: ${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
33USAGE
34	exit 1
35}
36
37# parse arguments
38while 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
57done
58shift $((${OPTIND} - 1))
59if [ $# -lt 1 ]; then
60	usage
61fi
62
63sets="$*"
64case "${sets}" in
65all)	sets="${nlists}" ;;
66esac
67
68# TBD clean up
69SCRATCH="$(${MKTEMP} -d "/var/tmp/${prog}.XXXXXX")"
70
71if [ $? -ne 0 ]; then
72	echo >&2 "${prog}: Could not create scratch directory."
73	exit 1
74fi
75
76PATH_MEMBERSHIP="${SCRATCH}/path-membership"
77PATH_TO_PKGNAME="${SCRATCH}/pathpkg.db"
78PARENT_PKGNAMES="${SCRATCH}/parent-pkgnames"
79PARENT_PATHNAMES="${SCRATCH}/parent-pathnames"
80
81echo >&2 "${prog}: indexing packages by pathnames"
82
83list_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
94if [ $? -ne 0 ]; then
95	echo >&2 "${prog}: error creating database, aborting"
96	exit 1
97fi
98
99echo >&2 "${prog}: computing parent pathnames"
100
101while read pathname pkgname; do
102	# print parent pathname.
103	# (This uses a cheap implementation of dirname from sets.subr.)
104	dirname "${pathname}"
105done < "${PATH_MEMBERSHIP}" > "${PARENT_PATHNAMES}"
106
107echo >&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
114if [ $? -ne 0 ]; then
115	echo >&2 "${prog}: error in parent-directory lookup, aborting"
116	exit 1
117fi
118
119echo >&2 "${prog}: checking for cyclic dependencies"
120
121tsort_errors="$(${TSORT} < "${SCRATCH}/alldeps" 2>&1 >/dev/null)"
122
123if [ -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
130fi
131
132echo >&2 "${prog}: removing redundant dependencies"
133
134${HOST_SH} "${rundir}/culldeps" < "${SCRATCH}/alldeps"
135
136if [ $? -ne 0 ]; then
137	echo >&2 "${prog}: error in culldeps, aborting"
138	exit 1
139fi
140