1 Return-Path: <bremner@tethera.net>
\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 EA22A6DE0173
\r
6 for <notmuch@notmuchmail.org>; Sun, 12 Jun 2016 18:06:16 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at cworth.org
\r
11 X-Spam-Status: No, score=-0.011 tagged_above=-999 required=5
\r
12 tests=[AWL=-0.000, SPF_PASS=-0.001, T_RP_MATCHES_RCVD=-0.01]
\r
14 Received: from arlo.cworth.org ([127.0.0.1])
\r
15 by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)
\r
16 with ESMTP id S2iLMys9U66d for <notmuch@notmuchmail.org>;
\r
17 Sun, 12 Jun 2016 18:06:08 -0700 (PDT)
\r
18 Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197])
\r
19 by arlo.cworth.org (Postfix) with ESMTPS id C46EA6DE0159
\r
20 for <notmuch@notmuchmail.org>; Sun, 12 Jun 2016 18:06:08 -0700 (PDT)
\r
21 Received: from remotemail by fethera.tethera.net with local (Exim 4.84)
\r
22 (envelope-from <bremner@tethera.net>)
\r
23 id 1bCGK9-0003wa-7e; Sun, 12 Jun 2016 21:05:53 -0400
\r
24 Received: (nullmailer pid 5680 invoked by uid 1000);
\r
25 Mon, 13 Jun 2016 01:06:04 -0000
\r
26 From: David Bremner <david@tethera.net>
\r
27 To: notmuch@notmuchmail.org
\r
28 Subject: [PATCH 7/8] CLI: add properties to dump output
\r
29 Date: Sun, 12 Jun 2016 22:05:54 -0300
\r
30 Message-Id: <1465779955-5539-8-git-send-email-david@tethera.net>
\r
31 X-Mailer: git-send-email 2.8.1
\r
32 In-Reply-To: <1465779955-5539-1-git-send-email-david@tethera.net>
\r
33 References: <1465779955-5539-1-git-send-email-david@tethera.net>
\r
35 Content-Type: text/plain; charset=UTF-8
\r
36 Content-Transfer-Encoding: 8bit
\r
37 X-BeenThere: notmuch@notmuchmail.org
\r
38 X-Mailman-Version: 2.1.20
\r
40 List-Id: "Use and development of the notmuch mail system."
\r
41 <notmuch.notmuchmail.org>
\r
42 List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,
\r
43 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
44 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>
\r
45 List-Post: <mailto:notmuch@notmuchmail.org>
\r
46 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
47 List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,
\r
48 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
49 X-List-Received-Date: Mon, 13 Jun 2016 01:06:17 -0000
\r
51 Part of providing extensibility via properties is to make sure that user
\r
52 data is not lost. Thus we need to be able to dump and restore
\r
55 doc/man1/notmuch-dump.rst | 18 ++++++---
\r
56 notmuch-client.h | 3 ++
\r
57 notmuch-dump.c | 85 +++++++++++++++++++++++++++++++++++++++----
\r
58 notmuch-new.c | 2 +-
\r
59 test/T610-message-property.sh | 21 +++++++++++
\r
60 5 files changed, 116 insertions(+), 13 deletions(-)
\r
62 diff --git a/doc/man1/notmuch-dump.rst b/doc/man1/notmuch-dump.rst
\r
63 index 94986a8..751850b 100644
\r
64 --- a/doc/man1/notmuch-dump.rst
\r
65 +++ b/doc/man1/notmuch-dump.rst
\r
66 @@ -71,7 +71,7 @@ Supported options for **dump** include
\r
67 characters. Note also that tags with spaces will not be
\r
68 correctly restored with this format.
\r
70 - ``--include=(config|tags)``
\r
71 + ``--include=(config|properties|tags)``
\r
73 Control what kind of metadata is included in the output.
\r
75 @@ -81,14 +81,22 @@ Supported options for **dump** include
\r
76 starts with "#@ ", followed by a space seperated key-value
\r
77 pair. Both key and value are hex encoded if needed.
\r
81 + Output per-message (key,value) metadata. Each line starts
\r
82 + with "#= ", followed by a message id, and a space seperated
\r
83 + list of key=value pairs. pair. Ids, keys and values are hex
\r
84 + encoded if needed.
\r
88 - Output per-message metadata, namely tags. See *format* above
\r
89 + Output per-message boolean metadata, namely tags. See *format* above
\r
90 for description of the output.
\r
92 - The default is to include both tags and configuration
\r
93 - information. As of version 2 of the dump format, there is a
\r
94 - header line of the following form
\r
95 + The default is to include all available types of data. The
\r
96 + option can be specified multiple times to select some subset. As
\r
97 + of version 2 of the dump format, there is a header line of the
\r
101 | #notmuch-dump <*format*>:<*version*> <*included*>
\r
102 diff --git a/notmuch-client.h b/notmuch-client.h
\r
103 index ebc092b..9ce2aef 100644
\r
104 --- a/notmuch-client.h
\r
105 +++ b/notmuch-client.h
\r
106 @@ -449,8 +449,11 @@ typedef enum dump_formats {
\r
107 typedef enum dump_includes {
\r
108 DUMP_INCLUDE_TAGS = 1,
\r
109 DUMP_INCLUDE_CONFIG = 2,
\r
110 + DUMP_INCLUDE_PROPERTIES = 4
\r
113 +#define DUMP_INCLUDE_DEFAULT (DUMP_INCLUDE_TAGS | DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_PROPERTIES)
\r
115 #define NOTMUCH_DUMP_VERSION 2
\r
118 diff --git a/notmuch-dump.c b/notmuch-dump.c
\r
119 index d80ed8b8..ec82660 100644
\r
120 --- a/notmuch-dump.c
\r
121 +++ b/notmuch-dump.c
\r
122 @@ -69,12 +69,77 @@ database_dump_config (notmuch_database_t *notmuch, gzFile output)
\r
124 print_dump_header (gzFile output, int output_format, int include)
\r
126 - gzprintf (output, "#notmuch-dump %s:%d %s%s%s\n",
\r
127 + const char *sep = "";
\r
129 + gzprintf (output, "#notmuch-dump %s:%d ",
\r
130 (output_format == DUMP_FORMAT_SUP) ? "sup" : "batch-tag",
\r
131 - NOTMUCH_DUMP_VERSION,
\r
132 - (include & DUMP_INCLUDE_CONFIG) ? "config" : "",
\r
133 - (include & DUMP_INCLUDE_TAGS) && (include & DUMP_INCLUDE_CONFIG) ? "," : "",
\r
134 - (include & DUMP_INCLUDE_TAGS) ? "tags" : "");
\r
135 + NOTMUCH_DUMP_VERSION);
\r
137 + if (include & DUMP_INCLUDE_CONFIG) {
\r
138 + gzputs (output, "config");
\r
141 + if (include & DUMP_INCLUDE_PROPERTIES) {
\r
142 + gzprintf (output, "%sproperties",sep);
\r
145 + if (include & DUMP_INCLUDE_TAGS) {
\r
146 + gzprintf (output, "%sproperties",sep);
\r
148 + gzputs (output, "\n");
\r
152 +dump_properties_message (void *ctx,
\r
153 + notmuch_message_t *message,
\r
155 + char **buffer_p, size_t *size_p)
\r
157 + const char *message_id;
\r
158 + notmuch_message_properties_t *list;
\r
159 + notmuch_bool_t first = TRUE;
\r
161 + message_id = notmuch_message_get_message_id (message);
\r
163 + if (strchr (message_id, '\n')) {
\r
164 + fprintf (stderr, "Warning: skipping message id containing line break: \"%s\"\n", message_id);
\r
168 + for (list = notmuch_message_get_properties (message, "", FALSE);
\r
169 + notmuch_message_properties_valid (list); notmuch_message_properties_move_to_next (list)) {
\r
170 + const char *key, *val;
\r
173 + if (hex_encode (ctx, message_id, buffer_p, size_p) != HEX_SUCCESS) {
\r
174 + fprintf (stderr, "Error: failed to hex-encode message-id %s\n", message_id);
\r
177 + gzprintf (output, "#= %s", *buffer_p);
\r
181 + key = notmuch_message_properties_key (list);
\r
182 + val = notmuch_message_properties_value (list);
\r
184 + if (hex_encode (ctx, key, buffer_p, size_p) != HEX_SUCCESS) {
\r
185 + fprintf (stderr, "Error: failed to hex-encode key %s\n", key);
\r
188 + gzprintf (output, " %s", *buffer_p);
\r
190 + if (hex_encode (ctx, val, buffer_p, size_p) != HEX_SUCCESS) {
\r
191 + fprintf (stderr, "Error: failed to hex-encode value %s\n", val);
\r
194 + gzprintf (output, "=%s", *buffer_p);
\r
196 + notmuch_message_properties_destroy (list);
\r
199 + gzprintf (output, "\n", *buffer_p);
\r
205 @@ -159,7 +224,7 @@ database_dump_file (notmuch_database_t *notmuch, gzFile output,
\r
206 return EXIT_FAILURE;
\r
209 - if (! (include & DUMP_INCLUDE_TAGS))
\r
210 + if (! (include & (DUMP_INCLUDE_TAGS | DUMP_INCLUDE_PROPERTIES)))
\r
211 return EXIT_SUCCESS;
\r
214 @@ -189,6 +254,11 @@ database_dump_file (notmuch_database_t *notmuch, gzFile output,
\r
215 &buffer, &buffer_size))
\r
216 return EXIT_FAILURE;
\r
218 + if ((include & DUMP_INCLUDE_PROPERTIES) &&
\r
219 + dump_properties_message (notmuch, message, output,
\r
220 + &buffer, &buffer_size))
\r
221 + return EXIT_FAILURE;
\r
223 notmuch_message_destroy (message);
\r
226 @@ -312,6 +382,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
\r
228 { NOTMUCH_OPT_KEYWORD_FLAGS, &include, "include", 'I',
\r
229 (notmuch_keyword_t []){ { "config", DUMP_INCLUDE_CONFIG },
\r
230 + { "properties", DUMP_INCLUDE_PROPERTIES },
\r
231 { "tags", DUMP_INCLUDE_TAGS} } },
\r
232 { NOTMUCH_OPT_STRING, &output_file_name, "output", 'o', 0 },
\r
233 { NOTMUCH_OPT_BOOLEAN, &gzip_output, "gzip", 'z', 0 },
\r
234 @@ -326,7 +397,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
\r
235 notmuch_process_shared_options (argv[0]);
\r
238 - include = DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS;
\r
239 + include = DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS | DUMP_INCLUDE_PROPERTIES;
\r
241 if (opt_index < argc) {
\r
242 query_str = query_string_from_args (notmuch, argc - opt_index, argv + opt_index);
\r
243 diff --git a/notmuch-new.c b/notmuch-new.c
\r
244 index 799fec2..c55dea7 100644
\r
245 --- a/notmuch-new.c
\r
246 +++ b/notmuch-new.c
\r
247 @@ -1042,7 +1042,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, char *argv[])
\r
250 if (notmuch_database_dump (notmuch, backup_name, "",
\r
251 - DUMP_FORMAT_BATCH_TAG, DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS, TRUE)) {
\r
252 + DUMP_FORMAT_BATCH_TAG, DUMP_INCLUDE_DEFAULT, TRUE)) {
\r
253 fprintf (stderr, "Backup failed. Aborting upgrade.");
\r
254 return EXIT_FAILURE;
\r
256 diff --git a/test/T610-message-property.sh b/test/T610-message-property.sh
\r
257 index b5ddb7a..e594979 100755
\r
258 --- a/test/T610-message-property.sh
\r
259 +++ b/test/T610-message-property.sh
\r
260 @@ -89,6 +89,17 @@ testkey2 = NULL
\r
262 test_expect_equal_file EXPECTED OUTPUT
\r
264 +test_begin_subtest "notmuch_message_remove_all_properties"
\r
265 +cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
\r
266 +EXPECT0(notmuch_message_remove_all_properties (message));
\r
267 +print_properties (message, "", FALSE);
\r
269 +cat <<'EOF' >EXPECTED
\r
273 +test_expect_equal_file EXPECTED OUTPUT
\r
275 test_begin_subtest "notmuch_message_get_properties: empty list"
\r
276 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
\r
278 @@ -188,4 +199,14 @@ cat <<'EOF' >EXPECTED
\r
280 test_expect_equal_file EXPECTED OUTPUT
\r
282 +test_begin_subtest "dump message properties"
\r
283 +cat <<EOF > PROPERTIES
\r
284 +#= 4EFC743A.3060609@april.org fancy%20key%20with%20%c3%a1cc%c3%a8nts=import%20value%20with%20= testkey1=alice testkey1=bob testkey1=testvalue1 testkey1=testvalue2 testkey3=alice3 testkey3=bob3 testkey3=testvalue3
\r
286 +cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
\r
287 +EXPECT0(notmuch_message_add_property (message, "fancy key with áccènts", "import value with ="));
\r
289 +notmuch dump | grep '^#=' > OUTPUT
\r
290 +test_expect_equal_file PROPERTIES OUTPUT
\r