Re: [PATCH] cli: add support for only printing the addresses in notmuch address

2017-12-19 Thread Jameson Graef Rollins
On Wed, Dec 20 2017, Jani Nikula  wrote:
> ~$ notmuch address --output=sender --output=recipients --output=address 
> --output=count id:878tdy8a2q@ligo.caltech.edu
> 1 notmuch@notmuchmail.org
> 1 jroll...@finestructure.net
> 1 d...@fifthhorseman.net
> 1 j...@nikula.org
>
> I prefer this to separate options.

Really?  If each is just a switch then why not:

~$ notmuch address --sender --recipients --address --count 
id:878tdy8a2q@ligo.caltech.edu

?  It's just shorter, right?

Also, this behavior is quite different than for search, in which only
the last --output applies.

> notmuch search uses separate --entire-thread, --body, and --include-html
> options, and I think those are getting messy.

The seem less messy than a "--output=" prefixed version of the same.

jamie.


signature.asc
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] cli: add support for only printing the addresses in notmuch address

2017-12-19 Thread Jani Nikula
On Tue, 19 Dec 2017, Jameson Graef Rollins  wrote:
> On Tue, Dec 19 2017, Daniel Kahn Gillmor  wrote:
>> On Tue 2017-12-19 13:23:55 -0800, Jameson Graef Rollins wrote:
>>> On Thu, Nov 02 2017, Jani Nikula  wrote:
 The notmuch address output is much more useful for scripts with just
 the addresses printed. Support this using the --output=address option.
>>>
>>> Isn't "address" kind of orthogonal to "sender" and "recipient"?  Isn't
>>> this more like the --output/--format distinction in search?
>>
>> i think i agree with Jamie here -- it'd be nice to be able to ask for
>> the addresses of the senders, or the addresses of the recipients.  how
>> would that be done here?
>
> Sorry, I see now that address already has the --format option with the
> expected values.  So I think either address-only or sender/recipient
> should be a separate option.

Note that you can give the notmuch address --output option multiple
times to control the output. For example,

~$ notmuch address --output=sender --output=recipients 
id:878tdy8a2q@ligo.caltech.edu
Jameson Graef Rollins 
Daniel Kahn Gillmor 
Jani Nikula 
notmuch@notmuchmail.org

~$ notmuch address --output=recipients --output=address 
id:878tdy8a2q@ligo.caltech.edu
d...@fifthhorseman.net
j...@nikula.org
notmuch@notmuchmail.org

~$ notmuch address --output=sender --output=recipients --output=address 
--output=count id:878tdy8a2q@ligo.caltech.edu
1   notmuch@notmuchmail.org
1   jroll...@finestructure.net
1   d...@fifthhorseman.net
1   j...@nikula.org

I prefer this to separate options.

notmuch search uses separate --entire-thread, --body, and --include-html
options, and I think those are getting messy.

BR,
Jani.
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Notmuch Emacs: tab completion for tags in Fcc:

2017-12-19 Thread Alex Abdo

All,

One small suggestion for Notmuch Emacs: it would be nice if there were 
tab completion for tags (and, if possible, folders) in the Fcc header 
when composing messages in Emacs.


There is already tab completion for tags in a number of other places, 
but for some reason, there isn’t tab completion in the Fcc header.


I’m not a programmer by trade (and in my limited tinkering, I 
haven’t touched Lisp or Elisp), but I’d be happy to give it a shot 
if someone pointed me to the right location in the code.


Thanks,
Alex

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] cli: add support for only printing the addresses in notmuch address

2017-12-19 Thread Jameson Graef Rollins
On Tue, Dec 19 2017, Daniel Kahn Gillmor  wrote:
> On Tue 2017-12-19 13:23:55 -0800, Jameson Graef Rollins wrote:
>> On Thu, Nov 02 2017, Jani Nikula  wrote:
>>> The notmuch address output is much more useful for scripts with just
>>> the addresses printed. Support this using the --output=address option.
>>
>> Isn't "address" kind of orthogonal to "sender" and "recipient"?  Isn't
>> this more like the --output/--format distinction in search?
>
> i think i agree with Jamie here -- it'd be nice to be able to ask for
> the addresses of the senders, or the addresses of the recipients.  how
> would that be done here?

Sorry, I see now that address already has the --format option with the
expected values.  So I think either address-only or sender/recipient
should be a separate option.

jamie.


signature.asc
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] cli: add support for only printing the addresses in notmuch address

2017-12-19 Thread Daniel Kahn Gillmor
On Tue 2017-12-19 13:23:55 -0800, Jameson Graef Rollins wrote:
> On Thu, Nov 02 2017, Jani Nikula  wrote:
>> The notmuch address output is much more useful for scripts with just
>> the addresses printed. Support this using the --output=address option.
>
> Isn't "address" kind of orthogonal to "sender" and "recipient"?  Isn't
> this more like the --output/--format distinction in search?

i think i agree with Jamie here -- it'd be nice to be able to ask for
the addresses of the senders, or the addresses of the recipients.  how
would that be done here?

  --dkg
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] cli: add support for only printing the addresses in notmuch address

2017-12-19 Thread Jameson Graef Rollins
On Thu, Nov 02 2017, Jani Nikula  wrote:
> The notmuch address output is much more useful for scripts with just
> the addresses printed. Support this using the --output=address option.

Isn't "address" kind of orthogonal to "sender" and "recipient"?  Isn't
this more like the --output/--format distinction in search?

jamie.


signature.asc
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v4] python: add decrypt_policy argument to Database.index_file()

2017-12-19 Thread Daniel Kahn Gillmor
On Tue 2017-12-19 07:23:35 -0400, David Bremner wrote:
> Daniel Kahn Gillmor  writes:
>
>> +Date: $(date -R)
>> +Message-ID: 
>> +MIME-Version: 1.0
>> +Content-Type: multipart/encrypted; boundary="=-=-=";
>> +protocol="application/pgp-encrypted"
>> +
>
> Can you explain why you explicitely set the date here? it seems to make
> the test less reproducible. In the end it doesn't matter much because
> your test ignores the date, but I feel like I'm missing something.

There's no good reason for setting it explicitly to "now" in this test.
I'll send a revised patch with a static datestring.

Sorry for the distraction!

--dkg


signature.asc
Description: PGP signature
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v5] python: add decrypt_policy argument to Database.index_file()

2017-12-19 Thread Daniel Kahn Gillmor
We adopt a pythonic idiom here with an optional argument, rather than
exposing the user to the C indexopts object directly.

This now includes a simple test to ensure that the decrypt_policy
argument works as expected.
---
 bindings/python/notmuch/database.py | 45 +++--
 bindings/python/notmuch/globals.py  |  5 +
 test/T390-python.sh | 39 
 3 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/bindings/python/notmuch/database.py 
b/bindings/python/notmuch/database.py
index fe09b330..a1ae14fc 100644
--- a/bindings/python/notmuch/database.py
+++ b/bindings/python/notmuch/database.py
@@ -29,6 +29,7 @@ from .globals import (
 NotmuchConfigListP,
 NotmuchDatabaseP,
 NotmuchDirectoryP,
+NotmuchIndexoptsP,
 NotmuchMessageP,
 NotmuchTagsP,
 )
@@ -73,6 +74,9 @@ class Database(object):
 MODE = Enum(['READ_ONLY', 'READ_WRITE'])
 """Constants: Mode in which to open the database"""
 
+DECRYPTION_POLICY = Enum(['FALSE', 'TRUE', 'AUTO', 'NOSTASH'])
+"""Constants: policies for decrypting messages during indexing"""
+
 """notmuch_database_get_directory"""
 _get_directory = nmlib.notmuch_database_get_directory
 _get_directory.argtypes = [NotmuchDatabaseP, c_char_p, 
POINTER(NotmuchDirectoryP)]
@@ -401,13 +405,25 @@ class Database(object):
 # return the Directory, init it with the absolute path
 return Directory(abs_dirpath, dir_p, self)
 
+_get_default_indexopts = nmlib.notmuch_database_get_default_indexopts
+_get_default_indexopts.argtypes = [NotmuchDatabaseP]
+_get_default_indexopts.restype = NotmuchIndexoptsP
+
+_indexopts_set_decrypt_policy = nmlib.notmuch_indexopts_set_decrypt_policy
+_indexopts_set_decrypt_policy.argtypes = [NotmuchIndexoptsP, c_uint]
+_indexopts_set_decrypt_policy.restype = None
+
+_indexopts_destroy = nmlib.notmuch_indexopts_destroy
+_indexopts_destroy.argtypes = [NotmuchIndexoptsP]
+_indexopts_destroy.restype = None
+
 _index_file = nmlib.notmuch_database_index_file
 _index_file.argtypes = [NotmuchDatabaseP, c_char_p,
  c_void_p,
  POINTER(NotmuchMessageP)]
 _index_file.restype = c_uint
 
-def index_file(self, filename, sync_maildir_flags=False):
+def index_file(self, filename, sync_maildir_flags=False, 
decrypt_policy=None):
 """Adds a new message to the database
 
 :param filename: should be a path relative to the path of the
@@ -428,6 +444,23 @@ class Database(object):
 API. You might want to look into the underlying method
 :meth:`Message.maildir_flags_to_tags`.
 
+:param decrypt_policy: If the message contains any encrypted
+parts, and decrypt_policy is set to
+:attr:`DECRYPTION_POLICY`.TRUE, notmuch will try to
+decrypt the message and index the cleartext, stashing any
+discovered session keys.  If it is set to
+:attr:`DECRYPTION_POLICY`.FALSE, it will never try to
+decrypt during indexing.  If it is set to
+:attr:`DECRYPTION_POLICY`.AUTO, then it will try to use
+any stashed session keys it knows about, but will not try
+to access the user's secret keys.
+:attr:`DECRYPTION_POLICY`.NOSTASH behaves the same as
+:attr:`DECRYPTION_POLICY`.TRUE except that no session keys
+are stashed in the database.  If decrypt_policy is set to
+None (the default), then the database itself will decide
+whether to decrypt, based on the `index.decrypt`
+configuration setting (see notmuch-config(1)).
+
 :returns: On success, we return
 
1) a :class:`Message` object that can be used for things
@@ -458,7 +491,15 @@ class Database(object):
 """
 self._assert_db_is_initialized()
 msg_p = NotmuchMessageP()
-status = self._index_file(self._db, _str(filename), c_void_p(None), 
byref(msg_p))
+indexopts = c_void_p(None)
+if decrypt_policy is not None:
+indexopts = self._get_default_indexopts(self._db)
+self._indexopts_set_decrypt_policy(indexopts, decrypt_policy)
+
+status = self._index_file(self._db, _str(filename), indexopts, 
byref(msg_p))
+
+if indexopts:
+self._indexopts_destroy(indexopts)
 
 if not status in [STATUS.SUCCESS, STATUS.DUPLICATE_MESSAGE_ID]:
 raise NotmuchError(status)
diff --git a/bindings/python/notmuch/globals.py 
b/bindings/python/notmuch/globals.py
index b33e10d3..97413996 100644
--- a/bindings/python/notmuch/globals.py
+++ b/bindings/python/notmuch/globals.py
@@ -93,3 +93,8 @@ NotmuchFilenamesP = POINTER(NotmuchFilenamesS)
 class NotmuchConfigListS(Structure):
 pass
 NotmuchConfigListP = POINTER(NotmuchConfigListS)
+
+
+class NotmuchIndexoptsS(Structure):
+

Re: Homebrew patch for GPG support

2017-12-19 Thread Alex Abdo
On 19 Dec 2017, at 6:33, David Bremner wrote:

> Just to double check, there's nothing we need to do upstream, right?

That’s right! Homebrew’s gmime installer now includes crypto support by 
default, allowing Homebrew notmuch users to more easily decrypt PGP email.

a

signature.asc
Description: OpenPGP digital signature
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCHES v4] Encourage explicit arguments for --decrypt in "show" and "reply"

2017-12-19 Thread Daniel Kahn Gillmor
This is a clean revision of the series that was first introduced at
id:20171212001858.706-1-...@fifthhorseman.net.  It needed to be
rebased after Jani's boolean/negation series.  It should now apply
cleanly.

I think it's important to apply this series before releasing 0.26,
because of the interaction between Jani's boolean/negation series and
the introduction of a keyword-based --decrypt for the indexing
subcommands.  For consistency, it would be unpleasant if some commands
offer --no-decrypt, while others require --decrypt=false.

Background
--

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)

Regards,

--dkg


___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v4 3/3] cli/reply: make --decrypt take a keyword

2017-12-19 Thread Daniel Kahn Gillmor
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 17f3c5ec..249b9664 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
 .
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 = , .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 = , .name = "decrypt", .present = _set },
+   { .opt_keyword = (int*)(), .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 : 

[PATCH v4 2/3] cli/show: make --decrypt take a keyword.

2017-12-19 Thread Daniel Kahn Gillmor
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 adf64a0a..17f3c5ec 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[] = {
 

[PATCH v4 1/3] cli: some keyword options can be supplied with no argument

2017-12-19 Thread Daniel Kahn Gillmor
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 a4a8bb4c..de9ce0cf 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, bool negate)
 {
@@ -32,16 +38,32 @@ _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, 
char next,
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 negate)
 {
@@ -53,45 +75,45 @@ _process_boolean_arg (const notmuch_opt_desc_t *arg_desc, 
char next,
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 = 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) {
 
 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, , 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. */
@@ -212,13 +234,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 || 

[PATCH] test: final named query test works regardless of Xapian FieldProcessor

2017-12-19 Thread Daniel Kahn Gillmor
This test passes with older versions of Xapian as well, because
neither query returns any results.

This should resolve the travis build failure at
https://travis-ci.org/notmuch/notmuch/builds/318571658

Signed-off-by: Daniel Kahn Gillmor 
---
 test/T600-named-queries.sh | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/test/T600-named-queries.sh b/test/T600-named-queries.sh
index e38dc5bb..abaee3b7 100755
--- a/test/T600-named-queries.sh
+++ b/test/T600-named-queries.sh
@@ -69,9 +69,6 @@ test_expect_equal_file EXPECTED OUTPUT
 test_begin_subtest "search nested named query"
 notmuch search query:test2 > OUTPUT
 notmuch search $QUERYSTR2 > EXPECTED
-if [ $NOTMUCH_HAVE_XAPIAN_FIELD_PROCESSOR -ne 1 ]; then
-test_subtest_known_broken
-fi
 test_expect_equal_file EXPECTED OUTPUT
 
 test_done
-- 
2.15.1

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


WIP, all subjects in value slot

2017-12-19 Thread David Bremner
This is a proof of concept for adding all subjects into the value
slot. It's enough to get fix the regexp search test earlier in the thread.
It doesn't yet sort subjects by filename.

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] WIP: add all subjects to value.

2017-12-19 Thread David Bremner
---
 lib/add-message.cc |  3 +--
 lib/message.cc | 52 --
 test/T670-duplicate-mid.sh |  1 -
 3 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/lib/add-message.cc b/lib/add-message.cc
index f5fac8be..095a1f37 100644
--- a/lib/add-message.cc
+++ b/lib/add-message.cc
@@ -538,8 +538,7 @@ notmuch_database_index_file (notmuch_database_t *notmuch,
if (ret)
goto DONE;
 
-   if (is_new || is_ghost)
-   _notmuch_message_set_header_values (message, date, from, subject);
+   _notmuch_message_set_header_values (message, date, from, subject);
 
if (!indexopts) {
def_indexopts = notmuch_database_get_default_indexopts (notmuch);
diff --git a/lib/message.cc b/lib/message.cc
index d5db89b6..c624e145 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -26,6 +26,8 @@
 
 #include 
 
+#include 
+
 struct _notmuch_message {
 notmuch_database_t *notmuch;
 Xapian::docid doc_id;
@@ -514,8 +516,14 @@ notmuch_message_get_header (notmuch_message_t *message, 
const char *header)
 
 if (slot != Xapian::BAD_VALUENO) {
try {
-   std::string value = message->doc.get_value (slot);
-
+   std::string raw = message->doc.get_value (slot);
+   std::string value;
+   if (slot == NOTMUCH_VALUE_SUBJECT) {
+   std::istringstream f(raw);
+   std::getline(f, value);
+   } else {
+   value = raw;
+   }
/* If we have NOTMUCH_FEATURE_FROM_SUBJECT_ID_VALUES, then
 * empty values indicate empty headers.  If we don't, then
 * it could just mean we didn't record the header. */
@@ -655,6 +663,27 @@ _notmuch_message_remove_indexed_terms (notmuch_message_t 
*message)
 }
 return NOTMUCH_PRIVATE_STATUS_SUCCESS;
 }
+/* Remove all values from a document; currently these are
+   all regenerated during indexing */
+
+notmuch_private_status_t
+_notmuch_message_remove_values (notmuch_message_t *message)
+{
+try {
+   message->doc.clear_values ();
+   message->modified = TRUE;
+} catch (const Xapian::Error ) {
+   notmuch_database_t *notmuch = message->notmuch;
+
+   if (!notmuch->exception_reported) {
+   _notmuch_database_log(_notmuch_message_database (message), "A 
Xapian exception occurred creating message: %s\n",
+ error.get_msg().c_str());
+   notmuch->exception_reported = TRUE;
+   }
+   return NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
+}
+return NOTMUCH_PRIVATE_STATUS_SUCCESS;
+}
 
 /* Return true if p points at "new" or "cur". */
 static bool is_maildir (const char *p)
@@ -1097,6 +1126,7 @@ _notmuch_message_set_header_values (notmuch_message_t 
*message,
const char *subject)
 {
 time_t time_value;
+std::string old_subject;
 
 /* GMime really doesn't want to see a NULL date, so protect its
  * sensibilities. */
@@ -1114,7 +1144,13 @@ _notmuch_message_set_header_values (notmuch_message_t 
*message,
 message->doc.add_value (NOTMUCH_VALUE_TIMESTAMP,
Xapian::sortable_serialise (time_value));
 message->doc.add_value (NOTMUCH_VALUE_FROM, from);
-message->doc.add_value (NOTMUCH_VALUE_SUBJECT, subject);
+
+old_subject = message->doc.get_value (NOTMUCH_VALUE_SUBJECT);
+if (old_subject.empty())
+   message->doc.add_value (NOTMUCH_VALUE_SUBJECT, subject);
+else
+   message->doc.add_value (NOTMUCH_VALUE_SUBJECT, old_subject + "\n" + 
subject);
+
 message->modified = true;
 }
 
@@ -1999,6 +2035,12 @@ notmuch_message_reindex (notmuch_message_t *message,
goto DONE;
 }
 
+private_status = _notmuch_message_remove_values (message);
+if (private_status) {
+   ret = COERCE_STATUS(private_status, "error values");
+   goto DONE;
+}
+
 ret = notmuch_message_remove_all_properties_with_prefix (message, 
"index.");
 if (ret)
goto DONE; /* XXX TODO: distinguish from other error returns above? */
@@ -2043,9 +2085,7 @@ notmuch_message_reindex (notmuch_message_t *message,
thread_id = orig_thread_id;
 
_notmuch_message_add_term (message, "thread", thread_id);
-   /* Take header values only from first filename */
-   if (found == 0)
-   _notmuch_message_set_header_values (message, date, from, subject);
+   _notmuch_message_set_header_values (message, date, from, subject);
 
ret = _notmuch_message_index_file (message, indexopts, message_file);
 
diff --git a/test/T670-duplicate-mid.sh b/test/T670-duplicate-mid.sh
index bf8cc3a8..cfc5dafb 100755
--- a/test/T670-duplicate-mid.sh
+++ b/test/T670-duplicate-mid.sh
@@ -48,7 +48,6 @@ notmuch search --output=files subject:'"message 2"' | 
notmuch_dir_sanitize > OUT
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest 'Regexp search for second subject'

Re: Homebrew patch for GPG support

2017-12-19 Thread David Bremner
"Alex Abdo"  writes:

> Hi all,
>
> I'm new to the notmuch community and am writing about a patch to
> Homebrew that made it easier for me to use notmuch with GPG on my Mac.
>
> I installed notmuch a few weeks ago using Homebrew, but I hadn't been
> able to use it to decrypt messages encrypted with PGP. dkg helped me
> debug the issue, which was that Homebrew's gmime package did not
> enable support for crypto by default, even with gpgme installed. I
> submitted a small pull request adding crypto support by default to
> gmime's package installer, which the Homebrew maintainers pushed
> today.
>
> Here's the patch:
>
> https://github.com/Homebrew/homebrew-core/pull/21780
>

Just to double check, there's nothing we need to do upstream, right?

> Thanks, and looking forward to getting more familiar with notmuch. I
> hope you don't mind if I send some suggestions around.
>

Of course! We're sometimes slow dealing with feature requests, but you
never know when someone will get inspired.

d
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: be more honest about test suite failures due to old libraries

2017-12-19 Thread David Bremner
Daniel Kahn Gillmor  writes:

> We have several places where tests are skipped or marked as though
> some test suite prereqs are missing, but in fact are due to building
> against older versions of libraries that don't support certain
> features.
>
> This series tries to be more honest about some of those tests by
> marking them as broken, rather than just skipping them.

pushed to master

d
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v4] python: add decrypt_policy argument to Database.index_file()

2017-12-19 Thread David Bremner
Daniel Kahn Gillmor  writes:

> +Date: $(date -R)
> +Message-ID: 
> +MIME-Version: 1.0
> +Content-Type: multipart/encrypted; boundary="=-=-=";
> + protocol="application/pgp-encrypted"
> +

Can you explain why you explicitely set the date here? it seems to make
the test less reproducible. In the end it doesn't matter much because
your test ignores the date, but I feel like I'm missing something.

d


___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 0/6] python: add bindings for notmuch_database_get_config{, _list}

2017-12-19 Thread David Bremner
l-...@web.de writes:

> Comming back after a long time (sorry for the wait).
>
> I now changed the binding for notmuch_database_get_config_list into a
> generator.  It is called get_configs in the python bindings (the "s"
> should indicate the iterable/generator nature like for dict.items or
> dict.keys).

Series pushed to master. Thanks for contributing to notmuch.

d
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch