lib: support splitting mail from database location.

Introduce a new configuration value for the mail root, and use it to
locate mail messages in preference to the database.path (which
previously implied the mail messages were also in this location.

Initially only a subset of the CLI is tested in a split
configuration. Further changes will be needed for the remainder of the
CLI to work in split configurations.
This commit is contained in:
David Bremner 2020-12-31 18:20:31 -04:00
parent 986056bdbc
commit e823d05ae6
9 changed files with 121 additions and 10 deletions

View file

@ -43,13 +43,22 @@ configuration file and corresponding database.
The available configuration items are described below. The available configuration items are described below.
**database.path** **database.path**
The top-level directory where your mail currently exists and to Notmuch will store its database here, (in
where mail will be delivered in the future. Files should be sub-directory named ``.notmuch`` if **database.mail\_root**
individual email messages. Notmuch will store its database within is unset).
a sub-directory of the path configured here named ``.notmuch``.
Default: ``$MAILDIR`` variable if set, otherwise ``$HOME/mail``. Default: ``$MAILDIR`` variable if set, otherwise ``$HOME/mail``.
**database.mail_root**
The top-level directory where your mail currently exists and to
where mail will be delivered in the future. Files should be
individual email messages.
History: this configuration value was introduced in notmuch 0.32.
Default: For compatibility with older configurations, the value of
database.path is used if **database.mail\_root** is unset.
**database.hook_dir** **database.hook_dir**
Directory containing hooks run by notmuch commands. See Directory containing hooks run by notmuch commands. See

View file

@ -406,6 +406,8 @@ _notmuch_config_key_to_string (notmuch_config_key_t key)
switch (key) { switch (key) {
case NOTMUCH_CONFIG_DATABASE_PATH: case NOTMUCH_CONFIG_DATABASE_PATH:
return "database.path"; return "database.path";
case NOTMUCH_CONFIG_MAIL_ROOT:
return "database.mail_root";
case NOTMUCH_CONFIG_HOOK_DIR: case NOTMUCH_CONFIG_HOOK_DIR:
return "database.hook_dir"; return "database.hook_dir";
case NOTMUCH_CONFIG_EXCLUDE_TAGS: case NOTMUCH_CONFIG_EXCLUDE_TAGS:
@ -428,7 +430,7 @@ _notmuch_config_key_to_string (notmuch_config_key_t key)
} }
static const char * static const char *
_notmuch_config_default (void *ctx, notmuch_config_key_t key) _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key)
{ {
char *path; char *path;
@ -436,11 +438,14 @@ _notmuch_config_default (void *ctx, notmuch_config_key_t key)
case NOTMUCH_CONFIG_DATABASE_PATH: case NOTMUCH_CONFIG_DATABASE_PATH:
path = getenv ("MAILDIR"); path = getenv ("MAILDIR");
if (path) if (path)
path = talloc_strdup (ctx, path); path = talloc_strdup (notmuch, path);
else else
path = talloc_asprintf (ctx, "%s/mail", path = talloc_asprintf (notmuch, "%s/mail",
getenv ("HOME")); getenv ("HOME"));
return path; return path;
case NOTMUCH_CONFIG_MAIL_ROOT:
/* by default, mail root is the same as database path */
return notmuch_database_get_path (notmuch);
case NOTMUCH_CONFIG_EXCLUDE_TAGS: case NOTMUCH_CONFIG_EXCLUDE_TAGS:
return ""; return "";
case NOTMUCH_CONFIG_NEW_TAGS: case NOTMUCH_CONFIG_NEW_TAGS:

View file

@ -1350,7 +1350,7 @@ _notmuch_database_relative_path (notmuch_database_t *notmuch,
const char *db_path, *relative; const char *db_path, *relative;
unsigned int db_path_len; unsigned int db_path_len;
db_path = notmuch_database_get_path (notmuch); db_path = notmuch_config_get (notmuch, NOTMUCH_CONFIG_MAIL_ROOT);
db_path_len = strlen (db_path); db_path_len = strlen (db_path);
relative = path; relative = path;

View file

@ -64,7 +64,7 @@ _notmuch_message_file_open_ctx (notmuch_database_t *notmuch,
if (unlikely (message == NULL)) if (unlikely (message == NULL))
return NULL; return NULL;
const char *prefix = notmuch_database_get_path (notmuch); const char *prefix = notmuch_config_get (notmuch, NOTMUCH_CONFIG_MAIL_ROOT);
if (prefix == NULL) if (prefix == NULL)
goto FAIL; goto FAIL;

View file

@ -1102,7 +1102,7 @@ _notmuch_message_ensure_filename_list (notmuch_message_t *message)
*colon = '\0'; *colon = '\0';
db_path = notmuch_database_get_path (message->notmuch); db_path = notmuch_config_get (message->notmuch, NOTMUCH_CONFIG_MAIL_ROOT);
directory = _notmuch_database_get_directory_path (local, directory = _notmuch_database_get_directory_path (local,
message->notmuch, message->notmuch,

View file

@ -2474,6 +2474,7 @@ notmuch_config_list_destroy (notmuch_config_list_t *config_list);
typedef enum _notmuch_config_key { typedef enum _notmuch_config_key {
NOTMUCH_CONFIG_FIRST, NOTMUCH_CONFIG_FIRST,
NOTMUCH_CONFIG_DATABASE_PATH = NOTMUCH_CONFIG_FIRST, NOTMUCH_CONFIG_DATABASE_PATH = NOTMUCH_CONFIG_FIRST,
NOTMUCH_CONFIG_MAIL_ROOT,
NOTMUCH_CONFIG_HOOK_DIR, NOTMUCH_CONFIG_HOOK_DIR,
NOTMUCH_CONFIG_EXCLUDE_TAGS, NOTMUCH_CONFIG_EXCLUDE_TAGS,
NOTMUCH_CONFIG_NEW_TAGS, NOTMUCH_CONFIG_NEW_TAGS,

View file

@ -263,6 +263,11 @@ _choose_xapian_path (void *ctx, const char *database_path, const char **xapian_p
if (status) if (status)
goto DONE; goto DONE;
trial_path = talloc_asprintf (ctx, "%s/xapian", database_path);
status = _trial_open (trial_path, message_ptr);
if (status != NOTMUCH_STATUS_PATH_ERROR)
goto DONE;
notmuch_path = talloc_asprintf (ctx, "%s/.notmuch", database_path); notmuch_path = talloc_asprintf (ctx, "%s/.notmuch", database_path);
status = _db_dir_exists (notmuch_path, message_ptr); status = _db_dir_exists (notmuch_path, message_ptr);
if (status) if (status)

90
test/T055-path-config.sh Executable file
View file

@ -0,0 +1,90 @@
#!/usr/bin/env bash
test_description='Configuration of mail-root and database path'
. $(dirname "$0")/test-lib.sh || exit 1
backup_config () {
local test_name=$(basename $0 .sh)
cp ${NOTMUCH_CONFIG} notmuch-config-backup.${test_name}
}
restore_config () {
local test_name=$(basename $0 .sh)
export NOTMUCH_CONFIG="${TMP_DIRECTORY}/notmuch-config"
unset CONFIG_PATH
unset DATABASE_PATH
unset NOTMUCH_PROFILE
cp notmuch-config-backup.${test_name} ${NOTMUCH_CONFIG}
}
split_config () {
local dir
backup_config
dir="$TMP_DIRECTORY/database.$test_count"
rm -rf $dir
mkdir $dir
notmuch config set database.path $dir
notmuch config set database.mail_root $MAIL_DIR
DATABASE_PATH=$dir
}
for config in traditional split; do
# start each set of tests with a known set of messages
add_email_corpus
case $config in
traditional)
backup_config
;;
split)
split_config
mv mail/.notmuch/xapian $DATABASE_PATH
;;
esac
test_begin_subtest "count ($config)"
output=$(notmuch count '*')
test_expect_equal "$output" '52'
test_begin_subtest "count+tag ($config)"
tag="tag${RANDOM}"
notmuch tag +$tag '*'
output=$(notmuch count tag:$tag)
notmuch tag -$tag '*'
test_expect_equal "$output" '52'
test_begin_subtest "address ($config)"
notmuch address --deduplicate=no --sort=newest-first --output=sender --output=recipients path:foo >OUTPUT
cat <<EOF >EXPECTED
Carl Worth <cworth@cworth.org>
notmuch@notmuchmail.org
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "dump ($config)"
notmuch dump is:attachment and is:signed | sort > OUTPUT
cat <<EOF > EXPECTED
#notmuch-dump batch-tag:3 config,properties,tags
+attachment +inbox +signed +unread -- id:20091118005829.GB25380@dottiness.seas.harvard.edu
+attachment +inbox +signed +unread -- id:20091118010116.GC25380@dottiness.seas.harvard.edu
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "dump + tag + restore ($config)"
notmuch dump '*' > EXPECTED
notmuch tag -inbox '*'
notmuch restore < EXPECTED
notmuch dump > OUTPUT
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "reindex ($config)"
notmuch search --output=messages '*' > EXPECTED
notmuch reindex '*'
notmuch search --output=messages '*' > OUTPUT
test_expect_equal_file EXPECTED OUTPUT
restore_config
done
test_done

View file

@ -364,6 +364,7 @@ EOF
cat <<'EOF' >EXPECTED cat <<'EOF' >EXPECTED
== stdout == == stdout ==
MAIL_DIR MAIL_DIR
MAIL_DIR
MAIL_DIR/.notmuch/hooks MAIL_DIR/.notmuch/hooks
inbox;unread inbox;unread