aboutsummaryrefslogtreecommitdiff
path: root/bin/grun
diff options
context:
space:
mode:
Diffstat (limited to 'bin/grun')
-rwxr-xr-xbin/grun102
1 files changed, 102 insertions, 0 deletions
diff --git a/bin/grun b/bin/grun
new file mode 100755
index 0000000..5884e9e
--- /dev/null
+++ b/bin/grun
@@ -0,0 +1,102 @@
+#!/bin/sh
+set -eu
+
+usage() {
+ cat <<-'EOF'
+ Usage:
+ grun [-r RECIPIENT] FILENAME -- COMMAND...
+ grun -h
+ EOF
+}
+
+help() {
+ cat <<-'EOF'
+
+ Options:
+ -r RECIPIENT the recipient to encrypt to. Can be given
+ multiple for multiple recipients.
+ -h, --help show this message
+
+ COMMAND A command to be executed, that accepts input
+ in STDIN and emits result in STDOUT, and emits
+ errors as non-zero return codes.
+ FILENAME The GPG-encrypted file to be processed. If it
+ doesn't exist yet, it will be created.
+
+ Examples:
+
+ Edit "secrets.txt.gpg" using `vipe` and the default recipient:
+
+ $ grun secrets.txt.gpg -- vipe
+
+ Delete lines containing "FIXME" in todos.gpg:
+
+ $ grun -r ABC123DEF321 todos.gpg -- sed '/FIXME/d'
+
+ If COMMAND emits a non-zero return code, the file is left
+ unmodified.
+ EOF
+}
+
+for flag in "$@"; do
+ case "$flag" in
+ --)
+ break
+ ;;
+ --help)
+ usage
+ help
+ exit
+ ;;
+ *)
+ ;;
+ esac
+done
+
+while getopts 'rh' flag; do
+ case "$flag" in
+ r)
+ RECIPIENTS_FLAG="${RECIPIENTS_FLAG:-} -r $OPTARG"
+ ;;
+ h)
+ usage
+ help
+ exit
+ ;;
+ *)
+ usage >&2
+ exit 2
+ ;;
+ esac
+done
+shift $((OPTIND - 1))
+
+assert_arg() {
+ if [ -z "$1" ]; then
+ printf 'Missing %s\n\n' "$2" >&2
+ usage >&2
+ exit 2
+ fi
+}
+
+FILENAME="${1:-}"
+assert_arg "$FILENAME" 'FILENAME'
+shift
+
+if [ "${1:-}" != '--' ]; then
+ printf 'Missing "--" separator\n\n' >&2
+ usage >&2
+ exit 2
+fi
+shift
+
+assert_arg "${1:-}" 'COMMAND'
+
+
+if [ ! -e "$FILENAME" ]; then
+ OUT="$(printf '' | "$@")"
+else
+ OUT="$(gpg -dq "$FILENAME" | "$@")"
+fi
+
+echo "$OUT" | gpg -e ${RECIPIENTS_FLAG:--r eu@euandre.org} | sponge "$FILENAME"