summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarkko Kniivilä <jkniiv@gmail.com>2015-09-05 23:31:42 +0300
committerGravatar Mike Burns <mike@mike-burns.com>2015-11-01 18:59:02 +0100
commitb3f25262c260e81a4bffaa6444b48013f902a04a (patch)
tree8e83ad07b4af379f48de7941779dc600a8f6d8b4
parent5f592878eed79dd28f9f93418f9456185fd21ac9 (diff)
Fix hooks so that they are run in the directory where they are located
Calls `find(1)` with the `-exec` action just like before but instead of `run_hooks()` letting `find` execute the hook directly it is wrapped in a shell one-liner which changes to the hook's directory and executes the hook with "./" prepended to its basename. These changes allow hooks to refer to dotfiles with relative paths. For instance we can call a Makefile two directories up simply with `make -C ../..`. Also make sure we are compatible with Solaris' Bourne shell and `find(1)`. Closes #150. Closes #149.
-rw-r--r--share/rcm.sh.in9
-rw-r--r--test/Makefile.am4
-rw-r--r--test/rcdn-hooks-run-in-situ.t28
-rw-r--r--test/rcup-hooks-run-in-situ.t27
4 files changed, 66 insertions, 2 deletions
diff --git a/share/rcm.sh.in b/share/rcm.sh.in
index d8fc19e..c7a3dfb 100644
--- a/share/rcm.sh.in
+++ b/share/rcm.sh.in
@@ -126,7 +126,14 @@ run_hooks() {
find_opts=-print
fi
- find "$hook_file" -type f \( \( -user $USER -perm -100 \) -o -perm -001 \) $find_opts -exec {} \;
+ # Emulate the non-POSIX-compliant `-execdir` action with `-exec` and a shell one-liner.
+ # The former is however a bit better when it comes to security. On the other hand
+ # running these hooks imply some level of trust; surely one doesn't clone somebody
+ # else's dotfiles repository without reviewing the hooks before doing an `rcup`?
+ find "$hook_file" -type f \( \( -user $USER -perm -100 \) -o -perm -001 \) \
+ -exec \
+ sh -c 'cd "`dirname $1`" && ./"`basename $1`"' arg0 '{}' \
+ \;
else
$DEBUG "no $when-$direction hook present for $dotfiles_dir, skipping"
fi
diff --git a/test/Makefile.am b/test/Makefile.am
index 4c5e059..d5aa210 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -27,7 +27,9 @@ TESTS = \
rcup-symlink-dirs.t \
rcup-usage.t \
rcdn-hooks.t \
- rcup-hooks.t
+ rcdn-hooks-run-in-situ.t \
+ rcup-hooks.t \
+ rcup-hooks-run-in-situ.t
dist_check_SCRIPTS = $(TESTS)
diff --git a/test/rcdn-hooks-run-in-situ.t b/test/rcdn-hooks-run-in-situ.t
new file mode 100644
index 0000000..17b8f09
--- /dev/null
+++ b/test/rcdn-hooks-run-in-situ.t
@@ -0,0 +1,28 @@
+ $ . "$TESTDIR/helper.sh"
+
+Use a pre-generated UUID in a filename to make sure the filename is unique to this test
+and also that the pre-down hook has found the right directory having found this file.
+
+ $ uniquish_file_prefix='test-hooks-run-in-situ-'
+ > uuid='5b811e03-5977-40e6-80ef-dd6c35013e56'
+ > uniquish_file=${uniquish_file_prefix}${uuid}
+
+Pre-down and post-down hooks should run by default. More importantly the hooks\' cwd should
+be the directory where they are situated. We test this by trying to find $uniquish_file.
+
+ $ touch .dotfiles/$uniquish_file
+ > mkdir -p .dotfiles/hooks/pre-down .dotfiles/hooks/post-down
+ > touch .dotfiles/hooks/pre-down/00-test.sh .dotfiles/hooks/post-down/00-test.sh
+ > chmod +x .dotfiles/hooks/pre-down/00-test.sh .dotfiles/hooks/post-down/00-test.sh
+
+ $ echo "echo ../../${uniquish_file_prefix}* > /tmp/test-$uuid" > .dotfiles/hooks/pre-down/00-test.sh
+ > echo "cat /tmp/test-$uuid; rm /tmp/test-$uuid" > .dotfiles/hooks/post-down/00-test.sh
+
+ $ rcdn
+ ../../test-hooks-run-in-situ-5b811e03-5977-40e6-80ef-dd6c35013e56
+
+Ensure that hooks run when output of lsrc is non-empty
+ $ touch .dotfiles/testrc
+ > rcup
+ > rcdn
+ ../../test-hooks-run-in-situ-5b811e03-5977-40e6-80ef-dd6c35013e56
diff --git a/test/rcup-hooks-run-in-situ.t b/test/rcup-hooks-run-in-situ.t
new file mode 100644
index 0000000..174c818
--- /dev/null
+++ b/test/rcup-hooks-run-in-situ.t
@@ -0,0 +1,27 @@
+ $ . "$TESTDIR/helper.sh"
+
+Use a pre-generated UUID in a filename to make sure the filename is unique to this test
+and also that the pre-up hook has found the right directory having found this file.
+
+ $ uniquish_file_prefix='test-hooks-run-in-situ-'
+ > uuid='820a557b-1acb-4e86-8c5b-feb2536b5777'
+ > uniquish_file=${uniquish_file_prefix}${uuid}
+
+Pre-up and post-up hooks should run by default. More importantly the hooks\' cwd should
+be the directory where they are situated. We test this by trying to find $uniquish_file.
+
+ $ touch .dotfiles/$uniquish_file
+ > mkdir -p .dotfiles/hooks/pre-up .dotfiles/hooks/post-up
+ > touch .dotfiles/hooks/pre-up/00-test.sh .dotfiles/hooks/post-up/00-test.sh
+ > chmod +x .dotfiles/hooks/pre-up/00-test.sh .dotfiles/hooks/post-up/00-test.sh
+
+ $ echo "echo ../../${uniquish_file_prefix}* > /tmp/test-$uuid" > .dotfiles/hooks/pre-up/00-test.sh
+ > echo "cat /tmp/test-$uuid; rm /tmp/test-$uuid" > .dotfiles/hooks/post-up/00-test.sh
+
+ $ rcup
+ ../../test-hooks-run-in-situ-820a557b-1acb-4e86-8c5b-feb2536b5777
+
+Ensure that hooks run when output of lsrc is non-empty
+ $ touch .dotfiles/testrc
+ > rcup
+ ../../test-hooks-run-in-situ-820a557b-1acb-4e86-8c5b-feb2536b5777