Shell programs

Shell programs are a joy. Today I wrote one that runs git push in all of the directories that I tend to work in—it’s useful for when I’m working offline and later want to push all of my work when I have a network connection.

#! /bin/zsh

# usage: pushall [<directories.txt>]
#
# The pushall command runs git-push in the directories listed—one per
# line—in the supplied file. Variables in the file will be
# expanded using the environment. If no file is supplied, pushall reads
# from the default config file at $HOME/.config/pushall/directories.

set -uo pipefail

push() {
	out="$(2>&1 { cd "$1" && git push; })"
	printf "%s: %s\n" "$(basename "$1")" "$out"
}

main() {
	file="${1:-$HOME/.config/pushall/directories}"
	while read -r d; do
		push "${(e)d}" &
	done < "$file"
	wait
}

main "$@"

It’s especially joyful when you make the program use a config file:

% cat ~/.config/pushall/directories
$HOME
$HOME/src/town
$HOME/src/algebraic
$HOME/src/membrane
$HOME/src/binutil
$HOME/src/new-system
$HOME/src/blks
%

and when the program’s output is terse:

% pushall
blks: Everything up-to-date
town: To github.com:littleroot/town.git
   1df06c0..6fbf6a4  main -> main
new-system: Everything up-to-date
binutil: Everything up-to-date
algebraic: Everything up-to-date
ns: Everything up-to-date
membrane: Everything up-to-date
%

I love programs that use a THING: RESULT output format.