unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* WIP: add --output=lastmod to notmuch tag
@ 2022-01-27 23:07 David Bremner
  2022-01-27 23:07 ` [PATCH 1/2] cli/tag: add --output={none,lastmod} argument David Bremner
  2022-01-27 23:07 ` [PATCH 2/2] WIP: support tag --output=lastmod David Bremner
  0 siblings, 2 replies; 3+ messages in thread
From: David Bremner @ 2022-01-27 23:07 UTC (permalink / raw)
  To: notmuch


This gives a compact and atomic (thanks to holding a write lock) way
of saving a tag change. It should probably also output the database
uuid, so we can catch mistakes like trying to undo a change with a
compaction in between.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] cli/tag: add --output={none,lastmod} argument
  2022-01-27 23:07 WIP: add --output=lastmod to notmuch tag David Bremner
@ 2022-01-27 23:07 ` David Bremner
  2022-01-27 23:07 ` [PATCH 2/2] WIP: support tag --output=lastmod David Bremner
  1 sibling, 0 replies; 3+ messages in thread
From: David Bremner @ 2022-01-27 23:07 UTC (permalink / raw)
  To: notmuch

This commit only changes the command line parsing, no new output is
added.
---
 notmuch-tag.c        | 10 ++++++++++
 test/T150-tagging.sh | 20 ++++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/notmuch-tag.c b/notmuch-tag.c
index 71ff06bf..c6ac51d2 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -22,6 +22,11 @@
 #include "tag-util.h"
 #include "string-util.h"
 
+typedef enum {
+    OUTPUT_NONE	= 0,
+    OUTPUT_LASTMOD	= 1 << 0,
+} output_t;
+
 static volatile sig_atomic_t interrupted;
 
 static void
@@ -228,6 +233,7 @@ notmuch_tag_command (notmuch_database_t *notmuch, int argc, char *argv[])
     const char *input_file_name = NULL;
     int opt_index;
     int ret;
+    int output = OUTPUT_NONE;
     notmuch_bool_t synchronize_flags;
 
     /* Set up our handler for SIGINT */
@@ -240,6 +246,10 @@ notmuch_tag_command (notmuch_database_t *notmuch, int argc, char *argv[])
     notmuch_opt_desc_t options[] = {
 	{ .opt_bool = &batch, .name = "batch" },
 	{ .opt_string = &input_file_name, .name = "input" },
+	{ .opt_keyword = &output, .name = "output", .keywords =
+	      (notmuch_keyword_t []){ { "none", OUTPUT_NONE },
+				      { "lastmod", OUTPUT_LASTMOD },
+				      { 0, 0 } } },
 	{ .opt_bool = &remove_all, .name = "remove-all" },
 	{ .opt_inherit = notmuch_shared_options },
 	{ }
diff --git a/test/T150-tagging.sh b/test/T150-tagging.sh
index 1a2fd77e..ce33dade 100755
--- a/test/T150-tagging.sh
+++ b/test/T150-tagging.sh
@@ -48,6 +48,12 @@ test_expect_equal "$output" "\
 thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; One (inbox tag1 unread)
 thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag1 unread)"
 
+test_begin_subtest "--output=none"
+output=$(notmuch tag --output=none +tag7 '*' 2>&1)
+notmuch tag -tag7 '*'
+test_expect_equal "$output" ""
+
+
 test_begin_subtest "Remove all"
 notmuch tag --remove-all One
 notmuch tag --remove-all +tag5 +tag6 +unread Two
@@ -124,6 +130,13 @@ notmuch search \* | notmuch_search_sanitize > OUTPUT
 notmuch restore --format=batch-tag < backup.tags
 test_expect_equal_file batch.expected OUTPUT
 
+test_begin_subtest "--input --output=none"
+notmuch dump --format=batch-tag > backup.tags
+notmuch tag --input=batch.in --output=none > OUTPUT
+notmuch search \* | notmuch_search_sanitize >> OUTPUT
+notmuch restore --format=batch-tag < backup.tags
+test_expect_equal_file batch.expected OUTPUT
+
 test_begin_subtest "--batch --input"
 notmuch dump --format=batch-tag > backup.tags
 notmuch tag --batch --input=batch.in
@@ -131,6 +144,13 @@ notmuch search \* | notmuch_search_sanitize > OUTPUT
 notmuch restore --format=batch-tag < backup.tags
 test_expect_equal_file batch.expected OUTPUT
 
+test_begin_subtest "--batch --input --output=none"
+notmuch dump --format=batch-tag > backup.tags
+notmuch tag --batch --input=batch.in --output=none > OUTPUT
+notmuch search \* | notmuch_search_sanitize >> OUTPUT
+notmuch restore --format=batch-tag < backup.tags
+test_expect_equal_file batch.expected OUTPUT
+
 test_begin_subtest "--batch --input --remove-all"
 notmuch dump --format=batch-tag > backup.tags
 notmuch tag +foo +bar -- One
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] WIP: support tag --output=lastmod
  2022-01-27 23:07 WIP: add --output=lastmod to notmuch tag David Bremner
  2022-01-27 23:07 ` [PATCH 1/2] cli/tag: add --output={none,lastmod} argument David Bremner
@ 2022-01-27 23:07 ` David Bremner
  1 sibling, 0 replies; 3+ messages in thread
From: David Bremner @ 2022-01-27 23:07 UTC (permalink / raw)
  To: notmuch

needs documentation, possibly more tests.

output format subject to change.

See the tests for examples of how this could be used in an undo facility
---
 notmuch-tag.c        | 20 +++++++++++++++-----
 test/T150-tagging.sh | 28 ++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/notmuch-tag.c b/notmuch-tag.c
index c6ac51d2..f7344b8d 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -124,12 +124,13 @@ _optimize_tag_query (void *ctx, const char *orig_query_string,
  */
 static int
 tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,
-	   tag_op_list_t *tag_ops, tag_op_flag_t flags)
+	   tag_op_list_t *tag_ops, tag_op_flag_t flags, int output)
 {
     notmuch_query_t *query;
     notmuch_messages_t *messages;
     notmuch_message_t *message;
     notmuch_status_t status;
+    unsigned long before;
 
     int ret = NOTMUCH_STATUS_SUCCESS;
 
@@ -159,6 +160,10 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,
     if (print_status_query ("notmuch tag", query, status))
 	return status;
 
+    if (output == OUTPUT_LASTMOD) {
+	before = notmuch_database_get_revision (notmuch, NULL);
+    }
+
     for (;
 	 notmuch_messages_valid (messages) && ! interrupted;
 	 notmuch_messages_move_to_next (messages)) {
@@ -171,12 +176,17 @@ tag_query (void *ctx, notmuch_database_t *notmuch, const char *query_string,
 
     notmuch_query_destroy (query);
 
+    if (output == OUTPUT_LASTMOD) {
+	unsigned long after = notmuch_database_get_revision (notmuch, NULL);
+	printf ("lastmod:%lu..%lu\n", before + 1, after);
+    }
+
     return ret || interrupted;
 }
 
 static int
 tag_file (void *ctx, notmuch_database_t *notmuch, tag_op_flag_t flags,
-	  FILE *input)
+	  FILE *input, int output)
 {
     char *line = NULL;
     char *query_string = NULL;
@@ -209,7 +219,7 @@ tag_file (void *ctx, notmuch_database_t *notmuch, tag_op_flag_t flags,
 	if (ret < 0)
 	    break;
 
-	ret = tag_query (ctx, notmuch, query_string, tag_ops, flags);
+	ret = tag_query (ctx, notmuch, query_string, tag_ops, flags, output);
 	if (ret)
 	    break;
     }
@@ -314,9 +324,9 @@ notmuch_tag_command (notmuch_database_t *notmuch, int argc, char *argv[])
 	tag_flags |= TAG_FLAG_REMOVE_ALL;
 
     if (batch)
-	ret = tag_file (notmuch, notmuch, tag_flags, input);
+	ret = tag_file (notmuch, notmuch, tag_flags, input, output);
     else
-	ret = tag_query (notmuch, notmuch, query_string, tag_ops, tag_flags);
+	ret = tag_query (notmuch, notmuch, query_string, tag_ops, tag_flags, output);
 
     notmuch_database_destroy (notmuch);
 
diff --git a/test/T150-tagging.sh b/test/T150-tagging.sh
index ce33dade..27b28e1e 100755
--- a/test/T150-tagging.sh
+++ b/test/T150-tagging.sh
@@ -53,6 +53,18 @@ output=$(notmuch tag --output=none +tag7 '*' 2>&1)
 notmuch tag -tag7 '*'
 test_expect_equal "$output" ""
 
+test_begin_subtest "--output=lastmod produces range"
+output=$(notmuch tag --output=lastmod +tag7 '*' | sed 's/[0-9][0-9]*/num/g' )
+notmuch tag -tag7 '*'
+test_expect_equal "$output" "lastmod:num..num"
+
+test_begin_subtest "--output=lastmod provides undo"
+notmuch dump > BEFORE
+tag=${RANDOM}
+range=$(notmuch tag --output=lastmod "+$tag" '*')
+notmuch tag "-$tag" "$range"
+notmuch dump > AFTER
+test_expect_equal_file BEFORE AFTER
 
 test_begin_subtest "Remove all"
 notmuch tag --remove-all One
@@ -118,6 +130,13 @@ cat > batch.in <<EOF
 -tag5 +tag6 Two
 EOF
 
+# partial input for use in undoing above changes
+cat > restore.in <<EOF
+-%40 +tag5 -tag6 -- 
+-tag1 +tag1 +tag4 +tag4 --
++tag5 -tag6 -- 
+EOF
+
 cat > batch.expected <<EOF
 thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; One (@ inbox tag6 unread)
 thread:XXX   2001-01-05 [1/1] Notmuch Test Suite; Two (inbox tag4 tag6 unread)
@@ -151,6 +170,15 @@ notmuch search \* | notmuch_search_sanitize >> OUTPUT
 notmuch restore --format=batch-tag < backup.tags
 test_expect_equal_file batch.expected OUTPUT
 
+backup_database
+test_begin_subtest "--batch --input --output=lastmod"
+notmuch dump > EXPECTED
+notmuch tag --batch --input=batch.in --output=lastmod > ranges
+paste -d ' ' restore.in ranges | notmuch tag --batch
+notmuch dump > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
 test_begin_subtest "--batch --input --remove-all"
 notmuch dump --format=batch-tag > backup.tags
 notmuch tag +foo +bar -- One
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-01-27 23:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-27 23:07 WIP: add --output=lastmod to notmuch tag David Bremner
2022-01-27 23:07 ` [PATCH 1/2] cli/tag: add --output={none,lastmod} argument David Bremner
2022-01-27 23:07 ` [PATCH 2/2] WIP: support tag --output=lastmod David Bremner

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).