#!/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 # # Arch keys to look for pkgExt=".pkg.tar.zst" deprivuser="maat" ### 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 60m sudo -u "$deprivuser" /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 | grep -E "${pkgExt}""\$"`; do printf "$pkg
" >> "$webfile" pkgname="$(basename "$pkg" | cut -f 1 -d '.' | sed 's/-[[:digit:]]\+$//')" # Remove old copies find "${pkgdir}/${suffix}/" -name "${pkgname}-[0-9]*" -exec rm {} \; 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 clean -fdX output="$(git pull 2>&1)" if [ -n "$incremental" ] && [ $( echo "$output" | grep -c 'Already up to date.' ) -eq 1 ]; then return; fi chown -R "$deprivuser": . 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 ] && [ `grep -E -c '^test:' Makefile` -ge 1 ]; then # Have to try to install dependencies first for dep in $(grep makedepends PKGBUILD | cut -f 2 -d '(' | cut -f 1 -d ')' | sed "s/'//g"); do pacman -S "$dep" --noconfirm --needed done # Check test status. timeout --preserve-status "$timeout" sudo -u "$deprivuser" /bin/bash -l -c "cd $PWD; 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 "$deprivuser": . rm -Rf AniNIX.[db,files]* sudo -u "$deprivuser" repo-add --sign ./AniNIX.db.tar.zst `ls -1 *"${pkgExt}"` cd aur/ rm -Rf aur.[db,files]* sudo -u "$deprivuser" repo-add --sign ./aur.db.tar.zst `ls -1 *"${pkgExt}"` set +x } ### Clean source tracking function CleanSrcTracking() { searchbase="${homedir}/src" for path in `find "$searchbase" -maxdepth 1 -mindepth 1 -type d`; do cd "$path" giturl="$(git config remote.origin.url)" if ! grep "$giturl" "$aurconf"; then cd "$searchbase" rm -Rf "$path" fi done } # Clear variables aurconf='/usr/local/etc/Maat/aur.list' baseurl='https://aninix.net/AniNIX' homedir="/srv/maat/" unset incremental unset skipPatching unset testing timeout="90s" # Stat tracking starttime=`date +%s` function usage() { ### Show helptext # param retcode: what to exit retcode="$1" cat <&2 exit 1 fi fi # Ensure work directories live if [ $( echo "$homedir" | grep -E -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 CleanSrcTracking for AniNIXrepo in `curl -s "$baseurl" | grep 'class="text primary 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