1 Return-Path: <bremner@tesseract.cs.unb.ca>
\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 arlo.cworth.org (Postfix) with ESMTP id 235EA6DE1778
\r
6 for <notmuch@notmuchmail.org>; Fri, 5 Jun 2015 10:30:59 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at cworth.org
\r
11 X-Spam-Status: No, score=0.239 tagged_above=-999 required=5 tests=[AWL=0.229,
\r
12 T_HEADER_FROM_DIFFERENT_DOMAINS=0.01] autolearn=disabled
\r
13 Received: from arlo.cworth.org ([127.0.0.1])
\r
14 by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)
\r
15 with ESMTP id YKAsOXzskGOw for <notmuch@notmuchmail.org>;
\r
16 Fri, 5 Jun 2015 10:30:57 -0700 (PDT)
\r
17 Received: from mx.xen14.node3324.gplhost.com (gitolite.debian.net
\r
19 by arlo.cworth.org (Postfix) with ESMTPS id 284546DE179F
\r
20 for <notmuch@notmuchmail.org>; Fri, 5 Jun 2015 10:30:57 -0700 (PDT)
\r
21 Received: from remotemail by mx.xen14.node3324.gplhost.com with local (Exim
\r
22 4.80) (envelope-from <bremner@tesseract.cs.unb.ca>)
\r
23 id 1Z0vRe-0002nz-Th; Fri, 05 Jun 2015 17:30:14 +0000
\r
24 Received: (nullmailer pid 24256 invoked by uid 1000); Fri, 05 Jun 2015
\r
26 From: David Bremner <david@tethera.net>
\r
27 To: notmuch@notmuchmail.org
\r
28 Subject: [PATCH 5/6] cli: add global option "--db-revision"
\r
29 Date: Fri, 5 Jun 2015 19:28:37 +0200
\r
30 Message-Id: <1433525318-23756-6-git-send-email-david@tethera.net>
\r
31 X-Mailer: git-send-email 2.1.4
\r
32 In-Reply-To: <1433525318-23756-1-git-send-email-david@tethera.net>
\r
33 References: <1432936375-astroid-4-0i1n6yczs2-1520@strange>
\r
34 <1433525318-23756-1-git-send-email-david@tethera.net>
\r
35 X-BeenThere: notmuch@notmuchmail.org
\r
36 X-Mailman-Version: 2.1.18
\r
38 List-Id: "Use and development of the notmuch mail system."
\r
39 <notmuch.notmuchmail.org>
\r
40 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
41 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
42 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>
\r
43 List-Post: <mailto:notmuch@notmuchmail.org>
\r
44 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
45 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
46 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
47 X-List-Received-Date: Fri, 05 Jun 2015 17:30:59 -0000
\r
49 The function notmuch_exit_if_unmatched_db_revision is split from
\r
50 notmuch_process_shared_options because it needs an open notmuch
\r
53 doc/man1/notmuch.rst | 10 ++++++++--
\r
54 notmuch-client.h | 4 ++++
\r
55 notmuch-compact.c | 4 ++++
\r
56 notmuch-config.c | 4 ++++
\r
57 notmuch-count.c | 2 ++
\r
58 notmuch-dump.c | 2 ++
\r
59 notmuch-insert.c | 2 ++
\r
60 notmuch-new.c | 3 ++-
\r
61 notmuch-reply.c | 2 ++
\r
62 notmuch-restore.c | 2 ++
\r
63 notmuch-search.c | 2 ++
\r
64 notmuch-setup.c | 4 ++++
\r
65 notmuch-show.c | 2 ++
\r
66 notmuch-tag.c | 2 ++
\r
67 notmuch.c | 18 ++++++++++++++++++
\r
68 test/T570-revision-tracking.sh | 26 ++++++++++++++++++++++++++
\r
69 test/random-corpus.c | 2 ++
\r
70 17 files changed, 88 insertions(+), 3 deletions(-)
\r
72 diff --git a/doc/man1/notmuch.rst b/doc/man1/notmuch.rst
\r
73 index ae0461a..b3f75a4 100644
\r
74 --- a/doc/man1/notmuch.rst
\r
75 +++ b/doc/man1/notmuch.rst
\r
76 @@ -49,9 +49,15 @@ Supported global options for ``notmuch`` include
\r
77 Specify the configuration file to use. This overrides any
\r
78 configuration file specified by ${NOTMUCH\_CONFIG}.
\r
80 + ``--db-revision=UUID``
\r
81 + Enforce that the database revision is UUID. This is useful to
\r
82 + detect rollover in modification counts on messages. You can
\r
83 + find this UUID in the first column of output from
\r
84 + ``notmuch count --output=modifications``
\r
86 All global options except ``--config`` can also be specified after the
\r
87 -command. For example, ``notmuch subcommand --version`` is equivalent to
\r
88 -``notmuch --version subcommand``.
\r
89 +command. For example, ``notmuch subcommand --db-revision`` is
\r
90 +equivalent to ``notmuch --db-revision subcommand``.
\r
94 diff --git a/notmuch-client.h b/notmuch-client.h
\r
95 index 78680aa..d3fab21 100644
\r
96 --- a/notmuch-client.h
\r
97 +++ b/notmuch-client.h
\r
98 @@ -466,7 +466,11 @@ notmuch_database_dump (notmuch_database_t *notmuch,
\r
99 notmuch_bool_t gzip_output);
\r
101 #include "command-line-arguments.h"
\r
103 +extern char *notmuch_requested_db_revision;
\r
104 extern const notmuch_opt_desc_t notmuch_shared_options [];
\r
105 +void notmuch_exit_if_unmatched_db_revision (notmuch_database_t *notmuch);
\r
107 void notmuch_process_shared_options (const char* subcommand_name);
\r
108 int notmuch_minimal_options (const char* subcommand_name,
\r
109 int argc, char **argv);
\r
110 diff --git a/notmuch-compact.c b/notmuch-compact.c
\r
111 index 5be551d..3da4bfb 100644
\r
112 --- a/notmuch-compact.c
\r
113 +++ b/notmuch-compact.c
\r
114 @@ -46,6 +46,10 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[])
\r
116 return EXIT_FAILURE;
\r
118 + if (notmuch_requested_db_revision)
\r
119 + fprintf (stderr, "Warning: ignoring --db-revision=%s\n",
\r
120 + notmuch_requested_db_revision);
\r
122 notmuch_process_shared_options (argv[0]);
\r
125 diff --git a/notmuch-config.c b/notmuch-config.c
\r
126 index 9348278..f1826e4 100644
\r
127 --- a/notmuch-config.c
\r
128 +++ b/notmuch-config.c
\r
129 @@ -878,6 +878,10 @@ notmuch_config_command (notmuch_config_t *config, int argc, char *argv[])
\r
131 return EXIT_FAILURE;
\r
133 + if (notmuch_requested_db_revision)
\r
134 + fprintf (stderr, "Warning: ignoring --db-revision=%s\n",
\r
135 + notmuch_requested_db_revision);
\r
137 /* skip at least subcommand argument */
\r
140 diff --git a/notmuch-count.c b/notmuch-count.c
\r
141 index 7c61ccb..dda85b5 100644
\r
142 --- a/notmuch-count.c
\r
143 +++ b/notmuch-count.c
\r
144 @@ -191,6 +191,8 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[])
\r
145 NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
\r
146 return EXIT_FAILURE;
\r
148 + notmuch_exit_if_unmatched_db_revision (notmuch);
\r
150 query_str = query_string_from_args (config, argc-opt_index, argv+opt_index);
\r
151 if (query_str == NULL) {
\r
152 fprintf (stderr, "Out of memory.\n");
\r
153 diff --git a/notmuch-dump.c b/notmuch-dump.c
\r
154 index fab22bd..9c0b82d 100644
\r
155 --- a/notmuch-dump.c
\r
156 +++ b/notmuch-dump.c
\r
157 @@ -215,6 +215,8 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
\r
158 NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much))
\r
159 return EXIT_FAILURE;
\r
161 + notmuch_exit_if_unmatched_db_revision (notmuch);
\r
163 char *output_file_name = NULL;
\r
166 diff --git a/notmuch-insert.c b/notmuch-insert.c
\r
167 index c277d62..42d346f 100644
\r
168 --- a/notmuch-insert.c
\r
169 +++ b/notmuch-insert.c
\r
170 @@ -536,6 +536,8 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[])
\r
171 NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much))
\r
172 return EXIT_FAILURE;
\r
174 + notmuch_exit_if_unmatched_db_revision (notmuch);
\r
176 /* Write the message to the Maildir new directory. */
\r
177 newpath = maildir_write_new (config, STDIN_FILENO, maildir);
\r
179 diff --git a/notmuch-new.c b/notmuch-new.c
\r
180 index 8ff1ade..2064a86 100644
\r
181 --- a/notmuch-new.c
\r
182 +++ b/notmuch-new.c
\r
183 @@ -995,10 +995,11 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
\r
184 fputs (status_string, stderr);
\r
185 free (status_string);
\r
188 return EXIT_FAILURE;
\r
191 + notmuch_exit_if_unmatched_db_revision (notmuch);
\r
193 if (notmuch_database_needs_upgrade (notmuch)) {
\r
194 time_t now = time (NULL);
\r
195 struct tm *gm_time = gmtime (&now);
\r
196 diff --git a/notmuch-reply.c b/notmuch-reply.c
\r
197 index 4464741..52e0d9b 100644
\r
198 --- a/notmuch-reply.c
\r
199 +++ b/notmuch-reply.c
\r
200 @@ -831,6 +831,8 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
\r
201 NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
\r
202 return EXIT_FAILURE;
\r
204 + notmuch_exit_if_unmatched_db_revision (notmuch);
\r
206 query = notmuch_query_create (notmuch, query_string);
\r
207 if (query == NULL) {
\r
208 fprintf (stderr, "Out of memory\n");
\r
209 diff --git a/notmuch-restore.c b/notmuch-restore.c
\r
210 index 2a534dc..3e96aa8 100644
\r
211 --- a/notmuch-restore.c
\r
212 +++ b/notmuch-restore.c
\r
213 @@ -165,6 +165,8 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[])
\r
216 notmuch_process_shared_options (argv[0]);
\r
217 + notmuch_exit_if_unmatched_db_revision (notmuch);
\r
219 name_for_error = input_file_name ? input_file_name : "stdin";
\r
222 diff --git a/notmuch-search.c b/notmuch-search.c
\r
223 index b89a17e..919837c 100644
\r
224 --- a/notmuch-search.c
\r
225 +++ b/notmuch-search.c
\r
226 @@ -583,6 +583,8 @@ _notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int ar
\r
227 return EXIT_FAILURE;
\r
230 + notmuch_exit_if_unmatched_db_revision (ctx->notmuch);
\r
232 query_str = query_string_from_args (ctx->notmuch, argc, argv);
\r
233 if (query_str == NULL) {
\r
234 fprintf (stderr, "Out of memory.\n");
\r
235 diff --git a/notmuch-setup.c b/notmuch-setup.c
\r
236 index 7dd5822..dffda81 100644
\r
237 --- a/notmuch-setup.c
\r
238 +++ b/notmuch-setup.c
\r
239 @@ -148,6 +148,10 @@ notmuch_setup_command (notmuch_config_t *config,
\r
240 if (notmuch_minimal_options ("setup", argc, argv) < 0)
\r
241 return EXIT_FAILURE;
\r
243 + if (notmuch_requested_db_revision)
\r
244 + fprintf (stderr, "Warning: ignoring --db-revision=%s\n",
\r
245 + notmuch_requested_db_revision);
\r
247 if (notmuch_config_is_new (config))
\r
248 welcome_message_pre_setup ();
\r
250 diff --git a/notmuch-show.c b/notmuch-show.c
\r
251 index b80933a..2535c8c 100644
\r
252 --- a/notmuch-show.c
\r
253 +++ b/notmuch-show.c
\r
254 @@ -1213,6 +1213,8 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
\r
255 NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
\r
256 return EXIT_FAILURE;
\r
258 + notmuch_exit_if_unmatched_db_revision (notmuch);
\r
260 query = notmuch_query_create (notmuch, query_string);
\r
261 if (query == NULL) {
\r
262 fprintf (stderr, "Out of memory\n");
\r
263 diff --git a/notmuch-tag.c b/notmuch-tag.c
\r
264 index 38d99aa..22446fe 100644
\r
265 --- a/notmuch-tag.c
\r
266 +++ b/notmuch-tag.c
\r
267 @@ -261,6 +261,8 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[])
\r
268 NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much))
\r
269 return EXIT_FAILURE;
\r
271 + notmuch_exit_if_unmatched_db_revision (notmuch);
\r
273 if (notmuch_config_get_maildir_synchronize_flags (config))
\r
274 tag_flags |= TAG_FLAG_MAILDIR_SYNC;
\r
276 diff --git a/notmuch.c b/notmuch.c
\r
277 index c528dce..fab737c 100644
\r
280 @@ -47,10 +47,12 @@ static int
\r
281 _help_for (const char *topic);
\r
283 static notmuch_bool_t print_version = FALSE, print_help = FALSE;
\r
284 +char *notmuch_requested_db_revision = NULL;
\r
286 const notmuch_opt_desc_t notmuch_shared_options [] = {
\r
287 { NOTMUCH_OPT_BOOLEAN, &print_version, "version", 'v', 0 },
\r
288 { NOTMUCH_OPT_BOOLEAN, &print_help, "help", 'h', 0 },
\r
289 + { NOTMUCH_OPT_STRING, ¬much_requested_db_revision, "db-revision", 'd', 0 },
\r
293 @@ -218,6 +220,22 @@ be supported in the future.\n", notmuch_format_version);
\r
298 +notmuch_exit_if_unmatched_db_revision (notmuch_database_t *notmuch)
\r
300 + const char *uuid = NULL;
\r
302 + if (!notmuch_requested_db_revision)
\r
304 + IGNORE_RESULT (notmuch_database_get_revision (notmuch, &uuid));
\r
306 + if (strcmp (notmuch_requested_db_revision, uuid) != 0){
\r
307 + fprintf (stderr, "Error: requested database revision %s does not match %s\n",
\r
308 + notmuch_requested_db_revision, uuid);
\r
314 exec_man (const char *page)
\r
316 diff --git a/test/T570-revision-tracking.sh b/test/T570-revision-tracking.sh
\r
317 index 062fd59..bb09bf6 100755
\r
318 --- a/test/T570-revision-tracking.sh
\r
319 +++ b/test/T570-revision-tracking.sh
\r
320 @@ -46,4 +46,30 @@ notmuch tag +a-random-tag-8743632 '*'
\r
321 after=$(notmuch count --output=modifications '*' | cut -f2)
\r
322 result=$(($before < $after))
\r
323 test_expect_equal 1 ${result}
\r
325 +notmuch count --output=modifications '*' | cut -f1 > UUID
\r
327 +test_expect_success 'search succeeds with correct db revision' \
\r
328 + "notmuch search --db-revision=$(cat UUID) '*'"
\r
330 +test_expect_success 'db-revision works as global option ' \
\r
331 + "notmuch --db-revision=$(cat UUID) search '*'"
\r
333 +test_expect_code 1 'db-revision works as global option II' \
\r
334 + "notmuch --db-revision=this-is-no-uuid search '*'"
\r
336 +test_expect_code 1 'search fails with incorrect db revision' \
\r
337 + "notmuch search --db-revision=this-is-no-uuid '*'"
\r
339 +test_expect_success 'show succeeds with correct db revision' \
\r
340 + "notmuch show --db-revision=$(cat UUID) '*'"
\r
342 +test_expect_code 1 'show fails with incorrect db revision' \
\r
343 + "notmuch show --db-revision=this-is-no-uuid '*'"
\r
345 +test_expect_success 'tag succeeds with correct db revision' \
\r
346 + "notmuch tag --db-revision=$(cat UUID) +test '*'"
\r
348 +test_expect_code 1 'tag fails with incorrect db revision' \
\r
349 + "notmuch show --db-revision=this-is-no-uuid '*' +test2"
\r
351 diff --git a/test/random-corpus.c b/test/random-corpus.c
\r
352 index b377eb4..542b453 100644
\r
353 --- a/test/random-corpus.c
\r
354 +++ b/test/random-corpus.c
\r
355 @@ -119,6 +119,8 @@ const notmuch_opt_desc_t notmuch_shared_options[] = {
\r
359 +char *notmuch_requested_db_revision = NULL;
\r
362 notmuch_process_shared_options (unused (const char *dummy))
\r