commit 1cf8cea074471577f784756fb1ca1f5ce9449432
parent 4fa5ed4c2dd8cd9c47add37725d99c74732867bc
Author: Byron Torres <b@torresjrjr.com>
Date: Fri, 7 Apr 2023 17:13:12 +0100
gfa*: revamp, output new lines lazily
Diffstat:
M | bin/gfa | | | 74 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
1 file changed, 55 insertions(+), 19 deletions(-)
diff --git a/bin/gfa b/bin/gfa
@@ -1,15 +1,26 @@
-#!/bin/sh -u
+#!/bin/sh -eu
# gfa -- fetch all git repos in cwd
println() {
- local line=$(( $1 + 1 )) column=$2 colour=$3 text=$4
- env printf '\r\e[%sB\e[%sC\e[%sm%s\e[m\r\e[%sA\e[%sC' \
- $line $column $colour "$text" $line $column
+ { flock 3
+ line=$1 column=$2 colour=$3 text=$4
+ lines=$( wc -l </tmp/gfa-lines )
+ offset=$(( $lines - $line + 1))
+ env printf '\r\e[%sA\e[%sC\e[%sm%s\e[m\r\e[%sB\r' \
+ $offset $column \
+ $colour "$text" \
+ $offset
+ } 3</tmp/gfa-mutex
}
worker() {
- local n=$1
- local dir="${2%/.git}"
+ local n="$( head -n1 /tmp/gfa-inits )"
+ local dir="${1%/.git}"
+
+ { flock 3
+ env printf '\n' | tee -a /tmp/gfa-lines
+ } 3</tmp/gfa-mutex
+
cd "$cwd"
cd "$dir"
println $n 0 0 "${dir#./}"
@@ -28,15 +39,19 @@ worker() {
case "$commits" in
-1)
- println $n $width 31 '?'
+ println "$n" $width 31 '?'
;;
0)
- println $n $width 0 '.'
+ println "$n" $width 0 '.'
;;
*)
- println $n $width 32 "($commits)"
+ println "$n" $width 32 "($commits)"
;;
esac
+
+ env printf '\n' >/tmp/gfa-done
+ env printf '\n' >/tmp/gfa-finis
+ return
}
@@ -45,19 +60,40 @@ repos=$( find -maxdepth 3 -path '*/.git' -not -path '*/_*' | sort )
[ "$repos" ] || printf >&2 'No git repos here\n'
-width="$(echo "$repos" | wc -L)"
-total="$(echo "$repos" | wc -l)"
+width="$(printf '%s\n' "$repos" | wc -L)"
+total="$(printf '%s\n' "$repos" | wc -l)"
+
+touch /tmp/gfa-dummy
+rm /tmp/gfa-*
+touch /tmp/gfa-lines
+touch /tmp/gfa-mutex
+mkfifo /tmp/gfa-inits /tmp/gfa-finis /tmp/gfa-done
-env printf '%s\r ~ \n' $(seq $(( total + 1 )))
-env printf '\e[%sA' $(( total + 1 ))
-env printf '[fetching repos]\r'
+winsz=32
+lines=0
+
+env printf '[fetching %s repos]\n' "$total"
-wg='' n=0
for dir in $repos
do
- worker $n "$dir" & wg="$wg $! " n=$(( n + 1 ))
- sleep 0.05
+ ( worker "$dir" )&
done
-wait $wg
-env printf '\r\e[%sB' $(( total + 1 ))
+worker_manager() {
+ for N in $(seq $total)
+ do
+ [ "$N" -gt $winsz ] && {
+ head -n1 /tmp/gfa-finis >/dev/null
+ }
+
+ env printf '%s\n' "$N"
+ sleep 0.1
+ done
+}
+
+worker_manager >/tmp/gfa-inits &
+
+for N in $(seq $total)
+do
+ head -n1 /tmp/gfa-done >/dev/null
+done