syspkgdeps revision 1.13 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 "checking for cyclic dependencies" 1>&2
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 "${tsort_errors}" 1>&2
128 echo "Above messages probably indicate an error in the lists" 1>&2
129 exit 1
130 fi
131
132 echo "removing redundant dependencies" 1>&2
133
134 ${HOST_SH} "${rundir}/culldeps" < "${SCRATCH}/alldeps"
135
136 if [ $? -ne 0 ]; then
137 echo "error in culldeps, aborting" 1>&2
138 exit 1
139 fi
140