#!/bin/sh set -e ORIGIN="Jones" LABEL="Jones" DISTS="etch lenny squeeze sid" ARCHS="i386 powerpc amd64" PRVBASE=~/public_debian PUBBASE=~/public_websites/debian.jones.dk #PUBTOSRC=../../public_debian debugprint() { [ -n "$DEBUG" ] || return 0 [ -z "$2" ] || [ "$DEBUG" -lt "$2" ] || return 0 echo 1>&2 "$1" } compactlist() { ( for item in $@; do echo $item; done ) \ | sort -u \ | tr '\n' ' ' \ | sed 's/[[:space:]]\+/ /g; s/^[[:space:]]//; s/[[:space:]]$//' } regexfromlist() { echo $@ | sed 's/[[:space:]]\+/\\|/g; s/^/\\(/; s/$/\\)/' } sectionsfromhintstream() { perl -ne 's/^Sections:\W*// && do { s/\W*,\W*/\n/g; s/\W*$/\n/; print; }' } pkginfofromprvpkgdir() { package="$(basename "$1")" pool="$(dirname "$1" | sed 's,.*/pool-\([^/]\+\)/\?.*,\1,; s,-all$,,')" dist="$(echo "$pool" | sed 's,[^a-z].*$,,')" buildhost="$(echo $(dirname "$@") | sed 's,^\([^/]\+\)/pool-.*,\1,')" echo "$package $pool $dist $buildhost" } archsfromdirs() { archs="$( \ find "$@" -type l -exec find '{}'/ -type f -name '*.deb' ';' \ | sed 's/^.*_\([a-z0-9-]\+\)\.deb$/\1/; s/\ball\b/'"$ARCHS"'/g' \ )" archs="$(compactlist $archs)" debugprint "Archs found: \"$archs\"" "2" for arch in $archs; do valid= for arch_supported in $ARCHS; do case $arch in $arch_supported) debugprint "Arch ok: \"$arch\"" "2" echo "$arch" valid=1 ;; esac done if [ -z "$valid" ]; then # TODO: Optionally just skip echo 1>&2 "ERROR: Unsupported architecture: \"$arch\"." exit 1 fi done } distsfromprvgrpdirs() { dists="$( \ find "$@" -type l -exec find '{}'/ -type f -name '*.deb' ';' \ | sed 's,^.*/sections/[^/]*/\([^/]\+\)/.*$,\1,' \ )" dists="$(compactlist $dists)" debugprint "Dists found: \"$dists\"" "2" for dist in $dists; do valid= for dist_supported in $DISTS; do case $dist in $dist_supported) debugprint "Dist ok: \"$dist\"" "2" echo "$dist" valid=1 ;; esac done if [ -z "$valid" ]; then # TODO: Optionally just skip echo 1>&2 "ERROR: Unsupported distribution: \"$dist\"." exit 1 fi done } genlist() { section="$1" dist="$2" arch="$3" srcdir="$4" basedir="$5" case "$arch" in source) destdir="$basedir/source"; cmd="dpkg-scansources"; file="Sources"; ;; *) destdir="$basedir/binary-$arch"; cmd="dpkg-scanpackages -a$arch"; file="Packages"; ;; esac mkdir -p "$destdir" debugprint "genlist: \"$cmd . /dev/null pkg/$section/\"" "2" ( cd "$srcdir" && $cmd . /dev/null pkg/$section/ ) > "$destdir/$file" if [ -s "$destdir/$file" ]; then debugprint "Finalizing list at \"$destdir/\"" "2" gzip -c "$destdir/$file" > "$destdir/$file.gz" bzip2 -c "$destdir/$file" > "$destdir/$file.bz2" cat < "$destdir/Release" Archive: $dist Component: $section Origin: $ORIGIN Label: $LABEL Architecture: $arch EOF else debugprint "purge empty list at \"$destdir/\"" "2" rm -f "$destdir/$file" "$destdir/$file.gz" "$destdir/$file.bz2" "$destdir/Release" rmdir -p --ignore-fail-on-non-empty "$destdir" fi } genrelease() { dist="$1" shift sections="$@" archs="$(archsfromdirs "$PRVBASE/sections"/*/"$dist")" archs="$(compactlist $archs)" case "$dist" in etch) suite="oldstable";; lenny) suite="stable";; squeeze) suite="testing";; sid) suite="unstable";; esac cat < "$PUBBASE/dists/$dist/Release" Origin: $ORIGIN Label: $LABEL Suite: $suite Codename: $dist Architectures: $archs Components: $sections EOF } packages="$@" packages="$(compactlist $packages)" debugprint "Packages: \"$packages\"" case "$packages" in -a|--all) pkg_re=".*" ;; "") echo 1>&2 "ERROR: No package(s) provided." exit 1 ;; *) pkg_re="\b$(regexfromlist $packages)\b" ;; esac # Find packages in $prvpkgdir belonging to $sections # # $PRVBASE/$buildhost/pool-$pool/$package/ # batchsections="$( \ find "$PRVBASE" -type f -regex '.*/'"$pkg_re"'/HINTS' -exec cat '{}' ';' \ | sectionsfromhintstream )" batchsections="$(compactlist $batchsections)" debugprint "Sections in batch: \"$batchsections\"" batchsections_re= if [ -n "$batchsections" ]; then batchsections_re="\b$(regexfromlist $batchsections)\b" else echo 1>&2 "ERROR: Package(s) $@ was not found in any section." exit 1 fi debugprint "Clean dangling symlinks below \"$PRVBASE\" and \"$PUBBASE\"..." symlinks -dr ${DEBUG:+-v} "$PRVBASE" "$PUBBASE" # Create/update symlink farms $prvgrpdir and $pubpkgdir # # $PRVBASE/sections/$section/$dist/$section/$package/$pool/$buildhost # $PUBBASE/pkg/$package/$pool/$buildhost # cd "$PRVBASE" && find * -type f -name HINTS -exec grep -q "^Sections:.*$batchsections_re" '{}' ';' -printf '%h\n' \ | while read prvpkgdir; do debugprint "prvpkgdir: \"$prvpkgdir\"" set -- $(pkginfofromprvpkgdir "$prvpkgdir") package="$1" pool="$2" dist="$3" buildhost="$4" shift 4 pkgsections="$(cat "$PRVBASE/$prvpkgdir/HINTS" | sectionsfromhintstream)" pkgsections="$(compactlist $pkgsections)" for section in $pkgsections; do subdir="$section/$package/$pool" mkdir -p "$PUBBASE/pkg/$subdir" ln -sf -T "$PRVBASE/$prvpkgdir" "$PUBBASE/pkg/$subdir/$buildhost" mkdir -p "$PRVBASE/sections/$section/$dist/$subdir" ln -sf -T "../../../../../../$prvpkgdir" "$PRVBASE/sections/$section/$dist/$subdir/$buildhost" done done # Create/update package lists # # $PUBBASE/dists/$dist/$section/{binary-$arch,source} # for section in $batchsections; do dists="$(distsfromprvgrpdirs "$PRVBASE/sections/$section")" for dist in $dists; do debugprint "genlists \"\$PRVBASE/sections/$section/$dist\" -> \"\$PUBBASE/dists/$dist/$section\"" prvgrpdir="$PRVBASE/sections/$section/$dist/$section" pubpkgdir="$PUBBASE/dists/$dist/$section" archs="$(archsfromdirs "$prvgrpdir")" for arch in $archs; do genlist "$section" "$dist" "$arch" "$prvgrpdir" "$pubpkgdir" done [ -z "$archs" ] || genlist "$section" "$dist" "source" "$prvgrpdir" "$pubpkgdir" done done # Create/update Release files # # $PUBBASE/dists/$dist/Release # allsections="$( \ find "$PRVBASE" -type f -name HINTS -exec cat '{}' ';' \ | sectionsfromhintstream )" allsections="$(compactlist $allsections)" debugprint "All sections: \"$allsections\"" dists="$(distsfromprvgrpdirs "$PRVBASE/sections")" dists="$(compactlist $dists)" for dist in $dists; do genrelease "$dist" ${allsections} done exit 0