1 Return-Path: <amdragon@mit.edu>
\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 1C8FC431FBF
\r
6 for <notmuch@notmuchmail.org>; Fri, 4 Apr 2014 15:05:57 -0700 (PDT)
\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org
\r
11 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5
\r
12 tests=[RCVD_IN_DNSWL_LOW=-0.7] 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 g1n8XGRddU0C for <notmuch@notmuchmail.org>;
\r
16 Fri, 4 Apr 2014 15:05:52 -0700 (PDT)
\r
17 Received: from dmz-mailsec-scanner-5.mit.edu (dmz-mailsec-scanner-5.mit.edu
\r
19 by olra.theworths.org (Postfix) with ESMTP id EDD00431FAF
\r
20 for <notmuch@notmuchmail.org>; Fri, 4 Apr 2014 15:05:51 -0700 (PDT)
\r
21 X-AuditID: 12074422-f79186d00000135a-f4-533f2cbfda6f
\r
22 Received: from mailhub-auth-3.mit.edu ( [18.9.21.43])
\r
23 (using TLS with cipher AES256-SHA (256/256 bits))
\r
24 (Client did not present a certificate)
\r
25 by dmz-mailsec-scanner-5.mit.edu (Symantec Messaging Gateway) with SMTP
\r
26 id C1.19.04954.FBC2F335; Fri, 4 Apr 2014 18:05:51 -0400 (EDT)
\r
27 Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])
\r
28 by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id s34M5ndx014052;
\r
29 Fri, 4 Apr 2014 18:05:50 -0400
\r
30 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])
\r
31 (authenticated bits=0)
\r
32 (User authenticated as amdragon@ATHENA.MIT.EDU)
\r
33 by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id s34M5mqO017034
\r
34 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT);
\r
35 Fri, 4 Apr 2014 18:05:49 -0400
\r
36 Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80)
\r
37 (envelope-from <amdragon@mit.edu>)
\r
38 id 1WWCFA-0004Ho-10; Fri, 04 Apr 2014 18:05:48 -0400
\r
39 Date: Fri, 4 Apr 2014 18:05:47 -0400
\r
40 From: Austin Clements <amdragon@MIT.EDU>
\r
41 To: David Bremner <david@tethera.net>
\r
42 Subject: Re: [Patch v6 1/6] dump: support gzipped and atomic output
\r
43 Message-ID: <20140404220547.GB15472@mit.edu>
\r
44 References: <1396554083-3892-1-git-send-email-david@tethera.net>
\r
45 <1396554083-3892-2-git-send-email-david@tethera.net>
\r
47 Content-Type: text/plain; charset=us-ascii
\r
48 Content-Disposition: inline
\r
49 In-Reply-To: <1396554083-3892-2-git-send-email-david@tethera.net>
\r
50 User-Agent: Mutt/1.5.21 (2010-09-15)
\r
51 X-Brightmail-Tracker:
\r
52 H4sIAAAAAAAAA+NgFmpileLIzCtJLcpLzFFi42IR4hTV1t2vYx9scHa+hMWN1m5Gi+s3ZzI7
\r
53 MHk8W3WL2WPLoffMAUxRXDYpqTmZZalF+nYJXBm7/kxlL1hWUPHkvHMD472wLkZODgkBE4nz
\r
54 z7YzQdhiEhfurWfrYuTiEBKYzSRx7/g9RghnA6PEyweLoZxTTBITem+xQjhLGCUezz/G3MXI
\r
55 wcEioCIx56YyyCg2AQ2JbfuXM4LYIgKqEle3TWYDsZkFpCW+/W4GWycs4Czx6dxpZhCbV0BH
\r
56 4u+ra2A1QgLlEqdefGCHiAtKnJz5hAWiV0vixr+XTCCrQOYs/8cBEuYUcJR4/6YBbJUo0AVT
\r
57 Tm5jm8AoNAtJ9ywk3bMQuhcwMq9ilE3JrdLNTczMKU5N1i1OTszLSy3SNdXLzSzRS00p3cQI
\r
58 Cmp2F6UdjD8PKh1iFOBgVOLh7dhhFyzEmlhWXJl7iFGSg0lJlLdLwT5YiC8pP6UyI7E4I76o
\r
59 NCe1+BCjBAezkgivjCpQjjclsbIqtSgfJiXNwaIkzvvW2ipYSCA9sSQ1OzW1ILUIJivDwaEk
\r
60 wbtFG6hRsCg1PbUiLTOnBCHNxMEJMpwHaPhakBre4oLE3OLMdIj8KUZFKXHeLVpACQGQREZp
\r
61 HlwvLOm8YhQHekWY9wRIOw8wYcF1vwIazAQ0uCHMDmRwSSJCSqqB0ZB9/8LvkdnvbQ+xKXz3
\r
62 OTuRb07THAXe0k3iW87b373Z/Wj9W+u9x17+2Np8i5dPryHodffZO2lcHOvKQtJmfti0ZNrn
\r
63 79+bcmVtVA/7MF33urf09kmpoNrzDleir/u+LbI/PPNgvFmdwaEn5z9va7ZNesuld3yxkPXX
\r
64 wrf2Tge/HPZ3b37WXq/EUpyRaKjFXFScCACNihoBFQMAAA==
\r
65 Cc: notmuch@notmuchmail.org
\r
66 X-BeenThere: notmuch@notmuchmail.org
\r
67 X-Mailman-Version: 2.1.13
\r
69 List-Id: "Use and development of the notmuch mail system."
\r
70 <notmuch.notmuchmail.org>
\r
71 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,
\r
72 <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>
\r
73 List-Archive: <http://notmuchmail.org/pipermail/notmuch>
\r
74 List-Post: <mailto:notmuch@notmuchmail.org>
\r
75 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>
\r
76 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,
\r
77 <mailto:notmuch-request@notmuchmail.org?subject=subscribe>
\r
78 X-List-Received-Date: Fri, 04 Apr 2014 22:05:57 -0000
\r
80 Quoth David Bremner on Apr 03 at 4:41 pm:
\r
81 > The main goal is to support gzipped output for future internal
\r
82 > calls (e.g. from notmuch-new) to notmuch_database_dump.
\r
84 > The additional dependency is not very heavy since xapian already pulls
\r
87 > We want the dump to be "atomic", in the sense that after running the
\r
88 > dump file is either present and complete, or not present. This avoids
\r
89 > certain classes of mishaps involving overwriting a good backup with a
\r
90 > bad or partial one.
\r
92 > INSTALL | 20 ++++++++--
\r
93 > Makefile.local | 2 +-
\r
94 > configure | 28 ++++++++++++--
\r
95 > doc/man1/notmuch-dump.rst | 3 ++
\r
96 > notmuch-client.h | 4 +-
\r
97 > notmuch-dump.c | 95 +++++++++++++++++++++++++++++++++++++----------
\r
98 > test/T240-dump-restore.sh | 12 ++++++
\r
99 > 7 files changed, 136 insertions(+), 28 deletions(-)
\r
101 > diff --git a/INSTALL b/INSTALL
\r
102 > index 690b0ef..b543c50 100644
\r
105 > @@ -20,8 +20,8 @@ configure stage.
\r
109 > -Notmuch depends on three libraries: Xapian, GMime 2.4 or 2.6, and
\r
110 > -Talloc which are each described below:
\r
111 > +Notmuch depends on four libraries: Xapian, GMime 2.4 or 2.6,
\r
112 > +Talloc, and zlib which are each described below:
\r
116 > @@ -60,6 +60,18 @@ Talloc which are each described below:
\r
118 > Talloc is available from http://talloc.samba.org/
\r
123 > + zlib is an extremely popular compression library. It is used
\r
124 > + by Xapian, so if you installed that you will already have
\r
125 > + zlib. You may need to install the zlib headers separately.
\r
127 > + Notmuch needs the transparent write feature of zlib introduced
\r
128 > + in version 1.2.5.2 (Dec. 2011).
\r
130 > + zlib is available from http://zlib.net
\r
132 > Building Documentation
\r
133 > ----------------------
\r
135 > @@ -79,11 +91,11 @@ dependencies with a simple simple command line. For example:
\r
137 > For Debian and similar:
\r
139 > - sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev python-sphinx
\r
140 > + sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev zlib1g-dev python-sphinx
\r
142 > For Fedora and similar:
\r
144 > - sudo yum install xapian-core-devel gmime-devel libtalloc-devel python-sphinx
\r
145 > + sudo yum install xapian-core-devel gmime-devel libtalloc-devel zlib-devel python-sphinx
\r
147 > On other systems, a similar command can be used, but the details of
\r
148 > the package names may be different.
\r
149 > diff --git a/Makefile.local b/Makefile.local
\r
150 > index cb7b106..e5a20a7 100644
\r
151 > --- a/Makefile.local
\r
152 > +++ b/Makefile.local
\r
153 > @@ -41,7 +41,7 @@ PV_FILE=bindings/python/notmuch/version.py
\r
154 > # Smash together user's values with our extra values
\r
155 > FINAL_CFLAGS = -DNOTMUCH_VERSION=$(VERSION) $(CPPFLAGS) $(CFLAGS) $(WARN_CFLAGS) $(extra_cflags) $(CONFIGURE_CFLAGS)
\r
156 > FINAL_CXXFLAGS = $(CPPFLAGS) $(CXXFLAGS) $(WARN_CXXFLAGS) $(extra_cflags) $(extra_cxxflags) $(CONFIGURE_CXXFLAGS)
\r
157 > -FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Lutil -lutil -Llib -lnotmuch $(AS_NEEDED_LDFLAGS) $(GMIME_LDFLAGS) $(TALLOC_LDFLAGS)
\r
158 > +FINAL_NOTMUCH_LDFLAGS = $(LDFLAGS) -Lutil -lutil -Llib -lnotmuch $(AS_NEEDED_LDFLAGS) $(GMIME_LDFLAGS) $(TALLOC_LDFLAGS) $(ZLIB_LDFLAGS)
\r
159 > FINAL_NOTMUCH_LINKER = CC
\r
160 > ifneq ($(LINKER_RESOLVES_LIBRARY_DEPENDENCIES),1)
\r
161 > FINAL_NOTMUCH_LDFLAGS += $(CONFIGURE_LDFLAGS)
\r
162 > diff --git a/configure b/configure
\r
163 > index 1d430b9..1d624f7 100755
\r
166 > @@ -340,6 +340,18 @@ else
\r
167 > errors=$((errors + 1))
\r
170 > +printf "Checking for zlib (>= 1.2.5.2)... "
\r
172 > +if pkg-config --atleast-version=1.2.5.2 zlib; then
\r
173 > + printf "Yes.\n"
\r
175 > + zlib_cflags=$(pkg-config --cflags zlib)
\r
176 > + zlib_ldflags=$(pkg-config --libs zlib)
\r
179 > + errors=$((errors + 1))
\r
182 > printf "Checking for talloc development files... "
\r
183 > if pkg-config --exists talloc; then
\r
185 > @@ -496,6 +508,11 @@ EOF
\r
186 > echo " Xapian library (including development files such as headers)"
\r
187 > echo " http://xapian.org/"
\r
189 > + if [ $have_zlib -eq 0 ]; then
\r
190 > + echo " zlib library (including development files such as headers)"
\r
191 > + echo " http://zlib.net/"
\r
194 > if [ $have_gmime -eq 0 ]; then
\r
195 > echo " Either GMime 2.4 library" $GMIME_24_VERSION_CTR "or GMime 2.6 library" $GMIME_26_VERSION_CTR
\r
196 > echo " (including development files such as headers)"
\r
197 > @@ -519,11 +536,11 @@ case a simple command will install everything you need. For example:
\r
199 > On Debian and similar systems:
\r
201 > - sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev
\r
202 > + sudo apt-get install libxapian-dev libgmime-2.6-dev libtalloc-dev zlib1g-dev
\r
204 > Or on Fedora and similar systems:
\r
206 > - sudo yum install xapian-core-devel gmime-devel libtalloc-devel
\r
207 > + sudo yum install xapian-core-devel gmime-devel libtalloc-devel zlib-devel
\r
209 > On other systems, similar commands can be used, but the details of the
\r
210 > package names may be different.
\r
211 > @@ -844,6 +861,10 @@ XAPIAN_LDFLAGS = ${xapian_ldflags}
\r
212 > GMIME_CFLAGS = ${gmime_cflags}
\r
213 > GMIME_LDFLAGS = ${gmime_ldflags}
\r
215 > +# Flags needed to compile and link against zlib
\r
216 > +ZLIB_CFLAGS = ${zlib_cflags}
\r
217 > +ZLIB_LDFLAGS = ${zlib_ldflags}
\r
219 > # Flags needed to compile and link against talloc
\r
220 > TALLOC_CFLAGS = ${talloc_cflags}
\r
221 > TALLOC_LDFLAGS = ${talloc_ldflags}
\r
222 > @@ -882,6 +903,7 @@ CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
\r
223 > -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
\r
225 > CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
\r
226 > + \$(ZLIB_CFLAGS) \\
\r
227 > \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
\r
228 > \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\
\r
229 > -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
\r
230 > @@ -892,5 +914,5 @@ CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
\r
231 > -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\
\r
232 > -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
\r
234 > -CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(XAPIAN_LDFLAGS)
\r
235 > +CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(ZLIB_LDFLAGS) \$(XAPIAN_LDFLAGS)
\r
237 > diff --git a/doc/man1/notmuch-dump.rst b/doc/man1/notmuch-dump.rst
\r
238 > index 17d1da5..d94cb4f 100644
\r
239 > --- a/doc/man1/notmuch-dump.rst
\r
240 > +++ b/doc/man1/notmuch-dump.rst
\r
241 > @@ -19,6 +19,9 @@ recreated from the messages themselves. The output of notmuch dump is
\r
242 > therefore the only critical thing to backup (and much more friendly to
\r
243 > incremental backup than the native database files.)
\r
246 > + Compress the output in a format compatible with **gzip(1)**.
\r
248 > ``--format=(sup|batch-tag)``
\r
249 > Notmuch restore supports two plain text dump formats, both with one
\r
250 > message-id per line, followed by a list of tags.
\r
251 > diff --git a/notmuch-client.h b/notmuch-client.h
\r
252 > index d110648..e1efbe0 100644
\r
253 > --- a/notmuch-client.h
\r
254 > +++ b/notmuch-client.h
\r
255 > @@ -450,7 +450,9 @@ typedef enum dump_formats {
\r
257 > notmuch_database_dump (notmuch_database_t *notmuch,
\r
258 > const char *output_file_name,
\r
259 > - const char *query_str, dump_format_t output_format);
\r
260 > + const char *query_str,
\r
261 > + dump_format_t output_format,
\r
262 > + notmuch_bool_t gzip_output);
\r
264 > #include "command-line-arguments.h"
\r
266 > diff --git a/notmuch-dump.c b/notmuch-dump.c
\r
267 > index 21702d7..2a7252a 100644
\r
268 > --- a/notmuch-dump.c
\r
269 > +++ b/notmuch-dump.c
\r
270 > @@ -21,9 +21,11 @@
\r
271 > #include "notmuch-client.h"
\r
272 > #include "hex-escape.h"
\r
273 > #include "string-util.h"
\r
274 > +#include <zlib.h>
\r
278 > -database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
279 > +database_dump_file (notmuch_database_t *notmuch, gzFile output,
\r
280 > const char *query_str, int output_format)
\r
282 > notmuch_query_t *query;
\r
283 > @@ -69,7 +71,7 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
286 > if (output_format == DUMP_FORMAT_SUP) {
\r
287 > - fprintf (output, "%s (", message_id);
\r
288 > + gzprintf (output, "%s (", message_id);
\r
291 > for (tags = notmuch_message_get_tags (message);
\r
292 > @@ -78,12 +80,12 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
293 > const char *tag_str = notmuch_tags_get (tags);
\r
296 > - fputs (" ", output);
\r
297 > + gzputs (output, " ");
\r
301 > if (output_format == DUMP_FORMAT_SUP) {
\r
302 > - fputs (tag_str, output);
\r
303 > + gzputs (output, tag_str);
\r
305 > if (hex_encode (notmuch, tag_str,
\r
306 > &buffer, &buffer_size) != HEX_SUCCESS) {
\r
307 > @@ -91,12 +93,12 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
309 > return EXIT_FAILURE;
\r
311 > - fprintf (output, "+%s", buffer);
\r
312 > + gzprintf (output, "+%s", buffer);
\r
316 > if (output_format == DUMP_FORMAT_SUP) {
\r
317 > - fputs (")\n", output);
\r
318 > + gzputs (output, ")\n");
\r
320 > if (make_boolean_term (notmuch, "id", message_id,
\r
321 > &buffer, &buffer_size)) {
\r
322 > @@ -104,7 +106,7 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
323 > message_id, strerror (errno));
\r
324 > return EXIT_FAILURE;
\r
326 > - fprintf (output, " -- %s\n", buffer);
\r
327 > + gzprintf (output, " -- %s\n", buffer);
\r
330 > notmuch_message_destroy (message);
\r
331 > @@ -121,24 +123,77 @@ database_dump_file (notmuch_database_t *notmuch, FILE *output,
\r
333 > notmuch_database_dump (notmuch_database_t *notmuch,
\r
334 > const char *output_file_name,
\r
335 > - const char *query_str, dump_format_t output_format)
\r
336 > + const char *query_str,
\r
337 > + dump_format_t output_format,
\r
338 > + notmuch_bool_t gzip_output)
\r
340 > - FILE *output = stdout;
\r
344 This should to gzclose_w output on all error paths. The easiest way
\r
345 to do that it probably to
\r
346 gzFile output = NULL;
\r
349 > + const char *mode = gzip_output ? "w9" : "wT";
\r
350 > + const char *name_for_error = output_file_name ? output_file_name : "stdout";
\r
352 > + char *tempname = NULL;
\r
353 > + int outfd = -1;
\r
357 > if (output_file_name) {
\r
358 > - output = fopen (output_file_name, "w");
\r
359 > - if (output == NULL) {
\r
360 > - fprintf (stderr, "Error opening %s for writing: %s\n",
\r
361 > - output_file_name, strerror (errno));
\r
362 > - return EXIT_FAILURE;
\r
364 > + tempname = talloc_asprintf (notmuch, "%s.XXXXXX", output_file_name);
\r
365 > + outfd = mkstemp (tempname);
\r
367 > + outfd = dup (STDOUT_FILENO);
\r
370 > + if (outfd < 0) {
\r
371 > + fprintf (stderr, "Bad output file %s\n", name_for_error);
\r
375 > + output = gzdopen (outfd, mode);
\r
377 > + if (output == NULL) {
\r
378 > + fprintf (stderr, "Error opening %s for (gzip) writing: %s\n",
\r
379 > + name_for_error, strerror (errno));
\r
380 > + if (close (outfd))
\r
381 > + fprintf (stderr, "Error closing %s during shutdown: %s\n",
\r
382 > + name_for_error, strerror (errno));
\r
386 > ret = database_dump_file (notmuch, output, query_str, output_format);
\r
387 > + if (ret) goto DONE;
\r
389 > - if (output != stdout)
\r
390 > - fclose (output);
\r
391 > + ret = gzflush (output, Z_FINISH);
\r
393 > + fprintf (stderr, "Error flushing output: %s\n", gzerror (output, NULL));
\r
397 > + if (output_file_name) {
\r
398 > + ret = fdatasync (outfd);
\r
400 > + fprintf (stderr, "Error syncing %s to disk: %s\n",
\r
401 > + name_for_error, strerror (errno));
\r
406 > + if (gzclose_w (output) != Z_OK) {
\r
407 > + ret = EXIT_FAILURE;
\r
411 ... output = NULL; here, and ...
\r
414 > + if (output_file_name) {
\r
415 > + ret = rename (tempname, output_file_name);
\r
417 > + fprintf (stderr, "Error renaming %s to %s: %s\n",
\r
418 > + tempname, output_file_name, strerror (errno));
\r
427 gzclose_w (output);
\r
430 > + if (ret != EXIT_SUCCESS && output_file_name)
\r
431 > + (void) unlink (tempname);
\r
435 > @@ -158,6 +213,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
\r
438 > int output_format = DUMP_FORMAT_BATCH_TAG;
\r
439 > + notmuch_bool_t gzip_output = 0;
\r
441 > notmuch_opt_desc_t options[] = {
\r
442 > { NOTMUCH_OPT_KEYWORD, &output_format, "format", 'f',
\r
443 > @@ -165,6 +221,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
\r
444 > { "batch-tag", DUMP_FORMAT_BATCH_TAG },
\r
446 > { NOTMUCH_OPT_STRING, &output_file_name, "output", 'o', 0 },
\r
447 > + { NOTMUCH_OPT_BOOLEAN, &gzip_output, "gzip", 'z', 0 },
\r
448 > { 0, 0, 0, 0, 0 }
\r
451 > @@ -181,7 +238,7 @@ notmuch_dump_command (notmuch_config_t *config, int argc, char *argv[])
\r
454 > ret = notmuch_database_dump (notmuch, output_file_name, query_str,
\r
455 > - output_format);
\r
456 > + output_format, gzip_output);
\r
458 > notmuch_database_destroy (notmuch);
\r
460 > diff --git a/test/T240-dump-restore.sh b/test/T240-dump-restore.sh
\r
461 > index 0004438..d79aca8 100755
\r
462 > --- a/test/T240-dump-restore.sh
\r
463 > +++ b/test/T240-dump-restore.sh
\r
464 > @@ -68,6 +68,18 @@ test_begin_subtest "dump --output=outfile --"
\r
465 > notmuch dump --output=dump-1-arg-dash.actual --
\r
466 > test_expect_equal_file dump.expected dump-1-arg-dash.actual
\r
468 > +# gzipped output
\r
470 > +test_begin_subtest "dump --gzip"
\r
471 > +notmuch dump --gzip > dump-gzip.gz
\r
472 > +gunzip dump-gzip.gz
\r
473 > +test_expect_equal_file dump.expected dump-gzip
\r
475 > +test_begin_subtest "dump --gzip --output=outfile"
\r
476 > +notmuch dump --gzip --output=dump-gzip-outfile.gz
\r
477 > +gunzip dump-gzip-outfile.gz
\r
478 > +test_expect_equal_file dump.expected dump-gzip-outfile
\r
480 > # Note, we assume all messages from cworth have a message-id
\r
481 > # containing cworth.org
\r