From: David Bremner <david@tethera.net>
To: notmuch@notmuchmail.org
Cc: David Bremner <david@tethera.net>
Subject: [PATCH 34/38] cli/new: convert to new config framework
Date: Sat, 16 Jan 2021 13:04:02 -0400 [thread overview]
Message-ID: <20210116170406.842014-35-david@tethera.net> (raw)
In-Reply-To: <20210116170406.842014-1-david@tethera.net>
In addition to the same type of changes as converting other
subcommands, add the possibility of creating a database at the top
level. It would probably make sense to use this for insert as well.
---
notmuch-client.h | 1 +
notmuch-new.c | 112 ++++++++++++++++++++++-----------------------
notmuch.c | 50 +++++++++++++++-----
test/T040-setup.sh | 2 +-
test/T050-new.sh | 6 +--
5 files changed, 97 insertions(+), 74 deletions(-)
diff --git a/notmuch-client.h b/notmuch-client.h
index a026002a..9e09c36a 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -257,6 +257,7 @@ typedef enum {
NOTMUCH_COMMAND_CONFIG_CREATE = 1 << 1,
NOTMUCH_COMMAND_DATABASE_EARLY = 1 << 2,
NOTMUCH_COMMAND_DATABASE_WRITE = 1 << 3,
+ NOTMUCH_COMMAND_DATABASE_CREATE = 1 << 4,
} notmuch_command_mode_t;
notmuch_config_t *
diff --git a/notmuch-new.c b/notmuch-new.c
index a5c3cb54..0f416939 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -48,8 +48,7 @@ typedef struct {
enum verbosity verbosity;
bool debug;
bool full_scan;
- const char **new_tags;
- size_t new_tags_length;
+ notmuch_config_values_t *new_tags;
const char **ignore_verbatim;
size_t ignore_verbatim_length;
regex_t *ignore_regex;
@@ -65,7 +64,7 @@ typedef struct {
_filename_list_t *removed_directories;
_filename_list_t *directory_mtimes;
- bool synchronize_flags;
+ notmuch_bool_t synchronize_flags;
} add_files_state_t;
static volatile sig_atomic_t do_print_progress = 0;
@@ -245,19 +244,17 @@ _special_directory (const char *entry)
}
static bool
-_setup_ignore (notmuch_config_t *config, add_files_state_t *state)
+_setup_ignore (notmuch_database_t *notmuch, add_files_state_t *state)
{
- const char **ignore_list, **ignore;
+ notmuch_config_values_t *ignore_list;
int nregex = 0, nverbatim = 0;
const char **verbatim = NULL;
regex_t *regex = NULL;
- ignore_list = notmuch_config_get_new_ignore (config, NULL);
- if (! ignore_list)
- return true;
-
- for (ignore = ignore_list; *ignore; ignore++) {
- const char *s = *ignore;
+ for (ignore_list = notmuch_config_get_values (notmuch, NOTMUCH_CONFIG_NEW_IGNORE);
+ notmuch_config_values_valid (ignore_list);
+ notmuch_config_values_move_to_next (ignore_list)) {
+ const char *s = notmuch_config_values_get (ignore_list);
size_t len = strlen (s);
if (len == 0) {
@@ -276,8 +273,8 @@ _setup_ignore (notmuch_config_t *config, add_files_state_t *state)
return false;
}
- r = talloc_strndup (config, s + 1, len - 2);
- regex = talloc_realloc (config, regex, regex_t, nregex + 1);
+ r = talloc_strndup (notmuch, s + 1, len - 2);
+ regex = talloc_realloc (notmuch, regex, regex_t, nregex + 1);
preg = ®ex[nregex];
rerr = regcomp (preg, r, REG_EXTENDED | REG_NOSUB);
@@ -295,7 +292,7 @@ _setup_ignore (notmuch_config_t *config, add_files_state_t *state)
talloc_free (r);
} else {
- verbatim = talloc_realloc (config, verbatim, const char *,
+ verbatim = talloc_realloc (notmuch, verbatim, const char *,
nverbatim + 1);
verbatim[nverbatim++] = s;
}
@@ -371,7 +368,7 @@ add_file (notmuch_database_t *notmuch, const char *filename,
add_files_state_t *state)
{
notmuch_message_t *message = NULL;
- const char **tag;
+ const char *tag;
notmuch_status_t status;
status = notmuch_database_begin_atomic (notmuch);
@@ -387,13 +384,17 @@ add_file (notmuch_database_t *notmuch, const char *filename,
if (state->synchronize_flags)
notmuch_message_maildir_flags_to_tags (message);
- for (tag = state->new_tags; *tag != NULL; tag++) {
+ for (notmuch_config_values_start (state->new_tags);
+ notmuch_config_values_valid (state->new_tags);
+ notmuch_config_values_move_to_next (state->new_tags)) {
notmuch_bool_t is_set;
+
+ tag = notmuch_config_values_get (state->new_tags);
/* Currently all errors from has_maildir_flag are fatal */
if ((status = notmuch_message_has_maildir_flag_st (message, 'S', &is_set)))
goto DONE;
- if (strcmp ("unread", *tag) != 0 || ! is_set) {
- notmuch_message_add_tag (message, *tag);
+ if (strcmp ("unread", tag) != 0 || ! is_set) {
+ notmuch_message_add_tag (message, tag);
}
}
@@ -962,8 +963,7 @@ remove_filename (notmuch_database_t *notmuch,
/* Recursively remove all filenames from the database referring to
* 'path' (or to any of its children). */
static notmuch_status_t
-_remove_directory (void *ctx,
- notmuch_database_t *notmuch,
+_remove_directory (notmuch_database_t *notmuch,
const char *path,
add_files_state_t *add_files_state)
{
@@ -979,7 +979,7 @@ _remove_directory (void *ctx,
for (files = notmuch_directory_get_child_files (directory);
notmuch_filenames_valid (files);
notmuch_filenames_move_to_next (files)) {
- absolute = talloc_asprintf (ctx, "%s/%s", path,
+ absolute = talloc_asprintf (notmuch, "%s/%s", path,
notmuch_filenames_get (files));
status = remove_filename (notmuch, absolute, add_files_state);
talloc_free (absolute);
@@ -990,9 +990,9 @@ _remove_directory (void *ctx,
for (subdirs = notmuch_directory_get_child_directories (directory);
notmuch_filenames_valid (subdirs);
notmuch_filenames_move_to_next (subdirs)) {
- absolute = talloc_asprintf (ctx, "%s/%s", path,
+ absolute = talloc_asprintf (notmuch, "%s/%s", path,
notmuch_filenames_get (subdirs));
- status = _remove_directory (ctx, notmuch, absolute, add_files_state);
+ status = _remove_directory (notmuch, absolute, add_files_state);
talloc_free (absolute);
if (status)
goto DONE;
@@ -1094,9 +1094,8 @@ _maybe_upgrade (notmuch_database_t *notmuch, add_files_state_t *state) {
}
int
-notmuch_new_command (notmuch_config_t *config, unused(notmuch_database_t *notmuch), int argc, char *argv[])
+notmuch_new_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
{
- notmuch_database_t *notmuch;
add_files_state_t add_files_state = {
.verbosity = VERBOSITY_NORMAL,
.debug = false,
@@ -1105,7 +1104,6 @@ notmuch_new_command (notmuch_config_t *config, unused(notmuch_database_t *notmuc
};
struct timeval tv_start;
int ret = 0;
- struct stat st;
const char *db_path;
char *dot_notmuch_path;
struct sigaction action;
@@ -1140,21 +1138,30 @@ notmuch_new_command (notmuch_config_t *config, unused(notmuch_database_t *notmuc
else if (verbose)
add_files_state.verbosity = VERBOSITY_VERBOSE;
- add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length);
- add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
- db_path = notmuch_config_get_database_path (config);
+ add_files_state.new_tags = notmuch_config_get_values (notmuch, NOTMUCH_CONFIG_NEW_TAGS);
+
+ if (print_status_database (
+ "notmuch new",
+ notmuch,
+ notmuch_config_get_bool (notmuch, NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS,
+ &add_files_state.synchronize_flags)))
+ return EXIT_FAILURE;
+
+ db_path = notmuch_config_get (notmuch, NOTMUCH_CONFIG_DATABASE_PATH);
add_files_state.db_path = db_path;
- if (! _setup_ignore (config, &add_files_state))
+ if (! _setup_ignore (notmuch, &add_files_state))
return EXIT_FAILURE;
- for (i = 0; i < add_files_state.new_tags_length; i++) {
- const char *error_msg;
+ for (notmuch_config_values_start (add_files_state.new_tags);
+ notmuch_config_values_valid (add_files_state.new_tags);
+ notmuch_config_values_move_to_next (add_files_state.new_tags)) {
+ const char *tag,*error_msg;
- error_msg = illegal_tag (add_files_state.new_tags[i], false);
+ tag = notmuch_config_values_get (add_files_state.new_tags);
+ error_msg = illegal_tag (tag, false);
if (error_msg) {
- fprintf (stderr, "Error: tag '%s' in new.tags: %s\n",
- add_files_state.new_tags[i], error_msg);
+ fprintf (stderr, "Error: tag '%s' in new.tags: %s\n", tag, error_msg);
return EXIT_FAILURE;
}
}
@@ -1165,34 +1172,21 @@ notmuch_new_command (notmuch_config_t *config, unused(notmuch_database_t *notmuc
return EXIT_FAILURE;
}
- dot_notmuch_path = talloc_asprintf (config, "%s/%s", db_path, ".notmuch");
+ dot_notmuch_path = talloc_asprintf (notmuch, "%s/%s", db_path, ".notmuch");
- if (stat (dot_notmuch_path, &st)) {
- int count;
+ notmuch_exit_if_unmatched_db_uuid (notmuch);
- count = 0;
+ if (notmuch_database_get_revision (notmuch, NULL) == 0) {
+ int count = 0;
count_files (db_path, &count, &add_files_state);
if (interrupted)
return EXIT_FAILURE;
if (add_files_state.verbosity >= VERBOSITY_NORMAL)
printf ("Found %d total files (that's not much mail).\n", count);
- if (notmuch_database_create (db_path, ¬much))
- return EXIT_FAILURE;
+
add_files_state.total_files = count;
} else {
- char *status_string = NULL;
- if (notmuch_database_open_verbose (db_path, NOTMUCH_DATABASE_MODE_READ_WRITE,
- ¬much, &status_string)) {
- if (status_string) {
- fputs (status_string, stderr);
- free (status_string);
- }
- return EXIT_FAILURE;
- }
-
- notmuch_exit_if_unmatched_db_uuid (notmuch);
-
if (_maybe_upgrade (notmuch, &add_files_state))
return EXIT_FAILURE;
@@ -1223,9 +1217,9 @@ notmuch_new_command (notmuch_config_t *config, unused(notmuch_database_t *notmuc
gettimeofday (&add_files_state.tv_start, NULL);
- add_files_state.removed_files = _filename_list_create (config);
- add_files_state.removed_directories = _filename_list_create (config);
- add_files_state.directory_mtimes = _filename_list_create (config);
+ add_files_state.removed_files = _filename_list_create (notmuch);
+ add_files_state.removed_directories = _filename_list_create (notmuch);
+ add_files_state.directory_mtimes = _filename_list_create (notmuch);
if (add_files_state.verbosity == VERBOSITY_NORMAL &&
add_files_state.output_is_a_tty && ! debugger_is_active ()) {
@@ -1252,7 +1246,7 @@ notmuch_new_command (notmuch_config_t *config, unused(notmuch_database_t *notmuc
gettimeofday (&tv_start, NULL);
for (f = add_files_state.removed_directories->head, i = 0; f && ! interrupted; f = f->next, i++) {
- ret = _remove_directory (config, notmuch, f->filename, &add_files_state);
+ ret = _remove_directory (notmuch, f->filename, &add_files_state);
if (ret)
goto DONE;
if (do_print_progress) {
@@ -1287,11 +1281,13 @@ notmuch_new_command (notmuch_config_t *config, unused(notmuch_database_t *notmuc
fprintf (stderr, "Note: A fatal error was encountered: %s\n",
notmuch_status_to_string (ret));
- notmuch_database_destroy (notmuch);
+ notmuch_database_close (notmuch);
if (hooks && ! ret && ! interrupted)
ret = notmuch_run_hook (db_path, "post-new");
+ notmuch_database_destroy (notmuch);
+
if (ret || interrupted)
return EXIT_FAILURE;
diff --git a/notmuch.c b/notmuch.c
index 3a299afa..7360e0e6 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -143,7 +143,8 @@ static command_t commands[] = {
"Notmuch main command." },
{ "setup", notmuch_setup_command, NOTMUCH_COMMAND_CONFIG_OPEN | NOTMUCH_COMMAND_CONFIG_CREATE,
"Interactively set up notmuch for first use." },
- { "new", notmuch_new_command, NOTMUCH_COMMAND_CONFIG_OPEN,
+ { "new", notmuch_new_command,
+ NOTMUCH_COMMAND_DATABASE_EARLY | NOTMUCH_COMMAND_DATABASE_WRITE | NOTMUCH_COMMAND_DATABASE_CREATE,
"Find and import new messages to the notmuch database." },
{ "insert", notmuch_insert_command, NOTMUCH_COMMAND_DATABASE_EARLY | NOTMUCH_COMMAND_DATABASE_WRITE,
"Add a new message into the maildir and notmuch database." },
@@ -504,23 +505,48 @@ main (int argc, char *argv[])
if (command->mode & NOTMUCH_COMMAND_DATABASE_EARLY) {
char *status_string = NULL;
notmuch_database_mode_t mode;
- if (command->mode & NOTMUCH_COMMAND_DATABASE_WRITE)
+ notmuch_status_t status;
+
+ if (command->mode & NOTMUCH_COMMAND_DATABASE_WRITE ||
+ command->mode & NOTMUCH_COMMAND_DATABASE_CREATE)
mode = NOTMUCH_DATABASE_MODE_READ_WRITE;
else
mode = NOTMUCH_DATABASE_MODE_READ_ONLY;
- if (notmuch_database_open_with_config (NULL,
- mode,
- config_file_name,
- NULL,
- ¬much,
- &status_string)) {
- if (status_string) {
- fputs (status_string, stderr);
- free (status_string);
+ if (command->mode & NOTMUCH_COMMAND_DATABASE_CREATE) {
+ status = notmuch_database_create_with_config (NULL,
+ config_file_name,
+ NULL,
+ ¬much,
+ &status_string);
+ if (status && status != NOTMUCH_STATUS_DATABASE_EXISTS) {
+ if (status_string) {
+ fputs (status_string, stderr);
+ free (status_string);
+ }
+
+ if (status == NOTMUCH_STATUS_NO_CONFIG)
+ fputs ("Try running 'notmuch setup' to create a configuration.", stderr);
+
+ return EXIT_FAILURE;
}
+ }
- return EXIT_FAILURE;
+ if (notmuch == NULL) {
+ status = notmuch_database_open_with_config (NULL,
+ mode,
+ config_file_name,
+ NULL,
+ ¬much,
+ &status_string);
+ if (status) {
+ if (status_string) {
+ fputs (status_string, stderr);
+ free (status_string);
+ }
+
+ return EXIT_FAILURE;
+ }
}
} else {
config = notmuch_config_open (local, config_file_name, command->mode);
diff --git a/test/T040-setup.sh b/test/T040-setup.sh
index fbfe200a..1223ebf7 100755
--- a/test/T040-setup.sh
+++ b/test/T040-setup.sh
@@ -6,7 +6,7 @@ test_description='"notmuch setup"'
test_begin_subtest "Notmuch new without a config suggests notmuch setup"
output=$(notmuch --config=new-notmuch-config new 2>&1)
test_expect_equal "$output" "\
-Configuration file new-notmuch-config not found.
+Error: cannot load config file.
Try running 'notmuch setup' to create a configuration."
test_begin_subtest "Create a new config interactively"
diff --git a/test/T050-new.sh b/test/T050-new.sh
index 009b2633..882939fa 100755
--- a/test/T050-new.sh
+++ b/test/T050-new.sh
@@ -324,10 +324,10 @@ test_expect_equal "$output" ""
OLDCONFIG=$(notmuch config get new.tags)
-test_begin_subtest "Empty tags in new.tags are forbidden"
+test_begin_subtest "Empty tags in new.tags are ignored"
notmuch config set new.tags "foo;;bar"
-output=$(NOTMUCH_NEW --debug 2>&1)
-test_expect_equal "$output" "Error: tag '' in new.tags: empty tag forbidden"
+output=$(NOTMUCH_NEW --quiet 2>&1)
+test_expect_equal "$output" ""
test_begin_subtest "Tags starting with '-' in new.tags are forbidden"
notmuch config set new.tags "-foo;bar"
--
2.29.2
next prev parent reply other threads:[~2021-01-16 17:06 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-01-16 17:03 v4 merged config David Bremner
2021-01-16 17:03 ` [PATCH 01/38] lib: add _notmuch_string_map_set David Bremner
2021-01-24 11:28 ` Tomi Ollila
2021-01-24 12:06 ` David Bremner
2021-01-16 17:03 ` [PATCH 02/38] lib: cache configuration information from database David Bremner
2021-01-16 17:03 ` [PATCH 03/38] lib: add stub for notmuch_database_open_with_config David Bremner
2021-01-16 17:03 ` [PATCH 04/38] lib/open: add support for config profiles and default locations David Bremner
2021-01-24 11:58 ` Tomi Ollila
2021-01-16 17:03 ` [PATCH 05/38] CLI: generalize notmuch_config_mode_t David Bremner
2021-01-16 17:03 ` [PATCH 06/38] lib/config: add notmuch_config_key_{get,set} David Bremner
2021-01-16 17:03 ` [PATCH 07/38] lib/open: load default values for known configuration keys David Bremner
2021-01-16 17:03 ` [PATCH 08/38] CLI: add (unused) database argument to subcommands David Bremner
2021-01-16 17:03 ` [PATCH 09/38] util: add strsplit_len: simplified strtok with delimiter escaping David Bremner
2021-01-16 17:03 ` [PATCH 10/38] lib/config: add config values iterator David Bremner
2021-01-16 17:03 ` [PATCH 11/38] lib/config: make values iterators restartable David Bremner
2021-01-16 17:03 ` [PATCH 12/38] CLI/count: switch to new configuration framework David Bremner
2021-01-16 17:03 ` [PATCH 13/38] cli/dump: convert to new config framework David Bremner
2021-01-16 17:03 ` [PATCH 14/38] lib: add notmuch_config_get_bool David Bremner
2021-01-16 17:03 ` [PATCH 15/38] CLI/restore: convert to new config framework David Bremner
2021-01-16 17:03 ` [PATCH 16/38] CLI/insert: " David Bremner
2021-01-16 17:03 ` [PATCH 17/38] cli/reindex: convert " David Bremner
2021-01-16 17:03 ` [PATCH 18/38] CLI/reply: convert to " David Bremner
2021-01-16 17:03 ` [PATCH 19/38] CLI/{search,address}: convert to new configuration framework David Bremner
2021-01-16 17:03 ` [PATCH 20/38] cli/config: add accessor for config file name David Bremner
2021-01-16 17:03 ` [PATCH 21/38] CLI/show: mostly switch show to new config framework David Bremner
2021-01-16 17:03 ` [PATCH 22/38] cli/tag: convert " David Bremner
2021-01-16 17:03 ` [PATCH 23/38] lib/config: add _notmuch_config_cache David Bremner
2021-01-16 17:03 ` [PATCH 24/38] lib: split notmuch_database_compact David Bremner
2021-01-16 17:03 ` [PATCH 25/38] cli/compact: convert to new configuration framework David Bremner
2021-01-16 17:03 ` [PATCH 26/38] bindings/notmuch2: add missing crypto error status codes David Bremner
2021-01-16 17:03 ` [PATCH 27/38] lib/config: add NOTMUCH_CONFIG_NEW_IGNORE David Bremner
2021-01-16 17:03 ` [PATCH 28/38] lib/open: factor out first part of open David Bremner
2021-01-16 17:03 ` [PATCH 29/38] lib: add NOTMUCH_STATUS_NO_CONFIG David Bremner
2021-01-16 17:03 ` [PATCH 30/38] lib/database: move n_d_create* to open.cc David Bremner
2021-01-16 17:03 ` [PATCH 31/38] lib: add NOTMUCH_STATUS_DATABASE_EXISTS David Bremner
2021-01-16 17:04 ` [PATCH 32/38] lib: introduce notmuch_database_create_with_config David Bremner
2021-01-16 17:04 ` [PATCH 33/38] cli/new: refactor database upgrade code David Bremner
2021-01-16 17:04 ` David Bremner [this message]
2021-01-16 17:04 ` [PATCH 35/38] lib/config: add HOOK_DIR David Bremner
2021-01-16 17:04 ` [PATCH 36/38] lib/open: set HOOK_DIR on open David Bremner
2021-01-16 17:04 ` [PATCH 37/38] CLI: use configured hook directory David Bremner
2021-01-24 12:59 ` Tomi Ollila
2021-01-16 17:04 ` [PATCH 38/38] doc: describe new config framework David Bremner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://notmuchmail.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210116170406.842014-35-david@tethera.net \
--to=david@tethera.net \
--cc=notmuch@notmuchmail.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhetil.org/notmuch.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).