[simple] add initial simple repo builder
This commit is contained in:
parent
ee7e8af9a0
commit
29682e821f
|
|
@ -0,0 +1,177 @@
|
||||||
|
#!/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
|
||||||
Loading…
Reference in New Issue