testpatches.sh - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       testpatches.sh (7546B)
       ---
            1 #!/bin/sh
            2 # TODO:
            3 # ? build:
            4 #   - set flags per project? (per version too?).
            5 #   - add build status (OK, FAIL, unknown), must be secure though.
            6 
            7 projects() {
            8 cat <<!__EOF__
            9 dmenu        tools.suckless.org/dmenu/patches
           10 dwm        dwm.suckless.org/patches
           11 ii        tools.suckless.org/ii/patches
           12 sent        tools.suckless.org/sent/patches
           13 sic        tools.suckless.org/sic/patches
           14 slock        tools.suckless.org/slock/patches
           15 st        st.suckless.org/patches
           16 surf        surf.suckless.org/patches
           17 tabbed        tools.suckless.org/tabbed/patches
           18 !__EOF__
           19 }
           20 
           21 wikidir="$(pwd)/sites"
           22 repodir="$(pwd)/repos"
           23 revdir="$(pwd)/rev"
           24 resultsdir="$(pwd)/results"
           25 builddir="$(pwd)/build"
           26 
           27 # dryrun patch command (OpenBSD).
           28 # must be unified diff (-u, so no ed script), -t and -C are dryrun (non-POSIX).
           29 dryrun="patch -u -p1 -t -C"
           30 
           31 # getdateutc()
           32 getdateutc() {
           33         # date as UTC+0 time.
           34         TZ="UTC+0" date
           35 }
           36 
           37 # log(s)
           38 log() {
           39         s="[$(date)] $1"
           40         echo "$s" >&2
           41 }
           42 
           43 # getprojects()
           44 getprojects() {
           45         # allow commenting to disable.
           46         projects | grep -v '^#'
           47 }
           48 
           49 # clone()
           50 clone() {
           51         getprojects | while read -r -- project dir; do
           52                 test -d "$repodir/$project" && continue
           53 
           54                 git clone --bare "git://git.suckless.org/$project" "$repodir/$project"
           55         done
           56 }
           57 
           58 # pull()
           59 pull() {
           60         getprojects | while read -r -- project dir; do
           61                 test -d "$repodir/$project" || continue
           62 
           63                 GIT_DIR="$repodir/$project" git fetch "git://git.suckless.org/$project"
           64         done
           65 }
           66 
           67 # listpatches()
           68 listpatches() {
           69         getprojects | while read -r -- project dir; do
           70                 find "$wikidir/$dir" -name "*.diff" | while read -r p; do
           71                         test -f "$p" || continue
           72 
           73                         b=$(basename "$p")
           74                         bb="${b%.diff}"
           75                         bb="${bb#${project}-}"
           76 
           77                         # NOTE: historical patches like "r1506" (mercurial) are ignored.
           78                         v=$(echo "$bb" | sed -En 's@^([0-9a-f\.]+)-.*$@\1@p')
           79                         if test -z "$v"; then
           80                                 v=$(echo "$bb" | sed -En 's@^.*-([0-9a-f\.]+)$@\1@p')
           81                         fi
           82 
           83                         # version not found, skip.
           84                         if test -z "$v"; then
           85                                 continue
           86                         fi
           87 
           88                         name="${p%.diff}"
           89                         name="${name##*/patches/}"
           90                         name="${name%%/*}"
           91 
           92                         printf '%s\t%s\t%s\t%s\t%s\n' "$project" "$v" "$dir" "$name" "$p"
           93                 done
           94         done
           95 }
           96 
           97 # checkoutrev(project, version)
           98 checkoutrev() {
           99         project="$1"
          100         v="$2"
          101 
          102         test -f "$revdir/$project/$v/fail" && return 1
          103         test -d "$revdir/$project/$v" && return 0
          104 
          105         cur=$(pwd)
          106         d="$revdir/$project/$v"
          107         mkdir -p "$d"
          108         cd "$d" || return 1
          109 
          110         GIT_DIR="$repodir/$project" \
          111                 git archive "$v" 2> "$revdir/$project/$v/fail" | \
          112                 tar xf - 2>/dev/null
          113         status=$?
          114         if test x"$status" != x"0"; then
          115                 status=1
          116         else
          117                 rm -f "$revdir/$project/$v/fail"
          118         fi
          119         cd "$cur"
          120 
          121         return $status
          122 }
          123 
          124 # preparebuilds()
          125 preparebuilds() {
          126         listpatches | while read -r -- project v dir name p; do
          127                 test -f "$p" || continue
          128 
          129                 # version quirks (wrong tagging).
          130                 if test x"$project" = x"sent"; then
          131                         if test x"$v" = x"1.0"; then
          132                                 v="1"
          133                                 test -e "$revdir/$project/1.0" || \
          134                                         ln -sf "$v" "$revdir/$project/1.0"
          135                         fi
          136                 fi
          137                 if test x"$project" = x"ii"; then
          138                         if test x"$v" = x"1.7"; then
          139                                 v="v1.7"
          140                                 test -e "$revdir/$project/1.7" || \
          141                                         ln -sf "$v" "$revdir/$project/1.7"
          142                         fi
          143                 fi
          144 
          145                 # prepare clean build directory for patch.
          146                 b=$(basename "$p")
          147                 b="${b%.diff}"
          148 
          149                 # cannot prepare revision for build: skip.
          150                 if ! checkoutrev "$project" "$v"; then
          151                         log "CANNOT CHECKOUT REVISION: $project v=$v, name=$name, patch=$b, error=$(cat "$revdir/$project/$v/fail")"
          152                         continue
          153                 fi
          154 
          155                 # already has clean builddir.
          156                 test -d "$builddir/$project/$b" && continue
          157                 cleanbuild "$project" "$v" "$b"
          158         done
          159 }
          160 
          161 # cleanbuild(project, version, build)
          162 cleanbuild() {
          163         project="$1"
          164         v="$2"
          165         b="$3"
          166 
          167         test -d "$builddir/$project/$b" && rm -rf "$builddir/$project/$b"
          168 
          169         mkdir -p "$builddir/$project"
          170         cp -r "$revdir/$project/$v" "$builddir/$project/$b"
          171 }
          172 
          173 # testpatches()
          174 testpatches() {
          175         # sort by project, name, version
          176         listpatches | sort -k1,1 -k4,4 -k2,2 | \
          177                 while read -r -- project v dir name p; do
          178                 test -f "$p" || continue
          179 
          180                 # cannot prepare revision for build: skip.
          181                 checkoutrev "$project" "$v" || continue
          182 
          183                 b=$(basename "$p")
          184                 b="${b%.diff}"
          185 
          186                 test -d "$builddir/$project/$b" || continue
          187                 cd "$builddir/$project/$b" || continue
          188 
          189                 # copy patch file for convenience / debugging.
          190                 cp "$p" "$builddir/$project/$b/p.diff"
          191 
          192                 # lenient: copy config.def.h to config.h if config.h doesn't exist.
          193                 #rm -f "$builddir/$project/$b/config.h" # DEBUG
          194                 #if test -f "$builddir/$project/$b/config.def.h"; then
          195                 #        if ! test -f "$builddir/$project/$b/config.h"; then
          196                 #                cp "$builddir/$project/$b/config.def.h" "$builddir/$project/$b/config.h"
          197                 #        fi
          198                 #fi
          199 
          200                 # patch (dryrun).
          201                 $dryrun < "$p" 2> "$builddir/$project/$b/patch.2.log" >"$builddir/$project/$b/patch.1.log"
          202                 applystatus=$?
          203 
          204                 # write results to metadata file (for creating views).
          205                 printf "%s\t%s\t%s\t%s\t%s\t%s\n" \
          206                         "$project" "$v" "$dir" "$name" "$applystatus" "$b" > "$builddir/$project/$b/metadata"
          207 
          208                 log "$p        $applystatus"
          209         done
          210 }
          211 
          212 # outputhtml()
          213 outputhtml() {
          214         index="$resultsdir/index.html"
          215         title="Last updated on $(getdateutc)"
          216 
          217 cat > "$index" <<!__EOF__
          218 <!DOCTYPE html>
          219 <html>
          220 <head>
          221 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
          222 <title>$title - Patch applystatus</title>
          223 <style type="text/css">
          224 table       { border-collapse: collapse; }
          225 td          { padding: 2px; }
          226 thead td    { background-color: #eee; }
          227 .s-0 td     { background-color: #ccffcc; }
          228 .s-1 td     { background-color: #ffcccc; }
          229 .s-2 td     { background-color: #ff0000; color: #fff; }
          230 </style>
          231 </head>
          232 <body>
          233 <h1>$title</h1>
          234 <table>
          235 <thead>
          236 <tr>
          237         <td><b>Project</b></td>
          238         <td><b>Version/revision</b></td>
          239         <td><b>Patch</b></td>
          240         <td><b>Patch</b></td>
          241         <td><b>Patch file</b></td>
          242         <td><b>Patch stdout</b></td>
          243         <td><b>Patch stderr</b></td>
          244         <td><b>Exitcode</b></td>
          245         <td><b>Status</b></td>
          246 </tr>
          247 </thead>
          248 <tbody>
          249 !__EOF__
          250 
          251         # sort by project, name, version
          252         find "$builddir" -name "metadata" -type f -exec cat {} \; | \
          253                 sort -k1,1 -k4,4 -k2,2 | \
          254                 while read -r -- project v dir name applystatus b; do
          255                 test -d "$builddir/$project/$b" || continue
          256 
          257                 # HTML output test
          258                 mkdir -p "$resultsdir/$b/"
          259                 cp \
          260                         "$builddir/$project/$b/p.diff"\
          261                         "$builddir/$project/$b/patch.2.log"\
          262                         "$builddir/$project/$b/patch.1.log"\
          263                         "$resultsdir/$b/"
          264 
          265                 statustext="OK"
          266                 pageurl="https://$dir/$name/"
          267 
          268                 case "$applystatus" in
          269                 0) statustext="OK";;
          270                 1) statustext="FAIL";;
          271                 2) statustext="CORRUPT";;
          272                 *) statustext="UNKNOWN";;
          273                 esac
          274 
          275                 cat >> "$index" <<!__EOF__
          276 <tr class="s-$applystatus">
          277         <td><a href="https://git.suckless.org/$project/">$project</a></td>
          278         <td>$v</td>
          279         <td><a href="$pageurl">$name</a></td>
          280         <td><a href="$pageurl">$b</a></td>
          281         <td><a href="$b/p.diff">[patch]</a></td>
          282         <td><a href="$b/patch.1.log">[stdout]</a></td>
          283         <td><a href="$b/patch.2.log">[stderr]</a></td>
          284         <td>$applystatus</td>
          285         <td>$statustext</td>
          286 </tr>
          287 !__EOF__
          288         done
          289 
          290         echo "</tbody></table></body></html>" >> "$index"
          291 }
          292 
          293 # outputcsv()
          294 outputcsv() {
          295         index="$resultsdir/index.csv"
          296 
          297         # sort by project, name, version
          298         find "$builddir" -name "metadata" -type f -exec cat {} \; | \
          299                 sort -k1,1 -k4,4 -k2,2 | \
          300                 while read -r -- project v dir name applystatus b; do
          301                 test -d "$builddir/$project/$b" || continue
          302 
          303                 printf '%s\n' "$project        $v        $name        $b        $applystatus" >> "$index"
          304         done
          305 }
          306 
          307 case "$1" in
          308 clone|pull)
          309         mkdir -p "$repodir"
          310         $1
          311         ;;
          312 clean)
          313         rm -rf "$revdir" "$builddir"
          314         ;;
          315 prepare)
          316         mkdir -p "$builddir" "$revdir"
          317         preparebuilds
          318         ;;
          319 test)
          320         testpatches
          321         ;;
          322 results)
          323         # output results
          324         rm -rf "$resultsdir"
          325         mkdir -p "$resultsdir"
          326         outputhtml
          327         outputcsv
          328         ;;
          329 *)
          330         echo "usage: $0 <clone | pull | clean | prepare | test | results>" >&2
          331         exit 1
          332         ;;
          333 esac