diff options
author | Zach van Rijn <me@zv.io> | 2022-04-30 01:00:37 -0500 |
---|---|---|
committer | Zach van Rijn <me@zv.io> | 2022-04-30 01:05:50 -0500 |
commit | 64b8c083f9685b15b9c9eb9af787f679daad012c (patch) | |
tree | d6b24e7bf0b388f487daaa33c02e201c2cf63205 /scripts/deplist | |
parent | d9fd5b1f036d17bcbdb7d38a02791561a1592f09 (diff) | |
download | packages-64b8c083f9685b15b9c9eb9af787f679daad012c.tar.gz packages-64b8c083f9685b15b9c9eb9af787f679daad012c.tar.bz2 packages-64b8c083f9685b15b9c9eb9af787f679daad012c.tar.xz packages-64b8c083f9685b15b9c9eb9af787f679daad012c.zip |
scripts/*: add dependency resolver.
Diffstat (limited to 'scripts/deplist')
-rwxr-xr-x | scripts/deplist | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/scripts/deplist b/scripts/deplist new file mode 100755 index 000000000..5eb51c95b --- /dev/null +++ b/scripts/deplist @@ -0,0 +1,179 @@ +#!/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 -n "${a}"; then + r=${a}; + else + b=$(grep " ${1} " "${HERE}"/.index | cut -d' ' -f2 | xargs); + r=${b}; + fi + printf "%s" "${r}"; +} + +## +# 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:mcookie) _d=$(parent ${d#cmd:*}); ;; + 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 + printf "E: dependency '%s' not found or excepted\n" "${_d}" 1>&2; + exit 1; + 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 + printf "E: dependency '%s' not found or excepted\n" "${_d}" 1>&2; + exit 1; + 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 |