CLI/{search,address}: convert to new configuration framework

Since we are already passing a search context around as a kind of
parameter block, add a new talloc context to that to replace relying
on 'config'.

Convert notmuch-search and notmuch-address at the same time, because
they share some code.

Add a test to make sure we don't break passing configuration as a
command line argument.
This commit is contained in:
David Bremner 2020-08-08 11:16:52 -03:00
parent 8588719eb1
commit d613d10ddd
4 changed files with 142 additions and 34 deletions

View file

@ -52,6 +52,7 @@ typedef enum {
typedef struct { typedef struct {
notmuch_database_t *notmuch; notmuch_database_t *notmuch;
void *talloc_ctx;
int format_sel; int format_sel;
sprinter_t *format; sprinter_t *format;
int exclude; int exclude;
@ -677,28 +678,29 @@ do_search_tags (const search_context_t *ctx)
} }
static int static int
_notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int argc, char *argv[]) _notmuch_search_prepare (search_context_t *ctx, int argc, char *argv[])
{ {
char *query_str; char *query_str;
unsigned int i;
char *status_string = NULL; if (! ctx->talloc_ctx)
ctx->talloc_ctx = talloc_new (NULL);
switch (ctx->format_sel) { switch (ctx->format_sel) {
case NOTMUCH_FORMAT_TEXT: case NOTMUCH_FORMAT_TEXT:
ctx->format = sprinter_text_create (config, stdout); ctx->format = sprinter_text_create (ctx->talloc_ctx, stdout);
break; break;
case NOTMUCH_FORMAT_TEXT0: case NOTMUCH_FORMAT_TEXT0:
if (ctx->output == OUTPUT_SUMMARY) { if (ctx->output == OUTPUT_SUMMARY) {
fprintf (stderr, "Error: --format=text0 is not compatible with --output=summary.\n"); fprintf (stderr, "Error: --format=text0 is not compatible with --output=summary.\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
ctx->format = sprinter_text0_create (config, stdout); ctx->format = sprinter_text0_create (ctx->talloc_ctx, stdout);
break; break;
case NOTMUCH_FORMAT_JSON: case NOTMUCH_FORMAT_JSON:
ctx->format = sprinter_json_create (config, stdout); ctx->format = sprinter_json_create (ctx->talloc_ctx, stdout);
break; break;
case NOTMUCH_FORMAT_SEXP: case NOTMUCH_FORMAT_SEXP:
ctx->format = sprinter_sexp_create (config, stdout); ctx->format = sprinter_sexp_create (ctx->talloc_ctx, stdout);
break; break;
default: default:
/* this should never happen */ /* this should never happen */
@ -707,18 +709,6 @@ _notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int ar
notmuch_exit_if_unsupported_format (); notmuch_exit_if_unsupported_format ();
if (notmuch_database_open_verbose (
notmuch_config_get_database_path (config),
NOTMUCH_DATABASE_MODE_READ_ONLY, &ctx->notmuch, &status_string)) {
if (status_string) {
fputs (status_string, stderr);
free (status_string);
}
return EXIT_FAILURE;
}
notmuch_exit_if_unmatched_db_uuid (ctx->notmuch); notmuch_exit_if_unmatched_db_uuid (ctx->notmuch);
query_str = query_string_from_args (ctx->notmuch, argc, argv); query_str = query_string_from_args (ctx->notmuch, argc, argv);
@ -748,21 +738,20 @@ _notmuch_search_prepare (search_context_t *ctx, notmuch_config_t *config, int ar
} }
if (ctx->exclude != NOTMUCH_EXCLUDE_FALSE) { if (ctx->exclude != NOTMUCH_EXCLUDE_FALSE) {
const char **search_exclude_tags; notmuch_config_values_t *exclude_tags;
size_t search_exclude_tags_length;
notmuch_status_t status; notmuch_status_t status;
search_exclude_tags = notmuch_config_get_search_exclude_tags ( for (exclude_tags = notmuch_config_get_values (ctx->notmuch, NOTMUCH_CONFIG_EXCLUDE_TAGS);
config, &search_exclude_tags_length); notmuch_config_values_valid (exclude_tags);
notmuch_config_values_move_to_next (exclude_tags)) {
for (i = 0; i < search_exclude_tags_length; i++) { status = notmuch_query_add_tag_exclude (ctx->query,
status = notmuch_query_add_tag_exclude (ctx->query, search_exclude_tags[i]); notmuch_config_values_get (exclude_tags));
if (status && status != NOTMUCH_STATUS_IGNORED) { if (status && status != NOTMUCH_STATUS_IGNORED) {
print_status_query ("notmuch search", ctx->query, status); print_status_query ("notmuch search", ctx->query, status);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
} }
notmuch_query_set_omit_excluded (ctx->query, ctx->exclude); notmuch_query_set_omit_excluded (ctx->query, ctx->exclude);
} }
@ -805,7 +794,7 @@ static const notmuch_opt_desc_t common_options[] = {
}; };
int int
notmuch_search_command (notmuch_config_t *config, unused(notmuch_database_t *notmuch), int argc, char *argv[]) notmuch_search_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
{ {
search_context_t *ctx = &search_context; search_context_t *ctx = &search_context;
int opt_index, ret; int opt_index, ret;
@ -832,6 +821,7 @@ notmuch_search_command (notmuch_config_t *config, unused(notmuch_database_t *not
{ } { }
}; };
ctx->notmuch = notmuch;
ctx->output = OUTPUT_SUMMARY; ctx->output = OUTPUT_SUMMARY;
opt_index = parse_arguments (argc, argv, options, 1); opt_index = parse_arguments (argc, argv, options, 1);
if (opt_index < 0) if (opt_index < 0)
@ -845,8 +835,7 @@ notmuch_search_command (notmuch_config_t *config, unused(notmuch_database_t *not
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (_notmuch_search_prepare (ctx, config, if (_notmuch_search_prepare (ctx, argc - opt_index, argv + opt_index))
argc - opt_index, argv + opt_index))
return EXIT_FAILURE; return EXIT_FAILURE;
switch (ctx->output) { switch (ctx->output) {
@ -871,7 +860,7 @@ notmuch_search_command (notmuch_config_t *config, unused(notmuch_database_t *not
} }
int int
notmuch_address_command (notmuch_config_t *config, unused(notmuch_database_t *notmuch), int argc, char *argv[]) notmuch_address_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
{ {
search_context_t *ctx = &search_context; search_context_t *ctx = &search_context;
int opt_index, ret; int opt_index, ret;
@ -897,6 +886,8 @@ notmuch_address_command (notmuch_config_t *config, unused(notmuch_database_t *no
{ } { }
}; };
ctx->notmuch = notmuch;
opt_index = parse_arguments (argc, argv, options, 1); opt_index = parse_arguments (argc, argv, options, 1);
if (opt_index < 0) if (opt_index < 0)
return EXIT_FAILURE; return EXIT_FAILURE;
@ -911,8 +902,7 @@ notmuch_address_command (notmuch_config_t *config, unused(notmuch_database_t *no
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (_notmuch_search_prepare (ctx, config, if (_notmuch_search_prepare (ctx, argc - opt_index, argv + opt_index))
argc - opt_index, argv + opt_index))
return EXIT_FAILURE; return EXIT_FAILURE;
ctx->addresses = g_hash_table_new_full (strcase_hash, strcase_equal, ctx->addresses = g_hash_table_new_full (strcase_hash, strcase_equal,

View file

@ -147,9 +147,9 @@ static command_t commands[] = {
"Find and import new messages to the notmuch database." }, "Find and import new messages to the notmuch database." },
{ "insert", notmuch_insert_command, NOTMUCH_COMMAND_DATABASE_EARLY | NOTMUCH_COMMAND_DATABASE_WRITE, { "insert", notmuch_insert_command, NOTMUCH_COMMAND_DATABASE_EARLY | NOTMUCH_COMMAND_DATABASE_WRITE,
"Add a new message into the maildir and notmuch database." }, "Add a new message into the maildir and notmuch database." },
{ "search", notmuch_search_command, NOTMUCH_COMMAND_CONFIG_OPEN, { "search", notmuch_search_command, NOTMUCH_COMMAND_DATABASE_EARLY,
"Search for messages matching the given search terms." }, "Search for messages matching the given search terms." },
{ "address", notmuch_address_command, NOTMUCH_COMMAND_CONFIG_OPEN, { "address", notmuch_address_command, NOTMUCH_COMMAND_DATABASE_EARLY,
"Get addresses from messages matching the given search terms." }, "Get addresses from messages matching the given search terms." },
{ "show", notmuch_show_command, NOTMUCH_COMMAND_CONFIG_OPEN, { "show", notmuch_show_command, NOTMUCH_COMMAND_CONFIG_OPEN,
"Show all messages matching the search terms." }, "Show all messages matching the search terms." },

View file

@ -268,4 +268,104 @@ notmuch reply query:$query_name >> OUTPUT
restore_config restore_config
test_expect_equal_file EXPECTED OUTPUT test_expect_equal_file EXPECTED OUTPUT
backup_database
test_begin_subtest "search with alternate config"
notmuch tag -- +foobar17 '*'
cp notmuch-config alt-config
notmuch --config=alt-config config set search.exclude_tags foobar17
output=$(notmuch --config=alt-config count '*')
test_expect_equal "$output" "0"
restore_database
cat <<EOF > EXPECTED
Before:
After:
thread:XXX 2009-11-18 [1/2] Carl Worth| Alex Botero-Lowry; [notmuch] [PATCH] Error out if no query is supplied to search instead of going into an infinite loop (attachment inbox unread)
thread:XXX 2009-11-18 [1/2] Carl Worth| Ingmar Vanhassel; [notmuch] [PATCH] Typsos (inbox unread)
thread:XXX 2009-11-18 [1/3] Carl Worth| Adrian Perez de Castro, Keith Packard; [notmuch] Introducing myself (inbox signed unread)
thread:XXX 2009-11-18 [1/3] Carl Worth| Israel Herraiz, Keith Packard; [notmuch] New to the list (inbox unread)
thread:XXX 2009-11-18 [1/3] Carl Worth| Jan Janak; [notmuch] What a great idea! (inbox unread)
thread:XXX 2009-11-18 [1/2] Carl Worth| Jan Janak; [notmuch] [PATCH] Older versions of install do not support -C. (inbox unread)
thread:XXX 2009-11-18 [1/3(4)] Carl Worth| Aron Griffis, Keith Packard; [notmuch] archive (inbox unread)
thread:XXX 2009-11-18 [1/2] Carl Worth| Keith Packard; [notmuch] [PATCH] Make notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (inbox unread)
thread:XXX 2009-11-18 [1/7] Carl Worth| Lars Kellogg-Stedman, Mikhail Gusarov, Keith Packard; [notmuch] Working with Maildir storage? (inbox signed unread)
thread:XXX 2009-11-18 [2/5] Carl Worth| Mikhail Gusarov, Keith Packard; [notmuch] [PATCH 1/2] Close message file after parsing message headers (inbox unread)
thread:XXX 2009-11-17 [1/2] Carl Worth| Alex Botero-Lowry; [notmuch] preliminary FreeBSD support (attachment inbox unread)
EOF
test_begin_subtest "search with saved query from config file"
query_name="test${RANDOM}"
backup_config
printf "Before:\n" > OUTPUT
notmuch search query:$query_name 2>&1 | notmuch_search_sanitize >> OUTPUT
printf "\n[query]\n${query_name} = from:cworth\n" >> notmuch-config
printf "After:\n" >> OUTPUT
notmuch search query:$query_name 2>&1 | notmuch_search_sanitize >> OUTPUT
restore_config
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "search with saved query from config file (xdg)"
query_name="test${RANDOM}"
xdg_config
printf "Before:\n" > OUTPUT
notmuch search query:$query_name 2>&1 | notmuch_search_sanitize >> OUTPUT
printf "\n[query]\n${query_name} = from:cworth\n" >> ${CONFIG_PATH}
printf "After:\n" >> OUTPUT
notmuch search query:$query_name 2>&1 | notmuch_search_sanitize >> OUTPUT
restore_config
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "search with saved query from config file (xdg + profile)"
query_name="test${RANDOM}"
xdg_config $query_name
printf "Before:\n" > OUTPUT
notmuch search query:$query_name 2>&1 | notmuch_search_sanitize >> OUTPUT
printf "\n[query]\n${query_name} = from:cworth\n" >> ${CONFIG_PATH}
printf "After:\n" >> OUTPUT
notmuch search query:$query_name 2>&1 | notmuch_search_sanitize >> OUTPUT
restore_config
test_expect_equal_file EXPECTED OUTPUT
cat <<EOF > EXPECTED
Before:
After:
Alex Botero-Lowry <alex.boterolowry@gmail.com>
Alexander Botero-Lowry <alex.boterolowry@gmail.com>
François Boulogne <boulogne.f@gmail.com>
Jjgod Jiang <gzjjgod@gmail.com>
EOF
test_begin_subtest "address: saved query from config file"
backup_config
query_name="test${RANDOM}"
printf "Before:\n" > OUTPUT
notmuch address --deduplicate=no --output=sender query:$query_name 2>&1 | sort >> OUTPUT
printf "\n[query]\n${query_name} = from:gmail.com\n" >> notmuch-config
printf "After:\n" >> OUTPUT
notmuch address --output=sender query:$query_name | sort >> OUTPUT
restore_config
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "address: saved query from config file (xdg)"
query_name="test${RANDOM}"
xdg_config
printf "Before:\n" > OUTPUT
notmuch address --deduplicate=no --output=sender query:$query_name 2>&1 | sort >> OUTPUT
printf "\n[query]\n${query_name} = from:gmail.com\n" >> ${CONFIG_PATH}
printf "After:\n" >> OUTPUT
notmuch address --output=sender query:$query_name | sort >> OUTPUT
restore_config
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "address: saved query from config file (xdg+profile)"
query_name="test${RANDOM}"
xdg_config $query_name
printf "Before:\n" > OUTPUT
notmuch address --deduplicate=no --output=sender query:$query_name 2>&1 | sort >> OUTPUT
printf "\n[query]\n${query_name} = from:gmail.com\n" >> ${CONFIG_PATH}
printf "After:\n" >> OUTPUT
notmuch address --output=sender query:$query_name | sort >> OUTPUT
restore_config
test_expect_equal_file EXPECTED OUTPUT
test_done test_done

View file

@ -108,4 +108,22 @@ MAIL_DIR/new/04:2,
EOF EOF
test_expect_equal_file EXPECTED OUTPUT test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "index user header, config from file"
field_name="Test"
printf "\n[index]\nheader.${field_name} = List-Id\n" >> notmuch-config
notmuch reindex '*'
notmuch search --output=files ${field_name}:notmuch | notmuch_search_files_sanitize | sort > OUTPUT
cat <<EOF > EXPECTED
MAIL_DIR/bar/baz/05:2,
MAIL_DIR/bar/baz/23:2,
MAIL_DIR/bar/baz/24:2,
MAIL_DIR/bar/cur/20:2,
MAIL_DIR/bar/new/21:2,
MAIL_DIR/bar/new/22:2,
MAIL_DIR/foo/cur/08:2,
MAIL_DIR/foo/new/03:2,
MAIL_DIR/new/04:2,
EOF
test_expect_equal_file EXPECTED OUTPUT
test_done test_done