208 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| 
 | |
| # File: maat-builder
 | |
| #
 | |
| # Description: This file allows a Maat host to build source packages
 | |
| #              and optionally upload to the AniNIX::Foundation
 | |
| #
 | |
| # Package: ConfigPackages/Maat
 | |
| # Copyright: WTFPL
 | |
| #
 | |
| # Author: darkfeather@aninix.net
 | |
| # 
 | |
| 
 | |
| ### Printing defaults
 | |
| passCell="<td style='color:green;'>PASS</td>";
 | |
| failCell="<td style='color:red;'>FAIL</td>";
 | |
| warnCell="<td style='color:yellow;'>N/A</td>";
 | |
| tableHead="<table style='text-align: left;'>\n<tr><th>Package</th><th>Testing Status</th><th>Build Status</th><th>Latest Build</th><th>Time and Log of Run</th></tr>";
 | |
| 
 | |
| ### 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 '<html>\n<head>\n<title>AniNIX::Maat \\\\ Build Results</title>\n<link rel="icon" type="image/png" href="https://aninix.net/mediawiki/images/9/90/MaatIcon.png" />\n<link rel="icon" type="image/png" href="/mediawiki/images/9/90/MaatIcon.png">\n<meta name="apple-mobile-web-app-capable" content="yes" />\n<link rel="stylesheet" type="text/css" href="/style.css">\n<link rel="apple-touch-icon" sizes="180x180" href="mediawiki/images/9/90/MaatIcon.png" />\n</head>\n<body>\n<h1>AniNIX::Maat \\\\ Build Status</h1>\nWEBSTATSGOHERE\n<h2>AnINIX Packages</h2>\n<p>These are packages written by the AniNIX. Their source is in <a href="https://aninix.net/foundation/" alt=AniNIX::Foundation>AniNIX::Foundation</a>.</p>\n' > "$webfile"
 | |
|     printf "$tableHead" >> "$webfile"
 | |
| }
 | |
| 
 | |
| ### Update the webfile to close up table tags and add stats. 
 | |
| function UpdateWebFile() {
 | |
|     sed -i "s#WEBSTATSGOHERE#<p>These are the AniNIX testing results. We found $passcount passing and $failcount failing packages, with $warncount warnings. It took $runtime seconds to finish.</p>#" "$webfile"
 | |
|     printf '</table>\n</body>\n</html>\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""<td>"  >> "$webfile"
 | |
|         # List passing versions
 | |
|         ls -1 *".pkg.tar.xz" | tr '\n' '`' | sed 's#`#<br/>#g' >> "$webfile" 
 | |
|         printf "</td>" >> "$webfile"
 | |
|         for pkg in `find . -type f | egrep ".pkg.tar.xz$"`; do 
 | |
|             mv "$pkg" "$pkgdir"/"$suffix"; 
 | |
|             mv "$pkg"".sig" "$pkgdir"/"$suffix"; 
 | |
|         done
 | |
|     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 '<tr style="border: 1px solid #FFF;"><td>'"<a href='$repo'>$repodir</a> -- $pkgbuild"'</td>' >> "$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 "<td><a href='/maat/$repodir.txt'>$(date +%F-%R)</a></td></tr>\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://aninix.net/foundation/'
 | |
| 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 `wget -q -O - "$baseurl" | grep toplevel-repo | cut -f 4 -d \' | sed "s#^#$baseurl#"`; do
 | |
|         BuildRepo "$AniNIXrepo" '.'
 | |
|     done
 | |
| fi
 | |
| printf '</table>\n<h2>AUR Packages</h3>\n<p>These are packages made by other ArchLinux users and uploaded to the <a href="https://aur.archlinux.org/" alt="ArchLinux AUR">AUR</a>.</p>\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
 | 
