[PATCHv2] cli: Hooks for tag-command
Dominik Peteler
dominik at with-h.at
Wed Jul 18 11:09:30 PDT 2012
hello,
I improved my patch according to Janis mail:
* new cli syntax: notmuch tag [ --no-hooks ] -- <tag ops> [ -- ] <search terms>
* adjusted man pages and wrote tests
I had the idea to improve this feature by passing the message-ids or the filename to the hooks.
What's your opinion about that ? Any suggestions ?
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 | 22 +++++++++++++++++++-
man/man5/notmuch-hooks.5 | 19 ++++++++++++++++++
notmuch-tag.c | 52 +++++++++++++++++++++++++++++++++++++++++++++---
test/hooks | 36 +++++++++++++++++++++++++++++++++
test/tagging | 28 ++++++++++++++++++++++++++
5 files changed, 153 insertions(+), 4 deletions(-)
diff --git a/man/man1/notmuch-tag.1 b/man/man1/notmuch-tag.1
index d810e1b..e00e189 100644
--- a/man/man1/notmuch-tag.1
+++ b/man/man1/notmuch-tag.1
@@ -4,7 +4,11 @@ notmuch-tag \- add/remove tags for all messages matching the search terms
.SH SYNOPSIS
.B notmuch tag
-.RI "+<" tag> "|\-<" tag "> [...] [\-\-] <" search-term ">..."
+.RI "+<" tag "> |\-<" tag "> [...] [\-\-] <" search-term ">..."
+
+.B notmuch tag
+.RB "[" --no-hooks "]"
+.RI "\-\- +<" tag "> |\-<" tag "> [...] \-\- <" search-term ">..."
.SH DESCRIPTION
@@ -29,6 +33,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..e193ef5 100644
--- a/man/man5/notmuch-hooks.5
+++ b/man/man5/notmuch-hooks.5
@@ -38,6 +38,25 @@ 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.
+.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.
+.RE
+
.SH SEE ALSO
diff --git a/notmuch-tag.c b/notmuch-tag.c
index 7d18639..7572059 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -174,9 +174,17 @@ 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;
+ /* Points to the position of the "--" delimiters, e. g.
+ * <optional arguments> arg_delimiters[0] <tag ops> arg_delimiters[1] <search terms>
+ *
+ * arg_delimiters[0] may remain -1 if there are no arguments given
+ * arg_delimiters[0] may remain -1 if there is no delimiter between tag ops and search terms */
+ int arg_delimiters[2] = {-1, -1};
+ notmuch_bool_t run_hooks = TRUE;
int i;
int ret;
@@ -197,11 +205,37 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
return 1;
}
+ /* Determine position of delimiters */
for (i = 0; i < argc; i++) {
if (strcmp (argv[i], "--") == 0) {
- i++;
- break;
+ if (arg_delimiters[1] == -1) {
+ arg_delimiters[1] = i;
+ } else if (arg_delimiters[0] == -1) {
+ arg_delimiters[0] = arg_delimiters[1];
+ arg_delimiters[1] = i;
+ } else {
+ fprintf (stderr, "Error: 'notmuch tag' requires delimiter \"--\" at most two times.\n");
+ return 1;
+ }
}
+ }
+
+ /* Process arguments if present */
+ for (i = 0; i < arg_delimiters[0]; i++) {
+ if (strcmp (argv[i], "--no-hooks") == 0) {
+ run_hooks = FALSE;
+ } else {
+ fprintf (stderr, "Error: 'notmuch tag' doesn't recognize argument '%s'.\n", argv[i]);
+ return 1;
+ }
+ }
+
+ /* Set arg_delimiters[1] to argc if no delimiters at all are present */
+ if (arg_delimiters[1] == -1)
+ arg_delimiters[1] = argc;
+
+ /* Read tag ops */
+ for (i = arg_delimiters[0]+1; i < arg_delimiters[1]; i++) {
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] == '-');
@@ -229,7 +263,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 +281,9 @@ notmuch_tag_command (void *ctx, int argc, char *argv[])
notmuch_database_destroy (notmuch);
+ if (!ret && run_hooks) {
+ ret = notmuch_run_hook (db_path, "post-tag");
+ }
+
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
diff --git a/test/tagging b/test/tagging
index e4782ed..5167f4f 100755
--- a/test/tagging
+++ b/test/tagging
@@ -46,4 +46,32 @@ test_expect_equal "$output" "\
thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 unread)
thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag4 unread)"
+test_begin_subtest "Arguments mixed with tag ops"
+notmuch tag +-no-hooks --no-hooks -- One
+notmuch tag --no-hooks +-no-hooks -tag4 -- Two
+output=$(notmuch search \* | notmuch_search_sanitize)
+test_expect_equal "$output" "\
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 unread)
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (-no-hooks inbox tag1 unread)"
+notmuch tag --no-hooks -- Two
+
+test_begin_subtest "Arguments with correct position"
+notmuch tag --no-hooks -- +tag4 -tag4 -- One
+output=$(notmuch search \* | notmuch_search_sanitize)
+test_expect_equal "$output" "\
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 unread)
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)"
+
+test_begin_subtest "Missing arguments"
+notmuch tag -- +tag4 -tag4 -- One
+output=$(notmuch search \* | notmuch_search_sanitize)
+test_expect_equal "$output" "\
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 unread)
+thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)"
+
+test_begin_subtest "Unknown argument"
+output=$(notmuch tag --no-blubb -- +tag4 -tag4 -- One 2>&1)
+test_expect_equal "$output" "\
+Error: 'notmuch tag' doesn't recognize argument '--no-blubb'."
+
test_done
--
1.7.11.2
More information about the notmuch
mailing list