From 69bb7f35b6e59fd3a3b1fb2d0f0367f7016cba80 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Fri, 9 Dec 2011 00:48:30 +0200 Subject: [PATCH] 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 --- NEWS | 10 ++++++++++ notmuch-new.c | 12 ++++++++++++ notmuch.1 | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- notmuch.c | 39 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 109 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index bb5e4d55..eaed960c 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,16 @@ 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 ----------- diff --git a/notmuch-new.c b/notmuch-new.c index 81a93500..bfb46001 100644 --- a/notmuch-new.c +++ b/notmuch-new.c @@ -811,6 +811,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) _filename_node_t *f; int i; notmuch_bool_t timer_is_active = FALSE; + notmuch_bool_t run_hooks = TRUE; add_files_state.verbose = 0; 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++) { if (STRNCMP_LITERAL (argv[i], "--verbose") == 0) { add_files_state.verbose = 1; + } else if (strcmp (argv[i], "--no-hooks") == 0) { + run_hooks = FALSE; } else { fprintf (stderr, "Unrecognized option: %s\n", argv[i]); 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); 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"); if (stat (dot_notmuch_path, &st)) { @@ -981,5 +990,8 @@ notmuch_new_command (void *ctx, int argc, char *argv[]) notmuch_database_close (notmuch); + if (run_hooks && !ret && !interrupted) + ret = notmuch_run_hook (db_path, "post-new"); + return ret || interrupted; } diff --git a/notmuch.1 b/notmuch.1 index 147319e5..3dbd67e1 100644 --- a/notmuch.1 +++ b/notmuch.1 @@ -85,7 +85,7 @@ The command is used to incorporate new mail into the notmuch database. .RS 4 .TP 4 -.B new +.BR new " [options...]" Find and import any new messages to the database. @@ -118,6 +118,22 @@ if has previously been completed, but .B "notmuch new" 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 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: $(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 The following environment variables can be used to control the behavior of notmuch. diff --git a/notmuch.c b/notmuch.c index d44ce9a0..c0ce026a 100644 --- a/notmuch.c +++ b/notmuch.c @@ -127,6 +127,32 @@ static const char search_terms_help[] = "\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[] = { { "setup", notmuch_setup_command, NULL, @@ -144,7 +170,7 @@ static command_t commands[] = { "\tInvoking notmuch with no command argument will run setup if\n" "\tthe setup command has not previously been completed." }, { "new", notmuch_new_command, - "[--verbose]", + "[options...]", "Find and import new messages to the notmuch database.", "\tScans all sub-directories of the mail directory, performing\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" "\tThese subsequent runs will be much quicker than the initial run.\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" "\n" + "\t--no-hooks\n" + "\n" + "\t\tPrevent hooks from being run.\n" + "\n" "\t--verbose\n" "\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 (search_terms_help); return 0; + } else if (strcmp (argv[0], "hooks") == 0) { + printf ("Help for <%s>\n\n", argv[0]); + printf (hooks_help); + return 0; } fprintf (stderr, -- 2.43.0