From 251d49847d1e5e8937b3db199aec4ff8de20b9bb Mon Sep 17 00:00:00 2001 From: David Bremner Date: Fri, 5 Jun 2015 19:28:37 +0200 Subject: [PATCH] [PATCH 5/6] cli: add global option "--db-revision" --- 8e/f4bde6970b50310f70bcd58ecafb77aa8f1998 | 366 ++++++++++++++++++++++ 1 file changed, 366 insertions(+) create mode 100644 8e/f4bde6970b50310f70bcd58ecafb77aa8f1998 diff --git a/8e/f4bde6970b50310f70bcd58ecafb77aa8f1998 b/8e/f4bde6970b50310f70bcd58ecafb77aa8f1998 new file mode 100644 index 000000000..409b7e3db --- /dev/null +++ b/8e/f4bde6970b50310f70bcd58ecafb77aa8f1998 @@ -0,0 +1,366 @@ +Return-Path: +X-Original-To: notmuch@notmuchmail.org +Delivered-To: notmuch@notmuchmail.org +Received: from localhost (localhost [127.0.0.1]) + by arlo.cworth.org (Postfix) with ESMTP id 235EA6DE1778 + for ; Fri, 5 Jun 2015 10:30:59 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at cworth.org +X-Spam-Flag: NO +X-Spam-Score: 0.239 +X-Spam-Level: +X-Spam-Status: No, score=0.239 tagged_above=-999 required=5 tests=[AWL=0.229, + T_HEADER_FROM_DIFFERENT_DOMAINS=0.01] autolearn=disabled +Received: from arlo.cworth.org ([127.0.0.1]) + by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024) + with ESMTP id YKAsOXzskGOw for ; + Fri, 5 Jun 2015 10:30:57 -0700 (PDT) +Received: from mx.xen14.node3324.gplhost.com (gitolite.debian.net + [87.98.215.224]) + by arlo.cworth.org (Postfix) with ESMTPS id 284546DE179F + for ; Fri, 5 Jun 2015 10:30:57 -0700 (PDT) +Received: from remotemail by mx.xen14.node3324.gplhost.com with local (Exim + 4.80) (envelope-from ) + id 1Z0vRe-0002nz-Th; Fri, 05 Jun 2015 17:30:14 +0000 +Received: (nullmailer pid 24256 invoked by uid 1000); Fri, 05 Jun 2015 + 17:28:42 -0000 +From: David Bremner +To: notmuch@notmuchmail.org +Subject: [PATCH 5/6] cli: add global option "--db-revision" +Date: Fri, 5 Jun 2015 19:28:37 +0200 +Message-Id: <1433525318-23756-6-git-send-email-david@tethera.net> +X-Mailer: git-send-email 2.1.4 +In-Reply-To: <1433525318-23756-1-git-send-email-david@tethera.net> +References: <1432936375-astroid-4-0i1n6yczs2-1520@strange> + <1433525318-23756-1-git-send-email-david@tethera.net> +X-BeenThere: notmuch@notmuchmail.org +X-Mailman-Version: 2.1.18 +Precedence: list +List-Id: "Use and development of the notmuch mail system." + +List-Unsubscribe: , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: , + +X-List-Received-Date: Fri, 05 Jun 2015 17:30:59 -0000 + +The function notmuch_exit_if_unmatched_db_revision is split from +notmuch_process_shared_options because it needs an open notmuch +database. +--- + doc/man1/notmuch.rst | 10 ++++++++-- + notmuch-client.h | 4 ++++ + notmuch-compact.c | 4 ++++ + notmuch-config.c | 4 ++++ + notmuch-count.c | 2 ++ + notmuch-dump.c | 2 ++ + notmuch-insert.c | 2 ++ + notmuch-new.c | 3 ++- + notmuch-reply.c | 2 ++ + notmuch-restore.c | 2 ++ + notmuch-search.c | 2 ++ + notmuch-setup.c | 4 ++++ + notmuch-show.c | 2 ++ + notmuch-tag.c | 2 ++ + notmuch.c | 18 ++++++++++++++++++ + test/T570-revision-tracking.sh | 26 ++++++++++++++++++++++++++ + test/random-corpus.c | 2 ++ + 17 files changed, 88 insertions(+), 3 deletions(-) + +diff --git a/doc/man1/notmuch.rst b/doc/man1/notmuch.rst +index ae0461a..b3f75a4 100644 +--- a/doc/man1/notmuch.rst ++++ b/doc/man1/notmuch.rst +@@ -49,9 +49,15 @@ Supported global options for ``notmuch`` include + Specify the configuration file to use. This overrides any + configuration file specified by ${NOTMUCH\_CONFIG}. + ++ ``--db-revision=UUID`` ++ Enforce that the database revision is UUID. This is useful to ++ detect rollover in modification counts on messages. You can ++ find this UUID in the first column of output from ++ ``notmuch count --output=modifications`` ++ + All global options except ``--config`` can also be specified after the +-command. For example, ``notmuch subcommand --version`` is equivalent to +-``notmuch --version subcommand``. ++command. For example, ``notmuch subcommand --db-revision`` is ++equivalent to ``notmuch --db-revision subcommand``. + + COMMANDS + ======== +diff --git a/notmuch-client.h b/notmuch-client.h +index 78680aa..d3fab21 100644 +--- a/notmuch-client.h ++++ b/notmuch-client.h +@@ -466,7 +466,11 @@ notmuch_database_dump (notmuch_database_t *notmuch, + notmuch_bool_t gzip_output); + + #include "command-line-arguments.h" ++ ++extern char *notmuch_requested_db_revision; + extern const notmuch_opt_desc_t notmuch_shared_options []; ++void notmuch_exit_if_unmatched_db_revision (notmuch_database_t *notmuch); ++ + void notmuch_process_shared_options (const char* subcommand_name); + int notmuch_minimal_options (const char* subcommand_name, + int argc, char **argv); +diff --git a/notmuch-compact.c b/notmuch-compact.c +index 5be551d..3da4bfb 100644 +--- a/notmuch-compact.c ++++ b/notmuch-compact.c +@@ -46,6 +46,10 @@ notmuch_compact_command (notmuch_config_t *config, int argc, char *argv[]) + if (opt_index < 0) + return EXIT_FAILURE; + ++ if (notmuch_requested_db_revision) ++ fprintf (stderr, "Warning: ignoring --db-revision=%s\n", ++ notmuch_requested_db_revision); ++ + notmuch_process_shared_options (argv[0]); + + if (! quiet) +diff --git a/notmuch-config.c b/notmuch-config.c +index 9348278..f1826e4 100644 +--- a/notmuch-config.c ++++ b/notmuch-config.c +@@ -878,6 +878,10 @@ notmuch_config_command (notmuch_config_t *config, int argc, char *argv[]) + if (opt_index < 0) + return EXIT_FAILURE; + ++ if (notmuch_requested_db_revision) ++ fprintf (stderr, "Warning: ignoring --db-revision=%s\n", ++ notmuch_requested_db_revision); ++ + /* skip at least subcommand argument */ + argc-= opt_index; + argv+= opt_index; +diff --git a/notmuch-count.c b/notmuch-count.c +index 7c61ccb..dda85b5 100644 +--- a/notmuch-count.c ++++ b/notmuch-count.c +@@ -191,6 +191,8 @@ notmuch_count_command (notmuch_config_t *config, int argc, char *argv[]) + NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) + return EXIT_FAILURE; + ++ notmuch_exit_if_unmatched_db_revision (notmuch); ++ + query_str = query_string_from_args (config, argc-opt_index, argv+opt_index); + if (query_str == NULL) { + fprintf (stderr, "Out of memory.\n"); +diff --git a/notmuch-dump.c b/notmuch-dump.c +index fab22bd..9c0b82d 100644 +--- a/notmuch-dump.c ++++ b/notmuch-dump.c +@@ -215,6 +215,8 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[]) + NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) + return EXIT_FAILURE; + ++ notmuch_exit_if_unmatched_db_revision (notmuch); ++ + char *output_file_name = NULL; + int opt_index; + +diff --git a/notmuch-insert.c b/notmuch-insert.c +index c277d62..42d346f 100644 +--- a/notmuch-insert.c ++++ b/notmuch-insert.c +@@ -536,6 +536,8 @@ notmuch_insert_command (notmuch_config_t *config, int argc, char *argv[]) + NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) + return EXIT_FAILURE; + ++ notmuch_exit_if_unmatched_db_revision (notmuch); ++ + /* Write the message to the Maildir new directory. */ + newpath = maildir_write_new (config, STDIN_FILENO, maildir); + if (! newpath) { +diff --git a/notmuch-new.c b/notmuch-new.c +index 8ff1ade..2064a86 100644 +--- a/notmuch-new.c ++++ b/notmuch-new.c +@@ -995,10 +995,11 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[]) + fputs (status_string, stderr); + free (status_string); + } +- + return EXIT_FAILURE; + } + ++ notmuch_exit_if_unmatched_db_revision (notmuch); ++ + if (notmuch_database_needs_upgrade (notmuch)) { + time_t now = time (NULL); + struct tm *gm_time = gmtime (&now); +diff --git a/notmuch-reply.c b/notmuch-reply.c +index 4464741..52e0d9b 100644 +--- a/notmuch-reply.c ++++ b/notmuch-reply.c +@@ -831,6 +831,8 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[]) + NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) + return EXIT_FAILURE; + ++ notmuch_exit_if_unmatched_db_revision (notmuch); ++ + query = notmuch_query_create (notmuch, query_string); + if (query == NULL) { + fprintf (stderr, "Out of memory\n"); +diff --git a/notmuch-restore.c b/notmuch-restore.c +index 2a534dc..3e96aa8 100644 +--- a/notmuch-restore.c ++++ b/notmuch-restore.c +@@ -165,6 +165,8 @@ notmuch_restore_command (notmuch_config_t *config, int argc, char *argv[]) + } + + notmuch_process_shared_options (argv[0]); ++ notmuch_exit_if_unmatched_db_revision (notmuch); ++ + name_for_error = input_file_name ? input_file_name : "stdin"; + + if (! accumulate) +diff --git a/notmuch-search.c b/notmuch-search.c +index b89a17e..919837c 100644 +--- a/notmuch-search.c ++++ b/notmuch-search.c +@@ -583,6 +583,8 @@ _notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int ar + return EXIT_FAILURE; + } + ++ notmuch_exit_if_unmatched_db_revision (ctx->notmuch); ++ + query_str = query_string_from_args (ctx->notmuch, argc, argv); + if (query_str == NULL) { + fprintf (stderr, "Out of memory.\n"); +diff --git a/notmuch-setup.c b/notmuch-setup.c +index 7dd5822..dffda81 100644 +--- a/notmuch-setup.c ++++ b/notmuch-setup.c +@@ -148,6 +148,10 @@ notmuch_setup_command (notmuch_config_t *config, + if (notmuch_minimal_options ("setup", argc, argv) < 0) + return EXIT_FAILURE; + ++ if (notmuch_requested_db_revision) ++ fprintf (stderr, "Warning: ignoring --db-revision=%s\n", ++ notmuch_requested_db_revision); ++ + if (notmuch_config_is_new (config)) + welcome_message_pre_setup (); + +diff --git a/notmuch-show.c b/notmuch-show.c +index b80933a..2535c8c 100644 +--- a/notmuch-show.c ++++ b/notmuch-show.c +@@ -1213,6 +1213,8 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) + NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) + return EXIT_FAILURE; + ++ notmuch_exit_if_unmatched_db_revision (notmuch); ++ + query = notmuch_query_create (notmuch, query_string); + if (query == NULL) { + fprintf (stderr, "Out of memory\n"); +diff --git a/notmuch-tag.c b/notmuch-tag.c +index 38d99aa..22446fe 100644 +--- a/notmuch-tag.c ++++ b/notmuch-tag.c +@@ -261,6 +261,8 @@ notmuch_tag_command (notmuch_config_t *config, int argc, char *argv[]) + NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much)) + return EXIT_FAILURE; + ++ notmuch_exit_if_unmatched_db_revision (notmuch); ++ + if (notmuch_config_get_maildir_synchronize_flags (config)) + tag_flags |= TAG_FLAG_MAILDIR_SYNC; + +diff --git a/notmuch.c b/notmuch.c +index c528dce..fab737c 100644 +--- a/notmuch.c ++++ b/notmuch.c +@@ -47,10 +47,12 @@ static int + _help_for (const char *topic); + + static notmuch_bool_t print_version = FALSE, print_help = FALSE; ++char *notmuch_requested_db_revision = NULL; + + const notmuch_opt_desc_t notmuch_shared_options [] = { + { NOTMUCH_OPT_BOOLEAN, &print_version, "version", 'v', 0 }, + { NOTMUCH_OPT_BOOLEAN, &print_help, "help", 'h', 0 }, ++ { NOTMUCH_OPT_STRING, ¬much_requested_db_revision, "db-revision", 'd', 0 }, + {0, 0, 0, 0, 0} + }; + +@@ -218,6 +220,22 @@ be supported in the future.\n", notmuch_format_version); + } + } + ++void ++notmuch_exit_if_unmatched_db_revision (notmuch_database_t *notmuch) ++{ ++ const char *uuid = NULL; ++ ++ if (!notmuch_requested_db_revision) ++ return; ++ IGNORE_RESULT (notmuch_database_get_revision (notmuch, &uuid)); ++ ++ if (strcmp (notmuch_requested_db_revision, uuid) != 0){ ++ fprintf (stderr, "Error: requested database revision %s does not match %s\n", ++ notmuch_requested_db_revision, uuid); ++ exit (1); ++ } ++} ++ + static void + exec_man (const char *page) + { +diff --git a/test/T570-revision-tracking.sh b/test/T570-revision-tracking.sh +index 062fd59..bb09bf6 100755 +--- a/test/T570-revision-tracking.sh ++++ b/test/T570-revision-tracking.sh +@@ -46,4 +46,30 @@ notmuch tag +a-random-tag-8743632 '*' + after=$(notmuch count --output=modifications '*' | cut -f2) + result=$(($before < $after)) + test_expect_equal 1 ${result} ++ ++notmuch count --output=modifications '*' | cut -f1 > UUID ++ ++test_expect_success 'search succeeds with correct db revision' \ ++ "notmuch search --db-revision=$(cat UUID) '*'" ++ ++test_expect_success 'db-revision works as global option ' \ ++ "notmuch --db-revision=$(cat UUID) search '*'" ++ ++test_expect_code 1 'db-revision works as global option II' \ ++ "notmuch --db-revision=this-is-no-uuid search '*'" ++ ++test_expect_code 1 'search fails with incorrect db revision' \ ++ "notmuch search --db-revision=this-is-no-uuid '*'" ++ ++test_expect_success 'show succeeds with correct db revision' \ ++ "notmuch show --db-revision=$(cat UUID) '*'" ++ ++test_expect_code 1 'show fails with incorrect db revision' \ ++ "notmuch show --db-revision=this-is-no-uuid '*'" ++ ++test_expect_success 'tag succeeds with correct db revision' \ ++ "notmuch tag --db-revision=$(cat UUID) +test '*'" ++ ++test_expect_code 1 'tag fails with incorrect db revision' \ ++ "notmuch show --db-revision=this-is-no-uuid '*' +test2" + test_done +diff --git a/test/random-corpus.c b/test/random-corpus.c +index b377eb4..542b453 100644 +--- a/test/random-corpus.c ++++ b/test/random-corpus.c +@@ -119,6 +119,8 @@ const notmuch_opt_desc_t notmuch_shared_options[] = { + { 0, 0, 0, 0, 0 } + }; + ++char *notmuch_requested_db_revision = NULL; ++ + void + notmuch_process_shared_options (unused (const char *dummy)) + { +-- +2.1.4 + -- 2.26.2