#!/bin/sh -e ## e.g. # # $ ./scripts/setup # $ ./scripts/deplist system | ./scripts/depsort # HERE="$(dirname $(readlink -f ${0}))"; BASE="${HERE}/.."; ## # Usage # if test ${#} = 0; then cat <<EOF Usage: ${0} REPO [REPO ...] EOF fi ## # Sanity check. The specified repositories exist. # for repo in ${@}; do if ! test -d "${BASE}/${repo}"; then printf "E: '%s' is not a valid repository!\n" "${repo}" 1>&2; exit 1; fi done ## # Find a package by name or find the parent package of a subpackage. # Note that the index is padded by a space on either side for easy grep. # # Usage: parent PACKAGE # parent () { a=$("${HERE}"/sgrep " ${1} " "${HERE}"/.index | cut -d' ' -f2 | xargs); if ! test -z "${a}"; then r=${a}; else b=$(grep " ${1} " "${HERE}"/.index | cut -d' ' -f2 | xargs); if ! test -z "${b}"; then r=${b}; else r=${1}; fi fi printf "%s" "${r}"; } ## # Prints a fatal error and exits. # nxdepf () { printf "E: dependency '%s' not found or excepted (needed by '%s')\n" "${1}" "${2}" 1>&2; exit 1; } ## # Do everything at once. # for repo in ${@}; do find "${BASE}/${repo}" -mindepth 1 -maxdepth 1 -type d | while read k; do ( ## # Source APKBUILD in a subshell to avoid contamination. # . "${k}/APKBUILD"; ## # Special-case some options. For example, '!check' means # that the 'checkdepends=' variable is not used. Ignore. # for m in ${options}; do case ${m} in !check) checkdepends=; ;; esac done ## # Aggregate all possible depends. Obviously if something # is not specified, it will be empty anyway. # # FIXME: Clean this up somehow. # cats=$(tr ' ' '\n' <<EOF | sort | uniq ${checkdepends} ${depends} ${depends_dev} ${makedepends} ${makedepends_build} ${makedepends_host} ${_core_depends} EOF ); ## # Construct canonical repository/package name. # p="${repo}/${k##*/}"; ## # Column 1 output. # printf "%s " "${p}"; test -z "${cats}" && printf "\n" && continue; # skip when empty; we are done for d in ${cats}; do ## # Trim out most of the qualifiers. # _d=${d}; # formatting _d=${_d%=*}; # remove =version _d=${_d%>*}; # remove >version _d=${_d%<*}; # remove <version _d=${_d%~*}; # remove ~version ## # Handle cases where a dependency is provided by another package. # case "${_d}" in !*) continue; ;; # override: system /bin/sh) _d=dash; ;; /sbin/init) _d=s6-linux-init; ;; cmd:sendmail) _d=ssmtp; ;; cmd:which) _d=debianutils; ;; libc-utils) _d=musl; ;; # override: user (FIXME: incomplete) cmd:byacc) _d=$(parent ${d#cmd:*}); ;; cmd:cpio) _d=$(parent libarchive-tools); ;; cmd:gzip) _d=$(parent ${d#cmd:*}); ;; cmd:yacc) _d=bison; ;; cmd:lex) _d=flex; ;; cmd:locale) _d=musl-locales; ;; cmd:mcookie) _d=$(parent ${d#cmd:*}); ;; cmd:pkg-config) _d=pkgconf; ;; cmd:unix2dos) _d=dos2unix; ;; cargo-*) _d=rust; ;; guile-dev) _d=guile; ;; llvm-dev) _d=$(parent llvm13-dev); ;; llvm-static) _d=$(parent llvm13-static); ;; llvm-test-*) _d=$(parent llvm13-test-utils); ;; py3-libxml2) _d=$(parent py-libxml2); ;; # automatic search *) _d=$(parent $_d); ;; esac ## # Determine relative path to dependency. It might be # in the wrong repository, in which case must fix. # # TODO: Clean up to accommodate any number of repos # and their policies. For example, 'kernel' if we do # end up creating that someday. # case "${repo}" in system) # nothing in system may depend on anything outside of system if ! test -f "${BASE}/${repo}/${_d}/APKBUILD"; then nxdepf "${_d}" "${p}"; fi path="${repo}/${_d}"; ;; user) # packages in user might depend on something in system if ! test -f "${BASE}/${repo}/${_d}/APKBUILD"; then if test -f "${BASE}/system/${_d}/APKBUILD"; then path="system/${_d}"; else nxdepf "${_d}" "${p}"; fi else path="${repo}/${_d}"; fi ;; esac ## # Print remaining columns of output if not parent. # printf " %s" "${path}"; done | tr ' ' '\n' | sed -e "\@${p}\$@d" | sort -u | xargs; # sort and remove duplicates ) done | sort; # sort only within a repo done