Merge branch 'release'

Conflicts:
        doc/man1/notmuch-reply.rst
	doc/man1/notmuch-show.rst

Conflicts taken from release (dkg's doc changes)
This commit is contained in:
David Bremner 2017-12-31 09:26:13 -04:00
commit 99407db25c
20 changed files with 230 additions and 80 deletions

59
NEWS
View file

@ -24,6 +24,17 @@ Support for re-indexing existing messages
archive, the recorded Subject: of may change upon reindexing, archive, the recorded Subject: of may change upon reindexing,
depending on the order in which the variants are indexed. depending on the order in which the variants are indexed.
Improved error reporting in notmuch new
Give more details when reporting certain Xapian exceptions.
Support maildir synced tags in `new.tags`
Tags `draft`, `flagged`, `passed`, and `replied` are now supported
in `new.tags`. The tag `unread` is still special in the presence of
maildir syncing, and will be added for files in `new/` regardless of
the setting of `new.tags`.
Encrypted Mail Encrypted Mail
-------------- --------------
@ -41,6 +52,54 @@ Indexing cleartext of encrypted e-mails
that the notmuch index itself is adequately protected. DO NOT USE that the notmuch index itself is adequately protected. DO NOT USE
this feature without considering the security of your index. this feature without considering the security of your index.
Library Changes
---------------
Indexing files with duplicate message-id
Files with duplicate message-id's are now indexed, and searchable
via terms and phrases. There are known issues related to
presentation of results and regular-expression search, but in
principle no mail file should be completely unsearchable now.
New functions to count files
Two new functions in the libnotmuch API:
`notmuch_message_count_files`, and `notmuch_thread_get_total_files`.
Change of return value of `notmuch_thread_get_authors`
In certain corner cases, `notmuch_thread_get_authors` previously
returned NULL. This has been replaced by an empty string, since the
possibility of NULL was not documented.
Python Bindings
---------------
Python bindings specific Debian packaging is removed
The bindings have been build by the top level Debian packaging for a
long time, and `bindings/python/debian` has bit-rotted.
Open mail files in binary mode when using Python 3
This avoids certain encoding related crashes under Python 3.
Add python bindings for notmuch_database_{get,set}_config*
nmbug
-----
nmbug's internal version increases to 0.3 in this notmuch release.
User-facing changes with this notmuch release:
* Accept failures to unset `core.worktree` in `clone`, which allows
nmbug to be used with Git 2.11.0 and later.
* Auto-checkout in `clone` if it wouldn't clobber existing content,
which makes the initial clone more convenient.
* Only error for invalid diff lines in `tags/`, which allows for
`README`s and similar in nmbug repositories.
Notmuch 0.25.3 (2017-12-08) Notmuch 0.25.3 (2017-12-08)
=========================== ===========================

View file

@ -1,3 +1,3 @@
# this file should be kept in sync with ../../../version # this file should be kept in sync with ../../../version
__VERSION__ = '0.26~rc0' __VERSION__ = '0.26~rc1'
SOVERSION = '5' SOVERSION = '5'

View file

@ -4,13 +4,19 @@
#include "error_util.h" #include "error_util.h"
#include "command-line-arguments.h" #include "command-line-arguments.h"
typedef enum {
OPT_FAILED, /* false */
OPT_OK, /* good */
OPT_GIVEBACK, /* pop one of the arguments you thought you were getting off the stack */
} opt_handled;
/* /*
Search the array of keywords for a given argument, assigning the Search the array of keywords for a given argument, assigning the
output variable to the corresponding value. Return false if nothing output variable to the corresponding value. Return false if nothing
matches. matches.
*/ */
static bool static opt_handled
_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next, _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next,
const char *arg_str, bool negate) const char *arg_str, bool negate)
{ {
@ -32,16 +38,32 @@ _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next,
else else
*arg_desc->opt_keyword = keywords->value; *arg_desc->opt_keyword = keywords->value;
return true; return OPT_OK;
} }
if (arg_desc->opt_keyword && arg_desc->keyword_no_arg_value && next != ':' && next != '=') {
for (keywords = arg_desc->keywords; keywords->name; keywords++) {
if (strcmp (arg_desc->keyword_no_arg_value, keywords->name) != 0)
continue;
*arg_desc->opt_keyword = keywords->value;
fprintf (stderr, "Warning: No known keyword option given for \"%s\", choosing value \"%s\"."
" Please specify the argument explicitly!\n", arg_desc->name, arg_desc->keyword_no_arg_value);
return OPT_GIVEBACK;
}
fprintf (stderr, "No matching keyword for option \"%s\" and default value \"%s\" is invalid.\n", arg_str, arg_desc->name);
return OPT_FAILED;
}
if (next != '\0') if (next != '\0')
fprintf (stderr, "Unknown keyword argument \"%s\" for option \"%s\".\n", arg_str, arg_desc->name); fprintf (stderr, "Unknown keyword argument \"%s\" for option \"%s\".\n", arg_str, arg_desc->name);
else else
fprintf (stderr, "Option \"%s\" needs a keyword argument.\n", arg_desc->name); fprintf (stderr, "Option \"%s\" needs a keyword argument.\n", arg_desc->name);
return false; return OPT_FAILED;
} }
static bool static opt_handled
_process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next, _process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next,
const char *arg_str, bool negate) const char *arg_str, bool negate)
{ {
@ -53,45 +75,45 @@ _process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next,
value = false; value = false;
} else { } else {
fprintf (stderr, "Unknown argument \"%s\" for (boolean) option \"%s\".\n", arg_str, arg_desc->name); fprintf (stderr, "Unknown argument \"%s\" for (boolean) option \"%s\".\n", arg_str, arg_desc->name);
return false; return OPT_FAILED;
} }
*arg_desc->opt_bool = negate ? !value : value; *arg_desc->opt_bool = negate ? !value : value;
return true; return OPT_OK;
} }
static bool static opt_handled
_process_int_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) { _process_int_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
char *endptr; char *endptr;
if (next == '\0' || arg_str[0] == '\0') { if (next == '\0' || arg_str[0] == '\0') {
fprintf (stderr, "Option \"%s\" needs an integer argument.\n", arg_desc->name); fprintf (stderr, "Option \"%s\" needs an integer argument.\n", arg_desc->name);
return false; return OPT_FAILED;
} }
*arg_desc->opt_int = strtol (arg_str, &endptr, 10); *arg_desc->opt_int = strtol (arg_str, &endptr, 10);
if (*endptr == '\0') if (*endptr == '\0')
return true; return OPT_OK;
fprintf (stderr, "Unable to parse argument \"%s\" for option \"%s\" as an integer.\n", fprintf (stderr, "Unable to parse argument \"%s\" for option \"%s\" as an integer.\n",
arg_str, arg_desc->name); arg_str, arg_desc->name);
return false; return OPT_FAILED;
} }
static bool static opt_handled
_process_string_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) { _process_string_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
if (next == '\0') { if (next == '\0') {
fprintf (stderr, "Option \"%s\" needs a string argument.\n", arg_desc->name); fprintf (stderr, "Option \"%s\" needs a string argument.\n", arg_desc->name);
return false; return OPT_FAILED;
} }
if (arg_str[0] == '\0' && ! arg_desc->allow_empty) { if (arg_str[0] == '\0' && ! arg_desc->allow_empty) {
fprintf (stderr, "String argument for option \"%s\" must be non-empty.\n", arg_desc->name); fprintf (stderr, "String argument for option \"%s\" must be non-empty.\n", arg_desc->name);
return false; return OPT_FAILED;
} }
*arg_desc->opt_string = arg_str; *arg_desc->opt_string = arg_str;
return true; return OPT_OK;
} }
/* Return number of non-NULL opt_* fields in opt_desc. */ /* Return number of non-NULL opt_* fields in opt_desc. */
@ -212,13 +234,15 @@ parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_
if (next != '=' && next != ':' && next != '\0') if (next != '=' && next != ':' && next != '\0')
continue; continue;
if (next == '\0' && next_arg != NULL && ! try->opt_bool) { bool lookahead = (next == '\0' && next_arg != NULL && ! try->opt_bool);
if (lookahead) {
next = ' '; next = ' ';
value = next_arg; value = next_arg;
opt_index ++; opt_index ++;
} }
bool opt_status = false; opt_handled opt_status = OPT_FAILED;
if (try->opt_keyword || try->opt_flags) if (try->opt_keyword || try->opt_flags)
opt_status = _process_keyword_arg (try, next, value, negate); opt_status = _process_keyword_arg (try, next, value, negate);
else if (try->opt_bool) else if (try->opt_bool)
@ -230,9 +254,12 @@ parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_
else else
INTERNAL_ERROR ("unknown or unhandled option \"%s\"", try->name); INTERNAL_ERROR ("unknown or unhandled option \"%s\"", try->name);
if (! opt_status) if (opt_status == OPT_FAILED)
return -1; return -1;
if (lookahead && opt_status == OPT_GIVEBACK)
opt_index --;
if (try->present) if (try->present)
*try->present = true; *try->present = true;

View file

@ -26,6 +26,10 @@ typedef struct notmuch_opt_desc {
const char **opt_string; const char **opt_string;
const char **opt_position; const char **opt_position;
/* for opt_keyword only: if no matching arguments were found, and
* keyword_no_arg_value is set, then use keyword_no_arg_value instead. */
const char *keyword_no_arg_value;
/* Must be set except for opt_inherit and opt_position. */ /* Must be set except for opt_inherit and opt_position. */
const char *name; const char *name;

View file

@ -351,7 +351,7 @@ _notmuch_reply()
return return
;; ;;
--decrypt) --decrypt)
COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) ) COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) )
return return
;; ;;
esac esac
@ -517,10 +517,14 @@ _notmuch_show()
COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) ) COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
return return
;; ;;
--exclude|--body|--decrypt) --exclude|--body)
COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) ) COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
return return
;; ;;
--decrypt)
COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) )
return
;;
esac esac
! $split && ! $split &&

6
debian/changelog vendored
View file

@ -1,3 +1,9 @@
notmuch (0.26~rc1-1) experimental; urgency=medium
* Second upstream release candidate
-- David Bremner <bremner@debian.org> Fri, 29 Dec 2017 16:49:37 -0400
notmuch (0.26~rc0-1) experimental; urgency=medium notmuch (0.26~rc0-1) experimental; urgency=medium
* Upstream release candidate * Upstream release candidate

View file

@ -51,7 +51,7 @@ except ImportError: # Python 2
from urllib import unquote as _unquote from urllib import unquote as _unquote
__version__ = '0.2' __version__ = '0.3'
_LOG = _logging.getLogger('nmbug') _LOG = _logging.getLogger('nmbug')
_LOG.setLevel(_logging.WARNING) _LOG.setLevel(_logging.WARNING)

View file

@ -70,20 +70,26 @@ Supported options for **reply** include
order, and copy values from the first that contains something order, and copy values from the first that contains something
other than only the user's addresses. other than only the user's addresses.
``--decrypt`` ``--decrypt=(false|auto|true)``
Decrypt any MIME encrypted parts found in the selected content
(ie. "multipart/encrypted" parts). Status of the decryption will
be reported (currently only supported with --format=json and
--format=sexp) and on successful decryption the
multipart/encrypted part will be replaced by the decrypted
content.
If a session key is already known for the message, then it will be If ``true``, decrypt any MIME encrypted parts found in the
decrypted automatically unless the user explicitly sets selected content (i.e., "multipart/encrypted" parts). Status
``--decrypt=false``. of the decryption will be reported (currently only supported
with --format=json and --format=sexp), and on successful
decryption the multipart/encrypted part will be replaced by
the decrypted content.
Decryption expects a functioning **gpg-agent(1)** to provide any If ``auto``, and a session key is already known for the
needed credentials. Without one, the decryption will likely fail. message, then it will be decrypted, but notmuch will not try
to access the user's secret keys.
Use ``false`` to avoid even automatic decryption.
Non-automatic decryption expects a functioning
**gpg-agent(1)** to provide any needed credentials. Without
one, the decryption will likely fail.
Default: ``auto``
See **notmuch-search-terms(7)** for details of the supported syntax for See **notmuch-search-terms(7)** for details of the supported syntax for
<search-terms>. <search-terms>.

View file

@ -110,22 +110,27 @@ Supported options for **show** include
supported with --format=json and --format=sexp), and the supported with --format=json and --format=sexp), and the
multipart/signed part will be replaced by the signed data. multipart/signed part will be replaced by the signed data.
``--decrypt`` ``--decrypt=(false|auto|true)``
Decrypt any MIME encrypted parts found in the selected content If ``true``, decrypt any MIME encrypted parts found in the
(ie. "multipart/encrypted" parts). Status of the decryption will selected content (i.e. "multipart/encrypted" parts). Status of
be reported (currently only supported with --format=json and the decryption will be reported (currently only supported
--format=sexp) and on successful decryption the with --format=json and --format=sexp) and on successful
multipart/encrypted part will be replaced by the decrypted decryption the multipart/encrypted part will be replaced by
content. the decrypted content.
If a session key is already known for the message, then it will be If ``auto``, and a session key is already known for the
decrypted automatically unless the user explicitly sets message, then it will be decrypted, but notmuch will not try
``--decrypt=false``. to access the user's keys.
Decryption expects a functioning **gpg-agent(1)** to provide any Use ``false`` to avoid even automatic decryption.
needed credentials. Without one, the decryption will fail.
Implies --verify. Non-automatic decryption expects a functioning
**gpg-agent(1)** to provide any needed credentials. Without
one, the decryption will fail.
Note: ``true`` implies --verify.
Default: ``auto``
``--exclude=(true|false)`` ``--exclude=(true|false)``
Specify whether to omit threads only matching search.tag\_exclude Specify whether to omit threads only matching search.tag\_exclude

View file

@ -593,7 +593,7 @@ the given type."
(set-buffer-multibyte nil)) (set-buffer-multibyte nil))
(let ((args `("show" "--format=raw" (let ((args `("show" "--format=raw"
,(format "--part=%s" (plist-get part :id)) ,(format "--part=%s" (plist-get part :id))
,@(when process-crypto '("--decrypt")) ,@(when process-crypto '("--decrypt=true"))
,(notmuch-id-to-query (plist-get msg :id)))) ,(notmuch-id-to-query (plist-get msg :id))))
(coding-system-for-read (coding-system-for-read
(if binaryp 'no-conversion (if binaryp 'no-conversion

View file

@ -181,7 +181,7 @@ mutiple parts get a header."
reply reply
original) original)
(when process-crypto (when process-crypto
(setq args (append args '("--decrypt")))) (setq args (append args '("--decrypt=true"))))
(if reply-all (if reply-all
(setq args (append args '("--reply-to=all"))) (setq args (append args '("--reply-to=all")))

View file

@ -32,7 +32,7 @@ is a possibly empty forest of replies.
" "
(let ((args '("show" "--format=sexp" "--format-version=4"))) (let ((args '("show" "--format=sexp" "--format-version=4")))
(if notmuch-show-process-crypto (if notmuch-show-process-crypto
(setq args (append args '("--decrypt")))) (setq args (append args '("--decrypt=true"))))
(setq args (append args search-terms)) (setq args (append args search-terms))
(apply #'notmuch-call-notmuch-sexp args))) (apply #'notmuch-call-notmuch-sexp args)))

View file

@ -704,8 +704,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
}; };
int format = FORMAT_DEFAULT; int format = FORMAT_DEFAULT;
int reply_all = true; int reply_all = true;
bool decrypt = false;
bool decrypt_set = false;
notmuch_opt_desc_t options[] = { notmuch_opt_desc_t options[] = {
{ .opt_keyword = &format, .name = "format", .keywords = { .opt_keyword = &format, .name = "format", .keywords =
@ -719,7 +717,12 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
(notmuch_keyword_t []){ { "all", true }, (notmuch_keyword_t []){ { "all", true },
{ "sender", false }, { "sender", false },
{ 0, 0 } } }, { 0, 0 } } },
{ .opt_bool = &decrypt, .name = "decrypt", .present = &decrypt_set }, { .opt_keyword = (int*)(&params.crypto.decrypt), .name = "decrypt",
.keyword_no_arg_value = "true", .keywords =
(notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
{ "auto", NOTMUCH_DECRYPT_AUTO },
{ "true", NOTMUCH_DECRYPT_NOSTASH },
{ 0, 0 } } },
{ .opt_inherit = notmuch_shared_options }, { .opt_inherit = notmuch_shared_options },
{ } { }
}; };
@ -729,8 +732,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
return EXIT_FAILURE; return EXIT_FAILURE;
notmuch_process_shared_options (argv[0]); notmuch_process_shared_options (argv[0]);
if (decrypt_set)
params.crypto.decrypt = decrypt ? NOTMUCH_DECRYPT_NOSTASH : NOTMUCH_DECRYPT_FALSE;
notmuch_exit_if_unsupported_format (); notmuch_exit_if_unsupported_format ();

View file

@ -1085,8 +1085,6 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
bool exclude = true; bool exclude = true;
bool entire_thread_set = false; bool entire_thread_set = false;
bool single_message; bool single_message;
bool decrypt = false;
bool decrypt_set = false;
notmuch_opt_desc_t options[] = { notmuch_opt_desc_t options[] = {
{ .opt_keyword = &format, .name = "format", .keywords = { .opt_keyword = &format, .name = "format", .keywords =
@ -1101,7 +1099,12 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
{ .opt_bool = &params.entire_thread, .name = "entire-thread", { .opt_bool = &params.entire_thread, .name = "entire-thread",
.present = &entire_thread_set }, .present = &entire_thread_set },
{ .opt_int = &params.part, .name = "part" }, { .opt_int = &params.part, .name = "part" },
{ .opt_bool = &decrypt, .name = "decrypt", .present = &decrypt_set }, { .opt_keyword = (int*)(&params.crypto.decrypt), .name = "decrypt",
.keyword_no_arg_value = "true", .keywords =
(notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
{ "auto", NOTMUCH_DECRYPT_AUTO },
{ "true", NOTMUCH_DECRYPT_NOSTASH },
{ 0, 0 } } },
{ .opt_bool = &params.crypto.verify, .name = "verify" }, { .opt_bool = &params.crypto.verify, .name = "verify" },
{ .opt_bool = &params.output_body, .name = "body" }, { .opt_bool = &params.output_body, .name = "body" },
{ .opt_bool = &params.include_html, .name = "include-html" }, { .opt_bool = &params.include_html, .name = "include-html" },
@ -1115,16 +1118,9 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
notmuch_process_shared_options (argv[0]); notmuch_process_shared_options (argv[0]);
if (decrypt_set) { /* explicit decryption implies verification */
if (decrypt) { if (params.crypto.decrypt == NOTMUCH_DECRYPT_NOSTASH)
/* we do not need or want to ask for session keys */
params.crypto.decrypt = NOTMUCH_DECRYPT_NOSTASH;
/* decryption implies verification */
params.crypto.verify = true; params.crypto.verify = true;
} else {
params.crypto.decrypt = NOTMUCH_DECRYPT_FALSE;
}
}
/* specifying a part implies single message display */ /* specifying a part implies single message display */
single_message = params.part >= 0; single_message = params.part >= 0;

View file

@ -223,7 +223,7 @@ output=$(notmuch search mimetype:multipart/encrypted and mimetype:application/pg
test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message 001 (encrypted inbox)" test_expect_equal "$output" "thread:XXX 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message 001 (encrypted inbox)"
test_begin_subtest "decryption, --format=text" test_begin_subtest "decryption, --format=text"
output=$(notmuch show --format=text --decrypt subject:"test encrypted message 001" \ output=$(notmuch show --format=text --decrypt=true subject:"test encrypted message 001" \
| notmuch_show_sanitize_all \ | notmuch_show_sanitize_all \
| sed -e 's|"created": [1234567890]*|"created": 946728000|') | sed -e 's|"created": [1234567890]*|"created": 946728000|')
expected=' message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX expected=' message{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX
@ -255,7 +255,7 @@ test_expect_equal \
"$expected" "$expected"
test_begin_subtest "decryption, --format=json" test_begin_subtest "decryption, --format=json"
output=$(notmuch show --format=json --decrypt subject:"test encrypted message 001" \ output=$(notmuch show --format=json --decrypt=true subject:"test encrypted message 001" \
| notmuch_json_show_sanitize \ | notmuch_json_show_sanitize \
| sed -e 's|"created": [1234567890]*|"created": 946728000|') | sed -e 's|"created": [1234567890]*|"created": 946728000|')
expected='[[[{"id": "XXXXX", expected='[[[{"id": "XXXXX",
@ -293,7 +293,7 @@ test_expect_equal_json \
"$expected" "$expected"
test_begin_subtest "decryption, --format=json, --part=4" test_begin_subtest "decryption, --format=json, --part=4"
output=$(notmuch show --format=json --part=4 --decrypt subject:"test encrypted message 001" \ output=$(notmuch show --format=json --part=4 --decrypt=true subject:"test encrypted message 001" \
| notmuch_json_show_sanitize \ | notmuch_json_show_sanitize \
| sed -e 's|"created": [1234567890]*|"created": 946728000|') | sed -e 's|"created": [1234567890]*|"created": 946728000|')
expected='{"id": 4, expected='{"id": 4,
@ -307,13 +307,13 @@ test_begin_subtest "decrypt attachment (--part=5 --format=raw)"
notmuch show \ notmuch show \
--format=raw \ --format=raw \
--part=5 \ --part=5 \
--decrypt \ --decrypt=true \
subject:"test encrypted message 001" >OUTPUT subject:"test encrypted message 001" >OUTPUT
test_expect_equal_file TESTATTACHMENT OUTPUT test_expect_equal_file TESTATTACHMENT OUTPUT
test_begin_subtest "decryption failure with missing key" test_begin_subtest "decryption failure with missing key"
mv "${GNUPGHOME}"{,.bak} mv "${GNUPGHOME}"{,.bak}
output=$(notmuch show --format=json --decrypt subject:"test encrypted message 001" \ output=$(notmuch show --format=json --decrypt=true subject:"test encrypted message 001" \
| notmuch_json_show_sanitize \ | notmuch_json_show_sanitize \
| sed -e 's|"created": [1234567890]*|"created": 946728000|') | sed -e 's|"created": [1234567890]*|"created": 946728000|')
expected='[[[{"id": "XXXXX", expected='[[[{"id": "XXXXX",
@ -351,7 +351,7 @@ test_expect_success \
test_begin_subtest "decryption + signature verification" test_begin_subtest "decryption + signature verification"
test_subtest_broken_gmime_2 test_subtest_broken_gmime_2
output=$(notmuch show --format=json --decrypt subject:"test encrypted message 002" \ output=$(notmuch show --format=json --decrypt=true subject:"test encrypted message 002" \
| notmuch_json_show_sanitize \ | notmuch_json_show_sanitize \
| sed -e 's|"created": [1234567890]*|"created": 946728000|') | sed -e 's|"created": [1234567890]*|"created": 946728000|')
expected='[[[{"id": "XXXXX", expected='[[[{"id": "XXXXX",
@ -384,7 +384,7 @@ test_expect_equal_json \
"$expected" "$expected"
test_begin_subtest "reply to encrypted message" test_begin_subtest "reply to encrypted message"
output=$(notmuch reply --decrypt subject:"test encrypted message 002" \ output=$(notmuch reply --decrypt=true subject:"test encrypted message 002" \
| notmuch_drop_mail_headers In-Reply-To References) | notmuch_drop_mail_headers In-Reply-To References)
expected='From: Notmuch Test Suite <test_suite@notmuchmail.org> expected='From: Notmuch Test Suite <test_suite@notmuchmail.org>
Subject: Re: test encrypted message 002 Subject: Re: test encrypted message 002

View file

@ -197,14 +197,14 @@ test_expect_equal \
"$output" \ "$output" \
"$expected" "$expected"
test_begin_subtest "show one of the messages with --decrypt" test_begin_subtest "show one of the messages with --decrypt=true"
output=$(notmuch show --decrypt thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }') output=$(notmuch show --decrypt=true thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
expected='This is a test encrypted message with a wumpus.' expected='This is a test encrypted message with a wumpus.'
test_expect_equal \ test_expect_equal \
"$output" \ "$output" \
"$expected" "$expected"
test_begin_subtest "Ensure that we cannot show the message without --decrypt" test_begin_subtest "Ensure that we cannot show the message with --decrypt=auto"
output=$(notmuch show thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }') output=$(notmuch show thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
expected='Non-text part: application/octet-stream' expected='Non-text part: application/octet-stream'
test_expect_equal \ test_expect_equal \

View file

@ -65,4 +65,36 @@ flags 1
EOF EOF
test_expect_equal_file EXPECTED OUTPUT test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "test keyword arguments without value"
$TEST_DIRECTORY/arg-test --boolkeyword bananas > OUTPUT
cat <<EOF > EXPECTED
boolkeyword 1
positional arg 1 bananas
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "test keyword arguments with non-default value separted by a space"
$TEST_DIRECTORY/arg-test --boolkeyword false bananas > OUTPUT
cat <<EOF > EXPECTED
boolkeyword 0
positional arg 1 bananas
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "test keyword arguments without value at the end"
$TEST_DIRECTORY/arg-test bananas --boolkeyword > OUTPUT
cat <<EOF > EXPECTED
boolkeyword 1
positional arg 1 bananas
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "test keyword arguments without value but with = (should be an error)"
$TEST_DIRECTORY/arg-test bananas --boolkeyword= > OUTPUT 2>&1
cat <<EOF > EXPECTED
Unknown keyword argument "" for option "boolkeyword".
Unrecognized option: --boolkeyword=
EOF
test_expect_equal_file EXPECTED OUTPUT
test_done test_done

View file

@ -191,7 +191,7 @@ This is an error (see *Notmuch errors* for more details)
=== ERROR === === ERROR ===
[XXX] [XXX]
This is an error This is an error
command: YYY/notmuch_fail show --format\\=sexp --format-version\\=4 --decrypt --exclude\\=false \\' \\* \\' command: YYY/notmuch_fail show --format\\=sexp --format-version\\=4 --decrypt\\=true --exclude\\=false \\' \\* \\'
exit status: 1 exit status: 1
stderr: stderr:
This is an error This is an error

View file

@ -7,13 +7,14 @@ int main(int argc, char **argv){
int opt_index=1; int opt_index=1;
int kw_val=0; int kw_val=0;
int kwb_val=0;
int fl_val=0; int fl_val=0;
int int_val=0; int int_val=0;
const char *pos_arg1=NULL; const char *pos_arg1=NULL;
const char *pos_arg2=NULL; const char *pos_arg2=NULL;
const char *string_val=NULL; const char *string_val=NULL;
bool bool_val = false; bool bool_val = false;
bool fl_set = false, int_set = false, bool_set = false, bool fl_set = false, int_set = false, bool_set = false, kwb_set = false,
kw_set = false, string_set = false, pos1_set = false, pos2_set = false; kw_set = false, string_set = false, pos1_set = false, pos2_set = false;
notmuch_opt_desc_t parent_options[] = { notmuch_opt_desc_t parent_options[] = {
@ -33,6 +34,12 @@ int main(int argc, char **argv){
{ "one", 1 }, { "one", 1 },
{ "two", 2 }, { "two", 2 },
{ 0, 0 } } }, { 0, 0 } } },
{ .opt_keyword = &kwb_val, .name = "boolkeyword", .present = &kwb_set,
.keyword_no_arg_value = "true", .keywords =
(notmuch_keyword_t []){ { "false", 0 },
{ "true", 1 },
{ "auto", 2 },
{ 0, 0 } } },
{ .opt_inherit = parent_options }, { .opt_inherit = parent_options },
{ .opt_string = &string_val, .name = "string", .present = &string_set }, { .opt_string = &string_val, .name = "string", .present = &string_set },
{ .opt_position = &pos_arg1, .present = &pos1_set }, { .opt_position = &pos_arg1, .present = &pos1_set },
@ -51,6 +58,9 @@ int main(int argc, char **argv){
if (kw_set) if (kw_set)
printf("keyword %d\n", kw_val); printf("keyword %d\n", kw_val);
if (kwb_set)
printf("boolkeyword %d\n", kwb_val);
if (fl_set) if (fl_set)
printf("flags %d\n", fl_val); printf("flags %d\n", fl_val);

View file

@ -1 +1 @@
0.26~rc0 0.26~rc1