From 453e88b806e00b76a91e052da3a536996fac94fb Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Thu, 29 Dec 2022 10:33:36 -0500 Subject: [PATCH] Exit if pre-up or pre-down hook exits non-zero This allows scripts to bail early if a check fails. --- Makefile.am | 2 ++ bin/rcdn.in | 5 +++++ bin/rcup.in | 5 +++++ share/rcm.sh.in | 6 ++++++ test/rcdn-hooks-failure.t | 16 ++++++++++++++++ test/rcup-hooks-failure.t | 15 +++++++++++++++ 6 files changed, 49 insertions(+) create mode 100644 test/rcdn-hooks-failure.t create mode 100644 test/rcup-hooks-failure.t diff --git a/Makefile.am b/Makefile.am index 06f25024..acb217c3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,9 +48,11 @@ TESTS = \ test/rcup-symlink-existing.t \ test/rcup-usage.t \ test/rcdn-hooks.t \ + test/rcdn-hooks-failure.t \ test/rcdn-hooks-run-in-situ.t \ test/rcdn-hooks-run-in-order.t \ test/rcup-hooks.t \ + test/rcup-hooks-failure.t \ test/rcup-hooks-run-in-situ.t \ test/rcup-hooks-run-in-order.t \ test/rcup-spaces.t diff --git a/bin/rcdn.in b/bin/rcdn.in index d69a175a..ed4ccfda 100755 --- a/bin/rcdn.in +++ b/bin/rcdn.in @@ -110,6 +110,11 @@ handle_command_line "$@" : ${DOTFILES_DIRS:=$DOTFILES_DIRS $DEFAULT_DOTFILES_DIR} run_hooks pre down +pre_dn_ret=$? + +if [ "$pre_dn_ret" -ne 0 ]; then + exit "$pre_dn_ret" +fi dests_and_srcs="$(eval "lsrc $LS_ARGS")" diff --git a/bin/rcup.in b/bin/rcup.in index 65f0ab8e..626bfe7e 100755 --- a/bin/rcup.in +++ b/bin/rcup.in @@ -296,6 +296,11 @@ handle_command_line "$@" : ${DOTFILES_DIRS:=$DOTFILES_DIRS $DEFAULT_DOTFILES_DIR} run_hooks pre up +pre_up_ret=$? + +if [ "$pre_up_ret" -ne 0 ]; then + exit "$pre_up_ret" +fi dests_and_srcs="$(eval "lsrc $LS_ARGS")" diff --git a/share/rcm.sh.in b/share/rcm.sh.in index 5d0a3734..47312d9c 100644 --- a/share/rcm.sh.in +++ b/share/rcm.sh.in @@ -143,6 +143,12 @@ run_hooks() { find "$hook_file" -type f \( \( -user $LOGNAME -perm -100 \) -o -perm -001 \) \ | sort | while read file; do sh -c 'cd -- "`dirname $1`" && ./"`basename $1`"' arg0 "$file" + hook_ret=$? + + if [ "$hook_ret" -ne 0 ]; then + echo "$when-$direction hook $file exited non-zero ($hook_ret)" >&2 + exit $hook_ret # NB. this only exits the while-read; caller must still check and exit + fi done else $DEBUG "no $when-$direction hook present for $dotfiles_dir, skipping" diff --git a/test/rcdn-hooks-failure.t b/test/rcdn-hooks-failure.t new file mode 100644 index 00000000..fcb13f19 --- /dev/null +++ b/test/rcdn-hooks-failure.t @@ -0,0 +1,16 @@ + $ . "$TESTDIR/helper.sh" + +Pre-down hooks failing should prevent rcdn continuing + + $ mkdir -p .dotfiles/hooks/pre-down + > printf "#!/bin/sh\necho '1'\nexit 7\n" > .dotfiles/hooks/pre-down/00-test.sh + > printf "#!/bin/sh\necho '2'\n" > .dotfiles/hooks/pre-down/01-test.sh + + $ chmod +x .dotfiles/hooks/pre-down/00-test.sh + > chmod +x .dotfiles/hooks/pre-down/01-test.sh + + $ rcdn + 1 + pre-down hook */.dotfiles/hooks/pre-down/00-test.sh exited non-zero (7) (glob) + [7] + diff --git a/test/rcup-hooks-failure.t b/test/rcup-hooks-failure.t new file mode 100644 index 00000000..4d34fd01 --- /dev/null +++ b/test/rcup-hooks-failure.t @@ -0,0 +1,15 @@ + $ . "$TESTDIR/helper.sh" + +Pre-up hooks failing should prevent rcup continuing + + $ mkdir -p .dotfiles/hooks/pre-up + > printf "#!/bin/sh\necho '1'\nexit 7\n" > .dotfiles/hooks/pre-up/00-test.sh + > printf "#!/bin/sh\necho '2'\n" > .dotfiles/hooks/pre-up/01-test.sh + + $ chmod +x .dotfiles/hooks/pre-up/00-test.sh + > chmod +x .dotfiles/hooks/pre-up/01-test.sh + + $ rcup + 1 + pre-up hook */.dotfiles/hooks/pre-up/00-test.sh exited non-zero (7) (glob) + [7]