This option causes notmuch insert to fail (with exit code 3) on failure
to index the message, or failure to set the tags on the message, or if
closing (flushing) the database fails.  Failure to sync tags to flags
has no effect.
---
 notmuch-insert.c | 57 +++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 17 deletions(-)

diff --git a/notmuch-insert.c b/notmuch-insert.c
index 29d82c9..83257f4 100644
--- a/notmuch-insert.c
+++ b/notmuch-insert.c
@@ -31,7 +31,8 @@
 enum {
     INSERT_EXIT_SUCCESS = 0,
     INSERT_EXIT_FAILURE = 1,
-    INSERT_EXIT_FAILED_WRITE = 2
+    INSERT_EXIT_FAILED_WRITE = 2,
+    INSERT_EXIT_FAILED_INDEX = 3
 };

 static volatile sig_atomic_t interrupted;
@@ -298,13 +299,15 @@ copy_stdin (int fdin, int fdout)
 }

 /* Add the specified message file to the notmuch database, applying tags.
- * The file is renamed to encode notmuch tags as maildir flags. */
-static void
+ * If synchronize_flags is set then file is renamed to encode notmuch tags as
+ * maildir flags. */
+static notmuch_bool_t
 add_file_to_database (notmuch_database_t *notmuch, const char *path,
                      tag_op_list_t *tag_ops, notmuch_bool_t synchronize_flags)
 {
     notmuch_message_t *message;
     notmuch_status_t status;
+    notmuch_status_t sync;

     status = notmuch_database_add_message (notmuch, path, &message);
     switch (status) {
@@ -324,23 +327,28 @@ add_file_to_database (notmuch_database_t *notmuch, const 
char *path,
     case NOTMUCH_STATUS_LAST_STATUS:
        fprintf (stderr, "Error: failed to add `%s' to notmuch database: %s\n",
                 path, notmuch_status_to_string (status));
-       return;
+       return FALSE;
     }

     if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) {
        /* Don't change tags of an existing message. */
-       if (synchronize_flags) {
-           status = notmuch_message_tags_to_maildir_flags (message);
-           if (status != NOTMUCH_STATUS_SUCCESS)
-               fprintf (stderr, "Error: failed to sync tags to maildir 
flags\n");
-       }
+       status = NOTMUCH_STATUS_SUCCESS;
     } else {
-       tag_op_flag_t flags = synchronize_flags ? TAG_FLAG_MAILDIR_SYNC : 0;
+       status = tag_op_list_apply (message, tag_ops, 0);
+    }

-       tag_op_list_apply (message, tag_ops, flags);
+    /* Call notmuch_message_tags_to_maildir_flags directly instead of doing it
+     * as part of tag_op_list_apply. For --must-index we want to succeed if
+     * tagging succeeds, but disregard whether synchronizing flags fails. */
+    if (status == NOTMUCH_STATUS_SUCCESS && synchronize_flags) {
+       sync = notmuch_message_tags_to_maildir_flags (message);
+       if (sync != NOTMUCH_STATUS_SUCCESS)
+           fprintf (stderr, "Error: failed to sync tags to maildir flags\n");
     }

     notmuch_message_destroy (message);
+
+    return (status == NOTMUCH_STATUS_SUCCESS);
 }

 static notmuch_bool_t
@@ -400,15 +408,19 @@ notmuch_insert_command (notmuch_config_t *config, int 
argc, char *argv[])
     char *query_string = NULL;
     const char *folder = NULL;
     notmuch_bool_t create_folder = FALSE;
+    notmuch_bool_t must_index = FALSE;
     notmuch_bool_t synchronize_flags;
     const char *maildir;
     char *newpath;
     int opt_index;
     unsigned int i;
+    notmuch_bool_t indexed;
+    notmuch_status_t status;

     notmuch_opt_desc_t options[] = {
        { NOTMUCH_OPT_STRING, &folder, "folder", 0, 0 },
        { NOTMUCH_OPT_BOOLEAN, &create_folder, "create-folder", 0, 0 },
+       { NOTMUCH_OPT_BOOLEAN, &must_index, "must-index", 0, 0 },
        { NOTMUCH_OPT_END, 0, 0, 0, 0 }
     };

@@ -485,12 +497,23 @@ notmuch_insert_command (notmuch_config_t *config, int 
argc, char *argv[])
        return INSERT_EXIT_FAILED_WRITE;
     }

-    /* Add the message to the index.
-     * Even if adding the message to the notmuch database fails,
-     * the message is on disk and we consider the delivery completed. */
-    add_file_to_database (notmuch, newpath, tag_ops,
+    /* Add the message to the index. */
+    indexed = add_file_to_database (notmuch, newpath, tag_ops,
                                    synchronize_flags);

-    notmuch_database_destroy (notmuch);
-    return INSERT_EXIT_SUCCESS;
+    /* If must_index is FALSE then succeed as the message is on disk.
+     * Otherwise message indexing and tagging must succeed, and the database
+     * must be flushed. Don't flush the database if there was an earlier
+     * error, so as to abandon the transaction (is there a better way?) */
+    if (! must_index) {
+       notmuch_database_destroy (notmuch);
+       return INSERT_EXIT_SUCCESS;
+    }
+    if (indexed) {
+       status = notmuch_database_destroy (notmuch);
+       if (status == NOTMUCH_STATUS_SUCCESS)
+           return INSERT_EXIT_SUCCESS;
+    }
+    unlink (newpath);
+    return INSERT_EXIT_FAILED_INDEX;
 }
-- 
1.8.4

Reply via email to