cli: add support for pre and post notmuch new hooks

Run notmuch new pre and post hooks, named "pre-new" and "post-new", if
present in the notmuch hooks directory. The hooks will be run before and
after incorporating new messages to the database.

Typical use cases for pre-new and post-new hooks are fetching or delivering
new mail to the maildir, and custom tagging of the mail incorporated to the
database.

Also add command line option --no-hooks to notmuch new to bypass the hooks.

Signed-off-by: Jani Nikula <jani@nikula.org>
This commit is contained in:
Jani Nikula 2011-12-09 00:48:30 +02:00 committed by David Bremner
parent d399b6b909
commit 69bb7f35b6
4 changed files with 109 additions and 2 deletions

10
NEWS
View file

@ -1,6 +1,16 @@
Notmuch 0.11 (201x-xx-xx) Notmuch 0.11 (201x-xx-xx)
========================= =========================
New command-line features
-------------------------
Hooks
Hooks have been introduced to notmuch. Hooks are scripts that notmuch
invokes before and after certain actions. Initially, "notmuch new"
supports "pre-new" and "post-new" hooks that are run before and after
importing new messages into the database.
Performance Performance
----------- -----------

View file

@ -811,6 +811,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
_filename_node_t *f; _filename_node_t *f;
int i; int i;
notmuch_bool_t timer_is_active = FALSE; notmuch_bool_t timer_is_active = FALSE;
notmuch_bool_t run_hooks = TRUE;
add_files_state.verbose = 0; add_files_state.verbose = 0;
add_files_state.output_is_a_tty = isatty (fileno (stdout)); add_files_state.output_is_a_tty = isatty (fileno (stdout));
@ -820,6 +821,8 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
for (i = 0; i < argc && argv[i][0] == '-'; i++) { for (i = 0; i < argc && argv[i][0] == '-'; i++) {
if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) { if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) {
add_files_state.verbose = 1; add_files_state.verbose = 1;
} else if (strcmp (argv[i], "--no-hooks") == 0) {
run_hooks = FALSE;
} else { } else {
fprintf (stderr, "Unrecognized option: %s\n", argv[i]); fprintf (stderr, "Unrecognized option: %s\n", argv[i]);
return 1; return 1;
@ -833,6 +836,12 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config); add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
db_path = notmuch_config_get_database_path (config); db_path = notmuch_config_get_database_path (config);
if (run_hooks) {
ret = notmuch_run_hook (db_path, "pre-new");
if (ret)
return ret;
}
dot_notmuch_path = talloc_asprintf (ctx, "%s/%s", db_path, ".notmuch"); dot_notmuch_path = talloc_asprintf (ctx, "%s/%s", db_path, ".notmuch");
if (stat (dot_notmuch_path, &st)) { if (stat (dot_notmuch_path, &st)) {
@ -981,5 +990,8 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
notmuch_database_close (notmuch); notmuch_database_close (notmuch);
if (run_hooks && !ret && !interrupted)
ret = notmuch_run_hook (db_path, "post-new");
return ret || interrupted; return ret || interrupted;
} }

View file

@ -85,7 +85,7 @@ The
command is used to incorporate new mail into the notmuch database. command is used to incorporate new mail into the notmuch database.
.RS 4 .RS 4
.TP 4 .TP 4
.B new .BR new " [options...]"
Find and import any new messages to the database. Find and import any new messages to the database.
@ -118,6 +118,22 @@ if
has previously been completed, but has previously been completed, but
.B "notmuch new" .B "notmuch new"
has not previously been run. has not previously been run.
The
.B new
command supports hooks. See the
.B "HOOKS"
section below for more details on hooks.
Supported options for
.B new
include
.RS 4
.TP 4
.BR \-\-no\-hooks
Prevents hooks from being run.
.RE
.RE .RE
Several of the notmuch commands accept search terms with a common Several of the notmuch commands accept search terms with a common
@ -705,6 +721,38 @@ specify a date range to return messages from 2009\-10\-01 until the
current time: current time:
$(date +%s \-d 2009\-10\-01)..$(date +%s) $(date +%s \-d 2009\-10\-01)..$(date +%s)
.SH HOOKS
Hooks are scripts (or arbitrary executables or symlinks to such) that notmuch
invokes before and after certain actions. These scripts reside in
the .notmuch/hooks directory within the database directory and must have
executable permissions.
The currently available hooks are described below.
.RS 4
.TP 4
.B pre\-new
This hook is invoked by the
.B new
command before scanning or importing new messages into the database. If this
hook exits with a non-zero status, notmuch will abort further processing of the
.B new
command.
Typically this hook is used for fetching or delivering new mail to be imported
into the database.
.RE
.RS 4
.TP 4
.B post\-new
This hook is invoked by the
.B new
command after new messages have been imported into the database and initial tags
have been applied. The hook will not be run if there have been any errors during
the scan or import.
Typically this hook is used to perform additional query\-based tagging on the
imported messages.
.RE
.SH ENVIRONMENT .SH ENVIRONMENT
The following environment variables can be used to control the The following environment variables can be used to control the
behavior of notmuch. behavior of notmuch.

View file

@ -127,6 +127,32 @@ static const char search_terms_help[] =
"\n" "\n"
"\t\t$(date +%%s -d 2009-10-01)..$(date +%%s)\n\n"; "\t\t$(date +%%s -d 2009-10-01)..$(date +%%s)\n\n";
static const char hooks_help[] =
"\tHooks are scripts (or arbitrary executables or symlinks to such) that\n"
"\tnotmuch invokes before and after certain actions. These scripts reside\n"
"\tin the .notmuch/hooks directory within the database directory and must\n"
"\thave executable permissions.\n"
"\n"
"\tThe currently available hooks are described below.\n"
"\n"
"\tpre-new\n"
"\t\tThis hook is invoked by the new command before scanning or\n"
"\t\timporting new messages into the database. If this hook exits\n"
"\t\twith a non-zero status, notmuch will abort further processing\n"
"\t\tof the new command.\n"
"\n"
"\t\tTypically this hook is used for fetching or delivering new\n"
"\t\tmail to be imported into the database.\n"
"\n"
"\tpost-new\n"
"\t\tThis hook is invoked by the new command after new messages\n"
"\t\thave been imported into the database and initial tags have\n"
"\t\tbeen applied. The hook will not be run if there have been any\n"
"\t\terrors during the scan or import.\n"
"\n"
"\t\tTypically this hook is used to perform additional query-based\n"
"\t\ttagging on the imported messages.\n\n";
static command_t commands[] = { static command_t commands[] = {
{ "setup", notmuch_setup_command, { "setup", notmuch_setup_command,
NULL, NULL,
@ -144,7 +170,7 @@ static command_t commands[] = {
"\tInvoking notmuch with no command argument will run setup if\n" "\tInvoking notmuch with no command argument will run setup if\n"
"\tthe setup command has not previously been completed." }, "\tthe setup command has not previously been completed." },
{ "new", notmuch_new_command, { "new", notmuch_new_command,
"[--verbose]", "[options...]",
"Find and import new messages to the notmuch database.", "Find and import new messages to the notmuch database.",
"\tScans all sub-directories of the mail directory, performing\n" "\tScans all sub-directories of the mail directory, performing\n"
"\tfull-text indexing on new messages that are found. Each new\n" "\tfull-text indexing on new messages that are found. Each new\n"
@ -159,8 +185,15 @@ static command_t commands[] = {
"\tis delivered and you wish to incorporate it into the database.\n" "\tis delivered and you wish to incorporate it into the database.\n"
"\tThese subsequent runs will be much quicker than the initial run.\n" "\tThese subsequent runs will be much quicker than the initial run.\n"
"\n" "\n"
"\tThe new command supports hooks. See \"notmuch help hooks\" for\n"
"\tmore details on hooks.\n"
"\n"
"\tSupported options for new include:\n" "\tSupported options for new include:\n"
"\n" "\n"
"\t--no-hooks\n"
"\n"
"\t\tPrevent hooks from being run.\n"
"\n"
"\t--verbose\n" "\t--verbose\n"
"\n" "\n"
"\t\tVerbose operation. Shows paths of message files as\n" "\t\tVerbose operation. Shows paths of message files as\n"
@ -529,6 +562,10 @@ notmuch_help_command (unused (void *ctx), int argc, char *argv[])
printf ("\n"); printf ("\n");
printf (search_terms_help); printf (search_terms_help);
return 0; return 0;
} else if (strcmp (argv[0], "hooks") == 0) {
printf ("Help for <%s>\n\n", argv[0]);
printf (hooks_help);
return 0;
} }
fprintf (stderr, fprintf (stderr,