aboutsummaryrefslogtreecommitdiff
path: root/src/infrastructure
diff options
context:
space:
mode:
authorEuAndreh <eu@euandre.org>2023-03-30 14:22:11 -0300
committerEuAndreh <eu@euandre.org>2023-03-30 14:34:47 -0300
commit11f3daea8627effd0127b28d2d46fb53af49a7fc (patch)
tree29a181aa5396ef8ffeb25dac07bd7e9dad7e31fc /src/infrastructure
parentbackup.sh: Fix capture of $STATUS to the desired behaviour (diff)
downloadtoph-11f3daea8627effd0127b28d2d46fb53af49a7fc.tar.gz
toph-11f3daea8627effd0127b28d2d46fb53af49a7fc.tar.xz
src/infrastructure/scripts/report.sh: v2
Now instead of working through each commit searially, we build a graph of steps and work on that by emitting make(1) code to be executed. May this code prove to be diffucult to modify or extend, this is a valid commit "checkpoint" to revert to in order to recover the *exact* same behaviour, but simpler code. Simple benchmarks suggest that: - on a single core, the scrit is ~15% slower; - with 2 cores it is as fast as the original; - as more cores are added, the faster it gets, up to $(nproc) when using more cores doesn't change anything. That means that it is a useful optimization for our desktops, but a hinderance for our current server, which only has a single core.
Diffstat (limited to 'src/infrastructure')
-rwxr-xr-xsrc/infrastructure/scripts/report.sh209
1 files changed, 152 insertions, 57 deletions
diff --git a/src/infrastructure/scripts/report.sh b/src/infrastructure/scripts/report.sh
index c766d41..0b63ffc 100755
--- a/src/infrastructure/scripts/report.sh
+++ b/src/infrastructure/scripts/report.sh
@@ -4,7 +4,7 @@ set -eu
usage() {
cat <<-'EOF'
Usage:
- report [-C REPO] -o DIRECTORY
+ report -o DIRECTORY [-K] [-S STEP]
report -h
EOF
}
@@ -14,8 +14,9 @@ help() {
Options:
- -C REPO change to REPO when doing Git operations (default: $PWD)
-o DIRECTORY the directory where to place the generated files
+ -K keep intermediary files
+ -S STEP which substep of the report to perform (default: top)
-h, --help show this message
@@ -92,15 +93,19 @@ for flag in "$@"; do
esac
done
-REPO="$PWD"
-while getopts 'C:o:h' flag; do
+KEEP_FILES=false
+STEP=top
+while getopts 'o:KS:h' flag; do
case "$flag" in
- C)
- REPO="$OPTARG"
- ;;
o)
OUTDIR="$OPTARG"
;;
+ K)
+ KEEP_FILES=true
+ ;;
+ S)
+ STEP="$OPTARG"
+ ;;
h)
usage
help
@@ -119,6 +124,7 @@ if [ -z "${OUTDIR:-}" ]; then
exit 2
fi
+
if [ -r src/infrastructure/config/conf.env ]; then
CONF=src/infrastructure/config/conf.env
else
@@ -129,7 +135,7 @@ fi
. "$CONF"
-esc() {
+escape_html() {
sed \
-e 's|&|\&amp;|g' \
-e 's|<|\&lt;|g' \
@@ -138,18 +144,93 @@ esc() {
-e "s|'|\&#39;|g"
}
-mkdir -p "$OUTDIR"
-cd "$OUTDIR"
-mkdir -p logs data
-for c in $(git -C "$REPO" notes list | cut -d' ' -f2); do
- git -C "$REPO" notes --ref=refs/notes/ci-data show "$c" > data/FILENAME-tmp
- FILENAME="$(grep '^filename ' data/FILENAME-tmp | cut -d' ' -f2-)"
- mv data/FILENAME-tmp data/"$FILENAME"
- git -C "$REPO" notes --ref=refs/notes/ci-logs show "$c" > logs/"$FILENAME"
-done
-{
+emit_stage0_make() {
+ git notes list | awk -v OUT="$OUTDIR" '{
+ printf "all: %s/stage0/%s\n\n", OUT, $2
+ printf "%s/stage0/%s:\n", OUT, $2
+ printf "\tgit notes --ref=refs/notes/ci-data show %s > $@\n\n", $2
+ }'
+ printf 'all:\n'
+ printf '\tprintf "%%s\\n" "$?" | tr " " "\\n"\n'
+}
+
+emit_stage1_make() {
+ awk -F/ -vCMD="'$0'" -vOUT="$OUTDIR" '{
+ printf "all: %s/stage1/%s.mk\n\n", OUT, $(NF)
+ printf "%s/stage1/%s.mk:\n", OUT, $(NF)
+ printf "\t%s -o \"%s\" -S stage1-exec < %s/stage0/%s > $@\n", CMD, OUT, OUT, $(NF)
+ }'
+ printf 'all:\n'
+ printf '\tcat -- "%s"/stage1/*.mk\n' "$OUTDIR"
+}
+
+stage1_exec() {
+ awk -vOUT="$OUTDIR" -vCMD="'$0'" '
+ { d[$1] = $2 }
+ END {
+ escaped = d["filename"]
+ gsub(/:/, "\\:", escaped)
+
+ gsub(/"/, "", d["duration"])
+
+ printf "all: %s/data/%s\n\n", OUT, escaped
+ printf "%s/data/%s:\n", OUT, escaped
+ printf "\tln -- %s/stage0/%s $@\n\n\n", OUT, d["sha"]
+
+ printf "all: %s/logs/%s\n\n", OUT, escaped
+ printf "%s/logs/%s:\n", OUT, escaped
+ printf "\tgit notes --ref=refs/notes/ci-logs show %s > $@\n\n\n", d["sha"]
+
+ printf "all: %s/msgs/%s\n\n", OUT, escaped
+ printf "%s/msgs/%s:\n", OUT, escaped
+ printf "\tif ! git show %s 1>/dev/null 2>&1; then \\\n", d["sha"]
+ printf "\t\tgit fetch origin %s; \\\n", d["sha"]
+ printf "\tfi\n"
+ printf "\tgit log -1 --format=%%B %s > $@\n\n\n", d["sha"]
+
+ printf "all: %s/html/%s\n\n", OUT, escaped
+ printf "%s/html/%s: %s/msgs/%s\n", OUT, escaped, OUT, escaped
+ printf "\t%s -o \"%s\" -S html-item \"%s\" \"%s\" \"%s\" \"%s\" \"%s/msgs/%s\" \"%s\" > $@\n\n\n",
+ CMD, OUT, d["status"], d["sha"], d["filename"], d["duration"], OUT, d["filename"], CGIT_URL
+ }
+ '
+}
+
+emit_html_item() {
+ STATUS="$1"
+ SHA="$2"
+ FILENAME="$3"
+ DURATION="$4"
+ MESSAGE_F="$5"
+ CGIT_URL="$6"
+
+ PASS='&#x2705;' # ✅
+ WARN='&#x1F40C;' # 🐌
+ FAIL='&#x274C;' # ❌
+ if [ "$STATUS" = 0 ]; then
+ if [ "$DURATION" -le 60 ]; then
+ STATUS_MARKER="$PASS"
+ else
+ STATUS_MARKER="$WARN"
+ fi
+ else
+ STATUS_MARKER="$FAIL"
+ fi
+ cat <<-EOF
+ <li id="$FILENAME">
+ <a href="#$FILENAME"><pre>#</pre></a>
+ $STATUS_MARKER - <pre>${DURATION}s</pre>
+ <pre>(<a href="${CGIT_URL}${SHA}">commit</a>)</pre>
+ <a href="logs/$FILENAME"><pre>$FILENAME</pre></a>
+ <br />
+ <code><pre>$(escape_html < "$MESSAGE_F")</pre></code>
+ </li>
+ EOF
+}
+
+emit_html_index() {
cat <<-EOF
<!DOCTYPE html>
<html lang="en">
@@ -212,48 +293,62 @@ done
<ol>
EOF
+ echo "$OUTDIR"/html/* |
+ tr ' ' '\n' |
+ LANG=C.UTF-8 sort -r |
+ xargs cat --
- PASS='&#x2705;' # ✅
- WARN='&#x1F40C;' # 🐌
- FAIL='&#x274C;' # ❌
- find data/ -type f | LANG=C.UTF-8 sort -r | while read -r f; do
- STATUS="$( grep '^status ' "$f" | cut -d' ' -f2- | esc)"
- SHA="$( grep '^sha ' "$f" | cut -d' ' -f2- | esc)"
- FILENAME="$(grep '^filename ' "$f" | cut -d' ' -f2- | esc)"
- DURATION="$(grep '^duration ' "$f" | cut -d' ' -f2- | cut -d'"' -f1 | esc)"
- MESSAGE="$({
- git -C "$REPO" log -1 --format=%B "$SHA" || {
- git fetch origin "$SHA"
- git -C "$REPO" log -1 --format=%B "$SHA"
- }
- } | esc)"
-
- if [ "$STATUS" = 0 ]; then
- if [ "$DURATION" -le 60 ]; then
- STATUS_MARKER="$PASS"
- else
- STATUS_MARKER="$WARN"
- fi
- else
- STATUS_MARKER="$FAIL"
- fi
-
- cat <<-EOF
- <li id="$FILENAME">
- <a href="#$FILENAME"><pre>#</pre></a>
- $STATUS_MARKER - <pre>${DURATION:-?}s</pre>
- <pre>(<a href="${CGIT_URL}${SHA}">commit</a>)</pre>
- <a href="logs/$FILENAME"><pre>$FILENAME</pre></a>
- <br />
- <code><pre>$MESSAGE</pre></code>
- </li>
- EOF
- done
-
- cat <<-EOF
+ cat <<-'EOF'
</ol>
</main>
</body>
</html>
EOF
-} > index.html
+}
+
+
+
+case "$STEP" in
+ top)
+ for d in stages stage0 stage1 data logs html msgs; do
+ mkdir -p -- "$OUTDIR/$d"
+ done
+
+ "$0" -o "$OUTDIR" -S stage0-make |
+ tee -- "$OUTDIR"/stages/stage0.mk |
+ make -sf- |
+ "$0" -o "$OUTDIR" -S stage1-make |
+ tee -- "$OUTDIR"/stages/stage1.mk |
+ make -sf- |
+ tee -- "$OUTDIR"/stages/stage2.mk |
+ make -sf-
+
+ "$0" -o "$OUTDIR" -S html
+
+ if [ "$KEEP_FILES" = false ]; then
+ for d in stages stage0 stage1 html msgs; do
+ rm -rf "${OUTDIR:?}/$d"
+ done
+ fi
+ ;;
+ stage0-make)
+ emit_stage0_make
+ ;;
+ stage1-make)
+ emit_stage1_make
+ ;;
+ stage1-exec)
+ stage1_exec
+ ;;
+ html-item)
+ emit_html_item "$@"
+ ;;
+ html)
+ emit_html_index > "$OUTDIR"/index.html
+ ;;
+ *)
+ printf 'Unsupported STEP type: "%s"\n\n' "$STEP" >&2
+ usage >&2
+ exit 2
+ ;;
+esac