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 072976DE1654
\r
6 for <notmuch@notmuchmail.org>; Sun, 9 Aug 2015 02:26:58 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at cworth.org
\r
11 X-Spam-Status: No, score=0.14 tagged_above=-999 required=5 tests=[AWL=0.130,
\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 hnABcBlJIUyN for <notmuch@notmuchmail.org>;
\r
16 Sun, 9 Aug 2015 02:26:56 -0700 (PDT)
\r
17 Received: from gitolite.debian.net (gitolite.debian.net [87.98.215.224])
\r
18 by arlo.cworth.org (Postfix) with ESMTPS id 280D36DE02D2
\r
19 for <notmuch@notmuchmail.org>; Sun, 9 Aug 2015 02:26:56 -0700 (PDT)
\r
20 Received: from remotemail by gitolite.debian.net with local (Exim 4.80)
\r
21 (envelope-from <bremner@tesseract.cs.unb.ca>)
\r
22 id 1ZOMru-0005Wl-3d; Sun, 09 Aug 2015 09:26:14 +0000
\r
23 Received: (nullmailer pid 7067 invoked by uid 1000); Sun, 09 Aug 2015
\r
25 From: David Bremner <david@tethera.net>
\r
26 To: notmuch@notmuchmail.org
\r
27 Subject: [PATCH 4/5] cli: add global option "--uuid"
\r
28 Date: Sun, 9 Aug 2015 11:24:44 +0200
\r
29 Message-Id: <1439112285-6681-5-git-send-email-david@tethera.net>
\r
30 X-Mailer: git-send-email 2.1.4
\r
31 In-Reply-To: <1439112285-6681-1-git-send-email-david@tethera.net>
\r
32 References: <1439112285-6681-1-git-send-email-david@tethera.net>
\r
33 X-BeenThere: notmuch@notmuchmail.org
\r
34 X-Mailman-Version: 2.1.18
\r
36 List-Id: "Use and development of the notmuch mail system."
\r
37 <notmuch.notmuchmail.org>
\r
38 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
39 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
40 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>
\r
41 List-Post: <mailto:notmuch@notmuchmail.org>
\r
42 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
43 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
44 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
45 X-List-Received-Date: Sun, 09 Aug 2015 09:26:58 -0000
\r
47 The function notmuch_exit_if_unmatched_db_uuid is split from
\r
48 notmuch_process_shared_options because it needs an open notmuch
\r
51 doc/man1/notmuch.rst | 12 ++++++++++--
\r
52 notmuch-client.h | 4 ++++
\r
53 notmuch-compact.c | 4 ++++
\r
54 notmuch-config.c | 4 ++++
\r
55 notmuch-count.c | 2 ++
\r
56 notmuch-dump.c | 2 ++
\r
57 notmuch-insert.c | 2 ++
\r
58 notmuch-new.c | 3 ++-
\r
59 notmuch-reply.c | 2 ++
\r
60 notmuch-restore.c | 2 ++
\r
61 notmuch-search.c | 2 ++
\r
62 notmuch-setup.c | 4 ++++
\r
63 notmuch-show.c | 2 ++
\r
64 notmuch-tag.c | 2 ++
\r
65 notmuch.c | 18 ++++++++++++++++++
\r
66 test/T570-revision-tracking.sh | 27 +++++++++++++++++++++++++++
\r
67 test/random-corpus.c | 2 ++
\r
68 17 files changed, 91 insertions(+), 3 deletions(-)
\r
70 diff --git a/doc/man1/notmuch.rst b/doc/man1/notmuch.rst
\r
71 index 0401c91..0b89544 100644
\r
72 --- a/doc/man1/notmuch.rst
\r
73 +++ b/doc/man1/notmuch.rst
\r
74 @@ -51,9 +51,17 @@ Supported global options for ``notmuch`` include
\r
75 Specify the configuration file to use. This overrides any
\r
76 configuration file specified by ${NOTMUCH\_CONFIG}.
\r
79 + Enforce that the database UUID (a unique identifier which
\r
80 + persists until e.g. the database is compacted)
\r
81 + is HEX; exit with an error if it is not. 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 --uuid=HEX`` is
\r
90 +equivalent to ``notmuch --uuid=HEX subcommand``.
\r
94 diff --git a/notmuch-client.h b/notmuch-client.h
\r
95 index 78680aa..4a4f86c 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_uuid;
\r
104 extern const notmuch_opt_desc_t notmuch_shared_options [];
\r
105 +void notmuch_exit_if_unmatched_db_uuid (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..61fccd8 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_uuid)
\r
119 + fprintf (stderr, "Warning: ignoring --uuid=%s\n",
\r
120 + notmuch_requested_db_uuid);
\r
122 notmuch_process_shared_options (argv[0]);
\r
125 diff --git a/notmuch-config.c b/notmuch-config.c
\r
126 index 9348278..d252bb2 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_uuid)
\r
134 + fprintf (stderr, "Warning: ignoring --uuid=%s\n",
\r
135 + notmuch_requested_db_uuid);
\r
137 /* skip at least subcommand argument */
\r
140 diff --git a/notmuch-count.c b/notmuch-count.c
\r
141 index 7c61ccb..091e376 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_uuid (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..24fc2f2 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_uuid (notmuch);
\r
163 char *output_file_name = NULL;
\r
166 diff --git a/notmuch-insert.c b/notmuch-insert.c
\r
167 index c277d62..5205c17 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_uuid (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 ee786a3..514e06a 100644
\r
181 --- a/notmuch-new.c
\r
182 +++ b/notmuch-new.c
\r
183 @@ -1009,10 +1009,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_uuid (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..7c5c28f 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_uuid (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..9abc64f 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_uuid (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..3076c3f 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_uuid (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..9aaf928 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_uuid)
\r
244 + fprintf (stderr, "Warning: ignoring --uuid=%s\n",
\r
245 + notmuch_requested_db_uuid);
\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..6ef3308 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_uuid (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..7ae98f6 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_uuid (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 9580c3f..ce6c575 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_uuid = 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_uuid, "uuid", 'u', 0 },
\r
293 @@ -218,6 +220,22 @@ be supported in the future.\n", notmuch_format_version);
\r
298 +notmuch_exit_if_unmatched_db_uuid (notmuch_database_t *notmuch)
\r
300 + const char *uuid = NULL;
\r
302 + if (!notmuch_requested_db_uuid)
\r
304 + IGNORE_RESULT (notmuch_database_get_revision (notmuch, &uuid));
\r
306 + if (strcmp (notmuch_requested_db_uuid, uuid) != 0){
\r
307 + fprintf (stderr, "Error: requested database revision %s does not match %s\n",
\r
308 + notmuch_requested_db_uuid, 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 008c5d0..74e3ba9 100755
\r
318 --- a/test/T570-revision-tracking.sh
\r
319 +++ b/test/T570-revision-tracking.sh
\r
320 @@ -46,4 +46,31 @@ 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 uuid' \
\r
328 + "notmuch search --uuid=$(cat UUID) '*'"
\r
330 +test_expect_success 'uuid works as global option ' \
\r
331 + "notmuch --uuid=$(cat UUID) search '*'"
\r
333 +test_expect_code 1 'uuid works as global option II' \
\r
334 + "notmuch --uuid=this-is-no-uuid search '*'"
\r
336 +test_expect_code 1 'search fails with incorrect uuid' \
\r
337 + "notmuch search --uuid=this-is-no-uuid '*'"
\r
339 +test_expect_success 'show succeeds with correct uuid' \
\r
340 + "notmuch show --uuid=$(cat UUID) '*'"
\r
342 +test_expect_code 1 'show fails with incorrect uuid' \
\r
343 + "notmuch show --uuid=this-is-no-uuid '*'"
\r
345 +test_expect_success 'tag succeeds with correct uuid' \
\r
346 + "notmuch tag --uuid=$(cat UUID) +test '*'"
\r
348 +test_expect_code 1 'tag fails with incorrect uuid' \
\r
349 + "notmuch tag --uuid=this-is-no-uuid '*' +test2"
\r
352 diff --git a/test/random-corpus.c b/test/random-corpus.c
\r
353 index b377eb4..d74271d 100644
\r
354 --- a/test/random-corpus.c
\r
355 +++ b/test/random-corpus.c
\r
356 @@ -119,6 +119,8 @@ const notmuch_opt_desc_t notmuch_shared_options[] = {
\r
360 +char *notmuch_requested_db_uuid = NULL;
\r
363 notmuch_process_shared_options (unused (const char *dummy))
\r