[PATCH v2 08/14] cli/reply: reduce the reply format abstractions
[notmuch-archives.git] / 6a / 22f1c8414d506c4b94e1733406e7270298caed
1 Return-Path: <thomas@schwinge.name>\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 olra.theworths.org (Postfix) with ESMTP id 40DA6431FD0\r
6         for <notmuch@notmuchmail.org>; Thu, 29 Sep 2011 10:37:53 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5\r
12         tests=[RCVD_IN_DNSWL_NONE=-0.0001] autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id 5RP3VPZiHZ-d for <notmuch@notmuchmail.org>;\r
16         Thu, 29 Sep 2011 10:37:52 -0700 (PDT)\r
17 Received: from smtprelay04.ispgateway.de (smtprelay04.ispgateway.de\r
18         [80.67.31.38])\r
19         by olra.theworths.org (Postfix) with ESMTP id 0E24F431FB6\r
20         for <notmuch@notmuchmail.org>; Thu, 29 Sep 2011 10:37:52 -0700 (PDT)\r
21 Received: from [87.180.87.168] (helo=stokes.schwinge.homeip.net)\r
22         by smtprelay04.ispgateway.de with esmtpa (Exim 4.68)\r
23         (envelope-from <thomas@schwinge.name>) id 1R9KYP-0004n3-Dc\r
24         for notmuch@notmuchmail.org; Thu, 29 Sep 2011 19:37:49 +0200\r
25 Received: (qmail 24622 invoked from network); 29 Sep 2011 17:37:44 -0000\r
26 Received: from kepler.schwinge.homeip.net (192.168.111.7)\r
27         by stokes.schwinge.homeip.net with QMQP; 29 Sep 2011 17:37:44 -0000\r
28 Received: (nullmailer pid 29670 invoked by uid 1000);\r
29         Thu, 29 Sep 2011 17:37:44 -0000\r
30 From: Thomas Schwinge <thomas@schwinge.name>\r
31 To: notmuch@notmuchmail.org\r
32 Subject: =?UTF-8?q?=5BPATCH=2C=20v2=5D=20notmuch=20restore=20--accumulate?=\r
33 Date: Thu, 29 Sep 2011 19:37:37 +0200\r
34 Message-Id: <1317317857-29636-1-git-send-email-thomas@schwinge.name>\r
35 X-Mailer: git-send-email 1.7.5.4\r
36 In-Reply-To: <1317317811-29540-1-git-send-email-thomas@schwinge.name>\r
37 References: <1317317811-29540-1-git-send-email-thomas@schwinge.name>\r
38 MIME-Version: 1.0\r
39 Content-Type: text/plain; charset=UTF-8\r
40 Content-Transfer-Encoding: 8bit\r
41 X-Df-Sender: dGhvbWFzQHNjaHdpbmdlLm5hbWU=\r
42 X-BeenThere: notmuch@notmuchmail.org\r
43 X-Mailman-Version: 2.1.13\r
44 Precedence: list\r
45 List-Id: "Use and development of the notmuch mail system."\r
46         <notmuch.notmuchmail.org>\r
47 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
48         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
49 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
50 List-Post: <mailto:notmuch@notmuchmail.org>\r
51 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
52 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
53         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
54 X-List-Received-Date: Thu, 29 Sep 2011 17:37:53 -0000\r
55 \r
56 From: Thomas Schwinge <thomas@schwinge.name>\r
57 \r
58 The --accumulate switch causes the union of the existing and new tags to be\r
59 applied, instead of replacing each message's tags as they are read in from the\r
60 dump file.\r
61 \r
62 ---\r
63 \r
64 Hi!\r
65 \r
66 Beware that I have not yet used this new functionality in the wild.  ;-)\r
67 (But I do plan to do so, soon.)  And, I think that the testsuite\r
68 enhancements cover quite a number of real-world scenarios.\r
69 \r
70 This is v2; it addresses Jameson's and Austin's comments.\r
71 \r
72 \r
73 Grüße,\r
74  Thomas\r
75 \r
76 ---\r
77 \r
78  NEWS              |    9 +++++++++\r
79  notmuch-restore.c |   42 +++++++++++++++++++++++++++++++++---------\r
80  notmuch.1         |   14 ++++++++++----\r
81  notmuch.c         |   10 +++++++---\r
82  test/dump-restore |   10 ----------\r
83  5 files changed, 59 insertions(+), 26 deletions(-)\r
84 \r
85 diff --git a/NEWS b/NEWS\r
86 index ee84e9a..2a184ef 100644\r
87 --- a/NEWS\r
88 +++ b/NEWS\r
89 @@ -12,6 +12,15 @@ Correct handling of interruptions during "notmuch new"\r
90    detect messages on resume, or leave the database in a state\r
91    temporarily or permanently inconsistent with the mail store.\r
92  \r
93 +New command-line features\r
94 +-------------------------\r
95 +\r
96 +Add "notmuch restore --accumulate" option\r
97 +\r
98 +  The --accumulate switch causes the union of the existing and new tags to be\r
99 +  applied, instead of replacing each message's tags as they are read in from\r
100 +  the dump file.\r
101 +\r
102  Library changes\r
103  ---------------\r
104  \r
105 diff --git a/notmuch-restore.c b/notmuch-restore.c\r
106 index f095f64..5aad60c 100644\r
107 --- a/notmuch-restore.c\r
108 +++ b/notmuch-restore.c\r
109 @@ -31,7 +31,8 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
110      size_t line_size;\r
111      ssize_t line_len;\r
112      regex_t regex;\r
113 -    int rerr;\r
114 +    notmuch_bool_t accumulate;\r
115 +    int i, rerr;\r
116  \r
117      config = notmuch_config_open (ctx, NULL, NULL);\r
118      if (config == NULL)\r
119 @@ -44,14 +45,28 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
120  \r
121      synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);\r
122  \r
123 -    if (argc) {\r
124 -       input = fopen (argv[0], "r");\r
125 -       if (input == NULL) {\r
126 -           fprintf (stderr, "Error opening %s for reading: %s\n",\r
127 -                    argv[0], strerror (errno));\r
128 -           return 1;\r
129 +    accumulate = FALSE;\r
130 +    input = NULL;\r
131 +    for (i = 0; i < argc; i++) {\r
132 +       if (STRNCMP_LITERAL (argv[i], "--accumulate") == 0) {\r
133 +           accumulate = TRUE;\r
134 +       } else {\r
135 +           if (input == NULL) {\r
136 +               input = fopen (argv[i], "r");\r
137 +               if (input == NULL) {\r
138 +                   fprintf (stderr, "Error opening %s for reading: %s\n",\r
139 +                            argv[i], strerror (errno));\r
140 +                   return 1;\r
141 +               }\r
142 +           } else {\r
143 +               fprintf (stderr,\r
144 +                        "Cannot read dump from more than one file: %s\n",\r
145 +                        argv[i]);\r
146 +               return 1;\r
147 +           }\r
148         }\r
149 -    } else {\r
150 +    }\r
151 +    if (input == NULL) {\r
152         printf ("No filename given. Reading dump from stdin.\n");\r
153         input = stdin;\r
154      }\r
155 @@ -94,6 +109,13 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
156             goto NEXT_LINE;\r
157         }\r
158  \r
159 +       /* In order to detect missing messages, this check/optimization is\r
160 +        * intentionally done *after* first finding the message.  */\r
161 +       if (accumulate && (file_tags == NULL || *file_tags == '\0'))\r
162 +       {\r
163 +           goto NEXT_LINE;\r
164 +       }\r
165 +\r
166         db_tags_str = NULL;\r
167         for (db_tags = notmuch_message_get_tags (message);\r
168              notmuch_tags_valid (db_tags);\r
169 @@ -115,7 +137,9 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
170         }\r
171  \r
172         notmuch_message_freeze (message);\r
173 -       notmuch_message_remove_all_tags (message);\r
174 +\r
175 +       if (!accumulate)\r
176 +           notmuch_message_remove_all_tags (message);\r
177  \r
178         next = file_tags;\r
179         while (next) {\r
180 diff --git a/notmuch.1 b/notmuch.1\r
181 index 5a8c83d..883371d 100644\r
182 --- a/notmuch.1\r
183 +++ b/notmuch.1\r
184 @@ -454,7 +454,7 @@ section below for details of the supported syntax for <search-terms>.\r
185  The\r
186  .BR dump " and " restore\r
187  commands can be used to create a textual dump of email tags for backup\r
188 -purposes, and to restore from that dump\r
189 +purposes, and to restore from that dump.\r
190  \r
191  .RS 4\r
192  .TP 4\r
193 @@ -462,17 +462,19 @@ purposes, and to restore from that dump\r
194  \r
195  Creates a plain-text dump of the tags of each message.\r
196  \r
197 -The output is to the given filename, if any, or to stdout.\r
198 +The output is written to the given filename, if any, or to stdout.\r
199  \r
200  These tags are the only data in the notmuch database that can't be\r
201  recreated from the messages themselves.  The output of notmuch dump is\r
202  therefore the only critical thing to backup (and much more friendly to\r
203  incremental backup than the native database files.)\r
204  .TP\r
205 -.BR restore " <filename>"\r
206 +.BR restore " [--accumulate] [<filename>]"\r
207  \r
208  Restores the tags from the given file (see\r
209 -.BR "notmuch dump" "."\r
210 +.BR "notmuch dump" ")."\r
211 +\r
212 +The input is read from the given filename, if any, or from stdin.\r
213  \r
214  Note: The dump file format is specifically chosen to be\r
215  compatible with the format of files produced by sup-dump.\r
216 @@ -480,6 +482,10 @@ So if you've previously been using sup for mail, then the\r
217  .B "notmuch restore"\r
218  command provides you a way to import all of your tags (or labels as\r
219  sup calls them).\r
220 +\r
221 +The --accumulate switch causes the union of the existing and new tags to be\r
222 +applied, instead of replacing each message's tags as they are read in from the\r
223 +dump file.\r
224  .RE\r
225  \r
226  The\r
227 diff --git a/notmuch.c b/notmuch.c\r
228 index f9d6629..9a9b0a2 100644\r
229 --- a/notmuch.c\r
230 +++ b/notmuch.c\r
231 @@ -377,20 +377,24 @@ static command_t commands[] = {\r
232      { "dump", notmuch_dump_command,\r
233        "[<filename>]",\r
234        "Create a plain-text dump of the tags for each message.",\r
235 -      "\tOutput is to the given filename, if any, or to stdout.\n"\r
236 +      "\tOutput is written to the given filename, if any, or to stdout.\n"\r
237        "\tThese tags are the only data in the notmuch database\n"\r
238        "\tthat can't be recreated from the messages themselves.\n"\r
239        "\tThe output of notmuch dump is therefore the only\n"\r
240        "\tcritical thing to backup (and much more friendly to\n"\r
241        "\tincremental backup than the native database files.)" },\r
242      { "restore", notmuch_restore_command,\r
243 -      "<filename>",\r
244 +      "[--accumulate] [<filename>]",\r
245        "Restore the tags from the given dump file (see 'dump').",\r
246 +      "\tInput is read from the given filename, if any, or from stdin.\n"\r
247        "\tNote: The dump file format is specifically chosen to be\n"\r
248        "\tcompatible with the format of files produced by sup-dump.\n"\r
249        "\tSo if you've previously been using sup for mail, then the\n"\r
250        "\t\"notmuch restore\" command provides you a way to import\n"\r
251 -      "\tall of your tags (or labels as sup calls them)." },\r
252 +      "\tall of your tags (or labels as sup calls them).\n"\r
253 +      "\tThe --accumulate switch causes the union of the existing and new\n"\r
254 +      "\ttags to be applied, instead of replacing each message's tags as\n"\r
255 +      "\tthey are read in from the dump file."},\r
256      { "config", notmuch_config_command,\r
257        "[get|set] <section>.<item> [value ...]",\r
258        "Get or set settings in the notmuch configuration file.",\r
259 diff --git a/test/dump-restore b/test/dump-restore\r
260 index d253756..be0eb2a 100755\r
261 --- a/test/dump-restore\r
262 +++ b/test/dump-restore\r
263 @@ -24,8 +24,6 @@ test_expect_success 'Clearing all tags' \\r
264    notmuch dump clear.actual &&\r
265    test_cmp clear.expected clear.actual'\r
266  \r
267 -# Missing notmuch restore --accumulate.\r
268 -test_subtest_known_broken\r
269  test_expect_success 'Accumulate original tags' \\r
270    'notmuch tag +ABC +DEF -- $search_term &&\r
271    notmuch restore --accumulate < dump.expected &&\r
272 @@ -42,27 +40,19 @@ test_expect_success 'Restore with nothing to do' \\r
273    notmuch dump > dump.actual &&\r
274    test_cmp dump.expected dump.actual'\r
275  \r
276 -# Missing notmuch restore --accumulate.\r
277 -test_subtest_known_broken\r
278  test_expect_success 'Restore with nothing to do, II' \\r
279    'notmuch restore --accumulate dump.expected &&\r
280    notmuch dump dump.actual &&\r
281    test_cmp dump.expected dump.actual'\r
282  \r
283 -# Missing notmuch restore --accumulate.\r
284 -test_subtest_known_broken\r
285  test_expect_success 'Restore with nothing to do, III' \\r
286    'notmuch restore --accumulate < clear.expected &&\r
287    notmuch dump dump.actual &&\r
288    test_cmp dump.expected dump.actual'\r
289  \r
290 -# notmuch restore currently only considers the first argument.\r
291 -test_subtest_known_broken\r
292  test_expect_success 'Invalid restore invocation' \\r
293    'test_must_fail notmuch restore dump.expected another_one'\r
294  \r
295 -# The follwing test already succeeds due to notmuch restore currently only\r
296 -# considering the first argument.\r
297  test_expect_success 'Invalid restore invocation, II' \\r
298    'test_must_fail notmuch restore --accumulate dump.expected another_one'\r
299  \r
300 -- \r
301 tg: (b968722..) t/restore-accumulate (depends on: master t/restore-accumulate-test)\r