[PATCHv2] cli: Hooks for tag-command

2012-07-31 Thread Jani Nikula
On Wed, 18 Jul 2012, Dominik Peteler  wrote:
> hello,
>
> I improved my patch according to Janis mail:
>  * new cli syntax: notmuch tag [ --no-hooks ] --  [ -- ]  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 ?

There are probably races there that are difficult to solve. Imagine two
concurrent 'notmuch tag' invocations. The db can't be locked across the
hooks. Also, if you relied solely on the passed message-ids or filenames
to do whatever your hook would do, interrupting 'notmuch tag' before the
hook is run would leave you in an inconsistent state.

>
> regards
>
> dominik

Note that this part of the patch ends up as the commit message in the
git repository. Please have a look at
http://notmuchmail.org/patchformatting/.

>
>
>
> 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.

I am not sure if the example is such a hot idea. Moving a file in the
maildir means you'd need to run 'notmuch new' again to inform notmuch of
the change. I.e. after tagging you couldn't view the message before
you've run 'notmuch new'.

Are there any other, perhaps more compelling reasons to have hooks in
'notmuch tag'? Can you give us some other examples, please?

> ---
>  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.
> + * arg_delimiters[0]  arg_delimiters[1] 
> 
> + *
> + * 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) {
> +  

Re: [PATCHv2] cli: Hooks for tag-command

2012-07-31 Thread Jani Nikula
On Wed, 18 Jul 2012, Dominik Peteler  wrote:
> hello,
>
> I improved my patch according to Janis mail:
>  * new cli syntax: notmuch tag [ --no-hooks ] --  [ -- ]  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 ?

There are probably races there that are difficult to solve. Imagine two
concurrent 'notmuch tag' invocations. The db can't be locked across the
hooks. Also, if you relied solely on the passed message-ids or filenames
to do whatever your hook would do, interrupting 'notmuch tag' before the
hook is run would leave you in an inconsistent state.

>
> regards
>
> dominik

Note that this part of the patch ends up as the commit message in the
git repository. Please have a look at
http://notmuchmail.org/patchformatting/.

>
>
>
> 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.

I am not sure if the example is such a hot idea. Moving a file in the
maildir means you'd need to run 'notmuch new' again to inform notmuch of
the change. I.e. after tagging you couldn't view the message before
you've run 'notmuch new'.

Are there any other, perhaps more compelling reasons to have hooks in
'notmuch tag'? Can you give us some other examples, please?

> ---
>  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.
> + * arg_delimiters[0]  arg_delimiters[1] 
> 
> + *
> + * 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) {
> +  

[PATCHv2] cli: Hooks for tag-command

2012-07-30 Thread Dominik Peteler
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 ] --  [ -- ]  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.
> + * arg_delimiters[0]  arg_delimiters[1] 
> 
> + *
> + * 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 recogniz

Re: [PATCHv2] cli: Hooks for tag-command

2012-07-30 Thread Dominik Peteler
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 ] --  [ -- ]  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.
> + * arg_delimiters[0]  arg_delimiters[1] 
> 
> + *
> + * 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 recogniz

[PATCHv2] cli: Hooks for tag-command

2012-07-18 Thread Dominik Peteler
hello,

I improved my patch according to Janis mail:
 * new cli syntax: notmuch tag [ --no-hooks ] --  [ -- ] 
 * 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.
+ * arg_delimiters[0]  arg_delimiters[1] 

+ *
+ * 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_pa

[PATCHv2] cli: Hooks for tag-command

2012-07-18 Thread Dominik Peteler
hello,

I improved my patch according to Janis mail:
 * new cli syntax: notmuch tag [ --no-hooks ] --  [ -- ] 
 * 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.
+ * arg_delimiters[0]  arg_delimiters[1] 

+ *
+ * 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_d