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