#!/bin/bash # File: maat-builder # # Description: This file allows a Maat host to build source packages # and optionally upload to the AniNIX/Foundation # # Package: Maat # Copyright: WTFPL # # Author: DarkFeather # ### Printing defaults passCell="PASS"; failCell="FAIL"; warnCell="N/A"; tableHead="\n"; ### Add helptext. function Usage() { echo "Usage: $0" echo " $0 [ -b basedir ] [ -c AUR.git.list ] [ -T ] [ -u https://base.url/ ]" echo " $0 -h" echo echo 'Add -v to increase verbosity or -h for help. Add the -l LOGFILE flags to log to a file' echo 'Add the -r REPOCMD, -C make-package-command, -p PKGBUILDName, -t test-command, and' echo 'the -e package-extension flags for compatibility with non-ArchLinux repos.' } ### Put the initial content in the webfile function SeedWebFile() { printf '\n\nAniNIX/Maat -- Build Results\n\n\n\n\n\n\n\n

AniNIX/Maat -- Build Status

\nWEBSTATSGOHERE\n

AnINIX Packages

\n

These are packages written by the AniNIX. Their source is in AniNIX/Foundation.

\n' > "$webfile" printf "$tableHead" >> "$webfile" } ### Update the webfile to close up table tags and add stats. function UpdateWebFile() { sed -i "s#WEBSTATSGOHERE#

These are the AniNIX testing results. We found $passcount passing and $failcount failing packages, with $warncount warnings. It took $runtime seconds to finish.

#" "$webfile" printf '
PackageTesting StatusBuild StatusLatest BuildTime and Log of Run
\n\n\n' >> "$webfile" mv "$webfile" "$webfilefinal" } ### Build the package. Assumes a PKGBUILD is resent in the repo. # param suffix: where to store the final package function BuildPackage() { suffix="$1" [ `pgrep -afc pacman` -eq 0 ] && rm -Rf /var/lib/pacman/db.lck nice -n 10 timeout --preserve-status 20m sudo -u "depriv" /usr/sbin/makepkg -sfc --noconfirm --sign &>> "$pkgdir"/"$repodir".txt if [ $? -ne 0 ]; then # Build failed. printf "$failCell""$warnCell" >> "$webfile" else # Build passed. printf "$passCell""" >> "$webfile" # List passing versions for pkg in `find . -type f | egrep ".pkg.tar.xz$"`; do printf "$pkg
" >> "$webfile" mv "$pkg" "$pkgdir"/"$suffix"; mv "$pkg"".sig" "$pkgdir"/"$suffix"; done printf "" >> "$webfile" fi } ### Build the repo passed as argument # param repo: the repo to build. # param suffix: where to store the final package function BuildRepo() { repo="$1" suffix="$2" cd "$srcdir" if [ -z "$repo" ]; then continue; fi repodir="$(basename "$repo" | sed 's/\.git$//')" #Set up the checkout if [ ! -d "$repodir" ]; then git clone "$repo" fi cd "$repodir" git reset --hard origin &>/dev/null output="$(git pull 2>&1)" chown -R "depriv": . echo "$output" > "$pkgdir"/"$repodir".txt # Find the PKGBuilds in the repo for pkgbuild in `find . -type f -name PKGBUILD`; do cd "$(dirname "$pkgbuild")" # Tell the status file about it. printf ''"$repodir -- $pkgbuild"'' >> "$webfile" if [ -f Makefile ] && [ `egrep -c '^test:' Makefile` -ge 1 ]; then # Check test status. timeout --preserve-status "$timeout" sudo -u "depriv" /bin/bash -l -c 'make test' &>> "$pkgdir"/"$repodir".txt if [ $? -ne 0 ]; then # Testing failed. printf "$failCell""$warnCell""$warnCell" >> "$webfile" else # Testing passed. printf "$passCell" >> "$webfile" BuildPackage "$suffix" fi else # Can't test -- usually from non-AniNIX repos. printf "$warnCell" >> "$webfile" BuildPackage "$suffix" fi # Timestamp printf "$(date +%F-%R)\n" >> "$webfile" cd "$cwd" if [ ! -z "$testing" ]; then break; fi done cd "$cwd" } ### Update the local repo function UpdateLocalRepo() { set -x cd "$pkgdir" chown -R "depriv": . # TODO Add deduplication of updated files -- keep latest 3 versions. rm -Rf AniNIX.[db,files]* sudo -u "depriv" repo-add --sign ./AniNIX.db.tar.xz `ls -1 *".pkg.tar.xz"` cd aur/ rm -Rf aur.[db,files]* sudo -u "depriv" repo-add --sign ./aur.db.tar.xz `ls -1 *".pkg.tar.xz"` set +x } # Clear variables aurconf='/usr/local/etc/Maat/aur.list' baseurl='https://foundation.aninix.net/AniNIX' homedir="/srv/maat/" unset incremental unset skipPatching unset testing timeout="90s" # Stat tracking starttime=`date +%s` # Parse arguments while getopts 'b:c:hil:st:Tv' OPTION; do case "${OPTION}" in b) homedir="${OPTARG}" ;; c) aurconf="${OPTARG}" ;; h) Usage; exit 0 ;; i) incremental=1 ;; l) cmdstring="$0"; for arg in $@; do if [ "$arg" != "-l" ] && [ "$arg" != "${OPTARG}" ]; then cmdstring="$cmdstring \"${arg}\""; fi; done; exec /bin/bash -c "$cmdstring | tee -a \"${OPTARG}\""; ;; s) skipPatching=1 ;; t) timeout="${OPTARG}" ;; T) export MAATTESTINGVAR=1; exec $0 -l ./testing.log -v -s -c <(echo https://aur.archlinux.org/cower.git) -b . ;; v) set -x ;; *) usage; exit 1 ;; esac done # Ensure we are up to date -- otherwise, building is not a good plan. if [ -x `which pacman` ] && [ -z "$skipPatching" ]; then pacman -Syu --noconfirm; if [ $? -ne 0 ]; then echo "Self patching failed -- please investigate!" 1>&2 exit 1 fi fi # Ensure work directories live if [ $( echo "$homedir" | egrep -c '^/') -ne 1 ]; then homedir="${PWD}/${homedir}" fi # Setup srcdir="${homedir}/src" && mkdir -p "${srcdir}" pkgdir="${homedir}/pkg" && mkdir -p "${pkgdir}" mkdir -p "${pkgdir}"/aur webdir="$pkgdir" webfilefinal="$webdir"/index.html webfile="$webdir"/index.html.tmp cwd="$(pwd)" SeedWebFile # Build AniNIX Repo if [ -n "$MAATTESTINGVAR" ]; then BuildRepo "$baseurl"/HelloWorld else for AniNIXrepo in `curl -s "$baseurl" | grep 'class="name"' | cut -f 4 -d \" | sed "s#^#https://$(echo "$baseurl" | cut -f 3 -d /)#" | sed 's/$/.git/'`; do BuildRepo "$AniNIXrepo" '.' done fi printf '\n

AUR Packages

\n

These are packages made by other ArchLinux users and uploaded to the AUR.

\n' >> "$webfile" printf "$tableHead" >> "$webfile" # Build AUR for repo in `cat "$aurconf"`; do BuildRepo "$repo" aur/; if [ ! -z "$MAATTESTINGVAR" ]; then break; fi done UpdateLocalRepo runtime=$(( `date +%s` - $starttime )) # Update stats failcount=$(grep -c "$failCell" "$webfile") warncount=$(grep -c "$warnCell" "$webfile") passcount=$( grep -v "$failCell" "$webfile" | grep -c "$passCell" ) UpdateWebFile # Exit