[PATCHv2] cli: Hooks for tag-command
Dominik Peteler
dominik at with-h.at
Mon Jul 30 05:39:28 PDT 2012
hello,
I hope I don't bother you but so far I didn't get any reply to my last mail with the patch for tag-command hooks.
Did you accept the patch or not ? If not, please tell my if I can improve it.
And do you have a opinion about my suggestion to pass the message-ids of retagged mails to the hook ?
regards
dominik
On Wed 2012-07-18 20:09, Dominik Peteler wrote:
> 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
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120730/c06d4d60/attachment-0001.pgp>
More information about the notmuch
mailing list