You should have received a copy of the GNU General Public License
along with this program, (in the COPYING-GPL-3 file in this
-directory). If not, see http://www.gnu.org/licenses/
+directory). If not, see https://www.gnu.org/licenses/
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+<https://www.gnu.org/philosophy/why-not-lgpl.html>.
It provides all the real machinery of indexing and searching,
(including the very nice parsing of the query string).
- Xapian is available from http://xapian.org
+ Xapian is available from https://xapian.org
Note: Notmuch will work best with Xapian 1.0.18 (or later) or
Xapian 1.1.4 (or later). Previous versions of Xapian (whether
made development of Notmuch much easier and much less prone to
memory leaks.
- Talloc is available from http://talloc.samba.org/
+ Talloc is available from https://talloc.samba.org/
zlib
----
# repository), we let git append identification of the actual commit.
PACKAGE=notmuch
-IS_GIT=$(shell if [ -d ${srcdir}/.git ] ; then echo yes ; else echo no; fi)
+IS_GIT=$(shell if [ -d ${srcdir}/.git -o -f ${srcdir}/.git ] ; then echo yes ; else echo no; fi)
ifeq ($(IS_GIT),yes)
DATE:=$(shell git --git-dir=${srcdir}/.git log --date=short -1 --pretty=format:%cd)
RELEASE_HOST=notmuchmail.org
RELEASE_DIR=/srv/notmuchmail.org/www/releases
-RELEASE_URL=http://notmuchmail.org/releases
+RELEASE_URL=https://notmuchmail.org/releases
TAR_FILE=$(PACKAGE)-$(VERSION).tar.gz
DEB_TAR_FILE=$(PACKAGE)_$(VERSION).orig.tar.gz
SHA1_FILE=$(TAR_FILE).sha1
@echo "the Xapian library to provide fast, full-text search with a convenient"
@echo "search syntax."
@echo ""
- @echo "For more about notmuch, see http://notmuchmail.org"
+ @echo "For more about notmuch, see https://notmuchmail.org"
# This is a chain of dependencies rather than a simple list simply to
# avoid the messages getting interleaved in the case of a parallel
+Notmuch 0.23 (UNRELEASED)
+=========================
+
+Ruby Bindings
+-------------
+
+Add support for `notmuch_database_get_all_tags`
+
Notmuch 0.22.1 (2016-07-19)
===========================
Python bindings have been updated and extended
- (docs online at http://packages.python.org/notmuch/)
+ (docs online at https://notmuch.readthedocs.io/)
New bindings:
-------------------------------
The website for Notmuch is:
- http://notmuchmail.org
+ https://notmuchmail.org
The mailing list address for the notmuch community is:
-If you're reading this on http://github.com/notmuch/notmuch, this is a
+If you're reading this on https://github.com/notmuch/notmuch, this is a
read-only mirror of the notmuch project.
-For more information about the project, see http://notmuchmail.org.
+For more information about the project, see https://notmuchmail.org.
Please don't send us pull requests on github. If you have a feature
branch that you want us to look at, use ``git send-email`` to send it
to notmuch@notmuchmail.org.
For more information about contributing to the project, see
-http://notmuchmail.org/contributing/.
+https://notmuchmail.org/contributing/.
- improve notmuch-addrlookup regexp
-[1] http://notmuchmail.org/
\ No newline at end of file
+[1] https://notmuchmail.org/
* completely in the future, but it's likely to be a specialized
* version of the general Xapian query syntax:
*
- * http://xapian.org/docs/queryparser.html
+ * https://xapian.org/docs/queryparser.html
*
* As a special case, passing either a length-zero string, (that is ""),
* or a string consisting of a single asterisk (that is "*"), will
==========================================
This module makes the functionality of the notmuch library
-(`http://notmuchmail.org`_) available to python. Successful import of
+(`https://notmuchmail.org`_) available to python. Successful import of
this modul depends on a libnotmuch.so|dll being available on the
user's system.
documentation with sphinx installed, go to the docs directory and
"make html". A static version of the documentation is available at:
- https://notmuch.readthedocs.org/projects/notmuch-python/
+ https://notmuch.readthedocs.io/projects/notmuch-python/
To build the python bindings, do
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+<https://www.gnu.org/philosophy/why-not-lgpl.html>.
.. currentmodule:: notmuch
The :mod:`notmuch` module provides an interface to the `notmuch
-<http://notmuchmail.org>`_ functionality, directly interfacing to a
+<https://notmuchmail.org>`_ functionality, directly interfacing to a
shared notmuch library. Within :mod:`notmuch`, the classes
:class:`Database`, :class:`Query` provide most of the core
functionality, returning :class:`Threads`, :class:`Messages` and
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010-2011 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
Copyright 2012 Justus Winter <4winter@informatik.uni-hamburg.de>
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
Jesse Rosenthal <jrosenthal@jhu.edu>
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
Jesse Rosenthal <jrosenthal@jhu.edu>
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
for more details.
You should have received a copy of the GNU General Public License
-along with notmuch. If not, see <http://www.gnu.org/licenses/>.
+along with notmuch. If not, see <https://www.gnu.org/licenses/>.
Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>
"""
description='Python binding of the notmuch mail search and indexing library.',
author='Sebastian Spaeth',
author_email='Sebastian@SSpaeth.de',
- url='http://notmuchmail.org/',
- download_url='http://notmuchmail.org/releases/notmuch-%s.tar.gz' % __VERSION__,
+ url='https://notmuchmail.org/',
+ download_url='https://notmuchmail.org/releases/notmuch-%s.tar.gz' % __VERSION__,
packages=['notmuch'],
keywords=['library', 'email'],
long_description='''Overview
========
The notmuch module provides an interface to the `notmuch
-<http://notmuchmail.org>`_ functionality, directly interfacing with a
+<https://notmuchmail.org>`_ functionality, directly interfacing with a
shared notmuch library. Notmuch provides a maildatabase that allows
for extremely quick searching and filtering of your email according to
various criteria.
The documentation for the latest notmuch release can be `viewed
-online <http://notmuch.readthedocs.org/>`_.
+online <https://notmuch.readthedocs.io/>`_.
Requirements
------------
'Topic :: Software Development :: Libraries'
],
platforms='',
- license='http://www.gnu.org/licenses/gpl-3.0.txt',
+ license='https://www.gnu.org/licenses/gpl-3.0.txt',
)
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
return Qnil;
}
+/*
+ * call-seq: DB.get_all_tags() => TAGS
+ *
+ * Returns a list of all tags found in the database.
+ */
+VALUE
+notmuch_rb_database_get_all_tags (VALUE self)
+{
+ notmuch_database_t *db;
+ notmuch_tags_t *tags;
+
+ Data_Get_Notmuch_Database (self, db);
+
+ tags = notmuch_database_get_all_tags (db);
+ if (!tags) {
+ const char *msg = notmuch_database_status_string (db);
+ if (!msg)
+ msg = "Unknown notmuch error";
+
+ rb_raise (notmuch_rb_eBaseError, "%s", msg);
+ }
+ return Data_Wrap_Struct (notmuch_rb_cTags, NULL, NULL, tags);
+}
+
/*
* call-seq: DB.query(query) => QUERY
*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
VALUE
notmuch_rb_database_find_message_by_filename (VALUE self, VALUE pathv);
+VALUE
+notmuch_rb_database_get_all_tags (VALUE self);
+
VALUE
notmuch_rb_database_query_create (VALUE self, VALUE qstrv);
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
notmuch_rb_database_find_message, 1); /* in database.c */
rb_define_method (notmuch_rb_cDatabase, "find_message_by_filename",
notmuch_rb_database_find_message_by_filename, 1); /* in database.c */
+ rb_define_method (notmuch_rb_cDatabase, "all_tags", notmuch_rb_database_get_all_tags, 0); /* in database.c */
rb_define_method (notmuch_rb_cDatabase, "query", notmuch_rb_database_query_create, 1); /* in database.c */
/*
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ali Polatel <alip@exherbo.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*/
#ifndef FUNCTION_ATTRIBUTES_H
bash-completion package [1] version 2.0, which depends on bash
version 3.2 or later.
- [1] http://bash-completion.alioth.debian.org/
+ [1] https://github.com/scop/bash-completion
notmuch-completion.zsh
# Copyright © 2013 Jani Nikula
#
# Based on the bash-completion package:
-# http://bash-completion.alioth.debian.org/
+# https://github.com/scop/bash-completion
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see http://www.gnu.org/licenses/ .
+# along with this program. If not, see https://www.gnu.org/licenses/ .
#
# Author: Jani Nikula <jani@nikula.org>
#
#! /bin/sh
+set -u
+
# Test whether this shell is capable of parameter substring processing.
( option='a/b'; : ${option#*/} ) 2>/dev/null || {
echo "
WITH_BASH=1
WITH_RUBY=1
WITH_ZSH=1
+WITH_RETRY_LOCK=1
usage ()
{
--without-emacs Do not install lisp file
--without-ruby Do not install ruby bindings
--without-zsh-completion Do not install zsh completions files
+ --without-retry-lock Do not use blocking xapian opens, even if available
Additional options are accepted for compatibility with other
configure-script calling conventions, but don't do anything yet:
fi
elif [ "${option}" = '--without-ruby' ] ; then
WITH_RUBY=0
+ elif [ "${option%%=*}" = '--with-retry-lock' ]; then
+ if [ "${option#*=}" = 'no' ]; then
+ WITH_RETRY_LOCK=0
+ else
+ WITH_RETRY_LOCK=1
+ fi
+ elif [ "${option}" = '--without-retry-lock' ] ; then
+ WITH_RETRY_LOCK=0
elif [ "${option%%=*}" = '--with-zsh-completion' ]; then
if [ "${option#*=}" = 'no' ]; then
WITH_ZSH=0
libdir_expanded="${PREFIX}/lib"
else
# very non-general variable expansion
- libdir_expanded=`echo "$LIBDIR" | sed "s|\\${prefix}|${PREFIX}|g; s|\\$prefix/|${PREFIX}/|; s|//*|/|g"`
+ libdir_expanded=$(echo "$LIBDIR" | sed "s|\\${prefix}|${PREFIX}|g; s|\\$prefix/|${PREFIX}/|; s|//*|/|g")
fi
cat <<EOF
errors=$((errors + 1))
fi
-# Compaction is only supported on Xapian > 1.2.6
have_xapian_compact=0
+have_xapian_field_processor=0
if [ ${have_xapian} = "1" ]; then
printf "Checking for Xapian compaction support... "
- case "${xapian_version}" in
- 0.*|1.[01].*|1.2.[0-5])
- printf "No (only available with Xapian > 1.2.6).\n" ;;
- [1-9]*.[0-9]*.[0-9]*)
- have_xapian_compact=1
- printf "Yes.\n" ;;
- *)
- printf "Unknown version.\n" ;;
- esac
-fi
+ cat>_compact.cc<<EOF
+#include <xapian.h>
+class TestCompactor : public Xapian::Compactor { };
+EOF
+ if ${CXX} ${CXXFLAGS_for_sh} ${xapian_cxxflags} -c _compact.cc -o _compact.o > /dev/null 2>&1
+ then
+ have_xapian_compact=1
+ printf "Yes.\n"
+ else
+ printf "No.\n"
+ fi
+
+ rm -f _compact.o _compact.cc
+
+ printf "Checking for Xapian FieldProcessor API... "
+ cat>_field_processor.cc<<EOF
+#include <xapian.h>
+class TitleFieldProcessor : public Xapian::FieldProcessor { };
+EOF
+ if ${CXX} ${CXXFLAGS_for_sh} ${xapian_cxxflags} -c _field_processor.cc -o _field_processor.o > /dev/null 2>&1
+ then
+ have_xapian_field_processor=1
+ printf "Yes.\n"
+ else
+ printf "No. (optional)\n"
+ fi
+
+ rm -f _field_processor.o _field_processor.cc
+
+ default_xapian_backend=""
+ # DB_RETRY_LOCK is only supported on Xapian > 1.3.2
+ have_xapian_db_retry_lock=0
+ if [ $WITH_RETRY_LOCK = "1" ]; then
+ printf "Checking for Xapian lock retry support... "
+ cat>_retry.cc<<EOF
+#include <xapian.h>
+int flag = Xapian::DB_RETRY_LOCK;
+EOF
+ if ${CXX} ${CXXFLAGS_for_sh} ${xapian_cxxflags} -c _retry.cc -o _retry.o > /dev/null 2>&1
+ then
+ have_xapian_db_retry_lock=1
+ printf "Yes.\n"
+ else
+ printf "No. (optional)\n"
+ fi
+ rm -f _retry.o _retry.cc
+ fi
-default_xapian_backend=""
-if [ ${have_xapian} = "1" ]; then
printf "Testing default Xapian backend... "
cat >_default_backend.cc <<EOF
#include <xapian.h>
Xapian::WritableDatabase db("test.db",Xapian::DB_CREATE_OR_OPEN);
}
EOF
- ${CXX} ${CXXLAGS} ${xapian_cxxflags} _default_backend.cc -o _default_backend ${xapian_ldflags}
+ ${CXX} ${CXXFLAGS_for_sh} ${xapian_cxxflags} _default_backend.cc -o _default_backend ${xapian_ldflags}
./_default_backend
if [ -f test.db/iamglass ]; then
default_xapian_backend=glass
else
default_xapian_backend=chert
fi
- printf "${default_xapian_backend}\n";
+ printf "%s\n" "${default_xapian_backend}";
rm -rf test.db _default_backend _default_backend.cc
fi
+
# we need to have a version >= 2.6.5 to avoid a crypto bug. We need
# 2.6.7 for permissive "From " header handling.
GMIME_MINVER=2.6.7
if pkg-config --exists 'glib-2.0 >= 2.22'; then
printf "Yes.\n"
have_glib=1
- glib_cflags=$(pkg-config --cflags glib-2.0)
- glib_ldflags=$(pkg-config --libs glib-2.0)
+ # these are included in gmime cflags and ldflags
+ # glib_cflags=$(pkg-config --cflags glib-2.0)
+ # glib_ldflags=$(pkg-config --libs glib-2.0)
else
printf "No.\n"
errors=$((errors + 1))
if command -v $name > /dev/null; then
have_python=1
python=$name
- printf "Yes ($name).\n"
+ printf "Yes (%s).\n" "$name"
break
fi
done
else
printf "No (but that's fine).\n"
have_valgrind=0
+ valgrind_cflags=
fi
printf "Checking for bash-completion (>= 1.90)... "
WITH_BASH=0
fi
-if [ -z "${EMACSLISPDIR}" ]; then
- EMACSLISPDIR='$(prefix)/share/emacs/site-lisp'
+if [ -z "${EMACSLISPDIR-}" ]; then
+ EMACSLISPDIR="\$(prefix)/share/emacs/site-lisp"
fi
-if [ -z "${EMACSETCDIR}" ]; then
- EMACSETCDIR='$(prefix)/share/emacs/site-lisp'
+if [ -z "${EMACSETCDIR-}" ]; then
+ EMACSETCDIR="\$(prefix)/share/emacs/site-lisp"
fi
printf "Checking if emacs is available... "
libdir_in_ldconfig=0
printf "Checking which platform we are on... "
-uname=`uname`
+uname=$(uname)
if [ $uname = "Darwin" ] ; then
printf "Mac OS X.\n"
platform=MACOSX
platform=OPENBSD
linker_resolves_library_dependencies=0
elif [ $uname = "Linux" ] || [ $uname = "GNU" ] ; then
- printf "$uname\n"
+ printf "%s\n" "$uname"
platform="$uname"
linker_resolves_library_dependencies=1
- printf "Checking for $libdir_expanded in ldconfig... "
+ printf "Checking for %s in ldconfig... " "$libdir_expanded"
ldconfig_paths=$(/sbin/ldconfig -N -X -v 2>/dev/null | sed -n -e 's,^\(/.*\):\( (.*)\)\?$,\1,p')
# Separate ldconfig_paths only on newline (not on any potential
# embedded space characters in any filenames). Note, we use a
fi
if [ $have_xapian -eq 0 ]; then
echo " Xapian library (including development files such as headers)"
- echo " http://xapian.org/"
+ echo " https://xapian.org/"
fi
if [ $have_zlib -eq 0 ]; then
echo " zlib library (>= version 1.2.5.2, including development files such as headers)"
fi
if [ $have_talloc -eq 0 ]; then
echo " The talloc library (including development files such as headers)"
- echo " http://talloc.samba.org/"
+ echo " https://talloc.samba.org/"
echo
fi
cat <<EOF
WARN_CXXFLAGS="${WARN_CXXFLAGS}${WARN_CXXFLAGS:+ }${flag}"
fi
done
-printf "\n\t${WARN_CXXFLAGS}\n"
+printf "\n\t%s\n" "${WARN_CXXFLAGS}"
WARN_CFLAGS="${WARN_CXXFLAGS}"
printf "Checking for available C compiler warning flags... "
WARN_CFLAGS="${WARN_CFLAGS}${WARN_CFLAGS:+ }${flag}"
fi
done
-printf "\n\t${WARN_CFLAGS}\n"
+printf "\n\t%s\n" "${WARN_CFLAGS}"
rm -f minimal minimal.c _libversion.c _libversion _libversion.sh
# Whether the Xapian version in use supports compaction
HAVE_XAPIAN_COMPACT = ${have_xapian_compact}
+# Whether the Xapian version in use supports field processors
+HAVE_XAPIAN_FIELD_PROCESSOR = ${have_xapian_field_processor}
+
+# Whether the Xapian version in use supports DB_RETRY_LOCK
+HAVE_XAPIAN_DB_RETRY_LOCK = ${have_xapian_db_retry_lock}
+
# Whether the getpwuid_r function is standards-compliant
# (if not, then notmuch will #define _POSIX_PTHREAD_SEMANTICS
# to enable the standards-compliant version -- needed for Solaris)
WITH_ZSH = ${WITH_ZSH}
# Combined flags for compiling and linking against all of the above
-CONFIGURE_CFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
- -DHAVE_CANONICALIZE_FILE_NAME=\$(HAVE_CANONICALIZE_FILE_NAME) \\
- \$(ZLIB_CFLAGS) \\
- \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
- \$(VALGRIND_CFLAGS) \\
- -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
- -DHAVE_STRSEP=\$(HAVE_STRSEP) \\
- -DHAVE_TIMEGM=\$(HAVE_TIMEGM) \\
- -DHAVE_D_TYPE=\$(HAVE_D_TYPE) \\
- -DSTD_GETPWUID=\$(STD_GETPWUID) \\
- -DSTD_ASCTIME=\$(STD_ASCTIME) \\
- -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\
- -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
-
-CONFIGURE_CXXFLAGS = -DHAVE_GETLINE=\$(HAVE_GETLINE) \$(GMIME_CFLAGS) \\
- -DHAVE_CANONICALIZE_FILE_NAME=\$(HAVE_CANONICALIZE_FILE_NAME) \\
- \$(ZLIB_CFLAGS) \\
- \$(TALLOC_CFLAGS) -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \\
- \$(VALGRIND_CFLAGS) \$(XAPIAN_CXXFLAGS) \\
- -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
- -DHAVE_STRSEP=\$(HAVE_STRSEP) \\
- -DHAVE_TIMEGM=\$(HAVE_TIMEGM) \\
- -DHAVE_D_TYPE=\$(HAVE_D_TYPE) \\
- -DSTD_GETPWUID=\$(STD_GETPWUID) \\
- -DSTD_ASCTIME=\$(STD_ASCTIME) \\
- -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\
- -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
+COMMON_CONFIGURE_CFLAGS = \\
+ \$(GMIME_CFLAGS) \$(TALLOC_CFLAGS) \$(ZLIB_CFLAGS) \\
+ -DHAVE_VALGRIND=\$(HAVE_VALGRIND) \$(VALGRIND_CFLAGS) \\
+ -DHAVE_GETLINE=\$(HAVE_GETLINE) \\
+ -DHAVE_CANONICALIZE_FILE_NAME=\$(HAVE_CANONICALIZE_FILE_NAME) \\
+ -DHAVE_STRCASESTR=\$(HAVE_STRCASESTR) \\
+ -DHAVE_STRSEP=\$(HAVE_STRSEP) \\
+ -DHAVE_TIMEGM=\$(HAVE_TIMEGM) \\
+ -DHAVE_D_TYPE=\$(HAVE_D_TYPE) \\
+ -DSTD_GETPWUID=\$(STD_GETPWUID) \\
+ -DSTD_ASCTIME=\$(STD_ASCTIME) \\
+ -DHAVE_XAPIAN_COMPACT=\$(HAVE_XAPIAN_COMPACT) \\
+ -DHAVE_XAPIAN_FIELD_PROCESSOR=\$(HAVE_XAPIAN_FIELD_PROCESSOR) \\
+ -DHAVE_XAPIAN_DB_RETRY_LOCK=\$(HAVE_XAPIAN_DB_RETRY_LOCK) \\
+ -DUTIL_BYTE_ORDER=\$(UTIL_BYTE_ORDER)
+
+CONFIGURE_CFLAGS = \$(COMMON_CONFIGURE_CFLAGS)
+
+CONFIGURE_CXXFLAGS = \$(COMMON_CONFIGURE_CFLAGS) \$(XAPIAN_CXXFLAGS)
CONFIGURE_LDFLAGS = \$(GMIME_LDFLAGS) \$(TALLOC_LDFLAGS) \$(ZLIB_LDFLAGS) \$(XAPIAN_LDFLAGS)
EOF
# Whether the Xapian version in use supports compaction
NOTMUCH_HAVE_XAPIAN_COMPACT=${have_xapian_compact}
+# Whether the Xapian version in use supports field processors
+NOTMUCH_HAVE_XAPIAN_FIELD_PROCESSOR=${have_xapian_field_processor}
+
+# Whether the Xapian version in use supports lock retry
+NOTMUCH_HAVE_XAPIAN_DB_RETRY_LOCK=${have_xapian_db_retry_lock}
+
# Which backend will Xapian use by default?
NOTMUCH_DEFAULT_XAPIAN_BACKEND=${default_xapian_backend}
[1]: http://www.mutt.org/
-[2]: http://notmuchmail.org/
-[3]: http://upsilon.cc/~zack/blog/posts/2011/01/how_to_use_Notmuch_with_Mutt/
+[2]: https://notmuchmail.org/
+[3]: https://upsilon.cc/~zack/blog/posts/2011/01/how_to_use_Notmuch_with_Mutt/
Requirements
notmuch-mutt is released under the terms of the GNU General Public License
(GPL), version 3 or above. A copy of the license is available online at
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
$mid = $1;
} else { # Message-ID header not found, synthesize a message id
# based on SHA1, as notmuch would do. See:
- # http://git.notmuchmail.org/git/notmuch/blob/HEAD:/lib/sha1.c
+ # https://git.notmuchmail.org/git/notmuch/blob/HEAD:/lib/sha1.c
my $sha = Digest::SHA->new(1);
$sha->add($_) foreach(@headers);
$sha->addfile(\*STDIN);
" General Public License for more details.
"
" You should have received a copy of the GNU General Public License
-" along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+" along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
"
" Authors: Bart Trojanowski <bart@jukie.net>
" Contributors: Felipe Contreras <felipe.contreras@gmail.com>,
endfunction
" this function was taken from git.vim, then fixed up
-" http://github.com/motemen/git-vim
+" https://github.com/motemen/git-vim
function! s:NM_shell_split(cmd)
let l:split_cmd = []
let cmd = a:cmd
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Authors: Jameson Rollins <jrollins@finestructure.net>
*/
gnupg <!nocheck>,
bash-completion (>=1.9.0~)
Standards-Version: 3.9.6
-Homepage: http://notmuchmail.org/
+Homepage: https://notmuchmail.org/
Vcs-Git: git://notmuchmail.org/git/notmuch
-Vcs-Browser: http://git.notmuchmail.org/git/notmuch
+Vcs-Browser: https://git.notmuchmail.org/git/notmuch
Package: notmuch
Architecture: any
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Chris Wilson <chris@chris-wilson.co.uk>
*/
my @lines;
open I, '-|', qw/env -i/, "PATH=$ENV{PATH}",
- qw/TERM=vt100 LANG=en_US.utf8 LC_ALL=en_US.utf8/,
+ qw/TERM=vt100 LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8/,
qw/GROFF_NO_SGR=1 MAN_KEEP_FORMATTING=1 MANWIDTH=80/,
qw/man/, $v or die "$!";
binmode I, ':utf8';
print <<'EOF';
The manual pages are licensed under
-[the GNU General Public License](http://www.gnu.org/licenses/gpl.txt),
+[the GNU General Public License](https://www.gnu.org/licenses/gpl.txt),
either version 3.0 or at your option any later version.
EOF
{
"meta": {
"title": "Notmuch Patches",
- "blurb": "For more information see <a href=\"http://notmuchmail.org/nmbug\">nmbug</a>",
+ "blurb": "For more information see <a href=\"https://notmuchmail.org/nmbug\">nmbug</a>",
"header": "<html><head></head><body><h1>{title}</h1><p>{blurb}</p><h2>Views</h2>",
"footer": "<hr><p>Generated: {datetime}</p></html>",
"message-url": "http://mid.gmane.org/{message-id}"
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see http://www.gnu.org/licenses/ .
+# along with this program. If not, see https://www.gnu.org/licenses/ .
"""
Manage notmuch tags with Git
See PEP 343 for details on context managers [1].
- [1]: http://legacy.python.org/dev/peps/pep-0343/
+ [1]: https://www.python.org/dev/peps/pep-0343/
"""
def __init__(self, **kwargs):
self.name = _tempfile.mkdtemp(**kwargs)
Xapian uses double-quotes for quoting strings. You can escape
internal quotes by repeating them [1,2,3].
- [1]: http://trac.xapian.org/ticket/128#comment:2
- [2]: http://trac.xapian.org/ticket/128#comment:17
- [3]: http://trac.xapian.org/changeset/13823/svn
+ [1]: https://trac.xapian.org/ticket/128#comment:2
+ [2]: https://trac.xapian.org/ticket/128#comment:17
+ [3]: https://trac.xapian.org/changeset/13823/svn
"""
return '"{0}"'.format(string.replace('"', '""'))
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see http://www.gnu.org/licenses/ .
+# along with this program. If not, see https://www.gnu.org/licenses/ .
"""Generate text and/or HTML for one or more notmuch searches.
{
"meta": {
"title": "Notmuch Patches",
- "blurb": "For more information see <a href=\"http://notmuchmail.org/nmbug\">nmbug</a>"
+ "blurb": "For more information see <a href=\"https://notmuchmail.org/nmbug\">nmbug</a>"
},
"views": [
;;
;; Authors: Tomi Ollila <tomi.ollila@iki.fi>
;;
-;; http://www.emacswiki.org/emacs/EmacsScripts was a useful starting point...
+;; https://www.emacswiki.org/emacs/EmacsScripts was a useful starting point...
;;
;; Licence: GPLv3+
;;
FORMULA_TRANSPARENT = YES
USE_MATHJAX = NO
MATHJAX_FORMAT = HTML-CSS
-MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_RELPATH = https://cdn.mathjax.org/mathjax/latest
MATHJAX_EXTENSIONS =
MATHJAX_CODEFILE =
SEARCHENGINE = YES
man1/notmuch-count
man1/notmuch-dump
notmuch-emacs
+ man1/notmuch-emacs-mua
man5/notmuch-hooks
man1/notmuch-insert
man1/notmuch-new
Default: ``gpg``.
+ **built_with.<name>**
+
+ Compile time feature <name>. Current possibilities include
+ "compact" (see **notmuch-compact(1)**)
+ and "field_processor" (see **notmuch-search-terms(7)**).
+
+ **query.<name>**
+
+ Expansion for named query called <name>. See
+ **notmuch-search-terms(7)** for more information about named
+ queries.
ENVIRONMENT
===========
characters. Note also that tags with spaces will not be
correctly restored with this format.
+ ``--include=(config|tags)``
+
+ Control what kind of metadata is included in the output.
+
+ **config**
+
+ Output configuration data stored in the database. Each line
+ starts with "#@ ", followed by a space seperated key-value
+ pair. Both key and value are hex encoded if needed.
+
+ **tags**
+
+ Output per-message metadata, namely tags. See *format* above
+ for description of the output.
+
+ The default is to include both tags and configuration
+ information. As of version 2 of the dump format, there is a
+ header line of the following form
+
+ |
+ | #notmuch-dump <*format*>:<*version*> <*included*>
+
+ where <*included*> is a comma separated list of the above
+ options.
+
``--output=``\ <filename>
Write output to given file instead of stdout.
format, this heuristic, based the fact that batch-tag format
contains no parentheses, should be accurate.
+ ``--include=(config|tags)``
+
+ Control what kind of metadata is restored.
+
+ **config**
+
+ Restore configuration data to the database. Each configuration line starts
+ with "#@ ", followed by a space seperated key-value pair.
+ Both key and value are hex encoded if needed.
+
+ **tags**
+
+ Output per-message metadata, namely tags. See *format* above
+ for more details.
+
+ The default is to restore both tags and configuration
+ information
+
``--input=``\ <filename>
Read input from given file instead of stdin.
functionality, it does not provide the most convenient interface for
that functionality. More sophisticated interfaces are expected to be
built on top of either the command-line interface, or more likely, on
-top of the notmuch library interface. See http://notmuchmail.org for
+top of the notmuch library interface. See https://notmuchmail.org for
more about alternate interfaces to notmuch. The emacs-based interface to
notmuch (available under **emacs/** in the Notmuch source distribution)
is probably the most widely used at this time.
**notmuch-search-terms(7)**, **notmuch-show(1)**, **notmuch-tag(1)**,
**notmuch-address(1)**
-The notmuch website: **http://notmuchmail.org**
+The notmuch website: **https://notmuchmail.org**
CONTACT
=======
- lastmod:<initial-revision>..<final-revision>
+- query:<name>
+
The **from:** prefix is used to match the name or address of the sender
of an email message.
conjunction with the **--uuid** argument to **notmuch search**
to find messages that have changed since an earlier query.
+The **query:** prefix allows queries to refer to previously saved
+queries added with **notmuch-config(1)**. Named queries are only
+available if notmuch is built with **Xapian Field Processors** (see
+below).
+
Operators
---------
Xapian (and hence notmuch) prefixes are either **boolean**, supporting
exact matches like "tag:inbox" or **probabilistic**, supporting a more flexible **term** based searching. The prefixes currently supported by notmuch are as follows.
-+------------------+-----------------------+
-|Boolean |Probabilistic |
-+------------------+-----------------------+
-| **tag:** **id:** | **from:** **to:** |
-|**thread:** |**subject:** |
-|**folder:** |**attachment:** |
-|**path:** |**mimetype:** |
-| | |
-+------------------+-----------------------+
+
+Boolean
+ **tag:**, **id:**, **thread:**, **folder:**, **path:**
+Probabilistic
+ **from:**, **to:**, **subject:**, **attachment:**, **mimetype:**
Terms and phrases
-----------------
date:<expr>..! can be used as a shorthand for date:<expr>..<expr>. The
expansion takes place before interpretation, and thus, for example,
date:monday..! matches from the beginning of Monday until the end of
-Monday. (Note that entering date:<expr> without "..", for example
-date:yesterday, won't work, as it's not interpreted as a range
-expression at all. Again, use date:yesterday..!)
+Monday.
+With **Xapian Field Processor** support (see below), non-range
+date queries such as date:yesterday will work, but otherwise
+will give unexpected results; if in doubt use date:yesterday..!
Currently, we do not support spaces in range expressions. You can
replace the spaces with '\_', or (in most cases) '-', or (in some cases)
Some time zone codes, e.g. UTC, EET.
+XAPIAN FIELD PROCESSORS
+=======================
+
+Certain optional features of the notmuch query processor rely on the
+presence of the Xapian field processor API. You can determine if your
+notmuch was built against a sufficiently recent version of Xapian by running
+
+::
+
+ % notmuch config get built_with.field_processor
+
+Currently the following features require field processor support:
+
+- non-range date queries, e.g. "date:today"
+- named queries e.g. "query:my_special_query"
+
SEE ALSO
========
|
| All tags: **[show]**
|
-| Type a search query and hit RET to view matching threads.
-| Edit saved searches with the ``edit`` button.
-| Hit RET or click on a saved search or tag name to view matching threads.
-| ``=`` to refresh this screen. ``s`` to search messages. ``q`` to quit.
-| **Customize** this page.
+| Hit \`?' for context-sensitive help in any Notmuch screen.
+| Customize Notmuch or this page.
You can change the overall appearance of the notmuch-hello screen by
customizing the variable :index:`notmuch-hello-sections`.
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Austin Clements <aclements@csail.mit.edu>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: David Edmondson <dme@dme.org>
;;
+(defun notmuch-address-from-minibuffer (prompt)
+ (if (not notmuch-address-command)
+ (read-string prompt)
+ (let ((rmap (copy-keymap minibuffer-local-map))
+ (omap minibuffer-local-map))
+ ;; Configure TAB to start completion when executing read-string.
+ ;; "Original" minibuffer keymap is restored just before calling
+ ;; notmuch-address-expand-name as it may also use minibuffer-local-map
+ ;; (completing-read probably does not but if something else is used there).
+ (define-key rmap (kbd "TAB") (lambda ()
+ (interactive)
+ (let ((enable-recursive-minibuffers t)
+ (minibuffer-local-map omap))
+ (notmuch-address-expand-name))))
+ (let ((minibuffer-local-map rmap))
+ (read-string prompt)))))
+
+;;
+
(provide 'notmuch-address)
;;; notmuch-address.el ends here
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Jameson Rollins <jrollins@finestructure.net>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: David Edmondson <dme@dme.org>
:group 'notmuch-hello
:group 'notmuch-hooks)
-(defvar notmuch-hello-url "http://notmuchmail.org"
+(defvar notmuch-hello-url "https://notmuchmail.org"
"The `notmuch' web site.")
(defvar notmuch-hello-custom-section-options
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Austin Clements <aclements@csail.mit.edu>
;; David Edmondson <dme@dme.org>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Carl Worth <cworth@cworth.org>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Jesse Rosenthal <jrosenthal@jhu.edu>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: David Edmondson <dme@dme.org>
(let ((notmuch-version (if (string= notmuch-emacs-version "unknown")
(notmuch-cli-version)
notmuch-emacs-version)))
- (concat "Notmuch/" notmuch-version " (http://notmuchmail.org)")))
+ (concat "Notmuch/" notmuch-version " (https://notmuchmail.org)")))
(defun notmuch-mua-user-agent-emacs ()
"Generate a `User-Agent:' string suitable for notmuch."
;; C-h f compose-mail says that headers should be specified as
;; (string . value); however all the rest of message expects
;; headers to be symbols, not strings (eg message-header-format-alist).
- ;; http://lists.gnu.org/archive/html/emacs-devel/2011-01/msg00337.html
+ ;; https://lists.gnu.org/archive/html/emacs-devel/2011-01/msg00337.html
;; We need to convert any string input, eg from rmail-start-mail.
(dolist (h other-headers other-headers)
(if (stringp (car h)) (setcar h (intern (capitalize (car h))))))))
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Austin Clements <aclements@csail.mit.edu>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: David Edmondson <dme@dme.org>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: David Bremner <david@tethera.net>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Carl Worth <cworth@cworth.org>
;; David Edmondson <dme@dme.org>
(defcustom notmuch-show-stash-mlarchive-link-alist
'(("Gmane" . "http://mid.gmane.org/")
- ("MARC" . "http://marc.info/?i=")
- ("Mail Archive, The" . "http://mid.mail-archive.com/")
- ("LKML" . "http://lkml.kernel.org/r/")
+ ("MARC" . "https://marc.info/?i=")
+ ("Mail Archive, The" . "https://mid.mail-archive.com/")
+ ("LKML" . "https://lkml.kernel.org/r/")
;; FIXME: can these services be searched by `Message-Id' ?
;; ("MarkMail" . "http://markmail.org/")
;; ("Nabble" . "http://nabble.com/")
(define-key map (kbd "TAB") 'notmuch-show-next-button)
(define-key map "f" 'notmuch-show-forward-message)
(define-key map "F" 'notmuch-show-forward-open-messages)
+ (define-key map "b" 'notmuch-show-resend-message)
(define-key map "l" 'notmuch-show-filter-thread)
(define-key map "r" 'notmuch-show-reply-sender)
(define-key map "R" 'notmuch-show-reply)
(notmuch-show-mark-read)
(notmuch-show-set-prop :seen t)))
+(defvar notmuch-show--seen-has-errored nil)
+(make-variable-buffer-local 'notmuch-show--seen-has-errored)
+
(defun notmuch-show-command-hook ()
(when (eq major-mode 'notmuch-show-mode)
;; We need to redisplay to get window-start and window-end correct.
(redisplay)
(save-excursion
- (funcall notmuch-show-mark-read-function (window-start) (window-end)))))
+ (condition-case err
+ (funcall notmuch-show-mark-read-function (window-start) (window-end))
+ ((debug error)
+ (unless notmuch-show--seen-has-errored
+ (setq notmuch-show--seen-has-errored 't)
+ (setq header-line-format
+ (concat header-line-format
+ (propertize " [some mark read tag changes may have failed]"
+ 'face font-lock-warning-face)))))))))
(defun notmuch-show-filter-thread (query)
"Filter or LIMIT the current thread based on a new query string.
(error "No open messages to forward."))
(notmuch-mua-new-forward-messages open-messages prompt-for-sender)))
+(defun notmuch-show-resend-message (addresses)
+ "Resend the current message."
+ (interactive (list (notmuch-address-from-minibuffer "Resend to: ")))
+ (when (y-or-n-p (concat "Confirm resend to " addresses " "))
+ (notmuch-show-view-raw-message)
+ (message-resend addresses)
+ (notmuch-bury-or-kill-this-buffer)))
+
(defun notmuch-show-next-message (&optional pop-at-end)
"Show the next message.
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Carl Worth <cworth@cworth.org>
;; Damien Cassou <damien.cassou@gmail.com>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: David Edmondson <dme@dme.org>
;; Mark Walters <markwalters1009@gmail.com>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;; Code:
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Carl Worth <cworth@cworth.org>
;; David Edmondson <dme@dme.org>
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Carl Worth <cworth@cworth.org>
;; Homepage: https://notmuchmail.org/
;;
;; You will first need to have the notmuch program installed and have a
;; notmuch database built in order to use this. See
-;; http://notmuchmail.org for details.
+;; https://notmuchmail.org for details.
;;
;; To install this software, copy it to a directory that is on the
;; `load-path' variable within emacs (a good candidate is
;;
;; Have fun, and let us know if you have any comment, questions, or
;; kudos: Notmuch list <notmuch@notmuchmail.org> (subscription is not
-;; required, but is available from http://notmuchmail.org).
+;; required, but is available from https://notmuchmail.org).
;;; Code:
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Jani Nikula <jani@nikula.org>
*/
$(dir)/message-file.c \
$(dir)/messages.c \
$(dir)/sha1.c \
+ $(dir)/built-with.c \
$(dir)/tags.c
libnotmuch_cxx_srcs = \
$(dir)/index.cc \
$(dir)/message.cc \
$(dir)/query.cc \
+ $(dir)/query-fp.cc \
+ $(dir)/config.cc \
$(dir)/thread.cc
libnotmuch_modules := $(libnotmuch_c_srcs:.c=.o) $(libnotmuch_cxx_srcs:.cc=.o)
--- /dev/null
+/* notmuch - Not much of an email program, (just index and search)
+ *
+ * Copyright © 2016 David Bremner
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ *
+ * Author: David Bremner <david@tethera.net>
+ */
+
+#include "notmuch.h"
+#include "notmuch-private.h"
+
+notmuch_bool_t
+notmuch_built_with (const char *name)
+{
+ if (STRNCMP_LITERAL (name, "compact") == 0) {
+ return HAVE_XAPIAN_COMPACT;
+ } else if (STRNCMP_LITERAL (name, "field_processor") == 0) {
+ return HAVE_XAPIAN_FIELD_PROCESSOR;
+ } else if (STRNCMP_LITERAL (name, "retry_lock") == 0) {
+ return HAVE_XAPIAN_DB_RETRY_LOCK;
+ } else {
+ return FALSE;
+ }
+}
--- /dev/null
+/* config.cc - API for database metadata
+ *
+ * Copyright © 2016 David Bremner
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ *
+ * Author: David Bremner <david@tethera.net>
+ */
+
+#include "notmuch.h"
+#include "notmuch-private.h"
+#include "database-private.h"
+
+static const std::string CONFIG_PREFIX = "C";
+
+struct _notmuch_config_list {
+ notmuch_database_t *notmuch;
+ Xapian::TermIterator iterator;
+ char *current_key;
+ char *current_val;
+};
+
+static int
+_notmuch_config_list_destroy (notmuch_config_list_t *list)
+{
+ /* invoke destructor w/o deallocating memory */
+ list->iterator.~TermIterator();
+ return 0;
+}
+
+notmuch_status_t
+notmuch_database_set_config (notmuch_database_t *notmuch,
+ const char *key,
+ const char *value)
+{
+ notmuch_status_t status;
+ Xapian::WritableDatabase *db;
+
+ status = _notmuch_database_ensure_writable (notmuch);
+ if (status)
+ return status;
+
+ try {
+ db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
+ db->set_metadata (CONFIG_PREFIX + key, value);
+ } catch (const Xapian::Error &error) {
+ status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ notmuch->exception_reported = TRUE;
+ _notmuch_database_log (notmuch, "Error: A Xapian exception occurred setting metadata: %s\n",
+ error.get_msg().c_str());
+ }
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
+static notmuch_status_t
+_metadata_value (notmuch_database_t *notmuch,
+ const char *key,
+ std::string &value)
+{
+ notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
+
+ try {
+ value = notmuch->xapian_db->get_metadata (CONFIG_PREFIX + key);
+ } catch (const Xapian::Error &error) {
+ status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ notmuch->exception_reported = TRUE;
+ _notmuch_database_log (notmuch, "Error: A Xapian exception occurred getting metadata: %s\n",
+ error.get_msg().c_str());
+ }
+ return status;
+}
+
+notmuch_status_t
+notmuch_database_get_config (notmuch_database_t *notmuch,
+ const char *key,
+ char **value)
+{
+ std::string strval;
+ notmuch_status_t status;
+
+ if (! value)
+ return NOTMUCH_STATUS_NULL_POINTER;
+
+ status = _metadata_value (notmuch, key, strval);
+ if (status)
+ return status;
+
+ *value = strdup (strval.c_str ());
+
+ return NOTMUCH_STATUS_SUCCESS;
+}
+
+notmuch_status_t
+notmuch_database_get_config_list (notmuch_database_t *notmuch,
+ const char *prefix,
+ notmuch_config_list_t **out)
+{
+ notmuch_config_list_t *list = NULL;
+ notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
+
+ list = talloc (notmuch, notmuch_config_list_t);
+ if (! list) {
+ status = NOTMUCH_STATUS_OUT_OF_MEMORY;
+ goto DONE;
+ }
+
+ talloc_set_destructor (list, _notmuch_config_list_destroy);
+ list->notmuch = notmuch;
+ list->current_key = NULL;
+ list->current_val = NULL;
+
+ try {
+
+ new(&(list->iterator)) Xapian::TermIterator (notmuch->xapian_db->metadata_keys_begin
+ (CONFIG_PREFIX + (prefix ? prefix : "")));
+
+ } catch (const Xapian::Error &error) {
+ _notmuch_database_log (notmuch, "A Xapian exception occurred getting metadata iterator: %s.\n",
+ error.get_msg().c_str());
+ notmuch->exception_reported = TRUE;
+ status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;
+ }
+
+ *out = list;
+
+ DONE:
+ if (status && list)
+ talloc_free (list);
+
+ return status;
+}
+
+notmuch_bool_t
+notmuch_config_list_valid (notmuch_config_list_t *metadata)
+{
+ if (metadata->iterator == metadata->notmuch->xapian_db->metadata_keys_end ())
+ return FALSE;
+
+ return TRUE;
+}
+
+const char *
+notmuch_config_list_key (notmuch_config_list_t *list)
+{
+ if (list->current_key)
+ talloc_free (list->current_key);
+
+ list->current_key = talloc_strdup (list, (*list->iterator).c_str () + CONFIG_PREFIX.length ());
+
+ return list->current_key;
+}
+
+const char *
+notmuch_config_list_value (notmuch_config_list_t *list)
+{
+ std::string strval;
+ notmuch_status_t status;
+ const char *key = notmuch_config_list_key (list);
+
+ /* TODO: better error reporting?? */
+ status = _metadata_value (list->notmuch, key, strval);
+ if (status)
+ return NULL;
+
+ if (list->current_val)
+ talloc_free (list->current_val);
+
+ list->current_val = talloc_strdup (list, strval.c_str ());
+ return list->current_val;
+}
+
+void
+notmuch_config_list_move_to_next (notmuch_config_list_t *list)
+{
+ list->iterator++;
+}
+
+void
+notmuch_config_list_destroy (notmuch_config_list_t *list)
+{
+ talloc_free (list);
+}
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
return a;
}
+#define NOTMUCH_QUERY_PARSER_FLAGS (Xapian::QueryParser::FLAG_BOOLEAN | \
+ Xapian::QueryParser::FLAG_PHRASE | \
+ Xapian::QueryParser::FLAG_LOVEHATE | \
+ Xapian::QueryParser::FLAG_BOOLEAN_ANY_CASE | \
+ Xapian::QueryParser::FLAG_WILDCARD | \
+ Xapian::QueryParser::FLAG_PURE_NOT)
+
struct _notmuch_database {
notmuch_bool_t exception_reported;
Xapian::TermGenerator *term_gen;
Xapian::ValueRangeProcessor *value_range_processor;
Xapian::ValueRangeProcessor *date_range_processor;
+#if HAVE_XAPIAN_FIELD_PROCESSOR
+ Xapian::FieldProcessor *date_field_processor;
+ Xapian::FieldProcessor *query_field_processor;
+#endif
Xapian::ValueRangeProcessor *last_mod_range_processor;
};
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
#include "database-private.h"
#include "parse-time-vrp.h"
+#include "query-fp.h"
#include "string-util.h"
#include <iostream>
#define STRINGIFY(s) _SUB_STRINGIFY(s)
#define _SUB_STRINGIFY(s) #s
+#if HAVE_XAPIAN_DB_RETRY_LOCK
+#define DB_ACTION (Xapian::DB_CREATE_OR_OPEN | Xapian::DB_RETRY_LOCK)
+#else
+#define DB_ACTION Xapian::DB_CREATE_OR_OPEN
+#endif
+
/* Here's the current schema for our database (for NOTMUCH_DATABASE_VERSION):
*
* We currently have three different types of documents (mail, ghost,
* generated is 1 and the value will be
* incremented for each thread ID.
*
+ * C* metadata keys starting with C indicate
+ * configuration data. It can be managed with the
+ * n_database_*config* API. There is a convention
+ * of hierarchical keys separated by '.' (e.g.
+ * query.notmuch stores the value for the named
+ * query 'notmuch'), but it is not enforced by the
+ * API.
+ *
* Obsolete metadata
* -----------------
*
/* With these prefix values we follow the conventions published here:
*
- * http://xapian.org/docs/omega/termprefixes.html
+ * https://xapian.org/docs/omega/termprefixes.html
*
* as much as makes sense. Note that I took some liberty in matching
* the reserved prefix values to notmuch concepts, (for example, 'G'
if (mode == NOTMUCH_DATABASE_MODE_READ_WRITE) {
notmuch->xapian_db = new Xapian::WritableDatabase (xapian_path,
- Xapian::DB_CREATE_OR_OPEN);
+ DB_ACTION);
} else {
notmuch->xapian_db = new Xapian::Database (xapian_path);
}
notmuch->term_gen->set_stemmer (Xapian::Stem ("english"));
notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);
notmuch->date_range_processor = new ParseTimeValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);
+#if HAVE_XAPIAN_FIELD_PROCESSOR
+ /* This currently relies on the query parser to pass anything
+ * with a .. to the range processor */
+ notmuch->date_field_processor = new DateFieldProcessor();
+ notmuch->query_parser->add_boolean_prefix("date", notmuch->date_field_processor);
+ notmuch->query_field_processor = new QueryFieldProcessor (*notmuch->query_parser, notmuch);
+ notmuch->query_parser->add_boolean_prefix("query", notmuch->query_field_processor);
+#endif
notmuch->last_mod_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_LAST_MOD, "lastmod:");
notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);
delete notmuch->last_mod_range_processor;
notmuch->last_mod_range_processor = NULL;
+#if HAVE_XAPIAN_FIELD_PROCESSOR
+ delete notmuch->date_field_processor;
+ notmuch->date_field_processor = NULL;
+ delete notmuch->query_field_processor;
+ notmuch->query_field_processor = NULL;
+#endif
+
return status;
}
* References header, if available. If not, fall back to the
* first message ID in the In-Reply-To header. */
if (last_ref_message_id) {
- _notmuch_message_add_term (message, "replyto",
- last_ref_message_id);
+ _notmuch_message_add_term (message, "replyto",
+ last_ref_message_id);
} else if (in_reply_to_message_id) {
_notmuch_message_add_term (message, "replyto",
in_reply_to_message_id);
if (stored_id.empty ()) {
return NULL;
} else {
- Xapian::WritableDatabase *db;
+ Xapian::WritableDatabase *db;
db = static_cast <Xapian::WritableDatabase *> (notmuch->xapian_db);
/* Clear the metadata for this message ID. We don't need it
* anymore. */
- db->set_metadata (metadata_key, "");
+ db->set_metadata (metadata_key, "");
- return talloc_strdup (ctx, stored_id.c_str ());
+ return talloc_strdup (ctx, stored_id.c_str ());
}
}
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
# we go through a bit of work to get the unmangled names of the
# typeinfo symbols because of
-# http://sourceware.org/bugzilla/show_bug.cgi?id=10326
+# https://sourceware.org/bugzilla/show_bug.cgi?id=10326
if [ $# -lt 2 ]; then
echo Usage: $0 header obj1 obj2 obj3
while read sym; do
demangled=$(c++filt $sym)
case $demangled in
- typeinfo*)
+ typeinfo*)
printf "\t$sym;\n"
;;
*)
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
{9, ' ', ' ', 10, 0},
{10, '\n', '\n', 11, 10},
{11, 'M', 'M', 12, 0},
- {12, ' ', '`', 12, 11}
+ {12, ' ', '`', 12, 11}
};
int next;
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
for (i = 0; i < ARRAY_SIZE(flag2tag); i++) {
if ((strchr (combined_flags, flag2tag[i].flag) != NULL)
- ^
+ ^
flag2tag[i].inverse)
{
status = notmuch_message_add_tag (message, flag2tag[i].tag);
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
((private_status >= (notmuch_private_status_t) NOTMUCH_STATUS_LAST_STATUS)\
? \
_internal_error (format " (%s).\n", \
- ##__VA_ARGS__, \
- __location__), \
+ ##__VA_ARGS__, \
+ __location__), \
(notmuch_status_t) NOTMUCH_PRIVATE_STATUS_SUCCESS \
: \
(notmuch_status_t) private_status)
notmuch_bool_t
_notmuch_doc_id_set_contains (notmuch_doc_id_set_t *doc_ids,
- unsigned int doc_id);
+ unsigned int doc_id);
void
_notmuch_doc_id_set_remove (notmuch_doc_id_set_t *doc_ids,
- unsigned int doc_id);
+ unsigned int doc_id);
/* querying xapian documents by type (e.g. "mail" or "ghost"): */
notmuch_status_t
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
typedef struct _notmuch_tags notmuch_tags_t;
typedef struct _notmuch_directory notmuch_directory_t;
typedef struct _notmuch_filenames notmuch_filenames_t;
+typedef struct _notmuch_config_list notmuch_config_list_t;
#endif /* __DOXYGEN__ */
/**
* completely in the future, but it's likely to be a specialized
* version of the general Xapian query syntax:
*
- * http://xapian.org/docs/queryparser.html
+ * https://xapian.org/docs/queryparser.html
*
* As a special case, passing either a length-zero string, (that is ""),
* or a string consisting of a single asterisk (that is "*"), will
void
notmuch_filenames_destroy (notmuch_filenames_t *filenames);
+
+/**
+ * set config 'key' to 'value'
+ *
+ */
+notmuch_status_t
+notmuch_database_set_config (notmuch_database_t *db, const char *key, const char *value);
+
+/**
+ * retrieve config item 'key', assign to 'value'
+ *
+ * keys which have not been previously set with n_d_set_config will
+ * return an empty string.
+ *
+ * return value is allocated by malloc and should be freed by the
+ * caller.
+ */
+notmuch_status_t
+notmuch_database_get_config (notmuch_database_t *db, const char *key, char **value);
+
+/**
+ * Create an iterator for all config items with keys matching a given prefix
+ */
+notmuch_status_t
+notmuch_database_get_config_list (notmuch_database_t *db, const char *prefix, notmuch_config_list_t **out);
+
+/**
+ * Is 'config_list' iterator valid (i.e. _key, _value, _move_to_next can be called).
+ */
+notmuch_bool_t
+notmuch_config_list_valid (notmuch_config_list_t *config_list);
+
+/**
+ * return key for current config pair
+ *
+ * return value is owned by the iterator, and will be destroyed by the
+ * next call to notmuch_config_list_key or notmuch_config_list_destroy.
+ */
+const char *
+notmuch_config_list_key (notmuch_config_list_t *config_list);
+
+/**
+ * return 'value' for current config pair
+ *
+ * return value is owned by the iterator, and will be destroyed by the
+ * next call to notmuch_config_list_value or notmuch config_list_destroy
+ */
+const char *
+notmuch_config_list_value (notmuch_config_list_t *config_list);
+
+
+/**
+ * move 'config_list' iterator to the next pair
+ */
+void
+notmuch_config_list_move_to_next (notmuch_config_list_t *config_list);
+
+/**
+ * free any resources held by 'config_list'
+ */
+void
+notmuch_config_list_destroy (notmuch_config_list_t *config_list);
+
+/**
+ * interrogate the library for compile time features
+ */
+notmuch_bool_t
+notmuch_built_with (const char *name);
/* @} */
NOTMUCH_END_DECLS
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Jani Nikula <jani@nikula.org>
*/
return valno;
}
+
+#if HAVE_XAPIAN_FIELD_PROCESSOR
+/* XXX TODO: is throwing an exception the right thing to do here? */
+Xapian::Query DateFieldProcessor::operator()(const std::string & str) {
+ time_t from, to, now;
+
+ /* Use the same 'now' for begin and end. */
+ if (time (&now) == (time_t) -1)
+ throw Xapian::QueryParserError("Unable to get current time");
+
+ if (parse_time_string (str.c_str (), &from, &now, PARSE_TIME_ROUND_DOWN))
+ throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'");
+
+ if (parse_time_string (str.c_str (), &to, &now, PARSE_TIME_ROUND_UP_INCLUSIVE))
+ throw Xapian::QueryParserError ("Didn't understand date specification '" + str + "'");
+
+ return Xapian::Query(Xapian::Query::OP_AND,
+ Xapian::Query(Xapian::Query::OP_VALUE_GE, 0, Xapian::sortable_serialise ((double) from)),
+ Xapian::Query(Xapian::Query::OP_VALUE_LE, 0, Xapian::sortable_serialise ((double) to)));
+}
+#endif
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Jani Nikula <jani@nikula.org>
*/
Xapian::valueno operator() (std::string &begin, std::string &end);
};
+#if HAVE_XAPIAN_FIELD_PROCESSOR
+class DateFieldProcessor : public Xapian::FieldProcessor {
+ Xapian::Query operator()(const std::string & str);
+};
+#endif
#endif /* NOTMUCH_PARSE_TIME_VRP_H */
--- /dev/null
+/* query-fp.cc - "query:" field processor glue
+ *
+ * This file is part of notmuch.
+ *
+ * Copyright © 2016 David Bremner
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ *
+ * Author: David Bremner <david@tethera.net>
+ */
+
+#include "database-private.h"
+#include "query-fp.h"
+#include <iostream>
+
+#if HAVE_XAPIAN_FIELD_PROCESSOR
+
+Xapian::Query
+QueryFieldProcessor::operator() (const std::string & name)
+{
+ std::string key = "query." + name;
+ char *expansion;
+ notmuch_status_t status;
+
+ status = notmuch_database_get_config (notmuch, key.c_str (), &expansion);
+ if (status) {
+ throw Xapian::QueryParserError ("error looking up key" + name);
+ }
+
+ return parser.parse_query (expansion, NOTMUCH_QUERY_PARSER_FLAGS);
+}
+#endif
--- /dev/null
+/* query-fp.h - query field processor glue
+ *
+ * This file is part of notmuch.
+ *
+ * Copyright © 2016 David Bremner
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
+ *
+ * Author: David Bremner <david@tethera.net>
+ */
+
+#ifndef NOTMUCH_QUERY_FP_H
+#define NOTMUCH_QUERY_FP_H
+
+#include <xapian.h>
+#include "notmuch.h"
+
+#if HAVE_XAPIAN_FIELD_PROCESSOR
+class QueryFieldProcessor : public Xapian::FieldProcessor {
+ protected:
+ Xapian::QueryParser &parser;
+ notmuch_database_t *notmuch;
+
+ public:
+ QueryFieldProcessor (Xapian::QueryParser &parser_, notmuch_database_t *notmuch_)
+ : parser(parser_), notmuch(notmuch_) { };
+
+ Xapian::Query operator()(const std::string & str);
+};
+#endif
+#endif /* NOTMUCH_QUERY_FP_H */
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset;
Xapian::MSetIterator iterator;
- unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
- Xapian::QueryParser::FLAG_PHRASE |
- Xapian::QueryParser::FLAG_LOVEHATE |
- Xapian::QueryParser::FLAG_BOOLEAN_ANY_CASE |
- Xapian::QueryParser::FLAG_WILDCARD |
- Xapian::QueryParser::FLAG_PURE_NOT);
if (strcmp (query_string, "") == 0 ||
strcmp (query_string, "*") == 0)
final_query = mail_query;
} else {
string_query = notmuch->query_parser->
- parse_query (query_string, flags);
+ parse_query (query_string, NOTMUCH_QUERY_PARSER_FLAGS);
final_query = Xapian::Query (Xapian::Query::OP_AND,
mail_query, string_query);
}
case NOTMUCH_SORT_MESSAGE_ID:
enquire.set_sort_by_value (NOTMUCH_VALUE_MESSAGE_ID, FALSE);
break;
- case NOTMUCH_SORT_UNSORTED:
+ case NOTMUCH_SORT_UNSORTED:
break;
}
void
_notmuch_doc_id_set_remove (notmuch_doc_id_set_t *doc_ids,
- unsigned int doc_id)
+ unsigned int doc_id)
{
if (doc_id < doc_ids->bound)
doc_ids->bitmap[DOCIDSET_WORD(doc_id)] &= ~(1 << DOCIDSET_BIT(doc_id));
type));
Xapian::Query string_query, final_query, exclude_query;
Xapian::MSet mset;
- unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN |
- Xapian::QueryParser::FLAG_PHRASE |
- Xapian::QueryParser::FLAG_LOVEHATE |
- Xapian::QueryParser::FLAG_BOOLEAN_ANY_CASE |
- Xapian::QueryParser::FLAG_WILDCARD |
- Xapian::QueryParser::FLAG_PURE_NOT);
if (strcmp (query_string, "") == 0 ||
strcmp (query_string, "*") == 0)
final_query = mail_query;
} else {
string_query = notmuch->query_parser->
- parse_query (query_string, flags);
+ parse_query (query_string, NOTMUCH_QUERY_PARSER_FLAGS);
final_query = Xapian::Query (Xapian::Query::OP_AND,
mail_query, string_query);
}
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
return result;
}
-
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
* Austin Clements <aclements@csail.mit.edu>
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Authors: Carl Worth <cworth@cworth.org>
* Keith Packard <keithp@keithp.com>
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
DUMP_FORMAT_SUP
} dump_format_t;
+typedef enum dump_includes {
+ DUMP_INCLUDE_TAGS = 1,
+ DUMP_INCLUDE_CONFIG = 2,
+} dump_include_t;
+
+#define NOTMUCH_DUMP_VERSION 2
+
int
notmuch_database_dump (notmuch_database_t *notmuch,
const char *output_file_name,
const char *query_str,
dump_format_t output_format,
+ dump_include_t include,
notmuch_bool_t gzip_output);
/* If status is non-zero (i.e. error) print appropriate
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Ben Gamari <bgamari.foss@gmail.com>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
static const char toplevel_config_comment[] =
" .notmuch-config - Configuration file for the notmuch mail system\n"
"\n"
- " For more information about notmuch, see http://notmuchmail.org";
+ " For more information about notmuch, see https://notmuchmail.org";
static const char database_config_comment[] =
" Database configuration\n"
return 0;
}
+#define BUILT_WITH_PREFIX "built_with."
+#define QUERY_PREFIX "query."
+
+static int
+_print_db_config(notmuch_config_t *config, const char *name)
+{
+ notmuch_database_t *notmuch;
+ char *val;
+
+ if (notmuch_database_open (notmuch_config_get_database_path (config),
+ NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
+ return EXIT_FAILURE;
+
+ /* XXX Handle UUID mismatch? */
+
+ if (print_status_database ("notmuch config", notmuch,
+ notmuch_database_get_config (notmuch, name, &val)))
+ return EXIT_FAILURE;
+
+ puts (val);
+
+ return EXIT_SUCCESS;
+}
+
static int
notmuch_config_command_get (notmuch_config_t *config, char *item)
{
tags = notmuch_config_get_new_tags (config, &length);
for (i = 0; i < length; i++)
printf ("%s\n", tags[i]);
+ } else if (STRNCMP_LITERAL (item, BUILT_WITH_PREFIX) == 0) {
+ printf ("%s\n",
+ notmuch_built_with (item + strlen (BUILT_WITH_PREFIX)) ? "true" : "false");
+ } else if (STRNCMP_LITERAL (item, QUERY_PREFIX) == 0) {
+ return _print_db_config (config, item);
} else {
char **value;
size_t i, length;
return 0;
}
+static int
+_set_db_config(notmuch_config_t *config, const char *key, int argc, char **argv)
+{
+ notmuch_database_t *notmuch;
+ const char *val = "";
+
+ if (argc > 1) {
+ /* XXX handle lists? */
+ fprintf (stderr, "notmuch config set: at most one value expected for %s\n", key);
+ return EXIT_FAILURE;
+ }
+
+ if (argc > 0) {
+ val = argv[0];
+ }
+
+ if (notmuch_database_open (notmuch_config_get_database_path (config),
+ NOTMUCH_DATABASE_MODE_READ_WRITE, ¬much))
+ return EXIT_FAILURE;
+
+ /* XXX Handle UUID mismatch? */
+
+ if (print_status_database ("notmuch config", notmuch,
+ notmuch_database_set_config (notmuch, key, val)))
+ return EXIT_FAILURE;
+
+ if (print_status_database ("notmuch config", notmuch,
+ notmuch_database_close (notmuch)))
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
+
static int
notmuch_config_command_set (notmuch_config_t *config, char *item, int argc, char *argv[])
{
char *group, *key;
+ if (STRNCMP_LITERAL (item, BUILT_WITH_PREFIX) == 0) {
+ fprintf (stderr, "Error: read only option: %s\n", item);
+ return 1;
+ }
+
+ if (STRNCMP_LITERAL (item, QUERY_PREFIX) == 0) {
+ return _set_db_config (config, item, argc, argv);
+ }
+
if (_item_split (item, &group, &key))
return 1;
return notmuch_config_save (config);
}
+static
+void
+_notmuch_config_list_built_with ()
+{
+ printf("%scompact=%s\n",
+ BUILT_WITH_PREFIX,
+ notmuch_built_with ("compact") ? "true" : "false");
+ printf("%sfield_processor=%s\n",
+ BUILT_WITH_PREFIX,
+ notmuch_built_with ("field_processor") ? "true" : "false");
+ printf("%sretry_lock=%s\n",
+ BUILT_WITH_PREFIX,
+ notmuch_built_with ("retry_lock") ? "true" : "false");
+}
+
+static int
+_list_db_config (notmuch_config_t *config)
+{
+ notmuch_database_t *notmuch;
+ notmuch_config_list_t *list;
+
+ if (notmuch_database_open (notmuch_config_get_database_path (config),
+ NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much))
+ return EXIT_FAILURE;
+
+ /* XXX Handle UUID mismatch? */
+
+
+ if (print_status_database ("notmuch config", notmuch,
+ notmuch_database_get_config_list (notmuch, "", &list)))
+ return EXIT_FAILURE;
+
+ for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
+ printf("%s=%s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
+ }
+ notmuch_config_list_destroy (list);
+
+ return EXIT_SUCCESS;
+}
+
static int
notmuch_config_command_list (notmuch_config_t *config)
{
g_strfreev (groups);
- return 0;
+ _notmuch_config_list_built_with ();
+ return _list_db_config (config);
}
int
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Keith Packard <keithp@keithp.com>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
#include "string-util.h"
#include <zlib.h>
+static int
+database_dump_config (notmuch_database_t *notmuch, gzFile output)
+{
+ notmuch_config_list_t *list;
+ int ret = EXIT_FAILURE;
+ char *buffer = NULL;
+ size_t buffer_size = 0;
+
+ if (print_status_database ("notmuch dump", notmuch,
+ notmuch_database_get_config_list (notmuch, NULL, &list)))
+ goto DONE;
+
+ for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
+ if (hex_encode (notmuch, notmuch_config_list_key (list),
+ &buffer, &buffer_size) != HEX_SUCCESS) {
+ fprintf (stderr, "Error: failed to hex-encode config key %s\n",
+ notmuch_config_list_key (list));
+ goto DONE;
+ }
+ gzprintf (output, "#@ %s", buffer);
+
+ if (hex_encode (notmuch, notmuch_config_list_value (list),
+ &buffer, &buffer_size) != HEX_SUCCESS) {
+ fprintf (stderr, "Error: failed to hex-encode config value %s\n",
+ notmuch_config_list_value (list) );
+ goto DONE;
+ }
+
+ gzprintf (output, " %s\n", buffer);
+ }
+
+ ret = EXIT_SUCCESS;
+
+ DONE:
+ if (list)
+ notmuch_config_list_destroy (list);
+
+ if (buffer)
+ talloc_free (buffer);
+
+ return ret;
+}
+
+static void
+print_dump_header (gzFile output, int output_format, int include)
+{
+ gzprintf (output, "#notmuch-dump %s:%d %s%s%s\n",
+ (output_format == DUMP_FORMAT_SUP) ? "sup" : "batch-tag",
+ NOTMUCH_DUMP_VERSION,
+ (include & DUMP_INCLUDE_CONFIG) ? "config" : "",
+ (include & DUMP_INCLUDE_TAGS) && (include & DUMP_INCLUDE_CONFIG) ? "," : "",
+ (include & DUMP_INCLUDE_TAGS) ? "tags" : "");
+}
static int
database_dump_file (notmuch_database_t *notmuch, gzFile output,
- const char *query_str, int output_format)
+ const char *query_str, int output_format, int include)
{
notmuch_query_t *query;
notmuch_messages_t *messages;
notmuch_message_t *message;
notmuch_tags_t *tags;
+ print_dump_header (output, output_format, include);
+
+ if (include & DUMP_INCLUDE_CONFIG) {
+ if (print_status_database ("notmuch dump", notmuch,
+ database_dump_config(notmuch,output)))
+ return EXIT_FAILURE;
+ }
+
+ if (! (include & DUMP_INCLUDE_TAGS))
+ return EXIT_SUCCESS;
+
if (! query_str)
query_str = "";
const char *output_file_name,
const char *query_str,
dump_format_t output_format,
+ dump_include_t include,
notmuch_bool_t gzip_output)
{
gzFile output = NULL;
goto DONE;
}
- ret = database_dump_file (notmuch, output, query_str, output_format);
+ ret = database_dump_file (notmuch, output, query_str, output_format, include);
if (ret) goto DONE;
ret = gzflush (output, Z_FINISH);
int opt_index;
int output_format = DUMP_FORMAT_BATCH_TAG;
+ int include = 0;
notmuch_bool_t gzip_output = 0;
notmuch_opt_desc_t options[] = {
(notmuch_keyword_t []){ { "sup", DUMP_FORMAT_SUP },
{ "batch-tag", DUMP_FORMAT_BATCH_TAG },
{ 0, 0 } } },
+ { NOTMUCH_OPT_KEYWORD_FLAGS, &include, "include", 'I',
+ (notmuch_keyword_t []){ { "config", DUMP_INCLUDE_CONFIG },
+ { "tags", DUMP_INCLUDE_TAGS} } },
{ NOTMUCH_OPT_STRING, &output_file_name, "output", 'o', 0 },
{ NOTMUCH_OPT_BOOLEAN, &gzip_output, "gzip", 'z', 0 },
{ NOTMUCH_OPT_INHERIT, (void *) ¬much_shared_options, NULL, 0, 0 },
notmuch_process_shared_options (argv[0]);
+ if (include == 0)
+ include = DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS;
+
if (opt_index < argc) {
query_str = query_string_from_args (notmuch, argc - opt_index, argv + opt_index);
if (query_str == NULL) {
}
ret = notmuch_database_dump (notmuch, output_file_name, query_str,
- output_format, gzip_output);
+ output_format, include, gzip_output);
notmuch_database_destroy (notmuch);
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see http://www.gnu.org/licenses/ .
+# along with this program. If not, see https://www.gnu.org/licenses/ .
#
# Authors: Jani Nikula <jani@nikula.org>
#
AUTO_DAEMON=
CREATE_FRAME=
+escape -v pwd "$PWD"
+
# The crux of it all: construct an elisp progn and eval it.
-ELISP="(prog1 'done (require 'notmuch) (notmuch-mua-new-mail)"
+ELISP="(prog1 'done (require 'notmuch) (cd \"$pwd\") (notmuch-mua-new-mail)"
# Short options compatible with mutt(1).
while getopts :s:c:b:i:h opt; do
ELISP="${ELISP} (message-goto-bcc) (insert \"${OPTARG}, \")"
;;
--body|i)
- ELISP="${ELISP} (message-goto-body) (cd \"${PWD}\") (insert-file \"${OPTARG}\")"
+ ELISP="${ELISP} (message-goto-body) (insert-file \"${OPTARG}\")"
;;
--print)
PRINT_ONLY=1
# Kill the terminal/frame if we're creating one.
if [ -z "$USE_EMACSCLIENT" -o -n "$CREATE_FRAME" -o -n "$NO_WINDOW" ]; then
- ELISP="${ELISP} (setq message-exit-actions (list #'save-buffers-kill-terminal))"
+ ELISP="${ELISP} (message-add-action #'save-buffers-kill-terminal 'exit)"
fi
# End progn.
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Peter Wang <novalazy@gmail.com>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
const char *path,
add_files_state_t *state)
{
- DIR *dir = NULL;
struct dirent *entry = NULL;
char *next = NULL;
time_t fs_mtime, db_mtime;
DONE:
if (next)
talloc_free (next);
- if (dir)
- closedir (dir);
if (fs_entries) {
for (i = 0; i < num_fs_entries; i++)
free (fs_entries[i]);
}
if (notmuch_database_dump (notmuch, backup_name, "",
- DUMP_FORMAT_BATCH_TAG, TRUE)) {
+ DUMP_FORMAT_BATCH_TAG, DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS, TRUE)) {
fprintf (stderr, "Backup failed. Aborting upgrade.");
return EXIT_FAILURE;
}
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Authors: Carl Worth <cworth@cworth.org>
* Keith Packard <keithp@keithp.com>
unsigned int n = 0;
/* Some mailing lists munge the Reply-To header despite it being A Bad
- * Thing, see http://www.unicom.com/pw/reply-to-harmful.html
+ * Thing, see http://marc.merlins.org/netrants/reply-to-harmful.html
*
* The munging is easy to detect, because it results in a
* redundant reply-to header, (with an address that already exists
return 1;
if (count != 1) {
- fprintf (stderr, "Error: search term did not match precisely one message.\n");
+ fprintf (stderr, "Error: search term did not match precisely one message (matched %d messages).\n", count);
return 1;
}
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
#include "string-util.h"
#include "zlib-extra.h"
+static int
+process_config_line (notmuch_database_t *notmuch, const char* line)
+{
+ const char *key_p, *val_p;
+ char *key, *val;
+ size_t key_len,val_len;
+ const char *delim = " \t\n";
+ int ret = EXIT_FAILURE;
+
+ void *local = talloc_new(NULL);
+
+ key_p = strtok_len_c (line, delim, &key_len);
+ val_p = strtok_len_c (key_p+key_len, delim, &val_len);
+
+ key = talloc_strndup (local, key_p, key_len);
+ val = talloc_strndup (local, val_p, val_len);
+ if (hex_decode_inplace (key) != HEX_SUCCESS ||
+ hex_decode_inplace (val) != HEX_SUCCESS ) {
+ fprintf (stderr, "hex decoding failure on line %s\n", line);
+ goto DONE;
+ }
+
+ if (print_status_database ("notmuch restore", notmuch,
+ notmuch_database_set_config (notmuch, key, val)))
+ goto DONE;
+
+ ret = EXIT_SUCCESS;
+
+ DONE:
+ talloc_free (local);
+ return ret;
+}
+
static regex_t regex;
/* Non-zero return indicates an error in retrieving the message,
int ret = 0;
int opt_index;
+ int include = 0;
int input_format = DUMP_FORMAT_AUTO;
if (notmuch_database_open (notmuch_config_get_database_path (config),
{ "batch-tag", DUMP_FORMAT_BATCH_TAG },
{ "sup", DUMP_FORMAT_SUP },
{ 0, 0 } } },
+ { NOTMUCH_OPT_KEYWORD_FLAGS, &include, "include", 'I',
+ (notmuch_keyword_t []){ { "config", DUMP_INCLUDE_CONFIG },
+ { "tags", DUMP_INCLUDE_TAGS} } },
+
{ NOTMUCH_OPT_STRING, &input_file_name, "input", 'i', 0 },
{ NOTMUCH_OPT_BOOLEAN, &accumulate, "accumulate", 'a', 0 },
{ NOTMUCH_OPT_INHERIT, (void *) ¬much_shared_options, NULL, 0, 0 },
notmuch_process_shared_options (argv[0]);
notmuch_exit_if_unmatched_db_uuid (notmuch);
+ if (include == 0) {
+ include = DUMP_INCLUDE_CONFIG | DUMP_INCLUDE_TAGS;
+ }
+
name_for_error = input_file_name ? input_file_name : "stdin";
if (! accumulate)
ret = EXIT_FAILURE;
goto DONE;
}
+
+ if ((include & DUMP_INCLUDE_CONFIG) && line_len >= 2 && line[0] == '#' && line[1] == '@') {
+ ret = process_config_line(notmuch, line+2);
+ if (ret)
+ goto DONE;
+ }
+
} while ((line_len == 0) ||
(line[0] == '#') ||
/* the cast is safe because we checked about for line_len < 0 */
(strspn (line, " \t\n") == (unsigned)line_len));
+ if (! (include & DUMP_INCLUDE_TAGS)) {
+ ret = EXIT_SUCCESS;
+ goto DONE;
+ }
+
char *p;
for (p = line; (input_format == DUMP_FORMAT_AUTO) && *p; p++) {
if (*p == '(')
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
return 1;
if (count != 1) {
- fprintf (stderr, "Error: search term did not match precisely one message.\n");
+ fprintf (stderr, "Error: search term did not match precisely one message (matched %d messages).\n", count);
return 1;
}
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Authors: Carl Worth <cworth@cworth.org>
* Keith Packard <keithp@keithp.com>
"You can also use \"notmuch show\" with any of the thread IDs resulting\n"
"from a search. Finally, you may want to explore using a more sophisticated\n"
"interface to notmuch such as the emacs interface implemented in notmuch.el\n"
- "or any other interface described at http://notmuchmail.org\n\n"
+ "or any other interface described at https://notmuchmail.org\n\n"
"And don't forget to run \"notmuch new\" whenever new mail arrives.\n\n"
"Have fun, and may your inbox never have much mail.\n\n",
notmuch_config_get_user_name (config),
Group: Applications/Internet
License: GPLv3+
-URL: http://notmuchmail.org/
+URL: https://notmuchmail.org/
-Source0: http://notmuchmail.org/releases/notmuch-%{version}.tar.gz
+Source0: https://notmuchmail.org/releases/notmuch-%{version}.tar.gz
BuildRequires: xapian-core-devel gmime-devel libtalloc-devel
BuildRequires: zlib-devel emacs-el emacs-nox python ruby ruby-devel perl
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Author: Jani Nikula <jani@nikula.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Author: Jani Nikula <jani@nikula.org>
*/
CORPUS_NAME := notmuch-email-corpus-$(PERFTEST_VERSION).tar.xz
TXZFILE := ${dir}/download/${CORPUS_NAME}
SIGFILE := ${TXZFILE}.asc
-DEFAULT_URL := http://notmuchmail.org/releases/${CORPUS_NAME}
+DEFAULT_URL := https://notmuchmail.org/releases/${CORPUS_NAME}
perf-test: time-test memory-test
$(TXZFILE):
@printf "\nPlease download ${TXZFILE} using:\n\n"
@printf "\t%% make download-corpus\n\n"
- @echo or see http://notmuchmail.org/corpus for download locations
+ @echo or see https://notmuchmail.org/corpus for download locations
@echo
@false
In case that fails or is too slow, check
- http://notmuchmail.org/corpus
+ https://notmuchmail.org/corpus
for a list of mirrors.
# Run tests
#
# Copyright (c) 2005 Junio C Hamano
+# Copyright (c) 2010 Notmuch Developers
#
# Adapted from a Makefile to a shell script by Carl Worth (2010)
exit 1
fi
-cd $(dirname "$0")
+cd "$(dirname "$0")"
for test in M*.sh; do
./"$test" "$@"
# Run tests
#
# Copyright (c) 2005 Junio C Hamano
+# Copyright (c) 2010 Notmuch Developers
#
# Adapted from a Makefile to a shell script by Carl Worth (2010)
exit 1
fi
-cd $(dirname "$0")
+cd "$(dirname "$0")"
for test in T*.sh; do
./"$test" "$@"
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Peter Feigl <peter.feigl@gmx.at>
*/
$(call quiet,CC) $^ -o $@ $(LDFLAGS) $(TALLOC_LDFLAGS)
random_corpus_deps = $(dir)/random-corpus.o $(dir)/database-test.o \
- notmuch-config.o command-line-arguments.o \
+ notmuch-config.o status.o command-line-arguments.o \
lib/libnotmuch.a util/libutil.a \
parse-time-string/libparse-time-string.a
name of your test. Tests will be run in order the 'ddd' part determines.
The test script should start with the standard "#!/usr/bin/env bash"
-with copyright notices, and an assignment to variable 'test_description',
-like this:
+and an assignment to variable 'test_description', like this:
#!/usr/bin/env bash
- #
- # Copyright (c) 2005 Junio C Hamano
- #
test_description='xxx test (option --frotz)
test_expect_equal "$(notmuch config get foo.nonexistent)" ""
test_begin_subtest "List all items"
-notmuch config set database.path "/canonical/path"
-output=$(notmuch config list)
-test_expect_equal "$output" "\
-database.path=/canonical/path
+notmuch config list 2>&1 | notmuch_config_sanitize > OUTPUT
+cat <<EOF > EXPECTED
+Error opening database at MAIL_DIR/.notmuch: No such file or directory
+database.path=MAIL_DIR
user.name=Notmuch Test Suite
user.primary_email=test_suite@notmuchmail.org
user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org
maildir.synchronize_flags=true
crypto.gpg_path=gpg
foo.string=this is another string value
-foo.list=this;is another;list value;"
+foo.list=this;is another;list value;
+built_with.compact=something
+built_with.field_processor=something
+built_with.retry_lock=something
+EOF
+test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "Top level --config=FILE option"
cp "${NOTMUCH_CONFIG}" alt-config
foo bar
baz
EOF
-output=$(notmuch --config=new-notmuch-config config list)
+output=$(notmuch --config=new-notmuch-config config list | notmuch_built_with_sanitize)
test_expect_equal "$output" "\
database.path=/path/to/maildir
user.name=Test Suite
new.ignore=
search.exclude_tags=baz;
maildir.synchronize_flags=true
-crypto.gpg_path=gpg"
+crypto.gpg_path=gpg
+built_with.compact=something
+built_with.field_processor=something
+built_with.retry_lock=something"
test_done
+%22%27%22%27%22%22%27%27 +inbox +tag4 +tag5 +unread -- id:msg-002@notmuch-test-suite
EOF
-notmuch dump --format=batch-tag | sort > OUTPUT
+NOTMUCH_DUMP_TAGS > OUTPUT
notmuch restore --format=batch-tag < BACKUP
test_expect_equal_file EXPECTED OUTPUT
+%21@%23%20%24%25%5e%26%2a%29-_=+%5b%7b%5c%20%7c%3b%3a%27%20%22,.%3c%60%7e +inbox +tag5 +unread -- id:msg-001@notmuch-test-suite
EOF
-notmuch dump --format=batch-tag | sort > OUTPUT
+NOTMUCH_DUMP_TAGS > OUTPUT
notmuch restore --format=batch-tag < BACKUP
test_expect_equal_file EXPECTED OUTPUT
+%2a@%7d%cf%b5%f4%85%80%adO3%da%a7 +=%e0%ac%95%c8%b3+%ef%aa%95%c8%a64w%c7%9d%c9%a2%cf%b3%d6%82%24B%c4%a9%c5%a1UX%ee%99%b0%27E7%ca%a4%d0%8b%5d +A%e1%a0%bc%de%8b%d5%b2V%d9%9b%f3%b5%a2%a3M%d8%a1u@%f0%a0%ac%948%7e%f0%ab%86%af%27 +L%df%85%ef%a1%a5m@%d3%96%c2%ab%d4%9f%ca%b8%f3%b3%a2%bf%c7%b1_u%d7%b4%c7%b1 +P%c4%98%2f +R +inbox +tag5 +unread +%7e%d1%8b%25%ec%a0%ae%d1%a0M%3b%e3%b6%b7%e9%a4%87%3c%db%9a%cc%a8%e1%96%9d +%c4%bf7%c7%ab9H%c4%99k%ea%91%bd%c3%8ck%e2%b3%8dk%c5%952V%e4%99%b2%d9%b3%e4%8b%bda%5b%24%c7%9b +%da%88=f%cc%b9I%ce%af%7b%c9%97%e3%b9%8bH%cb%92X%d2%8c6 +%dc%9crh%d2%86B%e5%97%a2%22t%ed%99%82d -- id:msg-001@notmuch-test-suite
EOF
-notmuch dump --format=batch-tag | sort > OUTPUT
+NOTMUCH_DUMP_TAGS > OUTPUT
notmuch restore --format=batch-tag < BACKUP
test_expect_equal_file EXPECTED OUTPUT
+foo%3a%3abar%25 +found%3a%3ait +inbox +tag5 +unread +winner -- id:msg-001@notmuch-test-suite
EOF
-notmuch dump --format=batch-tag | sort > OUTPUT
+NOTMUCH_DUMP_TAGS > OUTPUT
notmuch restore --format=batch-tag < BACKUP
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "Attempt to show multiple raw messages"
output=$(notmuch show --format=raw "*" 2>&1)
-test_expect_equal "$output" "Error: search term did not match precisely one message."
+test_expect_equal "$output" "Error: search term did not match precisely one message (matched 2 messages)."
test_begin_subtest "Show a raw message"
output=$(notmuch show --format=raw id:msg-001@notmuch-test-suite | notmuch_date_sanitize)
# Note, we assume all messages from cworth have a message-id
# containing cworth.org
-grep 'cworth[.]org' dump.expected > dump-cworth.expected
+{ head -1 dump.expected ; grep 'cworth[.]org' dump.expected; } > dump-cworth.expected
test_begin_subtest "dump -- from:cworth"
notmuch dump -- from:cworth > dump-dash-cworth.actual
test_expect_equal_file OUTPUT EXPECTED
test_begin_subtest "format=batch-tag, dump sanity check."
-notmuch dump --format=sup from:cworth | cut -f1 -d' ' | \
+NOTMUCH_DUMP_TAGS --format=sup from:cworth | cut -f1 -d' ' | \
sort > EXPECTED.$test_count
-notmuch dump --format=batch-tag from:cworth | sed 's/^.*-- id://' | \
+NOTMUCH_DUMP_TAGS --format=batch-tag from:cworth | sed 's/^.*-- id://' | \
sort > OUTPUT.$test_count
test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count
test_begin_subtest "format=batch-tag, missing newline"
printf "+a_tag_without_newline -- id:20091117232137.GA7669@griffis1.net" > IN
notmuch restore --accumulate < IN
-notmuch dump id:20091117232137.GA7669@griffis1.net > OUT
+NOTMUCH_DUMP_TAGS id:20091117232137.GA7669@griffis1.net > OUT
cat <<EOF > EXPECTED
+a_tag_without_newline +inbox +unread -- id:20091117232137.GA7669@griffis1.net
EOF
+ -- id:20091117232137.GA7669@griffis1.net
EOF
notmuch restore --format=batch-tag < EXPECTED.$test_count
-notmuch dump --format=batch-tag id:20091117232137.GA7669@griffis1.net > OUTPUT.$test_count
+NOTMUCH_DUMP_TAGS --format=batch-tag id:20091117232137.GA7669@griffis1.net > OUTPUT.$test_count
test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count
tag1='comic_swear=$&^%$^%\\//-+$^%$'
test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count
test_begin_subtest 'format=batch-tag, checking encoded output'
-notmuch dump --format=batch-tag -- from:cworth |\
+NOTMUCH_DUMP_TAGS --format=batch-tag -- from:cworth |\
awk "{ print \"+$enc1 +$enc2 +$enc3 -- \" \$5 }" > EXPECTED.$test_count
-notmuch dump --format=batch-tag -- from:cworth > OUTPUT.$test_count
+NOTMUCH_DUMP_TAGS --format=batch-tag -- from:cworth > OUTPUT.$test_count
test_expect_equal_file EXPECTED.$test_count OUTPUT.$test_count
test_begin_subtest 'restoring sane tags'
inbox,stashtest
${gen_msg_filename}
http://mid.gmane.org/bought
-http://marc.info/?i=bought
-http://mid.mail-archive.com/bought
+https://marc.info/?i=bought
+https://mid.mail-archive.com/bought
EOF
test_expect_equal_file OUTPUT EXPECTED
# This test tests whether hiding Xapian::Error symbols in libnotmuch
# also hides them for other users of libxapian. This is motivated by
-# the discussion in http://gcc.gnu.org/wiki/Visibility'
+# the discussion in https://gcc.gnu.org/wiki/Visibility'
test_description='exception symbol hiding'
test_begin_subtest 'running test' run_test
mkdir -p ${PWD}/fakedb/.notmuch
-( LD_LIBRARY_PATH="$TEST_DIRECTORY/../lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" \
- $TEST_DIRECTORY/symbol-test ${PWD}/fakedb ${PWD}/nonexistent \
- 2>&1 | notmuch_dir_sanitize | sed -e "s,\`,\',g" -e "s,${NOTMUCH_DEFAULT_XAPIAN_BACKEND},backend,g") > OUTPUT
+$TEST_DIRECTORY/symbol-test ${PWD}/fakedb ${PWD}/nonexistent 2>&1 \
+ | notmuch_dir_sanitize | sed -e "s,\`,\',g" -e "s,${NOTMUCH_DEFAULT_XAPIAN_BACKEND},backend,g" > OUTPUT
cat <<EOF > EXPECTED
A Xapian exception occurred opening database: Couldn't stat 'CWD/fakedb/.notmuch/xapian'
notmuch count --output=threads tag:inbox > EXPECTED
test_expect_equal_file OUTPUT EXPECTED
+test_begin_subtest "get all tags"
+test_ruby <<"EOF"
+require 'notmuch'
+$maildir = ENV['MAIL_DIR']
+if not $maildir then
+ abort('environment variable MAIL_DIR must be set')
+end
+@db = Notmuch::Database.new($maildir)
+@t = @db.all_tags()
+for tag in @t do
+ print tag,"\n"
+end
+EOF
+notmuch search --output=tags '*' > EXPECTED
+test_expect_equal_file OUTPUT EXPECTED
+
test_done
output=$(notmuch search date:2010-12-16..! | notmuch_search_sanitize)
test_expect_equal "$output" "thread:XXX 2010-12-16 [1/1] Olivier Berger; Essai accentué (inbox unread)"
+if [ "${NOTMUCH_HAVE_XAPIAN_FIELD_PROCESSOR}" = "1" ]; then
+ test_begin_subtest "Absolute date field"
+ output=$(notmuch search date:2010-12-16 | notmuch_search_sanitize)
+ test_expect_equal "$output" "thread:XXX 2010-12-16 [1/1] Olivier Berger; Essai accentué (inbox unread)"
+fi
+
test_begin_subtest "Absolute time range with TZ"
notmuch search date:18-Nov-2009_02:19:26-0800..2009-11-18_04:49:52-06:00 | notmuch_search_sanitize > OUTPUT
cat <<EOF >EXPECTED
--- /dev/null
+#!/usr/bin/env bash
+test_description="library config API"
+
+. ./test-lib.sh || exit 1
+
+add_email_corpus
+
+cat <<EOF > c_head
+#include <string.h>
+#include <stdlib.h>
+#include <notmuch-test.h>
+
+int main (int argc, char** argv)
+{
+ notmuch_database_t *db;
+ char *val;
+ notmuch_status_t stat;
+
+ EXPECT0(notmuch_database_open (argv[1], NOTMUCH_DATABASE_MODE_READ_WRITE, &db));
+
+EOF
+
+cat <<EOF > c_tail
+ EXPECT0(notmuch_database_destroy(db));
+}
+EOF
+
+test_begin_subtest "notmuch_database_{set,get}_config"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+ EXPECT0(notmuch_database_set_config (db, "testkey1", "testvalue1"));
+ EXPECT0(notmuch_database_set_config (db, "testkey2", "testvalue2"));
+ EXPECT0(notmuch_database_get_config (db, "testkey1", &val));
+ printf("testkey1 = %s\n", val);
+ EXPECT0(notmuch_database_get_config (db, "testkey2", &val));
+ printf("testkey2 = %s\n", val);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+testkey1 = testvalue1
+testkey2 = testvalue2
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+
+test_begin_subtest "notmuch_database_get_config_list: empty list"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+ notmuch_config_list_t *list;
+ EXPECT0(notmuch_database_get_config_list (db, "nonexistent", &list));
+ printf("valid = %d\n", notmuch_config_list_valid (list));
+ notmuch_config_list_destroy (list);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+valid = 0
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+
+test_begin_subtest "notmuch_database_get_config_list: all pairs"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+ notmuch_config_list_t *list;
+ EXPECT0(notmuch_database_set_config (db, "zzzafter", "afterval"));
+ EXPECT0(notmuch_database_set_config (db, "aaabefore", "beforeval"));
+ EXPECT0(notmuch_database_get_config_list (db, "", &list));
+ for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
+ printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
+ }
+ notmuch_config_list_destroy (list);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+aaabefore beforeval
+testkey1 testvalue1
+testkey2 testvalue2
+zzzafter afterval
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "notmuch_database_get_config_list: one prefix"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+ notmuch_config_list_t *list;
+ EXPECT0(notmuch_database_get_config_list (db, "testkey", &list));
+ for (; notmuch_config_list_valid (list); notmuch_config_list_move_to_next (list)) {
+ printf("%s %s\n", notmuch_config_list_key (list), notmuch_config_list_value(list));
+ }
+ notmuch_config_list_destroy (list);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+testkey1 testvalue1
+testkey2 testvalue2
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "dump config"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+ EXPECT0(notmuch_database_set_config (db, "key with spaces", "value, with, spaces!"));
+}
+EOF
+notmuch dump --include=config >OUTPUT
+cat <<'EOF' >EXPECTED
+#notmuch-dump batch-tag:2 config
+#@ aaabefore beforeval
+#@ key%20with%20spaces value,%20with,%20spaces%21
+#@ testkey1 testvalue1
+#@ testkey2 testvalue2
+#@ zzzafter afterval
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "restore config"
+notmuch dump --include=config >EXPECTED
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
+{
+ EXPECT0(notmuch_database_set_config (db, "testkey1", "mutatedvalue"));
+}
+EOF
+notmuch restore --include=config <EXPECTED
+notmuch dump --include=config >OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
+
+test_done
--- /dev/null
+#!/usr/bin/env bash
+test_description='named queries'
+. ./test-lib.sh || exit 1
+
+QUERYSTR="date:2009-11-18..2009-11-18 and tag:unread"
+
+test_expect_code 1 "error adding named query before initializing DB" \
+ "notmuch config set query.test \"$QUERYSTR\""
+
+add_email_corpus
+
+test_expect_success "adding named query" \
+ "notmuch config set query.test \"$QUERYSTR\""
+
+QUERYSTR2="query:test and subject:Maildir"
+test_expect_success "adding nested named query" \
+ "notmuch config set query.test2 \"$QUERYSTR2\""
+
+test_begin_subtest "retrieve named query"
+output=$(notmuch config get query.test)
+test_expect_equal "$QUERYSTR" "$output"
+
+test_begin_subtest "List all queries"
+notmuch config list | grep ^query | notmuch_config_sanitize > OUTPUT
+cat <<EOF > EXPECTED
+query.test=date:2009-11-18..2009-11-18 and tag:unread
+query.test2=query:test and subject:Maildir
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "dump named queries"
+notmuch dump | grep '^#@' > OUTPUT
+cat<<EOF > QUERIES.BEFORE
+#@ query.test date%3a2009-11-18..2009-11-18%20and%20tag%3aunread
+#@ query.test2 query%3atest%20and%20subject%3aMaildir
+EOF
+test_expect_equal_file QUERIES.BEFORE OUTPUT
+
+test_begin_subtest "delete named queries"
+notmuch dump > BEFORE
+notmuch config set query.test
+notmuch dump | grep '^#@' > OUTPUT
+cat<<EOF > EXPECTED
+#@ query.test2 query%3atest%20and%20subject%3aMaildir
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "restore named queries"
+notmuch restore < BEFORE
+notmuch dump | grep '^#@' > OUTPUT
+test_expect_equal_file QUERIES.BEFORE OUTPUT
+
+if [ $NOTMUCH_HAVE_XAPIAN_FIELD_PROCESSOR -eq 1 ]; then
+ test_begin_subtest "search named query"
+ notmuch search query:test > OUTPUT
+ notmuch search $QUERYSTR > EXPECTED
+ test_expect_equal_file EXPECTED OUTPUT
+
+ test_begin_subtest "search named query with other terms"
+ notmuch search query:test and subject:Maildir > OUTPUT
+ notmuch search $QUERYSTR and subject:Maildir > EXPECTED
+ test_expect_equal_file EXPECTED OUTPUT
+
+ test_begin_subtest "search nested named query"
+ notmuch search query:test2 > OUTPUT
+ notmuch search $QUERYSTR2 > EXPECTED
+ test_expect_equal_file EXPECTED OUTPUT
+fi
+
+test_done
--- /dev/null
+#!/usr/bin/env bash
+test_description="locking"
+. ./test-lib.sh || exit 1
+
+if [ "${NOTMUCH_HAVE_XAPIAN_DB_RETRY_LOCK}" = "0" ]; then
+ test_subtest_missing_external_prereq_["lock retry support"]=t
+fi
+
+add_email_corpus
+
+test_begin_subtest "blocking open"
+test_C ${MAIL_DIR} <<'EOF'
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <notmuch-test.h>
+
+void
+taggit (notmuch_database_t *db, const char *tag)
+{
+ notmuch_message_t *message;
+
+ EXPECT0 (notmuch_database_find_message (db, "4EFC743A.3060609@april.org", &message));
+ if (message == NULL) {
+ fprintf (stderr, "unable to find message");
+ exit (1);
+ }
+
+ EXPECT0 (notmuch_message_add_tag (message, tag));
+ notmuch_message_destroy (message);
+}
+
+int
+main (int argc, char **argv)
+{
+ pid_t child;
+ const char *path = argv[1];
+
+ child = fork ();
+ if (child == -1) {
+ fprintf (stderr, "fork failed\n");
+ exit (1);
+ }
+
+ if (child == 0) {
+ notmuch_database_t *db2;
+
+ sleep (1);
+ EXPECT0 (notmuch_database_open (path, NOTMUCH_DATABASE_MODE_READ_WRITE, &db2));
+ taggit (db2, "child");
+ EXPECT0 (notmuch_database_close (db2));
+ } else {
+ notmuch_database_t *db;
+
+ EXPECT0 (notmuch_database_open (path, NOTMUCH_DATABASE_MODE_READ_WRITE, &db));
+ taggit (db, "parent");
+ sleep (2);
+ EXPECT0 (notmuch_database_close (db));
+ wait (NULL);
+ }
+}
+
+EOF
+notmuch search --output=tags id:4EFC743A.3060609@april.org >> OUTPUT
+cat <<'EOF' >EXPECTED
+== stdout ==
+== stderr ==
+child
+inbox
+parent
+unread
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_done
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: David Bremner <david@tethera.net>
*/
# Run tests
#
# Copyright (c) 2005 Junio C Hamano
+# Copyright (c) 2010 Notmuch Developers
#
# Adapted from a Makefile to a shell script by Carl Worth (2010)
exit 1
fi
-cd $(dirname "$0")
+cd "$(dirname "$0")"
-TESTS=${NOTMUCH_TESTS:-`echo T[0-9][0-9][0-9]-*.sh`}
+TESTS=${NOTMUCH_TESTS:-T[0-9][0-9][0-9]-*.sh}
# Clean up any results from a previous run
-rm -r test-results >/dev/null 2>/dev/null
+rm -rf test-results
-# test for timeout utility
+# Test for timeout utility
if command -v timeout >/dev/null; then
- TEST_TIMEOUT_CMD="timeout 2m "
+ TEST_TIMEOUT_CMD="timeout 2m"
echo "INFO: using 2 minute timeout for tests"
else
TEST_TIMEOUT_CMD=""
--- /dev/null
+#ifndef _NOTMUCH_TEST_H
+#define _NOTMUCH_TEST_H
+#include <stdio.h>
+#include <notmuch.h>
+
+inline static void
+expect0(int line, notmuch_status_t ret)
+{
+ if (ret) {
+ fprintf (stderr, "line %d: %s\n", line, ret);
+ exit (1);
+ }
+}
+
+#define EXPECT0(v) expect0(__LINE__, v);
+#endif
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* Author: Jani Nikula <jani@nikula.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: David Bremner <david@tethera.net>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Authors: Carl Worth <cworth@cworth.org>
*/
# -*- makefile -*-
-TEST_DATABASE_MIRROR=http://notmuchmail.org/releases/test-databases
+TEST_DATABASE_MIRROR=https://notmuchmail.org/releases/test-databases
dir := test/test-databases
#
# Copyright (c) 2005 Junio C Hamano
+# Copyright (c) 2010 Notmuch Developers
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see http://www.gnu.org/licenses/ .
+# along with this program. If not, see https://www.gnu.org/licenses/ .
# This file contains common code to be used by both the regular
# (correctness) tests and the performance tests.
+# test-lib.sh defines die() which echoes to nonstandard fd where
+# output was redirected earlier in that file. If test-lib.sh is not
+# loaded, neither this redirection nor die() function were defined.
+#
+type die >/dev/null 2>&1 || die () { echo "$@" >&2; exit 1; }
+
find_notmuch_path ()
{
dir="$1"
TEST_DIRECTORY=$(pwd -P)
notmuch_path=`find_notmuch_path "$TEST_DIRECTORY"`
+# Prepend $TEST_DIRECTORY/../lib to LD_LIBRARY_PATH, to make tests work
+# on systems where ../notmuch depends on LD_LIBRARY_PATH.
+LD_LIBRARY_PATH=${TEST_DIRECTORY%/*}/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
+export LD_LIBRARY_PATH
+
# configure output
. $notmuch_path/sh.config || exit 1
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
-;; along with Notmuch. If not, see <http://www.gnu.org/licenses/>.
+;; along with Notmuch. If not, see <https://www.gnu.org/licenses/>.
;;
;; Authors: Dmitry Kurochkin <dmitry.kurochkin@gmail.com>
#
# Copyright (c) 2005 Junio C Hamano
+# Copyright (c) 2010 Notmuch Developers
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see http://www.gnu.org/licenses/ .
+# along with this program. If not, see https://www.gnu.org/licenses/ .
if [ ${BASH_VERSINFO[0]} -lt 4 ]; then
echo "Error: The notmuch test suite requires a bash version >= 4.0"
test_broken=0
test_success=0
-_die_common () {
+_exit_common () {
code=$?
trap - EXIT
set +ex
rm -rf "$TEST_TMPDIR"
}
-die () {
- _die_common
+trap_exit () {
+ _exit_common
if test -n "$GIT_EXIT_OK"
then
exit $code
fi
}
-die_signal () {
- _die_common
+trap_signal () {
+ _exit_common
echo >&6 "FATAL: $0: interrupted by signal" $((code - 128))
exit $code
}
+die () {
+ _exit_common
+ exec >&6
+ say_color error '%-6s' FATAL
+ echo " $*"
+ echo
+ echo "Unexpected exit while executing $0."
+ exit 1
+}
+
GIT_EXIT_OK=
# Note: TEST_TMPDIR *NOT* exported!
TEST_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/notmuch-test-$$.XXXXXX")
-trap 'die' EXIT
-trap 'die_signal' HUP INT TERM
+trap 'trap_exit' EXIT
+trap 'trap_signal' HUP INT TERM
test_decode_color () {
sed -e 's/.\[1m/<WHITE>/g' \
cp -a $TEST_DIRECTORY/corpus.mail ${MAIL_DIR}
else
cp -a $TEST_DIRECTORY/corpus ${MAIL_DIR}
- notmuch new >/dev/null
+ notmuch new >/dev/null || die "'notmuch new' failed while adding email corpus"
cp -a ${MAIL_DIR} $TEST_DIRECTORY/corpus.mail
fi
}
notmuch new "${@}" | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* total file'
}
+NOTMUCH_DUMP_TAGS ()
+{
+ # this relies on the default format being batch-tag, otherwise some tests will break
+ notmuch dump --include=tags "${@}" | sed '/^#/d' | sort
+}
+
notmuch_search_sanitize ()
{
perl -pe 's/("?thread"?: ?)("?)................("?)/\1\2XXX\3/'
{
sed 's/[0-9a-f]\{8\}-[0-9a-f]\{4\}-[0-9a-f]\{4\}-[0-9a-f]\{4\}-[0-9a-f]\{12\}/UUID/g'
}
+
+notmuch_built_with_sanitize ()
+{
+ sed 's/^built_with[.]\(.*\)=.*$/built_with.\1=something/'
+}
+
+notmuch_config_sanitize ()
+{
+ notmuch_dir_sanitize | notmuch_built_with_sanitize
+}
+
# End of notmuch helper functions
# Use test_set_prereq to tell that a particular prerequisite is available.
}
test_python() {
- export LD_LIBRARY_PATH=$TEST_DIRECTORY/../lib
- export PYTHONPATH=$TEST_DIRECTORY/../bindings/python
-
- (echo "import sys; _orig_stdout=sys.stdout; sys.stdout=open('OUTPUT', 'w')"; cat) \
- | $NOTMUCH_PYTHON -
+ # Note: if there is need to print debug information from python program,
+ # use stdout = os.fdopen(6, 'w') or stderr = os.fdopen(7, 'w')
+ PYTHONPATH="$TEST_DIRECTORY/../bindings/python${PYTHONPATH:+:$PYTHONPATH}" \
+ $NOTMUCH_PYTHON -B - > OUTPUT
}
test_ruby() {
- export LD_LIBRARY_PATH=$TEST_DIRECTORY/../lib
MAIL_DIR=$MAIL_DIR ruby -I $TEST_DIRECTORY/../bindings/ruby> OUTPUT
}
exec_file="test${test_count}"
test_file="${exec_file}.c"
cat > ${test_file}
- export LD_LIBRARY_PATH=${TEST_DIRECTORY}/../lib
- ${TEST_CC} ${TEST_CFLAGS} -I${TEST_DIRECTORY}/../lib -o ${exec_file} ${test_file} -L${TEST_DIRECTORY}/../lib/ -lnotmuch -ltalloc
+ ${TEST_CC} ${TEST_CFLAGS} -I${TEST_DIRECTORY} -I${TEST_DIRECTORY}/../lib -o ${exec_file} ${test_file} -L${TEST_DIRECTORY}/../lib/ -lnotmuch -ltalloc
echo "== stdout ==" > OUTPUT.stdout
echo "== stderr ==" > OUTPUT.stderr
./${exec_file} "$@" 1>>OUTPUT.stdout 2>>OUTPUT.stderr
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: David Bremner <david@tethera.net>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Jani Nikula <jani@nikula.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: Carl Worth <cworth@cworth.org>
*/
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/ .
+ * along with this program. If not, see https://www.gnu.org/licenses/ .
*
* Author: David Bremner <david@tethera.net>
*/