mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-12-22 09:24:54 +01:00
CLI: use configured hook directory
This enables support for hooks outside the database directory. It relies strongly on configuration information being usable between closing the database and destroying it.
This commit is contained in:
parent
0345bc57a0
commit
f61d88c6f4
5 changed files with 109 additions and 92 deletions
7
hooks.c
7
hooks.c
|
@ -24,14 +24,15 @@
|
|||
#include <sys/wait.h>
|
||||
|
||||
int
|
||||
notmuch_run_hook (const char *db_path, const char *hook)
|
||||
notmuch_run_hook (notmuch_database_t *notmuch, const char *hook)
|
||||
{
|
||||
char *hook_path;
|
||||
int status = 0;
|
||||
pid_t pid;
|
||||
|
||||
hook_path = talloc_asprintf (NULL, "%s/%s/%s/%s", db_path, ".notmuch",
|
||||
"hooks", hook);
|
||||
hook_path = talloc_asprintf (notmuch, "%s/%s",
|
||||
notmuch_config_get (notmuch, NOTMUCH_CONFIG_HOOK_DIR),
|
||||
hook);
|
||||
if (hook_path == NULL) {
|
||||
fprintf (stderr, "Out of memory\n");
|
||||
return 1;
|
||||
|
|
|
@ -339,7 +339,7 @@ const char *
|
|||
_notmuch_config_get_path (notmuch_config_t *config);
|
||||
|
||||
int
|
||||
notmuch_run_hook (const char *db_path, const char *hook);
|
||||
notmuch_run_hook (notmuch_database_t *notmuch, const char *hook);
|
||||
|
||||
bool
|
||||
debugger_is_active (void);
|
||||
|
|
|
@ -481,7 +481,6 @@ notmuch_insert_command (unused(notmuch_config_t *config),notmuch_database_t *not
|
|||
notmuch_process_shared_options (argv[0]);
|
||||
|
||||
|
||||
/* XXX TODO replace this use of DATABASE_PATH with something specific to hooks */
|
||||
db_path = notmuch_config_get (notmuch, NOTMUCH_CONFIG_DATABASE_PATH);
|
||||
|
||||
if (! db_path)
|
||||
|
@ -570,7 +569,7 @@ notmuch_insert_command (unused(notmuch_config_t *config),notmuch_database_t *not
|
|||
status = add_file (notmuch, newpath, tag_ops, synchronize_flags, keep, indexing_cli_choices.opts);
|
||||
|
||||
/* Commit changes. */
|
||||
close_status = notmuch_database_destroy (notmuch);
|
||||
close_status = notmuch_database_close (notmuch);
|
||||
if (close_status) {
|
||||
/* Hold on to the first error, if any. */
|
||||
if (! status)
|
||||
|
@ -595,9 +594,11 @@ notmuch_insert_command (unused(notmuch_config_t *config),notmuch_database_t *not
|
|||
|
||||
if (hooks && status == NOTMUCH_STATUS_SUCCESS) {
|
||||
/* Ignore hook failures. */
|
||||
notmuch_run_hook (db_path, "post-insert");
|
||||
notmuch_run_hook (notmuch, "post-insert");
|
||||
}
|
||||
|
||||
notmuch_database_destroy (notmuch);
|
||||
|
||||
talloc_free (local);
|
||||
|
||||
return status_to_exit (status);
|
||||
|
|
|
@ -1105,7 +1105,6 @@ notmuch_new_command (unused(notmuch_config_t *config), notmuch_database_t *notmu
|
|||
struct timeval tv_start;
|
||||
int ret = 0;
|
||||
const char *db_path;
|
||||
char *dot_notmuch_path;
|
||||
struct sigaction action;
|
||||
_filename_node_t *f;
|
||||
int opt_index;
|
||||
|
@ -1167,13 +1166,11 @@ notmuch_new_command (unused(notmuch_config_t *config), notmuch_database_t *notmu
|
|||
}
|
||||
|
||||
if (hooks) {
|
||||
ret = notmuch_run_hook (db_path, "pre-new");
|
||||
ret = notmuch_run_hook (notmuch, "pre-new");
|
||||
if (ret)
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
dot_notmuch_path = talloc_asprintf (notmuch, "%s/%s", db_path, ".notmuch");
|
||||
|
||||
notmuch_exit_if_unmatched_db_uuid (notmuch);
|
||||
|
||||
if (notmuch_database_get_revision (notmuch, NULL) == 0) {
|
||||
|
@ -1212,9 +1209,6 @@ notmuch_new_command (unused(notmuch_config_t *config), notmuch_database_t *notmu
|
|||
action.sa_flags = SA_RESTART;
|
||||
sigaction (SIGINT, &action, NULL);
|
||||
|
||||
talloc_free (dot_notmuch_path);
|
||||
dot_notmuch_path = NULL;
|
||||
|
||||
gettimeofday (&add_files_state.tv_start, NULL);
|
||||
|
||||
add_files_state.removed_files = _filename_list_create (notmuch);
|
||||
|
@ -1284,7 +1278,7 @@ notmuch_new_command (unused(notmuch_config_t *config), notmuch_database_t *notmu
|
|||
notmuch_database_close (notmuch);
|
||||
|
||||
if (hooks && ! ret && ! interrupted)
|
||||
ret = notmuch_run_hook (db_path, "post-new");
|
||||
ret = notmuch_run_hook (notmuch, "post-new");
|
||||
|
||||
notmuch_database_destroy (notmuch);
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
test_description='hooks'
|
||||
. $(dirname "$0")/test-lib.sh || exit 1
|
||||
|
||||
HOOK_DIR=${MAIL_DIR}/.notmuch/hooks
|
||||
|
||||
create_echo_hook () {
|
||||
local TOKEN="${RANDOM}"
|
||||
mkdir -p ${HOOK_DIR}
|
||||
|
@ -16,6 +14,7 @@ EOF
|
|||
}
|
||||
|
||||
create_failing_hook () {
|
||||
local HOOK_DIR=${2}
|
||||
mkdir -p ${HOOK_DIR}
|
||||
cat <<EOF >"${HOOK_DIR}/${1}"
|
||||
#!/bin/sh
|
||||
|
@ -24,98 +23,120 @@ EOF
|
|||
chmod +x "${HOOK_DIR}/${1}"
|
||||
}
|
||||
|
||||
rm_hooks () {
|
||||
rm -rf ${HOOK_DIR}
|
||||
}
|
||||
|
||||
# add a message to generate mail dir and database
|
||||
add_message
|
||||
# create maildir structure for notmuch-insert
|
||||
mkdir -p "$MAIL_DIR"/{cur,new,tmp}
|
||||
|
||||
test_begin_subtest "pre-new is run"
|
||||
rm_hooks
|
||||
generate_message
|
||||
create_echo_hook "pre-new" expected output
|
||||
notmuch new > /dev/null
|
||||
test_expect_equal_file expected output
|
||||
for config in traditional profile explicit XDG; do
|
||||
unset NOTMUCH_PROFILE
|
||||
notmuch config set database.hook_dir
|
||||
case $config in
|
||||
traditional)
|
||||
HOOK_DIR=${MAIL_DIR}/.notmuch/hooks
|
||||
;;
|
||||
profile)
|
||||
dir=${HOME}/.config/notmuch/other
|
||||
mkdir -p ${dir}
|
||||
HOOK_DIR=${dir}/hooks
|
||||
cp ${NOTMUCH_CONFIG} ${dir}/config
|
||||
export NOTMUCH_PROFILE=other
|
||||
;;
|
||||
explicit)
|
||||
HOOK_DIR=${HOME}/.notmuch-hooks
|
||||
mkdir -p $HOOK_DIR
|
||||
notmuch config set database.hook_dir $HOOK_DIR
|
||||
;;
|
||||
XDG)
|
||||
HOOK_DIR=${HOME}/.config/notmuch/default/hooks
|
||||
;;
|
||||
esac
|
||||
|
||||
test_begin_subtest "post-new is run"
|
||||
rm_hooks
|
||||
generate_message
|
||||
create_echo_hook "post-new" expected output
|
||||
notmuch new > /dev/null
|
||||
test_expect_equal_file expected output
|
||||
test_begin_subtest "pre-new is run [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
generate_message
|
||||
create_echo_hook "pre-new" expected output $HOOK_DIR
|
||||
notmuch new > /dev/null
|
||||
test_expect_equal_file expected output
|
||||
|
||||
test_begin_subtest "post-insert hook is run"
|
||||
rm_hooks
|
||||
generate_message
|
||||
create_echo_hook "post-insert" expected output
|
||||
notmuch insert < "$gen_msg_filename"
|
||||
test_expect_equal_file expected output
|
||||
test_begin_subtest "post-new is run [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
generate_message
|
||||
create_echo_hook "post-new" expected output $HOOK_DIR
|
||||
notmuch new > /dev/null
|
||||
test_expect_equal_file expected output
|
||||
|
||||
test_begin_subtest "pre-new is run before post-new"
|
||||
rm_hooks
|
||||
generate_message
|
||||
create_echo_hook "pre-new" pre-new.expected pre-new.output
|
||||
create_echo_hook "post-new" post-new.expected post-new.output
|
||||
notmuch new > /dev/null
|
||||
test_expect_equal_file post-new.expected post-new.output
|
||||
test_begin_subtest "post-insert hook is run [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
generate_message
|
||||
create_echo_hook "post-insert" expected output $HOOK_DIR
|
||||
notmuch insert < "$gen_msg_filename"
|
||||
test_expect_equal_file expected output
|
||||
|
||||
test_begin_subtest "pre-new non-zero exit status (hook status)"
|
||||
rm_hooks
|
||||
generate_message
|
||||
create_failing_hook "pre-new"
|
||||
output=`notmuch new 2>&1`
|
||||
test_expect_equal "$output" "Error: pre-new hook failed with status 13"
|
||||
test_begin_subtest "pre-new is run before post-new [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
generate_message
|
||||
create_echo_hook "pre-new" pre-new.expected pre-new.output $HOOK_DIR
|
||||
create_echo_hook "post-new" post-new.expected post-new.output $HOOK_DIR
|
||||
notmuch new > /dev/null
|
||||
test_expect_equal_file post-new.expected post-new.output
|
||||
|
||||
# depends on the previous subtest leaving broken hook behind
|
||||
test_begin_subtest "pre-new non-zero exit status (notmuch status)"
|
||||
test_expect_code 1 "notmuch new"
|
||||
test_begin_subtest "pre-new non-zero exit status (hook status) [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
generate_message
|
||||
create_failing_hook "pre-new" $HOOK_DIR
|
||||
output=`notmuch new 2>&1`
|
||||
test_expect_equal "$output" "Error: pre-new hook failed with status 13"
|
||||
|
||||
# depends on the previous subtests leaving 1 new message behind
|
||||
test_begin_subtest "pre-new non-zero exit status aborts new"
|
||||
rm_hooks
|
||||
output=$(NOTMUCH_NEW)
|
||||
test_expect_equal "$output" "Added 1 new message to the database."
|
||||
# depends on the previous subtest leaving broken hook behind
|
||||
test_begin_subtest "pre-new non-zero exit status (notmuch status) [${config}]"
|
||||
test_expect_code 1 "notmuch new"
|
||||
|
||||
test_begin_subtest "post-new non-zero exit status (hook status)"
|
||||
rm_hooks
|
||||
generate_message
|
||||
create_failing_hook "post-new"
|
||||
NOTMUCH_NEW 2>output.stderr >output
|
||||
cat output.stderr >> output
|
||||
echo "Added 1 new message to the database." > expected
|
||||
echo "Error: post-new hook failed with status 13" >> expected
|
||||
test_expect_equal_file expected output
|
||||
# depends on the previous subtests leaving 1 new message behind
|
||||
test_begin_subtest "pre-new non-zero exit status aborts new [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
output=$(NOTMUCH_NEW)
|
||||
test_expect_equal "$output" "Added 1 new message to the database."
|
||||
|
||||
# depends on the previous subtest leaving broken hook behind
|
||||
test_begin_subtest "post-new non-zero exit status (notmuch status)"
|
||||
test_expect_code 1 "notmuch new"
|
||||
test_begin_subtest "post-new non-zero exit status (hook status) [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
generate_message
|
||||
create_failing_hook "post-new" $HOOK_DIR
|
||||
NOTMUCH_NEW 2>output.stderr >output
|
||||
cat output.stderr >> output
|
||||
echo "Added 1 new message to the database." > expected
|
||||
echo "Error: post-new hook failed with status 13" >> expected
|
||||
test_expect_equal_file expected output
|
||||
|
||||
test_begin_subtest "post-insert hook does not affect insert status"
|
||||
rm_hooks
|
||||
generate_message
|
||||
create_failing_hook "post-insert"
|
||||
test_expect_success "notmuch insert < \"$gen_msg_filename\" > /dev/null"
|
||||
# depends on the previous subtest leaving broken hook behind
|
||||
test_begin_subtest "post-new non-zero exit status (notmuch status) [${config}]"
|
||||
test_expect_code 1 "notmuch new"
|
||||
|
||||
test_begin_subtest "hook without executable permissions"
|
||||
rm_hooks
|
||||
mkdir -p ${HOOK_DIR}
|
||||
cat <<EOF >"${HOOK_DIR}/pre-new"
|
||||
#!/bin/sh
|
||||
echo foo
|
||||
test_begin_subtest "post-insert hook does not affect insert status [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
generate_message
|
||||
create_failing_hook "post-insert" $HOOK_DIR
|
||||
test_expect_success "notmuch insert < \"$gen_msg_filename\" > /dev/null"
|
||||
|
||||
test_begin_subtest "hook without executable permissions [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
mkdir -p ${HOOK_DIR}
|
||||
cat <<EOF >"${HOOK_DIR}/pre-new"
|
||||
#!/bin/sh
|
||||
echo foo
|
||||
EOF
|
||||
output=`notmuch new 2>&1`
|
||||
test_expect_code 1 "notmuch new"
|
||||
output=`notmuch new 2>&1`
|
||||
test_expect_code 1 "notmuch new"
|
||||
|
||||
test_begin_subtest "hook execution failure"
|
||||
rm_hooks
|
||||
mkdir -p ${HOOK_DIR}
|
||||
cat <<EOF >"${HOOK_DIR}/pre-new"
|
||||
no hashbang, execl fails
|
||||
test_begin_subtest "hook execution failure [${config}]"
|
||||
rm -rf ${HOOK_DIR}
|
||||
mkdir -p ${HOOK_DIR}
|
||||
cat <<EOF >"${HOOK_DIR}/pre-new"
|
||||
no hashbang, execl fails
|
||||
EOF
|
||||
chmod +x "${HOOK_DIR}/pre-new"
|
||||
test_expect_code 1 "notmuch new"
|
||||
chmod +x "${HOOK_DIR}/pre-new"
|
||||
test_expect_code 1 "notmuch new"
|
||||
|
||||
rm -rf ${HOOK_DIR}
|
||||
done
|
||||
test_done
|
||||
|
|
Loading…
Reference in a new issue