unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* Encourage explicit arguments for --decrypt in "show" and "reply"
@ 2017-12-12  0:18 Daniel Kahn Gillmor
  2017-12-12  0:18 ` [PATCH 1/3] cli: some keyword options can be supplied with no argument Daniel Kahn Gillmor
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  0:18 UTC (permalink / raw)
  To: Notmuch Mail

The notmuch indexing subcommands ("new", "insert", and "reindex") now
have a --decrypt option that takes an argument (the decryption
policy), since the session-keys patches have landed.

But the viewing subcommands ("show" and "reply") have their
traditional --decrypt option that (as a boolean) need not take an
argument, having --decrypt not present means something different from
either --decrypt=true or --decrypt=false.

This series allows the user to explicitly choose --decrypt=auto for
the viewing subcommands, while allowing people to use the
argument-free form (as an alias for --decrypt=true), but warns the
user to encourage them to switch to using an explicit argument
instead.

This is useful normalizing work for the interface, so it's worthwhile
on its own. It is also necessary preparation in the event that we
decide we want to:

 * set up a notmuch configuration option that changes the default for
   --decrypt for the viewing subcommands
 
 * allow "notmuch show" to actually index encrypted messages upon
   their first encounter (e.g., via a new decryption policy, which
   i'll propose separately)

As always, review and feedback welcome!

       --dkg

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/3] cli: some keyword options can be supplied with no argument
  2017-12-12  0:18 Encourage explicit arguments for --decrypt in "show" and "reply" Daniel Kahn Gillmor
@ 2017-12-12  0:18 ` Daniel Kahn Gillmor
  2017-12-12  0:18 ` [PATCH 2/3] cli/show: make --decrypt take a keyword Daniel Kahn Gillmor
  2017-12-12  0:18 ` [PATCH 3/3] cli/reply: " Daniel Kahn Gillmor
  2 siblings, 0 replies; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  0:18 UTC (permalink / raw)
  To: Notmuch Mail

We might change some notmuch command line tools that used to be
booleans into keyword arguments.

In that case, there are some legacy tools that will expect to be able
to do "notmuch foo --bar" instead of "notmuch foo --bar=baz".

This patch makes it possible to support that older API, while
providing a warning and an encouragement to upgrade.
---
 command-line-arguments.c      | 59 +++++++++++++++++++++++++++++++------------
 command-line-arguments.h      |  4 +++
 test/T410-argument-parsing.sh | 24 ++++++++++++++++++
 test/arg-test.c               | 12 ++++++++-
 4 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/command-line-arguments.c b/command-line-arguments.c
index db73ca5e..d0e21693 100644
--- a/command-line-arguments.c
+++ b/command-line-arguments.c
@@ -4,13 +4,19 @@
 #include "error_util.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
   output variable to the corresponding value.  Return false if nothing
   matches.
 */
 
-static bool
+static opt_handled
 _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next, const char *arg_str) {
 
     const notmuch_keyword_t *keywords;
@@ -29,16 +35,32 @@ _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next, const char
 	else
 	    *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')
 	fprintf (stderr, "Unknown keyword argument \"%s\" for option \"%s\".\n", arg_str, arg_desc->name);
     else
 	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, const char *arg_str) {
     bool value;
 
@@ -48,45 +70,45 @@ _process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next, const char
 	value = false;
     } else {
 	fprintf (stderr, "Unknown argument \"%s\" for (boolean) option \"%s\".\n", arg_str, arg_desc->name);
-	return false;
+	return OPT_FAILED;
     }
 
     *arg_desc->opt_bool = 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) {
 
     char *endptr;
     if (next == '\0' || arg_str[0] == '\0') {
 	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);
     if (*endptr == '\0')
-	return true;
+	return OPT_OK;
 
     fprintf (stderr, "Unable to parse argument \"%s\" for option \"%s\" as an integer.\n",
 	     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) {
 
     if (next == '\0') {
 	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) {
 	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;
-    return true;
+    return OPT_OK;
 }
 
 /* Return number of non-NULL opt_* fields in opt_desc. */
@@ -186,13 +208,15 @@ parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_
 	if (next != '=' && next != ':' && next != '\0')
 	    continue;
 
+	bool incremented = false;
 	if (next == '\0' && next_arg != NULL && ! try->opt_bool) {
 	    next = ' ';
 	    value = next_arg;
+	    incremented = true;
 	    opt_index ++;
 	}
 
-	bool opt_status = false;
+	opt_handled opt_status = OPT_FAILED;
 	if (try->opt_keyword || try->opt_flags)
 	    opt_status = _process_keyword_arg (try, next, value);
 	else if (try->opt_bool)
@@ -204,9 +228,12 @@ parse_option (int argc, char **argv, const notmuch_opt_desc_t *options, int opt_
 	else
 	    INTERNAL_ERROR ("unknown or unhandled option \"%s\"", try->name);
 
-	if (! opt_status)
+	if (opt_status == OPT_FAILED)
 	    return -1;
 
+	if (incremented && opt_status == OPT_GIVEBACK)
+	    opt_index --;
+
 	if (try->present)
 	    *try->present = true;
 
diff --git a/command-line-arguments.h b/command-line-arguments.h
index c0228f7c..f722f97d 100644
--- a/command-line-arguments.h
+++ b/command-line-arguments.h
@@ -26,6 +26,10 @@ typedef struct notmuch_opt_desc {
     const char **opt_string;
     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. */
     const char *name;
 
diff --git a/test/T410-argument-parsing.sh b/test/T410-argument-parsing.sh
index 71ed7e38..22f6742c 100755
--- a/test/T410-argument-parsing.sh
+++ b/test/T410-argument-parsing.sh
@@ -37,4 +37,28 @@ positional arg 1 false
 EOF
 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 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
diff --git a/test/arg-test.c b/test/arg-test.c
index 7aff8255..a218f967 100644
--- a/test/arg-test.c
+++ b/test/arg-test.c
@@ -7,13 +7,14 @@ int main(int argc, char **argv){
     int opt_index=1;
 
     int kw_val=0;
+    int kwb_val=0;
     int fl_val=0;
     int int_val=0;
     const char *pos_arg1=NULL;
     const char *pos_arg2=NULL;
     const char *string_val=NULL;
     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;
 
     notmuch_opt_desc_t parent_options[] = {
@@ -33,6 +34,12 @@ int main(int argc, char **argv){
 				  { "one", 1 },
 				  { "two", 2 },
 				  { 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_string = &string_val, .name = "string", .present = &string_set },
 	{ .opt_position = &pos_arg1, .present = &pos1_set },
@@ -51,6 +58,9 @@ int main(int argc, char **argv){
     if (kw_set)
 	printf("keyword %d\n", kw_val);
 
+    if (kwb_set)
+	printf("boolkeyword %d\n", kwb_val);
+
     if (fl_set)
 	printf("flags %d\n", fl_val);
 
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] cli/show: make --decrypt take a keyword.
  2017-12-12  0:18 Encourage explicit arguments for --decrypt in "show" and "reply" Daniel Kahn Gillmor
  2017-12-12  0:18 ` [PATCH 1/3] cli: some keyword options can be supplied with no argument Daniel Kahn Gillmor
@ 2017-12-12  0:18 ` Daniel Kahn Gillmor
  2017-12-12  2:33   ` [PATCH v2] " Daniel Kahn Gillmor
  2017-12-12  0:18 ` [PATCH 3/3] cli/reply: " Daniel Kahn Gillmor
  2 siblings, 1 reply; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  0:18 UTC (permalink / raw)
  To: Notmuch Mail

We also expand tab completion for it, and update T357 to match.

Make use of the bool-to-keyword backward-compatibility feature.
---
 completion/notmuch-completion.bash |  6 +++++-
 doc/man1/notmuch-show.rst          | 37 +++++++++++++++++++++----------------
 notmuch-show.c                     | 27 +++++++++++++--------------
 test/T357-index-decryption.sh      |  6 +++---
 4 files changed, 42 insertions(+), 34 deletions(-)

diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
index fb093de8..4ab2e5f6 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -517,10 +517,14 @@ _notmuch_show()
 	    COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
 	    return
 	    ;;
-	--exclude|--body|--decrypt)
+	--exclude|--body)
 	    COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
 	    return
 	    ;;
+        --decrypt)
+	    COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) )
+	    return
+	    ;;
     esac
 
     ! $split &&
diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index 64caa7a6..7d2b38cb 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -115,22 +115,27 @@ Supported options for **show** include
         supported with --format=json and --format=sexp), and the
         multipart/signed part will be replaced by the signed data.
 
-    ``--decrypt``
-        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 decrypted automatically unless the user explicitly
-        sets ``--decrypt=false``.
-
-        Decryption expects a functioning **gpg-agent(1)** to provide any
-        needed credentials. Without one, the decryption will fail.
-
-        Implies --verify.
+    ``--decrypt=(false|auto|true)``
+        If ``true``, decrypt any MIME encrypted parts found in the
+        selected content (i.e. "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 ``auto``, and a session key is already known for the
+        message, then it will be decrypted, but notmuch will not try
+        to access the user's 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 fail.
+
+        Note: ``true`` implies --verify.
+
+        Default: ``auto``
 
     ``--exclude=(true|false)``
         Specify whether to omit threads only matching
diff --git a/notmuch-show.c b/notmuch-show.c
index d5adc370..ddd3c8c5 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1085,8 +1085,6 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
     bool exclude = true;
     bool entire_thread_set = false;
     bool single_message;
-    bool decrypt = false;
-    bool decrypt_set = false;
 
     notmuch_opt_desc_t options[] = {
 	{ .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",
 	  .present = &entire_thread_set },
 	{ .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.output_body, .name = "body" },
 	{ .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]);
 
-    if (decrypt_set) {
-	if (decrypt) {
-	    /* we do not need or want to ask for session keys */
-	    params.crypto.decrypt = NOTMUCH_DECRYPT_NOSTASH;
-	    /* decryption implies verification */
-	    params.crypto.verify = true;
-	} else {
-	    params.crypto.decrypt = NOTMUCH_DECRYPT_FALSE;
-	}
-    }
+    /* explicit decryption implies verification */
+    if (params.crypto.decrypt == NOTMUCH_DECRYPT_NOSTASH)
+	params.crypto.verify = true;
 
     /* specifying a part implies single message display */
     single_message = params.part >= 0;
@@ -1186,8 +1182,11 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
     params.crypto.gpgpath = notmuch_config_get_crypto_gpg_path (config);
 #endif
 
+    notmuch_database_mode_t mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
+    if (params.crypto.decrypt == NOTMUCH_DECRYPT_TRUE)
+	mode = NOTMUCH_DATABASE_MODE_READ_WRITE;
     if (notmuch_database_open (notmuch_config_get_database_path (config),
-			       NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))
+			       mode, &notmuch))
 	return EXIT_FAILURE;
 
     notmuch_exit_if_unmatched_db_uuid (notmuch);
diff --git a/test/T357-index-decryption.sh b/test/T357-index-decryption.sh
index 6b8a8261..2b8e05b8 100755
--- a/test/T357-index-decryption.sh
+++ b/test/T357-index-decryption.sh
@@ -197,14 +197,14 @@ test_expect_equal \
     "$output" \
     "$expected"
 
-test_begin_subtest "show one of the messages with --decrypt"
-output=$(notmuch show --decrypt thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
+test_begin_subtest "show one of the messages with --decrypt=true"
+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.'
 test_expect_equal \
     "$output" \
     "$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 }')
 expected='Non-text part: application/octet-stream'
 test_expect_equal \
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] cli/reply: make --decrypt take a keyword
  2017-12-12  0:18 Encourage explicit arguments for --decrypt in "show" and "reply" Daniel Kahn Gillmor
  2017-12-12  0:18 ` [PATCH 1/3] cli: some keyword options can be supplied with no argument Daniel Kahn Gillmor
  2017-12-12  0:18 ` [PATCH 2/3] cli/show: make --decrypt take a keyword Daniel Kahn Gillmor
@ 2017-12-12  0:18 ` Daniel Kahn Gillmor
  2017-12-12  6:52   ` [PATCH v2] " Daniel Kahn Gillmor
  2 siblings, 1 reply; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  0:18 UTC (permalink / raw)
  To: Notmuch Mail

This brings the --decrypt argument to "notmuch reply" into line with
the other --decrypt arguments (in "show", "new", "insert", and
"reindex").  This patch is really just about bringing consistency to
the user interface.
---
 completion/notmuch-completion.bash |  2 +-
 doc/man1/notmuch-reply.rst         | 34 ++++++++++++++++++++--------------
 notmuch-reply.c                    | 11 ++++++-----
 3 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
index 4ab2e5f6..a24b8a08 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -351,7 +351,7 @@ _notmuch_reply()
 	    return
 	    ;;
 	--decrypt)
-	    COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
+	    COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) )
 	    return
 	    ;;
     esac
diff --git a/doc/man1/notmuch-reply.rst b/doc/man1/notmuch-reply.rst
index ede77930..1b62e075 100644
--- a/doc/man1/notmuch-reply.rst
+++ b/doc/man1/notmuch-reply.rst
@@ -72,20 +72,26 @@ Supported options for **reply** include
             in this order, and copy values from the first that contains
             something other than only the user's addresses.
 
-    ``--decrypt``
-        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 decrypted automatically unless the user explicitly
-        sets ``--decrypt=false``.
-
-        Decryption expects a functioning **gpg-agent(1)** to provide any
-        needed credentials. Without one, the decryption will likely fail.
+    ``--decrypt=(false|auto|true)``
+
+        If ``true``, decrypt any MIME encrypted parts found in the
+        selected content (i.e., "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 ``auto``, and a session key is already known for the
+        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
 <search-terms>.
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 5cdf642b..75cf7ecb 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -704,8 +704,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
     };
     int format = FORMAT_DEFAULT;
     int reply_all = true;
-    bool decrypt = false;
-    bool decrypt_set = false;
 
     notmuch_opt_desc_t options[] = {
 	{ .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 },
 				  { "sender", false },
 				  { 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 },
 	{ }
     };
@@ -729,8 +732,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
 	return EXIT_FAILURE;
 
     notmuch_process_shared_options (argv[0]);
-    if (decrypt_set)
-	params.crypto.decrypt = decrypt ? NOTMUCH_DECRYPT_NOSTASH : NOTMUCH_DECRYPT_FALSE;
 
     notmuch_exit_if_unsupported_format ();
 
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2] cli/show: make --decrypt take a keyword.
  2017-12-12  0:18 ` [PATCH 2/3] cli/show: make --decrypt take a keyword Daniel Kahn Gillmor
@ 2017-12-12  2:33   ` Daniel Kahn Gillmor
  2017-12-12  2:36     ` Daniel Kahn Gillmor
  2017-12-12  6:51     ` [PATCH v3] " Daniel Kahn Gillmor
  0 siblings, 2 replies; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  2:33 UTC (permalink / raw)
  To: Notmuch Mail

We also expand tab completion for it, and update T357 to match.

Make use of the bool-to-keyword backward-compatibility feature.
---
 completion/notmuch-completion.bash |  6 +++++-
 doc/man1/notmuch-show.rst          | 37 +++++++++++++++++++++----------------
 notmuch-show.c                     | 22 +++++++++-------------
 test/T357-index-decryption.sh      |  6 +++---
 4 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
index fb093de8..4ab2e5f6 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -517,10 +517,14 @@ _notmuch_show()
 	    COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
 	    return
 	    ;;
-	--exclude|--body|--decrypt)
+	--exclude|--body)
 	    COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
 	    return
 	    ;;
+        --decrypt)
+	    COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) )
+	    return
+	    ;;
     esac
 
     ! $split &&
diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index 64caa7a6..7d2b38cb 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -115,22 +115,27 @@ Supported options for **show** include
         supported with --format=json and --format=sexp), and the
         multipart/signed part will be replaced by the signed data.
 
-    ``--decrypt``
-        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 decrypted automatically unless the user explicitly
-        sets ``--decrypt=false``.
-
-        Decryption expects a functioning **gpg-agent(1)** to provide any
-        needed credentials. Without one, the decryption will fail.
-
-        Implies --verify.
+    ``--decrypt=(false|auto|true)``
+        If ``true``, decrypt any MIME encrypted parts found in the
+        selected content (i.e. "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 ``auto``, and a session key is already known for the
+        message, then it will be decrypted, but notmuch will not try
+        to access the user's 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 fail.
+
+        Note: ``true`` implies --verify.
+
+        Default: ``auto``
 
     ``--exclude=(true|false)``
         Specify whether to omit threads only matching
diff --git a/notmuch-show.c b/notmuch-show.c
index d5adc370..9871159d 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1085,8 +1085,6 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
     bool exclude = true;
     bool entire_thread_set = false;
     bool single_message;
-    bool decrypt = false;
-    bool decrypt_set = false;
 
     notmuch_opt_desc_t options[] = {
 	{ .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",
 	  .present = &entire_thread_set },
 	{ .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.output_body, .name = "body" },
 	{ .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]);
 
-    if (decrypt_set) {
-	if (decrypt) {
-	    /* we do not need or want to ask for session keys */
-	    params.crypto.decrypt = NOTMUCH_DECRYPT_NOSTASH;
-	    /* decryption implies verification */
-	    params.crypto.verify = true;
-	} else {
-	    params.crypto.decrypt = NOTMUCH_DECRYPT_FALSE;
-	}
-    }
+    /* explicit decryption implies verification */
+    if (params.crypto.decrypt == NOTMUCH_DECRYPT_NOSTASH)
+	params.crypto.verify = true;
 
     /* specifying a part implies single message display */
     single_message = params.part >= 0;
diff --git a/test/T357-index-decryption.sh b/test/T357-index-decryption.sh
index 6b8a8261..2b8e05b8 100755
--- a/test/T357-index-decryption.sh
+++ b/test/T357-index-decryption.sh
@@ -197,14 +197,14 @@ test_expect_equal \
     "$output" \
     "$expected"
 
-test_begin_subtest "show one of the messages with --decrypt"
-output=$(notmuch show --decrypt thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
+test_begin_subtest "show one of the messages with --decrypt=true"
+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.'
 test_expect_equal \
     "$output" \
     "$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 }')
 expected='Non-text part: application/octet-stream'
 test_expect_equal \
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] cli/show: make --decrypt take a keyword.
  2017-12-12  2:33   ` [PATCH v2] " Daniel Kahn Gillmor
@ 2017-12-12  2:36     ` Daniel Kahn Gillmor
  2017-12-12  6:51     ` [PATCH v3] " Daniel Kahn Gillmor
  1 sibling, 0 replies; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  2:36 UTC (permalink / raw)
  To: Notmuch Mail

On Mon 2017-12-11 21:33:57 -0500, Daniel Kahn Gillmor wrote:
> We also expand tab completion for it, and update T357 to match.
>
> Make use of the bool-to-keyword backward-compatibility feature.

v2 of this patch just removes an unnecessary attempt to open the
database read-write.  That isn't necessary here, though it will be
necessary if we want to enable future versions of "notmuch show" that
can also interactively add a message to the index.

I removed it from this series so that the interface normalization here
(which is valuable whether or not we decide to augment "notmuch show" as
described) doesn't get distracted by the change.

sorry for the quick revision.

      --dkg

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v3] cli/show: make --decrypt take a keyword.
  2017-12-12  2:33   ` [PATCH v2] " Daniel Kahn Gillmor
  2017-12-12  2:36     ` Daniel Kahn Gillmor
@ 2017-12-12  6:51     ` Daniel Kahn Gillmor
  2017-12-12  6:56       ` Daniel Kahn Gillmor
  1 sibling, 1 reply; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  6:51 UTC (permalink / raw)
  To: Notmuch Mail

We also expand tab completion for it, update the emacs bindings, and
update T350, T357, and T450 to match.

Make use of the bool-to-keyword backward-compatibility feature.
---
 completion/notmuch-completion.bash |  6 +++++-
 doc/man1/notmuch-show.rst          | 37 +++++++++++++++++++++----------------
 emacs/notmuch-lib.el               |  2 +-
 emacs/notmuch-query.el             |  2 +-
 notmuch-show.c                     | 22 +++++++++-------------
 test/T350-crypto.sh                | 12 ++++++------
 test/T357-index-decryption.sh      |  6 +++---
 test/T450-emacs-show.sh            |  2 +-
 8 files changed, 47 insertions(+), 42 deletions(-)

diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
index fb093de8..4ab2e5f6 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -517,10 +517,14 @@ _notmuch_show()
 	    COMPREPLY=( $( compgen -W "text json sexp mbox raw" -- "${cur}" ) )
 	    return
 	    ;;
-	--exclude|--body|--decrypt)
+	--exclude|--body)
 	    COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
 	    return
 	    ;;
+        --decrypt)
+	    COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) )
+	    return
+	    ;;
     esac
 
     ! $split &&
diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst
index 64caa7a6..7d2b38cb 100644
--- a/doc/man1/notmuch-show.rst
+++ b/doc/man1/notmuch-show.rst
@@ -115,22 +115,27 @@ Supported options for **show** include
         supported with --format=json and --format=sexp), and the
         multipart/signed part will be replaced by the signed data.
 
-    ``--decrypt``
-        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 decrypted automatically unless the user explicitly
-        sets ``--decrypt=false``.
-
-        Decryption expects a functioning **gpg-agent(1)** to provide any
-        needed credentials. Without one, the decryption will fail.
-
-        Implies --verify.
+    ``--decrypt=(false|auto|true)``
+        If ``true``, decrypt any MIME encrypted parts found in the
+        selected content (i.e. "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 ``auto``, and a session key is already known for the
+        message, then it will be decrypted, but notmuch will not try
+        to access the user's 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 fail.
+
+        Note: ``true`` implies --verify.
+
+        Default: ``auto``
 
     ``--exclude=(true|false)``
         Specify whether to omit threads only matching
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 010be454..a7e02710 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -593,7 +593,7 @@ the given type."
 		       (set-buffer-multibyte nil))
 		     (let ((args `("show" "--format=raw"
 				   ,(format "--part=%s" (plist-get part :id))
-				   ,@(when process-crypto '("--decrypt"))
+				   ,@(when process-crypto '("--decrypt=true"))
 				   ,(notmuch-id-to-query (plist-get msg :id))))
 			   (coding-system-for-read
 			    (if binaryp 'no-conversion
diff --git a/emacs/notmuch-query.el b/emacs/notmuch-query.el
index 592fd8f1..563e4acf 100644
--- a/emacs/notmuch-query.el
+++ b/emacs/notmuch-query.el
@@ -32,7 +32,7 @@ is a possibly empty forest of replies.
 "
   (let ((args '("show" "--format=sexp" "--format-version=4")))
     (if notmuch-show-process-crypto
-	(setq args (append args '("--decrypt"))))
+	(setq args (append args '("--decrypt=true"))))
     (setq args (append args search-terms))
     (apply #'notmuch-call-notmuch-sexp args)))
 
diff --git a/notmuch-show.c b/notmuch-show.c
index d5adc370..9871159d 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1085,8 +1085,6 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
     bool exclude = true;
     bool entire_thread_set = false;
     bool single_message;
-    bool decrypt = false;
-    bool decrypt_set = false;
 
     notmuch_opt_desc_t options[] = {
 	{ .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",
 	  .present = &entire_thread_set },
 	{ .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.output_body, .name = "body" },
 	{ .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]);
 
-    if (decrypt_set) {
-	if (decrypt) {
-	    /* we do not need or want to ask for session keys */
-	    params.crypto.decrypt = NOTMUCH_DECRYPT_NOSTASH;
-	    /* decryption implies verification */
-	    params.crypto.verify = true;
-	} else {
-	    params.crypto.decrypt = NOTMUCH_DECRYPT_FALSE;
-	}
-    }
+    /* explicit decryption implies verification */
+    if (params.crypto.decrypt == NOTMUCH_DECRYPT_NOSTASH)
+	params.crypto.verify = true;
 
     /* specifying a part implies single message display */
     single_message = params.part >= 0;
diff --git a/test/T350-crypto.sh b/test/T350-crypto.sh
index 38615677..761ff553 100755
--- a/test/T350-crypto.sh
+++ b/test/T350-crypto.sh
@@ -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_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 \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='\fmessage{ id:XXXXX depth:0 match:1 excluded:0 filename:XXXXX
@@ -255,7 +255,7 @@ test_expect_equal \
     "$expected"
 
 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 \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
@@ -293,7 +293,7 @@ test_expect_equal_json \
     "$expected"
 
 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 \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='{"id": 4,
@@ -307,13 +307,13 @@ test_begin_subtest "decrypt attachment (--part=5 --format=raw)"
 notmuch show \
     --format=raw \
     --part=5 \
-    --decrypt \
+    --decrypt=true \
     subject:"test encrypted message 001" >OUTPUT
 test_expect_equal_file TESTATTACHMENT OUTPUT
 
 test_begin_subtest "decryption failure with missing key"
 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 \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
@@ -351,7 +351,7 @@ test_expect_success \
 
 test_begin_subtest "decryption + signature verification"
 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 \
     | sed -e 's|"created": [1234567890]*|"created": 946728000|')
 expected='[[[{"id": "XXXXX",
diff --git a/test/T357-index-decryption.sh b/test/T357-index-decryption.sh
index 6b8a8261..2b8e05b8 100755
--- a/test/T357-index-decryption.sh
+++ b/test/T357-index-decryption.sh
@@ -197,14 +197,14 @@ test_expect_equal \
     "$output" \
     "$expected"
 
-test_begin_subtest "show one of the messages with --decrypt"
-output=$(notmuch show --decrypt thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
+test_begin_subtest "show one of the messages with --decrypt=true"
+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.'
 test_expect_equal \
     "$output" \
     "$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 }')
 expected='Non-text part: application/octet-stream'
 test_expect_equal \
diff --git a/test/T450-emacs-show.sh b/test/T450-emacs-show.sh
index 8db0e49b..3555a939 100755
--- a/test/T450-emacs-show.sh
+++ b/test/T450-emacs-show.sh
@@ -191,7 +191,7 @@ This is an error (see *Notmuch errors* for more details)
 === ERROR ===
 [XXX]
 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
 stderr:
 This is an error
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2] cli/reply: make --decrypt take a keyword
  2017-12-12  0:18 ` [PATCH 3/3] cli/reply: " Daniel Kahn Gillmor
@ 2017-12-12  6:52   ` Daniel Kahn Gillmor
  2017-12-12  6:57     ` Daniel Kahn Gillmor
  0 siblings, 1 reply; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  6:52 UTC (permalink / raw)
  To: Notmuch Mail

This brings the --decrypt argument to "notmuch reply" into line with
the other --decrypt arguments (in "show", "new", "insert", and
"reindex").  This patch is really just about bringing consistency to
the user interface.

We also use the recommended form in the emacs MUA when replying, and
update test T350 to match.
---
 completion/notmuch-completion.bash |  2 +-
 doc/man1/notmuch-reply.rst         | 34 ++++++++++++++++++++--------------
 emacs/notmuch-mua.el               |  2 +-
 notmuch-reply.c                    | 11 ++++++-----
 test/T350-crypto.sh                |  2 +-
 5 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
index 4ab2e5f6..a24b8a08 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -351,7 +351,7 @@ _notmuch_reply()
 	    return
 	    ;;
 	--decrypt)
-	    COMPREPLY=( $( compgen -W "true false" -- "${cur}" ) )
+	    COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) )
 	    return
 	    ;;
     esac
diff --git a/doc/man1/notmuch-reply.rst b/doc/man1/notmuch-reply.rst
index ede77930..1b62e075 100644
--- a/doc/man1/notmuch-reply.rst
+++ b/doc/man1/notmuch-reply.rst
@@ -72,20 +72,26 @@ Supported options for **reply** include
             in this order, and copy values from the first that contains
             something other than only the user's addresses.
 
-    ``--decrypt``
-        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 decrypted automatically unless the user explicitly
-        sets ``--decrypt=false``.
-
-        Decryption expects a functioning **gpg-agent(1)** to provide any
-        needed credentials. Without one, the decryption will likely fail.
+    ``--decrypt=(false|auto|true)``
+
+        If ``true``, decrypt any MIME encrypted parts found in the
+        selected content (i.e., "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 ``auto``, and a session key is already known for the
+        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
 <search-terms>.
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 7a341ebf..59b546a6 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -181,7 +181,7 @@ mutiple parts get a header."
 	reply
 	original)
     (when process-crypto
-      (setq args (append args '("--decrypt"))))
+      (setq args (append args '("--decrypt=true"))))
 
     (if reply-all
 	(setq args (append args '("--reply-to=all")))
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 5cdf642b..75cf7ecb 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -704,8 +704,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
     };
     int format = FORMAT_DEFAULT;
     int reply_all = true;
-    bool decrypt = false;
-    bool decrypt_set = false;
 
     notmuch_opt_desc_t options[] = {
 	{ .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 },
 				  { "sender", false },
 				  { 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 },
 	{ }
     };
@@ -729,8 +732,6 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
 	return EXIT_FAILURE;
 
     notmuch_process_shared_options (argv[0]);
-    if (decrypt_set)
-	params.crypto.decrypt = decrypt ? NOTMUCH_DECRYPT_NOSTASH : NOTMUCH_DECRYPT_FALSE;
 
     notmuch_exit_if_unsupported_format ();
 
diff --git a/test/T350-crypto.sh b/test/T350-crypto.sh
index 761ff553..a776ec35 100755
--- a/test/T350-crypto.sh
+++ b/test/T350-crypto.sh
@@ -384,7 +384,7 @@ test_expect_equal_json \
     "$expected"
 
 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)
 expected='From: Notmuch Test Suite <test_suite@notmuchmail.org>
 Subject: Re: test encrypted message 002
-- 
2.15.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v3] cli/show: make --decrypt take a keyword.
  2017-12-12  6:51     ` [PATCH v3] " Daniel Kahn Gillmor
@ 2017-12-12  6:56       ` Daniel Kahn Gillmor
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  6:56 UTC (permalink / raw)
  To: Notmuch Mail

On Tue 2017-12-12 01:51:57 -0500, Daniel Kahn Gillmor wrote:
> We also expand tab completion for it, update the emacs bindings, and
> update T350, T357, and T450 to match.
>
> Make use of the bool-to-keyword backward-compatibility feature.

and now revision 3 of this patch includes transitioning the emacs
bindings to use explicit arguments for --decrypt, and covering the rest
of the test suite as well.

I think it's settled down now. :)

  --dkg

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2] cli/reply: make --decrypt take a keyword
  2017-12-12  6:52   ` [PATCH v2] " Daniel Kahn Gillmor
@ 2017-12-12  6:57     ` Daniel Kahn Gillmor
  0 siblings, 0 replies; 10+ messages in thread
From: Daniel Kahn Gillmor @ 2017-12-12  6:57 UTC (permalink / raw)
  To: Notmuch Mail

On Tue 2017-12-12 01:52:52 -0500, Daniel Kahn Gillmor wrote:
> This brings the --decrypt argument to "notmuch reply" into line with
> the other --decrypt arguments (in "show", "new", "insert", and
> "reindex").  This patch is really just about bringing consistency to
> the user interface.

v2 of this patch covers:

> We also use the recommended form in the emacs MUA when replying, and
> update test T350 to match.

  --dkg

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2017-12-12  6:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-12  0:18 Encourage explicit arguments for --decrypt in "show" and "reply" Daniel Kahn Gillmor
2017-12-12  0:18 ` [PATCH 1/3] cli: some keyword options can be supplied with no argument Daniel Kahn Gillmor
2017-12-12  0:18 ` [PATCH 2/3] cli/show: make --decrypt take a keyword Daniel Kahn Gillmor
2017-12-12  2:33   ` [PATCH v2] " Daniel Kahn Gillmor
2017-12-12  2:36     ` Daniel Kahn Gillmor
2017-12-12  6:51     ` [PATCH v3] " Daniel Kahn Gillmor
2017-12-12  6:56       ` Daniel Kahn Gillmor
2017-12-12  0:18 ` [PATCH 3/3] cli/reply: " Daniel Kahn Gillmor
2017-12-12  6:52   ` [PATCH v2] " Daniel Kahn Gillmor
2017-12-12  6:57     ` Daniel Kahn Gillmor

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).