1 Return-Path: <dominik@with-h.at>
\r
2 X-Original-To: notmuch@notmuchmail.org
\r
3 Delivered-To: notmuch@notmuchmail.org
\r
4 Received: from localhost (localhost [127.0.0.1])
\r
5 by olra.theworths.org (Postfix) with ESMTP id 7481B431FBF
\r
6 for <notmuch@notmuchmail.org>; Mon, 30 Jul 2012 05:41:19 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]
\r
13 Received: from olra.theworths.org ([127.0.0.1])
\r
14 by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id Uss7dRFTcjhE for <notmuch@notmuchmail.org>;
\r
16 Mon, 30 Jul 2012 05:41:17 -0700 (PDT)
\r
17 Received: from www73.your-server.de (www73.your-server.de [213.133.104.73])
\r
18 (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
\r
19 (No client certificate requested)
\r
20 by olra.theworths.org (Postfix) with ESMTPS id 126A9431FAE
\r
21 for <notmuch@notmuchmail.org>; Mon, 30 Jul 2012 05:41:17 -0700 (PDT)
\r
22 Received: from [78.46.5.203] (helo=sslproxy01.your-server.de)
\r
23 by www73.your-server.de with esmtpsa (TLSv1:AES256-SHA:256)
\r
24 (Exim 4.74) (envelope-from <dominik@with-h.at>) id 1SvpHa-0002ER-O6
\r
25 for notmuch@notmuchmail.org; Mon, 30 Jul 2012 14:41:10 +0200
\r
26 Received: from [132.187.246.115] (helo=fuckup.uni-wuerzburg.de)
\r
27 by sslproxy01.your-server.de with esmtpsa
\r
28 (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.72)
\r
29 (envelope-from <dominik@with-h.at>) id 1SvpHR-0003tl-IF
\r
30 for notmuch@notmuchmail.org; Mon, 30 Jul 2012 14:41:02 +0200
\r
31 Date: Mon, 30 Jul 2012 14:39:28 +0200
\r
32 From: Dominik Peteler <dominik@with-h.at>
\r
33 To: notmuch@notmuchmail.org
\r
34 Subject: Re: [PATCHv2] cli: Hooks for tag-command
\r
35 Message-ID: <20120730123928.GA749@fuckup.uni-wuerzburg.de>
\r
37 <CAB+hUn_XHQQ9MDaVXvOMzfM8SdKCWUgnjNQvxJaQWWyc3H621Q@mail.gmail.com>
\r
38 <1342634970-12991-1-git-send-email-dominik@with-h.at>
\r
40 Content-Type: multipart/signed; micalg=pgp-sha1;
\r
41 protocol="application/pgp-signature"; boundary="5vNYLRcllDrimb99"
\r
42 Content-Disposition: inline
\r
43 In-Reply-To: <1342634970-12991-1-git-send-email-dominik@with-h.at>
\r
44 X-PGP-Key: http://www.with-h.at/pubkey.asc
\r
45 User-Agent: Mutt/1.5.21 (2011-07-01)
\r
46 X-Authenticated-Sender: dude@with-h.at
\r
47 X-Virus-Scanned: Clear (ClamAV 0.97.3/15190/Mon Jul 30 10:41:49 2012)
\r
48 X-Mailman-Approved-At: Mon, 30 Jul 2012 06:47:37 -0700
\r
49 X-BeenThere: notmuch@notmuchmail.org
\r
50 X-Mailman-Version: 2.1.13
\r
52 List-Id: "Use and development of the notmuch mail system."
\r
53 <notmuch.notmuchmail.org>
\r
54 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
55 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
56 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
57 List-Post: <mailto:notmuch@notmuchmail.org>
\r
58 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
59 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
60 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
61 X-List-Received-Date: Mon, 30 Jul 2012 12:41:19 -0000
\r
65 Content-Type: text/plain; charset=us-ascii
\r
66 Content-Disposition: inline
\r
67 Content-Transfer-Encoding: quoted-printable
\r
71 I hope I don't bother you but so far I didn't get any reply to my last mail=
\r
72 with the patch for tag-command hooks.
\r
73 Did you accept the patch or not ? If not, please tell my if I can improve i=
\r
75 And do you have a opinion about my suggestion to pass the message-ids of re=
\r
76 tagged mails to the hook ?
\r
84 On Wed 2012-07-18 20:09, Dominik Peteler wrote:
\r
87 > I improved my patch according to Janis mail:
\r
88 > * new cli syntax: notmuch tag [ --no-hooks ] -- <tag ops> [ -- ] <search=
\r
90 > * adjusted man pages and wrote tests
\r
92 > I had the idea to improve this feature by passing the message-ids or the =
\r
93 filename to the hooks.
\r
94 > What's your opinion about that ? Any suggestions ?
\r
102 > There are two hooks:
\r
103 > * pre-tag: Run before tagging
\r
104 > * post-tag: Run after
\r
106 > This allows users to react on changes of tags. For example,
\r
107 > you might want to move a message to a special Maildir
\r
108 > depending on its notmuch tags.
\r
110 > man/man1/notmuch-tag.1 | 22 +++++++++++++++++++-
\r
111 > man/man5/notmuch-hooks.5 | 19 ++++++++++++++++++
\r
112 > notmuch-tag.c | 52 ++++++++++++++++++++++++++++++++++++++++++=
\r
114 > test/hooks | 36 +++++++++++++++++++++++++++++++++
\r
115 > test/tagging | 28 ++++++++++++++++++++++++++
\r
116 > 5 files changed, 153 insertions(+), 4 deletions(-)
\r
118 > diff --git a/man/man1/notmuch-tag.1 b/man/man1/notmuch-tag.1
\r
119 > index d810e1b..e00e189 100644
\r
120 > --- a/man/man1/notmuch-tag.1
\r
121 > +++ b/man/man1/notmuch-tag.1
\r
122 > @@ -4,7 +4,11 @@ notmuch-tag \- add/remove tags for all messages matching=
\r
127 > -.RI "+<" tag> "|\-<" tag "> [...] [\-\-] <" search-term ">..."
\r
128 > +.RI "+<" tag "> |\-<" tag "> [...] [\-\-] <" search-term ">..."
\r
131 > +.RB "[" --no-hooks "]"
\r
132 > +.RI "\-\- +<" tag "> |\-<" tag "> [...] \-\- <" search-term ">..."
\r
136 > @@ -29,6 +33,22 @@ updates the maildir flags according to tag changes if =
\r
138 > configuration option is enabled. See \fBnotmuch-config\fR(1) for
\r
143 > +command supports hooks. See \fBnotmuch-hooks(5)\fR
\r
144 > +for more details on hooks.
\r
146 > +Supported options for
\r
151 > +.BR \-\-no\-hooks
\r
153 > +Prevents hooks from being run.
\r
159 > \fBnotmuch\fR(1), \fBnotmuch-config\fR(1), \fBnotmuch-count\fR(1),
\r
160 > diff --git a/man/man5/notmuch-hooks.5 b/man/man5/notmuch-hooks.5
\r
161 > index b914a29..e193ef5 100644
\r
162 > --- a/man/man5/notmuch-hooks.5
\r
163 > +++ b/man/man5/notmuch-hooks.5
\r
164 > @@ -38,6 +38,25 @@ the scan or import.
\r
165 > Typically this hook is used to perform additional query\-based tagging o=
\r
167 > imported messages.
\r
172 > +This hook is invoked by the
\r
174 > +command before tagging messages. If this
\r
175 > +hook exits with a non-zero status, notmuch will abort further processing=
\r
183 > +This hook is invoked by the
\r
185 > +command after messages have been tagged. The hook will not be run if the=
\r
186 re have been any errors during
\r
193 > diff --git a/notmuch-tag.c b/notmuch-tag.c
\r
194 > index 7d18639..7572059 100644
\r
195 > --- a/notmuch-tag.c
\r
196 > +++ b/notmuch-tag.c
\r
197 > @@ -174,9 +174,17 @@ notmuch_tag_command (void *ctx, int argc, char *argv=
\r
199 > int tag_ops_count =3D 0;
\r
200 > char *query_string;
\r
201 > notmuch_config_t *config;
\r
202 > + const char *db_path;
\r
203 > notmuch_database_t *notmuch;
\r
204 > struct sigaction action;
\r
205 > notmuch_bool_t synchronize_flags;
\r
206 > + /* Points to the position of the "--" delimiters, e. g.
\r
207 > + * <optional arguments> arg_delimiters[0] <tag ops> arg_delimiter=
\r
208 s[1] <search terms>
\r
210 > + * arg_delimiters[0] may remain -1 if there are no arguments given
\r
211 > + * arg_delimiters[0] may remain -1 if there is no delimiter between =
\r
212 tag ops and search terms */
\r
213 > + int arg_delimiters[2] =3D {-1, -1};
\r
214 > + notmuch_bool_t run_hooks =3D TRUE;
\r
218 > @@ -197,11 +205,37 @@ notmuch_tag_command (void *ctx, int argc, char *arg=
\r
223 > + /* Determine position of delimiters */
\r
224 > for (i =3D 0; i < argc; i++) {
\r
225 > if (strcmp (argv[i], "--") =3D=3D 0) {
\r
228 > + if (arg_delimiters[1] =3D=3D -1) {
\r
229 > + arg_delimiters[1] =3D i;
\r
230 > + } else if (arg_delimiters[0] =3D=3D -1) {
\r
231 > + arg_delimiters[0] =3D arg_delimiters[1];
\r
232 > + arg_delimiters[1] =3D i;
\r
234 > + fprintf (stderr, "Error: 'notmuch tag' requires delimiter \"--\" at mo=
\r
241 > + /* Process arguments if present */
\r
242 > + for (i =3D 0; i < arg_delimiters[0]; i++) {
\r
243 > + if (strcmp (argv[i], "--no-hooks") =3D=3D 0) {
\r
244 > + run_hooks =3D FALSE;
\r
246 > + fprintf (stderr, "Error: 'notmuch tag' doesn't recognize argument '=
\r
252 > + /* Set arg_delimiters[1] to argc if no delimiters at all are present=
\r
254 > + if (arg_delimiters[1] =3D=3D -1)
\r
255 > + arg_delimiters[1] =3D argc;
\r
257 > + /* Read tag ops */
\r
258 > + for (i =3D arg_delimiters[0]+1; i < arg_delimiters[1]; i++) {
\r
259 > if (argv[i][0] =3D=3D '+' || argv[i][0] =3D=3D '-') {
\r
260 > tag_ops[tag_ops_count].tag =3D argv[i] + 1;
\r
261 > tag_ops[tag_ops_count].remove =3D (argv[i][0] =3D=3D '-');
\r
262 > @@ -229,7 +263,15 @@ notmuch_tag_command (void *ctx, int argc, char *argv=
\r
264 > if (config =3D=3D NULL)
\r
267 > - if (notmuch_database_open (notmuch_config_get_database_path (config),
\r
268 > + db_path =3D notmuch_config_get_database_path (config);
\r
270 > + if (run_hooks) {
\r
271 > + ret =3D notmuch_run_hook (db_path, "pre-tag");
\r
276 > + if (notmuch_database_open (db_path,
\r
277 > NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much))
\r
280 > @@ -239,5 +281,9 @@ notmuch_tag_command (void *ctx, int argc, char *argv[=
\r
283 > notmuch_database_destroy (notmuch);
\r
285 > + if (!ret && run_hooks) {
\r
286 > + ret =3D notmuch_run_hook (db_path, "post-tag");
\r
291 > diff --git a/test/hooks b/test/hooks
\r
292 > index 77e8569..ae857cc 100755
\r
295 > @@ -31,6 +31,7 @@ rm_hooks () {
\r
296 > # add a message to generate mail dir and database
\r
299 > +# {pre,post}-new hooks
\r
300 > test_begin_subtest "pre-new is run"
\r
303 > @@ -101,4 +102,39 @@ EOF
\r
304 > chmod +x "${HOOK_DIR}/pre-new"
\r
305 > test_expect_code 1 "hook execution failure" "notmuch new"
\r
309 > +# {pre,post}-tag hooks
\r
310 > +test_begin_subtest "pre-tag is run"
\r
312 > +generate_message
\r
313 > +create_echo_hook "pre-tag" expected output
\r
314 > +notmuch tag +foo -- '*' > /dev/null
\r
315 > +test_expect_equal_file expected output
\r
317 > +test_begin_subtest "post-tag is run"
\r
319 > +generate_message
\r
320 > +create_echo_hook "post-tag" expected output
\r
321 > +notmuch tag +foo -- '*' > /dev/null
\r
322 > +test_expect_equal_file expected output
\r
324 > +test_begin_subtest "pre-tag is run before post-new"
\r
326 > +generate_message
\r
327 > +create_echo_hook "pre-tag" pre-tag.expected pre-tag.output
\r
328 > +create_echo_hook "post-tag" post-tag.expected post-tag.output
\r
329 > +notmuch tag +foo -- '*' > /dev/null
\r
330 > +test_expect_equal_file post-tag.expected post-tag.output
\r
332 > +test_begin_subtest "pre-tag non-zero exit status (hook status)"
\r
334 > +generate_message
\r
335 > +create_failing_hook "pre-tag"
\r
336 > +output=3D`notmuch tag +foo -- '*' 2>&1`
\r
337 > +test_expect_equal "$output" "Error: pre-tag hook failed with status 13"
\r
339 > +# depends on the previous subtest leaving broken hook behind
\r
340 > +test_expect_code 1 "pre-tag non-zero exit status (notmuch status)" "notm=
\r
341 uch tag +foo -- '*'"
\r
344 > diff --git a/test/tagging b/test/tagging
\r
345 > index e4782ed..5167f4f 100755
\r
346 > --- a/test/tagging
\r
347 > +++ b/test/tagging
\r
348 > @@ -46,4 +46,32 @@ test_expect_equal "$output" "\
\r
349 > thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 u=
\r
351 > thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 tag4 u=
\r
354 > +test_begin_subtest "Arguments mixed with tag ops"
\r
355 > +notmuch tag +-no-hooks --no-hooks -- One
\r
356 > +notmuch tag --no-hooks +-no-hooks -tag4 -- Two
\r
357 > +output=3D$(notmuch search \* | notmuch_search_sanitize)
\r
358 > +test_expect_equal "$output" "\
\r
359 > +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 u=
\r
361 > +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (-no-hooks inbox t=
\r
363 > +notmuch tag --no-hooks -- Two
\r
365 > +test_begin_subtest "Arguments with correct position"
\r
366 > +notmuch tag --no-hooks -- +tag4 -tag4 -- One
\r
367 > +output=3D$(notmuch search \* | notmuch_search_sanitize)
\r
368 > +test_expect_equal "$output" "\
\r
369 > +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 u=
\r
371 > +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread=
\r
374 > +test_begin_subtest "Missing arguments"
\r
375 > +notmuch tag -- +tag4 -tag4 -- One
\r
376 > +output=3D$(notmuch search \* | notmuch_search_sanitize)
\r
377 > +test_expect_equal "$output" "\
\r
378 > +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; One (:\" inbox tag1 u=
\r
380 > +thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread=
\r
383 > +test_begin_subtest "Unknown argument"
\r
384 > +output=3D$(notmuch tag --no-blubb -- +tag4 -tag4 -- One 2>&1)
\r
385 > +test_expect_equal "$output" "\
\r
386 > +Error: 'notmuch tag' doesn't recognize argument '--no-blubb'."
\r
394 Content-Type: application/pgp-signature
\r
396 -----BEGIN PGP SIGNATURE-----
\r
397 Version: GnuPG v2.0.19 (GNU/Linux)
\r
399 iQIcBAEBAgAGBQJQFoCAAAoJEFxmf0CweVkTFrkQAJtoYSf5F5C4+sRjc4QAqzZN
\r
400 Sa9ZUgDpacVhx5jcPgEwJpyAmTIoBl70jpZtUyz/r2/jb9ofcaRhRWi+SUhZUSDi
\r
401 cA0lSq4W9HoRvz0AiuggdgzE0ydungL+CJsrWwQZrVYnXMcpoVf+NIKCnkGU2dZo
\r
402 I7fGRWeSklfGysKehsKHX3G8UUzvicnr7EBd7gWN5+x9PE6RJZXNR/cx9YiRS03s
\r
403 n1kvfEPyyK3J8l2Gz42Vh16/RmFPAFc07/aIpylOp8l4qBz6WDWQy7gGFDjwFscU
\r
404 P4NlPC0fugCLawnF4z+H/5zffhLN9BL5LvsQ3p9AZ0PLLlmfVuke54y/g07PuIOO
\r
405 a4HyIeyhHsXdJcJYut7xFxzFN8kt89yfXtLVUSRO6OOAOwcGF8UEhdf6UYGKn3wZ
\r
406 zLMkF+vXmkDIKq7RfwvNX++pR/NXU14zDfZ5s1ywuZ0tBmmiqjfVa8hh1zh3HrdB
\r
407 PQGh2AnSFrZRCCcvXsmVVvCsybC6fKrldrNRB/q7lNyn6W8TyeKZObGu0cshHEi0
\r
408 KKNl5olunoiKUN2cSc8uoa9Kc1BFek91SLz0+gdOlV3FKlEGGBPnmihDanDFZATg
\r
409 07qw8XvcdK3/pSgNVVGRc6Lcr+xyYLJ1dC0dBB+jDQBlE4dj0guChF93IEa/MXTv
\r
410 Od3M+3RH8oSHRGMUvL1a
\r
412 -----END PGP SIGNATURE-----
\r
414 --5vNYLRcllDrimb99--
\r