Last active
September 13, 2021 17:50
-
-
Save jirutka/6717f68c7f76c9425b21d0cbe2eaa007 to your computer and use it in GitHub Desktop.
Some helper scripts for checking dependencies of Alpine packages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# This scripts checks the given list of packages if they have | |
# reverse dependencies (i.e. there are packages which depends on them). | |
# Dependencies that are on the list are excluded. | |
# | |
# Usage: $0 LIST | |
set -eu | |
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" | |
find_revdeps() { | |
local pkgname="$1" | |
local excludes="$2" | |
"$SCRIPT_DIR"/abuild-deps -ors $pkgname \ | |
| grep -vFf "$excludes" \ | |
| sort | uniq | |
} | |
has_maintainer() { | |
local pkgname="$1" | |
local abuild="$pkgname/APKBUILD" | |
if [ -f "$abuild" ]; then | |
grep -qE '# Maintainer: *\w+' "$abuild" | |
else | |
echo "ERROR: $abuild does not exist!" >&2 | |
fi | |
} | |
mark_unmaintained() { | |
local pkg; for pkg in $@; do | |
if has_maintainer $pkg; then | |
printf "%s " $pkg | |
else | |
printf "%s* " $pkg | |
fi | |
done | |
} | |
pkglist="$1" | |
echo '# PKGNAME <- list of packages that (make)depends on PKGNAME' >&2 | |
cat "$pkglist" | while read pkgname; do | |
revdeps="$(find_revdeps "$pkgname" "$pkglist")" | |
if [ -n "$revdeps" ]; then | |
printf "%s <- %s\n" "$pkgname" "$(mark_unmaintained $revdeps)" | |
fi | |
done | |
echo '' | |
echo '* package without a maintainer' >&2 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Script for resolving (reverse) dependencies (both runtime and buildtime) | |
# of an abuild. It uses abuild-deps-index to build index of dependencies | |
# and abuild-origin to translate to/from origin name. | |
# | |
set -eu | |
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" | |
export PATH="$SCRIPT_DIR:$PATH" | |
find_deps() { | |
cat "$DEPS_INDEX" \ | |
| grep $(printf '-e ^%s\s ' $@) \ | |
| cut -d ' ' -f 2 \ | |
| sort | uniq | |
} | |
find_rdeps() { | |
cat "$DEPS_INDEX" \ | |
| grep $(printf '-e \s%s$ ' $@) \ | |
| cut -d ' ' -f 1 \ | |
| sort | uniq | |
} | |
usage() { | |
cat <<-EOF | |
Usage: $0 [options] PKGNAME | |
Find all (reverse) dependencies, both runtime and buildtime, of PKGNAME. | |
Note that this script is just a quick hack with many limitations! | |
It ignores version ranges, archs and "provides". | |
Options: | |
-c Rebuild indexes. | |
-h Show this message. | |
-o Print origins instead of (sub)packages. | |
-r Resolve reverse dependencies. | |
-s Include subpackages of PKGNAME. | |
Environment: | |
REPODIR Path of the abuilds repository (defaults to .) | |
DEPS_INDEX Path of the dependencies index (defaults to \$REPODIR/deps.idx). | |
EOF | |
} | |
: ${REPODIR:="."} | |
: ${DEPS_INDEX:="$(readlink -f "$REPODIR/deps.idx")"} | |
origin='no' | |
reindex='no' | |
reverse='no' | |
incl_subpkgs='no' | |
while getopts 'chors' opt; do | |
case $opt in | |
c) reindex='yes';; | |
o) origin='yes';; | |
r) reverse='yes';; | |
s) incl_subpkgs='yes';; | |
h) usage; exit 0;; | |
--) break;; | |
esac | |
done | |
shift $(($OPTIND - 1)) | |
if [ $# -ne 1 ]; then | |
usage; exit 1 | |
fi | |
pkgnames="$1" | |
cd "$REPODIR" | |
if [ "$reindex" = 'yes' ] || [ ! -f "$DEPS_INDEX" ]; then | |
abuild-deps-index "$REPODIR" | |
abuild-origin-index "$REPODIR" | |
fi | |
if [ "$incl_subpkgs" = 'yes' ]; then | |
pkgnames="$(abuild-origin -r $1)" | |
fi | |
deps='' | |
if [ "$reverse" = 'yes' ]; then | |
deps="$(find_rdeps $pkgnames)" | |
else | |
deps="$(find_deps $pkgnames)" | |
fi | |
if [ "$origin" = 'yes' ]; then | |
printf '%s\n' $deps | xargs -I% abuild-origin % | sort | uniq | |
else | |
printf '%s\n' $deps | |
fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -eu | |
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" | |
export PATH="$SCRIPT_DIR:$PATH" | |
# $1: dependency name | |
resolve_dep() { | |
local name="$1" | |
apk info -d "$name" \ | |
| head -n 1 \ | |
| sed -En 's/^(.*)-[^-]+-r[0-9]+ .*/\1/p' | |
} | |
usage() { | |
cat >&2 <<-EOF | |
Usage: $0 <main | community | testing> | |
Check missing dependencies (both runtime and buildtime) of abuilds | |
in the specified repository. | |
Note that this script is just a quick hack with many limitations! | |
It ignores version ranges and archs. | |
EOF | |
} | |
if [ $# -ne 1 ] || [ "$1" = '-h' ]; then | |
usage; exit 1 | |
exit 1 | |
fi | |
repo="$1" | |
case "$repo" in | |
testing) repos='testing community main';; | |
community) repos='community main';; | |
main) repos='main';; | |
*) repos="$repo main";; | |
esac | |
for dir in $repos; do | |
if [ ! -d "$dir" ]; then | |
echo "ERROR: Directory $dir does not exist in $(pwd)" >&2 | |
exit 1 | |
fi | |
if [ -f "$dir/deps.idx" ]; then | |
echo "Using existing index $dir/deps.idx" >&2 | |
else | |
abuild-deps-index $dir | |
fi | |
if [ -f "$dir/origins.idx" ]; then | |
echo "Using exiting index $dir/origins.idx" >&2 | |
else | |
abuild-origin-index $dir | |
fi | |
done | |
pkgs_file="$(mktemp)" | |
( for dir in $repos; do cat $dir/origins.idx; done ) \ | |
| cut -d ' ' -f 1 \ | |
| sort | uniq \ | |
> "$pkgs_file" | |
cd "$repo" | |
echo '' | |
echo "# PKGNAME <- List of packages that (make)depends on missing PKGNAME" >&2 | |
cat deps.idx | cut -d ' ' -f 2 | sort | uniq \ | |
| grep -vFf "$pkgs_file" | while read pkgname; do | |
# XXX: We don't index "provides", so try to resolve the $pkgname with | |
# apk and if found, check if it's in the $pkgs_file. | |
pkgname="$(resolve_dep $pkgname)" | |
if [ -n "$pkgname" ] && ! grep -Fq "$pkgname" "$pkgs_file"; then | |
printf '%s <- %s\n' "$pkgname" "$(abuild-deps -ro $pkgname | tr '\n' ' ')" | |
fi | |
done | |
rm "$pkgs_file" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -eu | |
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" | |
export PATH="$SCRIPT_DIR:$PATH" | |
eval_in_abuild() { | |
local startdir="$(dirname "$1")"; shift | |
( | |
set +eu | |
cd "$startdir" | |
. /usr/share/abuild/functions.sh | |
. APKBUILD | |
eval "$(cat)" | |
) | |
} | |
# $1: path of APKBUILD file | |
pkg_names() { | |
eval_in_abuild "$1" <<-'EOF' | |
printf '%s\n' $pkgname $subpackages | cut -d : -f 1 | |
EOF | |
} | |
# $1: path of APKBUILD file | |
pkg_makedepends() { | |
eval_in_abuild "$1" <<-'EOF' | |
printf '%s\n' $makedepends | sed 's/[<>=][^ ]*//' | |
EOF | |
} | |
# $1: dependency name (e.g. so:libc) | |
resolve_autodep() { | |
local name="$1" | |
local pkgname="$(cat "$AUTODEPS_CACHE" | grep "^$name " | cut -d ' ' -f 2)" | |
if [ -n "$pkgname" ]; then | |
echo "$pkgname"; return 0 | |
fi | |
pkgname="$(apk info -d "$name" | head -n 1 | sed -En 's/^(.*)-[^-]+-r[0-9]+ .*/\1/p')" | |
if [ -n "$pkgname" ]; then | |
printf '%s %s\n' "$name" "$pkgname" >> "$AUTODEPS_CACHE" | |
echo "$pkgname" | |
return 0 | |
fi | |
return 1 | |
} | |
# XXX: apk info --depends is very slow. | |
# $1: pkgname | |
pkg_depends() { | |
local pkgname="$1" | |
local dep line | |
apk info --depends "$pkgname" | tail -n +2 | head -n -1 | while read line; do | |
dep="$(echo "$line" | sed 's/[<>=][^ ]*//')" | |
case "$line" in | |
*:*) resolve_autodep "$dep" || echo "WARNING: $dep not found!" >&2;; | |
!*) ;; | |
'') break;; | |
*) echo "$dep";; | |
esac | |
done | |
} | |
usage() { | |
cat >&2 <<-EOF | |
Usage: $0 [REPODIR] | |
Index all dependencies (both runtime and buildtime) of abuilds in | |
REPODIR (default is current directory). | |
This script is just a hack, not a complete production-ready solution! | |
EOF | |
} | |
if [ "${1:-}" = '-h' ]; then | |
usage; exit 1 | |
fi | |
repodir="${1:-"$(pwd)"}" | |
: ${DEPS_INDEX:="$repodir/deps.idx"} | |
: ${AUTODEPS_CACHE:="$(mktemp)"} | |
tmpfile="$(mktemp)" | |
total="$(find "$repodir" -name APKBUILD | wc -l)" | |
count=1 | |
touch "$AUTODEPS_CACHE" | |
echo "Indexing dependencies in $repodir..." >&2 | |
find "$repodir" -name APKBUILD | while read -r abuild; do | |
printf "[%d/%d] %s\n" $count $total "${abuild%/*}" | |
makedepends="$(pkg_makedepends "$abuild")" | |
for pkg in $(pkg_names "$abuild"); do | |
for dep in $(pkg_depends "$pkg") $makedepends; do | |
printf '%s %s\n' $pkg $dep >> "$tmpfile" | |
done | |
done | |
count=$(( count + 1 )) | |
done | |
echo "Completed. Writing index into $DEPS_INDEX" >&2 | |
cat "$tmpfile" | sort | uniq > "$DEPS_INDEX" | |
rm "$tmpfile" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -eu | |
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" | |
export PATH="$SCRIPT_DIR:$PATH" | |
usage() { | |
cat <<-EOF | |
Usage: $0 [options] PKGNAME | |
Resolve origin name of (sub)package PKGNAME, or subpackages of PKGNAME. | |
Options: | |
-c Rebuild indexes. | |
-h Show this message. | |
-r Resolve subpackages instead of origin. | |
Environment: | |
REPODIR Path of the abuilds repository (defaults to .) | |
ORIGINS_INDEX Path of the origins index (defaults to \$REPODIR/origins.idx). | |
EOF | |
} | |
: ${REPODIR:="."} | |
: ${ORIGINS_INDEX:="$REPODIR/origins.idx"} | |
reindex='no' | |
reverse='no' | |
while getopts 'chr' opt; do | |
case $opt in | |
c) reindex='yes';; | |
r) reverse='yes';; | |
h) usage; exit 0;; | |
--) break;; | |
esac | |
done | |
shift $(($OPTIND - 1)) | |
if [ $# -ne 1 ]; then | |
usage; exit 1 | |
fi | |
if [ "$reindex" = 'yes' ] || [ ! -f "$ORIGINS_INDEX" ]; then | |
abuild-origin-index "$REPODIR" | |
fi | |
if [ "$reverse" = 'yes' ]; then | |
out="$(cat "$ORIGINS_INDEX" | grep " $1$" | cut -d ' ' -f 1)" | |
else | |
out="$(cat "$ORIGINS_INDEX" | grep "^$1 " | cut -d ' ' -f 2)" | |
fi | |
[ -n "$out" ] && echo "$out" || exit 1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -eu | |
# $1: path of APKBUILD file | |
pkg_subpkgs() { | |
local startdir="$(dirname "$1")" | |
( | |
set +eu | |
cd "$startdir" | |
. /usr/share/abuild/functions.sh | |
. APKBUILD | |
printf '%s\n' $subpackages | cut -d : -f 1 | |
) | |
} | |
usage() { | |
cat >&2 <<-EOF | |
Usage: $0 [REPODIR] | |
Index names of origin and subpackages in REPODIR (default is | |
current directory). | |
This script is just a hack, not a complete production-ready solution! | |
EOF | |
} | |
if [ "${1:-}" = '-h' ]; then | |
usage; exit 1 | |
fi | |
repodir="${1:-"$(pwd)"}" | |
: ${ORIGINS_INDEX:="$repodir/origins.idx"} | |
tmpfile="$(mktemp)" | |
echo "Indexing (sub)packages in $repodir..." >&2 | |
find "$repodir" -name APKBUILD | while read -r abuild; do | |
origin="$(basename "${abuild%/*}")" | |
for pkgname in $origin $(pkg_subpkgs "$abuild"); do | |
printf "%s %s\n" $pkgname $origin >> "$tmpfile" | |
done | |
done | |
echo "Completed. Writing index into $ORIGINS_INDEX" >&2 | |
mv "$tmpfile" "$ORIGINS_INDEX" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment