Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id 1FA52431FC3 for ; Mon, 16 Jul 2012 23:04:47 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: 0 X-Spam-Level: X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3kmB97ShtoIg for ; Mon, 16 Jul 2012 23:04:45 -0700 (PDT) X-Greylist: delayed 1617 seconds by postgrey-1.32 at olra; Mon, 16 Jul 2012 23:04:45 PDT Received: from www73.your-server.de (www73.your-server.de [213.133.104.73]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by olra.theworths.org (Postfix) with ESMTPS id 2371A431FBC for ; Mon, 16 Jul 2012 23:04:45 -0700 (PDT) Received: from [78.46.5.204] (helo=sslproxy02.your-server.de) by www73.your-server.de with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.74) (envelope-from ) id 1Sr0Tf-00010u-Ig; Tue, 17 Jul 2012 07:37:43 +0200 Received: from [188.194.53.208] (helo=localhost.localdomain) by sslproxy02.your-server.de with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.72) (envelope-from ) id 1Sr0Te-0001dT-16; Tue, 17 Jul 2012 07:37:42 +0200 From: Dominik Peteler To: notmuch@notmuchmail.org Subject: [PATCH] cli: Hooks for tag-command Date: Tue, 17 Jul 2012 07:36:13 +0200 Message-Id: <1342503373-16979-1-git-send-email-dominik@with-h.at> X-Mailer: git-send-email 1.7.11.2 X-Authenticated-Sender: dude@with-h.at X-Virus-Scanned: Clear (ClamAV 0.97.3/15142/Tue Jul 17 04:44:44 2012) X-Mailman-Approved-At: Tue, 17 Jul 2012 14:24:57 -0700 Cc: Dominik Peteler X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jul 2012 06:04:47 -0000 hello, I attached some modifications which I made to notmuch. Comes with man pages and test. regards dominik There are two hooks: * pre-tag: Run before tagging * post-tag: Run after This allows users to react on changes of tags. For example, you might want to move a message to a special Maildir depending on its notmuch tags. --- man/man1/notmuch-tag.1 | 17 +++++++++++++++++ man/man5/notmuch-hooks.5 | 23 +++++++++++++++++++++++ notmuch-tag.c | 25 +++++++++++++++++++++---- test/hooks | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 4 deletions(-) diff --git a/man/man1/notmuch-tag.1 b/man/man1/notmuch-tag.1 index d810e1b..8d8b7b2 100644 --- a/man/man1/notmuch-tag.1 +++ b/man/man1/notmuch-tag.1 @@ -4,6 +4,7 @@ notmuch-tag \- add/remove tags for all messages matching the search terms .SH SYNOPSIS .B notmuch tag +.RB "[" --no-hooks "]" .RI "+<" tag> "|\-<" tag "> [...] [\-\-] <" search-term ">..." .SH DESCRIPTION @@ -29,6 +30,22 @@ updates the maildir flags according to tag changes if the configuration option is enabled. See \fBnotmuch-config\fR(1) for details. +The +.B tag +command supports hooks. See \fBnotmuch-hooks(5)\fR +for more details on hooks. + +Supported options for +.B tag +include +.RS 4 +.TP 4 +.BR \-\-no\-hooks + +Prevents hooks from being run. +.RE +.RE + .SH SEE ALSO \fBnotmuch\fR(1), \fBnotmuch-config\fR(1), \fBnotmuch-count\fR(1), diff --git a/man/man5/notmuch-hooks.5 b/man/man5/notmuch-hooks.5 index b914a29..7399627 100644 --- a/man/man5/notmuch-hooks.5 +++ b/man/man5/notmuch-hooks.5 @@ -38,6 +38,29 @@ the scan or import. Typically this hook is used to perform additional query\-based tagging on the imported messages. .RE +.RS 4 +.TP 4 +.B pre\-tag +This hook is invoked by the +.B tag +command before tagging messages. If this +hook exits with a non-zero status, notmuch will abort further processing of the +.B tag +command. + +Typically this hook is used for syncing the Maildir with notmuch tags. +.RE +.RS 4 +.TP 4 +.B post\-tag +This hook is invoked by the +.B tag +command after messages have been tagged. The hook will not be run if there have been any errors during +the tagging. + +Typically this hook is used for syncing the Maildir with notmuch tags. +.RE + .SH SEE ALSO diff --git a/notmuch-tag.c b/notmuch-tag.c index 7d18639..e98d3a0 100644 --- a/notmuch-tag.c +++ b/notmuch-tag.c @@ -174,9 +174,11 @@ notmuch_tag_command (void *ctx, int argc, char *argv[]) int tag_ops_count = 0; char *query_string; notmuch_config_t *config; + const char *db_path; notmuch_database_t *notmuch; struct sigaction action; notmuch_bool_t synchronize_flags; + notmuch_bool_t run_hooks = TRUE; int i; int ret; @@ -198,11 +200,12 @@ notmuch_tag_command (void *ctx, int argc, char *argv[]) } for (i = 0; i < argc; i++) { - if (strcmp (argv[i], "--") == 0) { + if (strcmp (argv[i], "--no-hooks") == 0) { + run_hooks = FALSE; + } else if (strcmp (argv[i], "--") == 0) { i++; break; - } - if (argv[i][0] == '+' || argv[i][0] == '-') { + } else if (argv[i][0] == '+' || argv[i][0] == '-') { tag_ops[tag_ops_count].tag = argv[i] + 1; tag_ops[tag_ops_count].remove = (argv[i][0] == '-'); tag_ops_count++; @@ -229,7 +232,15 @@ notmuch_tag_command (void *ctx, int argc, char *argv[]) if (config == NULL) return 1; - if (notmuch_database_open (notmuch_config_get_database_path (config), + db_path = notmuch_config_get_database_path (config); + + if (run_hooks) { + ret = notmuch_run_hook (db_path, "pre-tag"); + if (ret) + return ret; + } + + if (notmuch_database_open (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) return 1; @@ -239,5 +250,11 @@ notmuch_tag_command (void *ctx, int argc, char *argv[]) notmuch_database_destroy (notmuch); + if (run_hooks) { + ret = notmuch_run_hook (db_path, "post-tag"); + if (ret) + return ret; + } + return ret; } diff --git a/test/hooks b/test/hooks index 77e8569..ae857cc 100755 --- a/test/hooks +++ b/test/hooks @@ -31,6 +31,7 @@ rm_hooks () { # add a message to generate mail dir and database add_message +# {pre,post}-new hooks test_begin_subtest "pre-new is run" rm_hooks generate_message @@ -101,4 +102,39 @@ EOF chmod +x "${HOOK_DIR}/pre-new" test_expect_code 1 "hook execution failure" "notmuch new" + + +# {pre,post}-tag hooks +test_begin_subtest "pre-tag is run" +rm_hooks +generate_message +create_echo_hook "pre-tag" expected output +notmuch tag +foo -- '*' > /dev/null +test_expect_equal_file expected output + +test_begin_subtest "post-tag is run" +rm_hooks +generate_message +create_echo_hook "post-tag" expected output +notmuch tag +foo -- '*' > /dev/null +test_expect_equal_file expected output + +test_begin_subtest "pre-tag is run before post-new" +rm_hooks +generate_message +create_echo_hook "pre-tag" pre-tag.expected pre-tag.output +create_echo_hook "post-tag" post-tag.expected post-tag.output +notmuch tag +foo -- '*' > /dev/null +test_expect_equal_file post-tag.expected post-tag.output + +test_begin_subtest "pre-tag non-zero exit status (hook status)" +rm_hooks +generate_message +create_failing_hook "pre-tag" +output=`notmuch tag +foo -- '*' 2>&1` +test_expect_equal "$output" "Error: pre-tag hook failed with status 13" + +# depends on the previous subtest leaving broken hook behind +test_expect_code 1 "pre-tag non-zero exit status (notmuch status)" "notmuch tag +foo -- '*'" + test_done -- 1.7.11.2