iiab-tools/scripts/simple_builder.sh

178 lines
4.8 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
# gen_simple_inplace.sh
# Generate PEP 503 "simple" indexes in-place for existing directories:
# <SIMPLE_DIR>/<pkg>/index.html
# Optionally generates:
# <SIMPLE_DIR>/index.html
die() { echo "ERROR: $*" >&2; exit 1; }
SIMPLE_DIR=""
ONLY_PKG=""
NO_TOP=0
DO_VERIFY=0
VERIFY_ONLY=0
while [ $# -gt 0 ]; do
case "$1" in
--simple-dir) SIMPLE_DIR="${2:-}"; shift 2 ;;
--pkg) ONLY_PKG="${2:-}"; shift 2 ;;
--no-top) NO_TOP=1; shift ;;
--verify) DO_VERIFY=1; shift ;;
--verify-only) VERIFY_ONLY=1; DO_VERIFY=1; shift ;;
-h|--help)
cat <<'EOF'
Usage:
./gen_simple_inplace.sh --simple-dir /var/www/.../simple
./gen_simple_inplace.sh --simple-dir /var/www/.../simple --pkg cffi --no-top
./gen_simple_inplace.sh --simple-dir /var/www/.../simple --verify
./gen_simple_inplace.sh --simple-dir /var/www/.../simple --verify-only
Options:
--no-top Don't rewrite /simple/index.html
--verify Verify that each <pkg>/index.html href exists and sha256 matches
--verify-only Verify only (do not regenerate any index.html)
EOF
exit 0
;;
*) die "Unknown arg: $1" ;;
esac
done
[ -n "$SIMPLE_DIR" ] || die "--simple-dir is required"
[ -d "$SIMPLE_DIR" ] || die "Not a directory: $SIMPLE_DIR"
is_artifact() {
case "$1" in
*.whl|*.tar.gz|*.zip|*.tgz) return 0 ;;
*) return 1 ;;
esac
}
verify_pkg_index() {
local pkgdir="$1"
local pkgname="$2"
local idx="$pkgdir/index.html"
local errs=0
if [ ! -f "$idx" ]; then
echo "VERIFY FAIL [$pkgname]: missing index.html" >&2
return 1
fi
# Extract href targets like: filename#sha256=....
# We assume filenames don't contain quotes/spaces (true for wheels/sdists typically).
while IFS= read -r href; do
[ -n "$href" ] || continue
local file="${href%%#sha256=*}"
local want="${href##*#sha256=}"
if [ ! -f "$pkgdir/$file" ]; then
echo "VERIFY FAIL [$pkgname]: missing file: $file" >&2
errs=$((errs+1))
continue
fi
local got
got="$(sha256sum "$pkgdir/$file" | awk '{print $1}')"
if [ "$got" != "$want" ]; then
echo "VERIFY FAIL [$pkgname]: sha256 mismatch for $file" >&2
echo " want: $want" >&2
echo " got : $got" >&2
errs=$((errs+1))
fi
done < <(
# Pull href="..."; keep only those containing #sha256=
grep -oE 'href="[^"]+"' "$idx" \
| sed -E 's/^href="(.*)"$/\1/' \
| grep -E '#sha256=' || true
)
if [ "$errs" -gt 0 ]; then
echo "VERIFY FAIL [$pkgname]: $errs error(s)" >&2
return 1
fi
echo "VERIFY OK [$pkgname]"
return 0
}
write_pkg_index() {
local pkgdir="$1"
local pkgname="$2"
local idx="$pkgdir/index.html"
# Collect artifacts in that pkg dir
mapfile -t files < <(find "$pkgdir" -maxdepth 1 -type f \( -name '*.whl' -o -name '*.tar.gz' -o -name '*.zip' -o -name '*.tgz' \) -printf '%f\n' | sort)
# If no artifacts, skip (or you can still write an empty index if you want)
[ "${#files[@]}" -gt 0 ] || return 0
{
echo "<!doctype html>"
echo "<html><head><meta charset=\"utf-8\"><title>${pkgname}</title></head><body>"
for bn in "${files[@]}"; do
# hash the file in place
sha="$(sha256sum "$pkgdir/$bn" | awk '{print $1}')"
printf '<a href="%s#sha256=%s">%s</a><br/>\n' "$bn" "$sha" "$bn"
done
echo "</body></html>"
} > "$idx"
}
# Determine package dirs
pkg_dirs=()
if [ -n "$ONLY_PKG" ]; then
[ -d "$SIMPLE_DIR/$ONLY_PKG" ] || die "Package dir not found: $SIMPLE_DIR/$ONLY_PKG"
pkg_dirs+=("$SIMPLE_DIR/$ONLY_PKG")
else
# All subdirs except hidden ones
while IFS= read -r d; do
pkg_dirs+=("$d")
done < <(find "$SIMPLE_DIR" -mindepth 1 -maxdepth 1 -type d ! -name '.*' | sort)
fi
if [ "$VERIFY_ONLY" -eq 0 ]; then
# Generate per-package indexes
for d in "${pkg_dirs[@]}"; do
pkg="$(basename "$d")"
write_pkg_index "$d" "$pkg"
done
# Top index (optional)
if [ "$NO_TOP" -eq 0 ] && [ -z "$ONLY_PKG" ]; then
top="$SIMPLE_DIR/index.html"
{
echo "<!doctype html>"
echo "<html><head><meta charset=\"utf-8\"><title>Simple Index</title></head><body>"
for d in "${pkg_dirs[@]}"; do
pkg="$(basename "$d")"
if find "$d" -maxdepth 1 -type f \( -name '*.whl' -o -name '*.tar.gz' -o -name '*.zip' -o -name '*.tgz' \) | grep -q .; then
printf '<a href="./%s/">%s</a><br/>\n' "$pkg" "$pkg"
fi
done
echo "</body></html>"
} > "$top"
fi
fi
if [ "$DO_VERIFY" -eq 1 ]; then
vfail=0
for d in "${pkg_dirs[@]}"; do
pkg="$(basename "$d")"
if ! verify_pkg_index "$d" "$pkg"; then
vfail=1
fi
done
if [ "$vfail" -ne 0 ]; then
die "Verification failed"
fi
fi
if [ "$VERIFY_ONLY" -eq 1 ]; then
echo "OK: verified indexes under: $SIMPLE_DIR"
else
echo "OK: indexes generated under: $SIMPLE_DIR"
fi