summaryrefslogtreecommitdiff
path: root/scripts/deplist
diff options
context:
space:
mode:
authorZach van Rijn <me@zv.io>2022-04-30 01:00:37 -0500
committerZach van Rijn <me@zv.io>2022-04-30 01:05:50 -0500
commit64b8c083f9685b15b9c9eb9af787f679daad012c (patch)
treed6b24e7bf0b388f487daaa33c02e201c2cf63205 /scripts/deplist
parentd9fd5b1f036d17bcbdb7d38a02791561a1592f09 (diff)
downloadpackages-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-xscripts/deplist179
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