Re: [PATCH] emacs: wash: make word-wrap bound message width
[notmuch-archives.git] / 73 / f83b8238efb1dbd4460ca05b6412a74976e14a
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 3E88D6DE091B\r
6  for <notmuch@notmuchmail.org>; Sat,  6 Aug 2016 06:53:07 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at cworth.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.004\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.004 tagged_above=-999 required=5\r
12  tests=[AWL=-0.005, HEADER_FROM_DIFFERENT_DOMAINS=0.001]\r
13  autolearn=disabled\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 tC0-fn3Idznt for <notmuch@notmuchmail.org>;\r
17  Sat,  6 Aug 2016 06:52:59 -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 816EE6DE02AF\r
20  for <notmuch@notmuchmail.org>; Sat,  6 Aug 2016 06:52:55 -0700 (PDT)\r
21 Received: from remotemail by fethera.tethera.net with local (Exim 4.84_2)\r
22  (envelope-from <bremner@tesseract.cs.unb.ca>)\r
23  id 1bW22I-0007Du-Fu; Sat, 06 Aug 2016 09:53:10 -0400\r
24 Received: (nullmailer pid 4137 invoked by uid 1000);\r
25  Sat, 06 Aug 2016 13:52:44 -0000\r
26 From: David Bremner <david@tethera.net>\r
27 To: notmuch@notmuchmail.org\r
28 Subject: [PATCH 7/9] CLI: add properties to dump output\r
29 Date: Sat,  6 Aug 2016 22:52:37 +0900\r
30 Message-Id: <1470491559-3946-8-git-send-email-david@tethera.net>\r
31 X-Mailer: git-send-email 2.8.1\r
32 In-Reply-To: <1470491559-3946-1-git-send-email-david@tethera.net>\r
33 References: <1470491559-3946-1-git-send-email-david@tethera.net>\r
34 MIME-Version: 1.0\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
39 Precedence: list\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: Sat, 06 Aug 2016 13:53:07 -0000\r
50 \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
53 properties.\r
54 ---\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
61 \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
69  \r
70 -    ``--include=(config|tags)``\r
71 +    ``--include=(config|properties|tags)``\r
72  \r
73      Control what kind of metadata is included in the output.\r
74  \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
78  \r
79 +      **properties**\r
80 +\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
85 +\r
86        **tags**\r
87  \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
91  \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
98 +      following form\r
99  \r
100        |\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
111  } dump_include_t;\r
112  \r
113 +#define DUMP_INCLUDE_DEFAULT (DUMP_INCLUDE_TAGS | DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_PROPERTIES)\r
114 +\r
115  #define NOTMUCH_DUMP_VERSION 2\r
116  \r
117  int\r
118 diff --git a/notmuch-dump.c b/notmuch-dump.c\r
119 index d80ed8b8..e7965ce 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
123  static void\r
124  print_dump_header (gzFile output, int output_format, int include)\r
125  {\r
126 -    gzprintf (output, "#notmuch-dump %s:%d %s%s%s\n",\r
127 +    const char *sep = "";\r
128 +\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
136 +\r
137 +    if (include & DUMP_INCLUDE_CONFIG) {\r
138 +       gzputs (output, "config");\r
139 +       sep = ",";\r
140 +    }\r
141 +    if (include & DUMP_INCLUDE_PROPERTIES) {\r
142 +       gzprintf (output, "%sproperties", sep);\r
143 +       sep = ",";\r
144 +    }\r
145 +    if (include & DUMP_INCLUDE_TAGS) {\r
146 +       gzprintf (output, "%sproperties", sep);\r
147 +    }\r
148 +    gzputs (output, "\n");\r
149 +}\r
150 +\r
151 +static int\r
152 +dump_properties_message (void *ctx,\r
153 +                        notmuch_message_t *message,\r
154 +                        gzFile output,\r
155 +                        char **buffer_p, size_t *size_p)\r
156 +{\r
157 +    const char *message_id;\r
158 +    notmuch_message_properties_t *list;\r
159 +    notmuch_bool_t first = TRUE;\r
160 +\r
161 +    message_id = notmuch_message_get_message_id (message);\r
162 +\r
163 +    if (strchr (message_id, '\n')) {\r
164 +       fprintf (stderr, "Warning: skipping message id containing line break: \"%s\"\n", message_id);\r
165 +       return 0;\r
166 +    }\r
167 +\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
171 +\r
172 +       if (first) {\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
175 +               return 1;\r
176 +           }\r
177 +           gzprintf (output, "#= %s", *buffer_p);\r
178 +           first = FALSE;\r
179 +       }\r
180 +\r
181 +       key = notmuch_message_properties_key (list);\r
182 +       val = notmuch_message_properties_value (list);\r
183 +\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
186 +           return 1;\r
187 +       }\r
188 +       gzprintf (output, " %s", *buffer_p);\r
189 +\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
192 +           return 1;\r
193 +       }\r
194 +       gzprintf (output, "=%s", *buffer_p);\r
195 +    }\r
196 +    notmuch_message_properties_destroy (list);\r
197 +\r
198 +    if (! first)\r
199 +       gzprintf (output, "\n", *buffer_p);\r
200 +\r
201 +    return 0;\r
202  }\r
203  \r
204  static int\r
205 @@ -159,7 +224,7 @@ database_dump_file (notmuch_database_t *notmuch, gzFile output,\r
206             return EXIT_FAILURE;\r
207      }\r
208  \r
209 -    if (! (include & DUMP_INCLUDE_TAGS))\r
210 +    if (! (include & (DUMP_INCLUDE_TAGS | DUMP_INCLUDE_PROPERTIES)))\r
211         return EXIT_SUCCESS;\r
212  \r
213      if (! query_str)\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
217  \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
222 +\r
223         notmuch_message_destroy (message);\r
224      }\r
225  \r
226 @@ -312,6 +382,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])\r
227                                   { 0, 0 } } },\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
236  \r
237      if (include == 0)\r
238 -       include = DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS;\r
239 +       include = DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS | DUMP_INCLUDE_PROPERTIES;\r
240  \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
248             }\r
249  \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
255             }\r
256 diff --git a/test/T610-message-property.sh b/test/T610-message-property.sh\r
257 index b5ddb7a..a9b76de 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
261  EOF\r
262  test_expect_equal_file EXPECTED OUTPUT\r
263  \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, NULL));\r
267 +print_properties (message, "", FALSE);\r
268 +EOF\r
269 +cat <<'EOF' >EXPECTED\r
270 +== stdout ==\r
271 +== stderr ==\r
272 +EOF\r
273 +test_expect_equal_file EXPECTED OUTPUT\r
274 +\r
275  test_begin_subtest "notmuch_message_get_properties: empty list"\r
276  cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}\r
277  {\r
278 @@ -188,4 +199,14 @@ cat <<'EOF' >EXPECTED\r
279  EOF\r
280  test_expect_equal_file EXPECTED OUTPUT\r
281  \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
285 +EOF\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
288 +EOF\r
289 +notmuch dump | grep '^#=' > OUTPUT\r
290 +test_expect_equal_file PROPERTIES OUTPUT\r
291 +\r
292  test_done\r
293 -- \r
294 2.8.1\r
295 \r