unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* v1: convert remaining CLI to new configuration
@ 2021-03-04 13:01 David Bremner
  2021-03-04 13:01 ` [PATCH 01/27] lib: add missing status strings David Bremner
                   ` (27 more replies)
  0 siblings, 28 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch

This completes the planned overhaul of configuration handling. It
obsoletes [1], and needs to be applied on top of [2]. I will post a
rebased version of [2] fairly soon.

[1]: id:20210220164448.3956011-1-david@tethera.net
[2]: id:20210208004109.1192719-1-david@tethera.net

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 01/27] lib: add missing status strings
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 02/27] test: convert random-corpus to use n_d_open_with_config David Bremner
                   ` (26 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

---
 lib/database.cc | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lib/database.cc b/lib/database.cc
index ffd42ac4..87ad1385 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -292,12 +292,20 @@ notmuch_status_to_string (notmuch_status_t status)
 	return "Operation requires a database upgrade";
     case NOTMUCH_STATUS_PATH_ERROR:
 	return "Path supplied is illegal for this function";
+    case NOTMUCH_STATUS_IGNORED:
+	return "Argument was ignored";
+    case NOTMUCH_STATUS_ILLEGAL_ARGUMENT:
+	return "Illegal argument for function";
     case NOTMUCH_STATUS_MALFORMED_CRYPTO_PROTOCOL:
 	return "Crypto protocol missing, malformed, or unintelligible";
     case NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION:
 	return "Crypto engine initialization failure";
     case NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL:
 	return "Unknown crypto protocol";
+    case NOTMUCH_STATUS_NO_CONFIG:
+	return "No configuration file found";
+    case NOTMUCH_STATUS_DATABASE_EXISTS:
+	return "Database exists, not recreated";
     default:
     case NOTMUCH_STATUS_LAST_STATUS:
 	return "Unknown error status value";
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 02/27] test: convert random-corpus to use n_d_open_with_config
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
  2021-03-04 13:01 ` [PATCH 01/27] lib: add missing status strings David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 03/27] lib/open: pull _load_key_file out of _choose_database_path David Bremner
                   ` (25 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Remove one more usage of notmuch_config_get_database_path
---
 test/random-corpus.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/test/random-corpus.c b/test/random-corpus.c
index ff413252..67e106e0 100644
--- a/test/random-corpus.c
+++ b/test/random-corpus.c
@@ -141,7 +141,6 @@ main (int argc, char **argv)
     void *ctx = talloc_new (NULL);
 
     const char *config_path = NULL;
-    notmuch_config_t *config;
     notmuch_database_t *notmuch;
 
     int num_messages = 500;
@@ -179,12 +178,12 @@ main (int argc, char **argv)
 	exit (1);
     }
 
-    config = notmuch_config_open (ctx, config_path, false);
-    if (config == NULL)
-	return 1;
-
-    if (notmuch_database_open (notmuch_config_get_database_path (config),
-			       NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))
+    if (notmuch_database_open_with_config (NULL,
+					   NOTMUCH_DATABASE_MODE_READ_WRITE,
+					   config_path,
+					   NULL,
+					   &notmuch,
+					   NULL))
 	return 1;
 
     srandom (seed);
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 03/27] lib/open: pull _load_key_file out of _choose_database_path
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
  2021-03-04 13:01 ` [PATCH 01/27] lib: add missing status strings David Bremner
  2021-03-04 13:01 ` [PATCH 02/27] test: convert random-corpus to use n_d_open_with_config David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 04/27] lib: provide notmuch_database_load_config David Bremner
                   ` (24 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Although this increases code duplication, it also increases
flexibility in handling various combinations of missing config file
and missing database.
---
 lib/open.cc | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/lib/open.cc b/lib/open.cc
index e5ef351e..e1ad957f 100644
--- a/lib/open.cc
+++ b/lib/open.cc
@@ -183,27 +183,18 @@ _db_dir_exists (const char *database_path, char **message)
 
 static notmuch_status_t
 _choose_database_path (void * ctx,
-                       const char *config_path,
 		       const char *profile,
-		       GKeyFile **key_file,
+		       GKeyFile *key_file,
 		       const char **database_path,
 		       bool *split,
 		       char **message)
 {
-    notmuch_status_t status;
-
-    status =_load_key_file (config_path, profile, key_file);
-    if (status) {
-	*message = strdup ("Error: cannot load config file.\n");
-	return status;
-    }
-
     if (! *database_path) {
        *database_path = getenv ("NOTMUCH_DATABASE");
     }
 
-    if (! *database_path && *key_file)
-	*database_path = g_key_file_get_value (*key_file, "database", "path", NULL);
+    if (! *database_path && key_file)
+	*database_path = g_key_file_get_value (key_file, "database", "path", NULL);
 
     if (! *database_path) {
 	*database_path = _xdg_dir (ctx, "XDG_DATA_HOME", ".local/share", profile);
@@ -482,8 +473,14 @@ notmuch_database_open_with_config (const char *database_path,
 	goto DONE;
     }
 
-    if ((status = _choose_database_path (local, config_path, profile,
-					 &key_file, &database_path, &split,
+    status =_load_key_file (config_path, profile, &key_file);
+    if (status) {
+	message = strdup ("Error: cannot load config file.\n");
+	goto DONE;
+    }
+
+    if ((status = _choose_database_path (local, profile, key_file,
+					 &database_path, &split,
 					 &message)))
 	goto DONE;
 
@@ -569,9 +566,14 @@ notmuch_database_create_with_config (const char *database_path,
 	goto DONE;
     }
 
-    if ((status = _choose_database_path (local, config_path, profile,
-					 &key_file, &database_path, &split,
-					 &message)))
+    status =_load_key_file (config_path, profile, &key_file);
+    if (status) {
+	message = strdup ("Error: cannot load config file.\n");
+	goto DONE;
+    }
+
+    if ((status = _choose_database_path (local, profile, key_file,
+					 &database_path, &split, &message)))
 	goto DONE;
 
     status = _db_dir_exists (database_path, &message);
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 04/27] lib: provide notmuch_database_load_config
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (2 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 03/27] lib/open: pull _load_key_file out of _choose_database_path David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 05/27] lib/config: add notmuch_config_get_values_string David Bremner
                   ` (23 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This is mainly targetted at notmuch-config.c, or similar applications
that don't necessarily need both a configuration file and a database
to exist.
---
 lib/notmuch.h          |  27 ++++++
 lib/open.cc            |  96 ++++++++++++++++++++++
 test/T590-libconfig.sh | 182 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 302 insertions(+), 3 deletions(-)

diff --git a/lib/notmuch.h b/lib/notmuch.h
index 5e4f1dac..8d4a4716 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -442,6 +442,33 @@ notmuch_database_open_with_config (const char *database_path,
 				   const char *profile,
 				   notmuch_database_t **database,
 				   char **error_message);
+
+
+/**
+ * Loads configuration from config file, database, and/or defaults
+ *
+ * For description of arguments, @see notmuch_database_open_with_config
+ *
+ * @retval NOTMUCH_STATUS_SUCCESS: Successfully loaded (some) configuration.
+ *
+ * @retval NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory.
+ *
+ * @retval NOTMUCH_STATUS_FILE_ERROR: An error occurred trying to open the
+ *	database or config file (such as permission denied, or file not found,
+ *	etc.)
+ *
+ * @retval NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred.
+ *
+ * @since libnotmuch 5.4 (notmuch 0.32)
+ */
+
+notmuch_status_t
+notmuch_database_load_config (const char *database_path,
+			      const char *config_path,
+			      const char *profile,
+			      notmuch_database_t **database,
+			      char **error_message);
+
 /**
  * Create a new notmuch database located at 'database_path', using
  * configuration in 'config_path'.
diff --git a/lib/open.cc b/lib/open.cc
index e1ad957f..58385592 100644
--- a/lib/open.cc
+++ b/lib/open.cc
@@ -709,3 +709,99 @@ notmuch_database_reopen (notmuch_database_t *notmuch,
     notmuch->open = true;
     return NOTMUCH_STATUS_SUCCESS;
 }
+
+notmuch_status_t
+_maybe_load_config_from_database (notmuch_database_t *notmuch,
+				  GKeyFile *key_file,
+				  const char *database_path,
+				  const char *profile)
+{
+    char *message; /* ignored */
+
+    if (_db_dir_exists (database_path, &message))
+	return NOTMUCH_STATUS_SUCCESS;
+
+    _set_database_path (notmuch, database_path);
+
+    if (_notmuch_choose_xapian_path (notmuch, database_path, &notmuch->xapian_path, &message))
+	return NOTMUCH_STATUS_SUCCESS;
+
+    (void) _finish_open (notmuch, profile, NOTMUCH_DATABASE_MODE_READ_ONLY, key_file, &message);
+
+    return NOTMUCH_STATUS_SUCCESS;
+}
+
+notmuch_status_t
+notmuch_database_load_config (const char *database_path,
+			      const char *config_path,
+			      const char *profile,
+			      notmuch_database_t **database,
+			      char **status_string)
+{
+    notmuch_status_t status = NOTMUCH_STATUS_SUCCESS, warning = NOTMUCH_STATUS_SUCCESS;
+    void *local = talloc_new (NULL);
+    notmuch_database_t *notmuch = NULL;
+    char *message = NULL;
+    GKeyFile *key_file = NULL;
+    bool split = false;
+
+    _init_libs ();
+
+    notmuch = _alloc_notmuch ();
+    if (!notmuch) {
+	status = NOTMUCH_STATUS_OUT_OF_MEMORY;
+	goto DONE;
+    }
+
+    status =_load_key_file (config_path, profile, &key_file);
+    switch (status) {
+    case NOTMUCH_STATUS_SUCCESS:
+    case NOTMUCH_STATUS_NO_CONFIG:
+	warning = status;
+	break;
+    default:
+	message = strdup ("Error: cannot load config file.\n");
+	goto DONE;
+    }
+
+    status = _choose_database_path (local, profile, key_file,
+				    &database_path, &split, &message);
+    switch (status) {
+	/* weirdly NULL_POINTER is what is returned if we fail to find
+	 * a database */
+    case NOTMUCH_STATUS_NULL_POINTER:
+    case NOTMUCH_STATUS_SUCCESS:
+	break;
+    default:
+	goto DONE;
+    }
+
+    if (database_path) {
+	status = _maybe_load_config_from_database (notmuch, key_file, database_path, profile);
+	if (status)
+	    goto DONE;
+    }
+
+    if (key_file) {
+	status = _notmuch_config_load_from_file (notmuch, key_file);
+	if (status)
+	    goto DONE;
+    }
+    status = _notmuch_config_load_defaults (notmuch);
+    if (status)
+	goto DONE;
+
+ DONE:
+    talloc_free (local);
+
+    if (status_string)
+	*status_string = message;
+
+    if (database)
+	*database = notmuch;
+
+    if (status)
+	return status;
+    else
+	return warning;
+}
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 310668a9..dc9964cf 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -538,7 +538,7 @@ cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
    printf("test.key2 = %s\n", val);
 }
 EOF
-NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
+export NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
 unset NOTMUCH_DATABASE
 cat <<'EOF' >EXPECTED
 == stdout ==
@@ -549,7 +549,7 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "NOTMUCH_DATABASE overrides config"
-old_path=$(notmuch config get database.path)
+cp notmuch-config notmuch-config.bak
 notmuch config set database.path /nonexistent
 export NOTMUCH_DATABASE=${MAIL_DIR}
 cat c_head - c_tail <<'EOF' | test_C %NULL% '' %NULL%
@@ -568,8 +568,184 @@ test.key1 = testvalue1
 test.key2 = testvalue2
 == stderr ==
 EOF
-notmuch config set database.path "${old_path}"
+cp notmuch-config.bak notmuch-config
+test_expect_equal_file EXPECTED OUTPUT
+
+cat <<EOF > c_head2
+#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;
+   char *msg = NULL;
+
+   for (int i = 1; i < argc; i++)
+      if (strcmp (argv[i], "%NULL%") == 0) argv[i] = NULL;
+
+   stat = notmuch_database_load_config (argv[1],
+                                        argv[2],
+                                        argv[3],
+                                        &db,
+                                        &msg);
+   if (stat != NOTMUCH_STATUS_SUCCESS  && stat != NOTMUCH_STATUS_NO_CONFIG) {
+     fprintf (stderr, "error opening database\n%d: %s\n%s\n", stat,
+	      notmuch_status_to_string (stat), msg ? msg : "");
+     exit (1);
+   }
+EOF
+
+
+test_begin_subtest "notmuch_database_get_config (ndlc)"
+echo NOTMUCH_CONFIG=$NOTMUCH_CONFIG
+echo NOTMUCH_PROFILE=$NOTMUCH_PROFILE
+echo HOME=$HOME
+cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
+{
+   EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
+   printf("test.key1 = %s\n", val);
+   EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
+   printf("test.key2 = %s\n", val);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+test.key1 = testvalue1
+test.key2 = testvalue2
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+
+test_begin_subtest "notmuch_database_get_config_list: all pairs (ndlc)"
+cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
+{
+   notmuch_config_list_t *list;
+   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
+key with spaces value, with, spaces!
+test.key1 testvalue1
+test.key2 testvalue2
+zzzafter afterval
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "notmuch_database_get_config_list: one prefix (ndlc)"
+cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
+{
+   notmuch_config_list_t *list;
+   EXPECT0(notmuch_database_get_config_list (db, "test.key", &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 ==
+test.key1 testvalue1
+test.key2 testvalue2
+== stderr ==
+EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "list by keys (ndlc)"
+notmuch config set search.exclude_tags "foo;bar;fub"
+notmuch config set new.ignore "sekrit_junk"
+cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
+{
+    notmuch_config_key_t key;
+    for (key = NOTMUCH_CONFIG_FIRST;
+	 key < NOTMUCH_CONFIG_LAST;
+	 key = (notmuch_config_key_t)(key + 1)) {
+	const char *val = notmuch_config_get (db, key);
+        printf("%s\n", val ? val : "NULL" );
+    }
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+MAIL_DIR
+MAIL_DIR
+MAIL_DIR/.notmuch/hooks
+MAIL_DIR/.notmuch/backups
+foo;bar;fub
+unread;inbox;
+sekrit_junk
+true
+test_suite@notmuchmail.org
+test_suite_other@notmuchmail.org;test_suite@otherdomain.org
+Notmuch Test Suite
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "load default values (ndlc, nonexistent config)"
+cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} /nonexistent %NULL%
+{
+    notmuch_config_key_t key;
+    for (key = NOTMUCH_CONFIG_FIRST;
+	 key < NOTMUCH_CONFIG_LAST;
+	 key = (notmuch_config_key_t)(key + 1)) {
+	const char *val = notmuch_config_get (db, key);
+	printf("%s\n", val ? val : "NULL" );
+    }
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+MAIL_DIR
+MAIL_DIR
+MAIL_DIR/.notmuch/hooks
+MAIL_DIR/.notmuch/backups
+
+inbox;unread
+NULL
+true
+NULL
+NULL
+NULL
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+backup_database
+test_begin_subtest "override config from \${HOME}/.notmuch-config (ndlc)"
+ovconfig=${HOME}/.notmuch-config
+cp ${NOTMUCH_CONFIG} ${ovconfig}
+old_NOTMUCH_CONFIG=${NOTMUCH_CONFIG}
+unset NOTMUCH_CONFIG
+notmuch --config=${ovconfig} config set test.key1 overridden-home
+cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
+{
+   EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
+   printf("test.key1 = %s\n", val);
+   EXPECT0(notmuch_database_get_config (db, "test.key2", &val));
+   printf("test.key2 = %s\n", val);
+}
+EOF
+rm -f ${ovconfig}
+NOTMUCH_CONFIG=${old_NOTMUCH_CONFIG}
+cat <<'EOF' >EXPECTED
+== stdout ==
+test.key1 = overridden-home
+test.key2 = testvalue2
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
 
 test_done
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 05/27] lib/config: add notmuch_config_get_values_string
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (3 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 04/27] lib: provide notmuch_database_load_config David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 06/27] lib/config: add config_pairs iterators David Bremner
                   ` (22 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This is to support the less common (at least in the notmuch codebase)
case of accessing a ;-delimited list config value with an arbitrary
string key.
---
 lib/config.cc          | 14 ++++++++++----
 lib/notmuch.h          | 17 ++++++++++++++++-
 test/T590-libconfig.sh | 23 +++++++++++++++++++++++
 3 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/lib/config.cc b/lib/config.cc
index 32ed6f8f..cec2e9de 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -258,13 +258,19 @@ _notmuch_config_load_from_database (notmuch_database_t *notmuch)
 notmuch_config_values_t *
 notmuch_config_get_values (notmuch_database_t *notmuch, notmuch_config_key_t key)
 {
-    notmuch_config_values_t *values = NULL;
-    bool ok = false;
-
     const char *key_str = _notmuch_config_key_to_string (key);
 
     if (! key_str)
-	goto DONE;
+	return NULL;
+
+    return notmuch_config_get_values_string (notmuch, key_str);
+}
+
+notmuch_config_values_t *
+notmuch_config_get_values_string (notmuch_database_t *notmuch, const char *key_str)
+{
+    notmuch_config_values_t *values = NULL;
+    bool ok = false;
 
     values = talloc (notmuch, notmuch_config_values_t);
     if (unlikely(! values))
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 8d4a4716..9a4f94f5 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -2493,7 +2493,6 @@ notmuch_config_list_move_to_next (notmuch_config_list_t *config_list);
 void
 notmuch_config_list_destroy (notmuch_config_list_t *config_list);
 
-
 /**
  * Configuration keys known to libnotmuch
  */
@@ -2564,6 +2563,22 @@ notmuch_config_set (notmuch_database_t *notmuch, notmuch_config_key_t key, const
 notmuch_config_values_t *
 notmuch_config_get_values (notmuch_database_t *notmuch, notmuch_config_key_t key);
 
+/**
+ * Returns an iterator for a ';'-delimited list of configuration values
+ *
+ * These values reflect all configuration information given at the
+ * time the database was opened.
+ *
+ * @param[in] notmuch database
+ * @param[in] key configuration key
+ *
+ * @since libnotmuch 5.4 (notmuch 0.32)
+ *
+ * @retval NULL in case of error.
+ */
+notmuch_config_values_t *
+notmuch_config_get_values_string (notmuch_database_t *notmuch, const char *key);
+
 /**
  * Is the given 'config_values' iterator pointing at a valid element.
  *
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index dc9964cf..edbba6c4 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -255,6 +255,29 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 restore_database
 
+test_begin_subtest "notmuch_config_get_values_string"
+cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
+{
+    notmuch_config_values_t *values;
+    EXPECT0(notmuch_database_set_config (db, "test.list", "x;y;z"));
+    for (values = notmuch_config_get_values_string (db, "test.list");
+	 notmuch_config_values_valid (values);
+	 notmuch_config_values_move_to_next (values))
+    {
+	  puts (notmuch_config_values_get (values));
+    }
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+x
+y
+z
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+restore_database
+
 test_begin_subtest "notmuch_config_get_values (restart)"
 cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
 {
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 06/27] lib/config: add config_pairs iterators
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (4 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 05/27] lib/config: add notmuch_config_get_values_string David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 07/27] lib/config: set defaults for user full name David Bremner
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

The layer of shims here seems a bit wasteful compared to just calling
the corresponding string map functions directly, but it allows control
over the API (calling with notmuch_database_t *) and flexibility for
future changes.
---
 lib/config.cc          | 39 ++++++++++++++++++++++++++++++
 lib/notmuch.h          | 21 ++++++++++++++++
 test/T590-libconfig.sh | 54 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 114 insertions(+)

diff --git a/lib/config.cc b/lib/config.cc
index cec2e9de..de919b87 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -38,6 +38,10 @@ struct _notmuch_config_values {
     void *children; /* talloc_context */
 };
 
+struct _notmuch_config_pairs {
+    notmuch_string_map_iterator_t *iter;
+};
+
 static const char * _notmuch_config_key_to_string (notmuch_config_key_t key);
 
 static int
@@ -331,6 +335,41 @@ notmuch_config_values_destroy (notmuch_config_values_t *values) {
     talloc_free (values);
 }
 
+notmuch_config_pairs_t *
+notmuch_config_get_pairs (notmuch_database_t *notmuch,
+			  const char *prefix)
+{
+    notmuch_config_pairs_t *pairs = talloc(notmuch,notmuch_config_pairs_t);
+    pairs->iter = _notmuch_string_map_iterator_create (notmuch->config, prefix, false);
+    return pairs;
+}
+
+notmuch_bool_t
+notmuch_config_pairs_valid (notmuch_config_pairs_t *pairs) {
+    return _notmuch_string_map_iterator_valid (pairs->iter);
+}
+
+void
+notmuch_config_pairs_move_to_next (notmuch_config_pairs_t *pairs) {
+    _notmuch_string_map_iterator_move_to_next (pairs->iter);
+}
+
+const char *
+notmuch_config_pairs_key (notmuch_config_pairs_t *pairs) {
+    return _notmuch_string_map_iterator_key (pairs->iter);
+}
+
+const char *
+notmuch_config_pairs_value (notmuch_config_pairs_t *pairs) {
+    return _notmuch_string_map_iterator_value (pairs->iter);
+}
+
+void
+notmuch_config_pairs_destroy (notmuch_config_pairs_t *pairs) {
+    _notmuch_string_map_iterator_destroy (pairs->iter);
+    talloc_free (pairs);
+}
+
 notmuch_status_t
 _notmuch_config_load_from_file (notmuch_database_t *notmuch,
 				GKeyFile *file)
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 9a4f94f5..f050d2b6 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -245,6 +245,7 @@ typedef struct _notmuch_directory notmuch_directory_t;
 typedef struct _notmuch_filenames notmuch_filenames_t;
 typedef struct _notmuch_config_list notmuch_config_list_t;
 typedef struct _notmuch_config_values notmuch_config_values_t;
+typedef struct _notmuch_config_pairs notmuch_config_pairs_t;
 typedef struct _notmuch_indexopts notmuch_indexopts_t;
 #endif /* __DOXYGEN__ */
 
@@ -2638,6 +2639,26 @@ notmuch_config_values_start (notmuch_config_values_t *values);
 void
 notmuch_config_values_destroy (notmuch_config_values_t *values);
 
+
+notmuch_config_pairs_t *
+notmuch_config_get_pairs (notmuch_database_t *notmuch,
+			  const char *prefix);
+
+notmuch_bool_t
+notmuch_config_pairs_valid (notmuch_config_pairs_t *pairs);
+
+void
+notmuch_config_pairs_move_to_next (notmuch_config_pairs_t *pairs);
+
+const char *
+notmuch_config_pairs_key (notmuch_config_pairs_t *pairs);
+
+const char *
+notmuch_config_pairs_value (notmuch_config_pairs_t *pairs);
+
+void
+notmuch_config_pairs_destroy (notmuch_config_pairs_t *pairs);
+
 /**
  * get a configuration value from an open database as Boolean
  *
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index edbba6c4..49cc382a 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -770,5 +770,59 @@ EOF
 test_expect_equal_file EXPECTED OUTPUT
 restore_database
 
+test_begin_subtest "notmuch_config_get_pairs: prefix (ndlc)"
+cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
+{
+   notmuch_config_pairs_t *list;
+   for (list =  notmuch_config_get_pairs (db, "user.");
+        notmuch_config_pairs_valid (list);
+        notmuch_config_pairs_move_to_next (list)) {
+     printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
+   }
+   notmuch_config_pairs_destroy (list);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+user.name Notmuch Test Suite
+user.other_email test_suite_other@notmuchmail.org;test_suite@otherdomain.org
+user.primary_email test_suite@notmuchmail.org
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "notmuch_config_get_pairs: all pairs (ndlc)"
+cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} ${NOTMUCH_CONFIG} %NULL%
+{
+   notmuch_config_pairs_t *list;
+   for (list =  notmuch_config_get_pairs (db, "");
+        notmuch_config_pairs_valid (list);
+        notmuch_config_pairs_move_to_next (list)) {
+     printf("%s %s\n", notmuch_config_pairs_key (list), notmuch_config_pairs_value(list));
+   }
+   notmuch_config_pairs_destroy (list);
+}
+EOF
+cat <<'EOF' >EXPECTED
+== stdout ==
+aaabefore beforeval
+database.backup_dir MAIL_DIR/.notmuch/backups
+database.hook_dir MAIL_DIR/.notmuch/hooks
+database.mail_root MAIL_DIR
+database.path MAIL_DIR
+key with spaces value, with, spaces!
+maildir.synchronize_flags true
+new.ignore sekrit_junk
+new.tags unread;inbox;
+search.exclude_tags foo;bar;fub
+test.key1 testvalue1
+test.key2 testvalue2
+user.name Notmuch Test Suite
+user.other_email test_suite_other@notmuchmail.org;test_suite@otherdomain.org
+user.primary_email test_suite@notmuchmail.org
+zzzafter afterval
+== stderr ==
+EOF
+test_expect_equal_file EXPECTED OUTPUT
 
 test_done
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 07/27] lib/config: set defaults for user full name
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (5 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 06/27] lib/config: add config_pairs iterators David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 08/27] lib/config: set default for primary user email David Bremner
                   ` (20 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This just copies code from from the CLI into the library. New test
infrastructure is needed because apparently we have never tested this
code path.
---
 lib/config.cc          | 48 +++++++++++++++++++++++++++++++++++++++++-
 test/T590-libconfig.sh | 13 ++++++++----
 test/test-lib.sh       |  7 ++++++
 3 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/lib/config.cc b/lib/config.cc
index de919b87..1741bf99 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -22,6 +22,8 @@
 #include "notmuch-private.h"
 #include "database-private.h"
 
+#include <pwd.h>
+
 static const std::string CONFIG_PREFIX = "C";
 
 struct _notmuch_config_list {
@@ -430,6 +432,41 @@ notmuch_config_get_bool (notmuch_database_t *notmuch, notmuch_config_key_t key,
     return NOTMUCH_STATUS_SUCCESS;
 }
 
+static const char *
+_get_name_from_passwd_file (void *ctx)
+{
+    long pw_buf_size;
+    char *pw_buf;
+    struct passwd passwd, *ignored;
+    const char *name;
+    int e;
+
+    pw_buf_size = sysconf (_SC_GETPW_R_SIZE_MAX);
+    if (pw_buf_size == -1) pw_buf_size = 64;
+    pw_buf = (char *) talloc_size (ctx, pw_buf_size);
+
+    while ((e = getpwuid_r (getuid (), &passwd, pw_buf,
+			    pw_buf_size, &ignored)) == ERANGE) {
+	pw_buf_size = pw_buf_size * 2;
+	pw_buf = (char *) talloc_zero_size (ctx, pw_buf_size);
+    }
+
+    if (e == 0) {
+	char *comma = strchr (passwd.pw_gecos, ',');
+	if (comma)
+	    name = talloc_strndup (ctx, passwd.pw_gecos,
+				   comma - passwd.pw_gecos);
+	else
+	    name = talloc_strdup (ctx, passwd.pw_gecos);
+    } else {
+	name = talloc_strdup (ctx, "");
+    }
+
+    talloc_free (pw_buf);
+
+    return name;
+}
+
 static const char *
 _notmuch_config_key_to_string (notmuch_config_key_t key) {
     switch (key) {
@@ -463,6 +500,7 @@ _notmuch_config_key_to_string (notmuch_config_key_t key) {
 static const char *
 _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key) {
     char *path;
+    const char* name;
 
     switch (key) {
     case NOTMUCH_CONFIG_DATABASE_PATH:
@@ -482,10 +520,18 @@ _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key)
 	return "inbox;unread";
     case NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS:
 	return "true";
+    case NOTMUCH_CONFIG_USER_NAME:
+	name = getenv ("NAME");
+	if (name)
+	    name = talloc_strdup (notmuch, name);
+	else
+	    name = _get_name_from_passwd_file (notmuch);
+
+	return name;
+	break;
     case NOTMUCH_CONFIG_HOOK_DIR:
     case NOTMUCH_CONFIG_BACKUP_DIR:
     case NOTMUCH_CONFIG_NEW_IGNORE:
-    case NOTMUCH_CONFIG_USER_NAME:
     case NOTMUCH_CONFIG_PRIMARY_EMAIL:
     case NOTMUCH_CONFIG_OTHER_EMAIL:
 	return NULL;
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 49cc382a..2c6e726c 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -384,6 +384,9 @@ cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} '' %NULL%
     }
 }
 EOF
+
+notmuch_passwd_sanitize < OUTPUT > OUTPUT.clean
+
 cat <<'EOF' >EXPECTED
 == stdout ==
 MAIL_DIR
@@ -396,11 +399,11 @@ NULL
 true
 NULL
 NULL
-NULL
+USER_FULL_NAME
 == stderr ==
 EOF
 unset MAILDIR
-test_expect_equal_file EXPECTED OUTPUT
+test_expect_equal_file EXPECTED OUTPUT.clean
 
 backup_database
 test_begin_subtest "override config from \${NOTMUCH_CONFIG}"
@@ -727,6 +730,8 @@ cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} /nonexistent %NULL%
     }
 }
 EOF
+
+notmuch_passwd_sanitize < OUTPUT > OUTPUT.clean
 cat <<'EOF' >EXPECTED
 == stdout ==
 MAIL_DIR
@@ -739,10 +744,10 @@ NULL
 true
 NULL
 NULL
-NULL
+USER_FULL_NAME
 == stderr ==
 EOF
-test_expect_equal_file EXPECTED OUTPUT
+test_expect_equal_file EXPECTED OUTPUT.clean
 
 backup_database
 test_begin_subtest "override config from \${HOME}/.notmuch-config (ndlc)"
diff --git a/test/test-lib.sh b/test/test-lib.sh
index 29baa0c1..e881dc40 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -694,6 +694,13 @@ notmuch_built_with_sanitize ()
     sed 's/^built_with[.]\(.*\)=.*$/built_with.\1=something/'
 }
 
+notmuch_passwd_sanitize ()
+{
+    local user=$(id -un)
+    local full_name=$(getent passwd $user | cut -d: -f 5 | cut -d, -f1)
+    sed "s/$full_name/USER_FULL_NAME/"
+}
+
 notmuch_config_sanitize ()
 {
     notmuch_dir_sanitize | notmuch_built_with_sanitize
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 08/27] lib/config: set default for primary user email
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (6 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 07/27] lib/config: set defaults for user full name David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 09/27] lib/open: canonicalize relative path read from config file David Bremner
                   ` (19 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This is mainly copying code from the CLI into the lib. The CLI copy
will be deleted in a later commit.
---
 lib/config.cc          | 70 +++++++++++++++++++++++++++++++++++++++---
 test/T590-libconfig.sh |  7 ++---
 test/test-lib.sh       |  6 +++-
 3 files changed, 73 insertions(+), 10 deletions(-)

diff --git a/lib/config.cc b/lib/config.cc
index 1741bf99..cfb5bd13 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -23,6 +23,7 @@
 #include "database-private.h"
 
 #include <pwd.h>
+#include <netdb.h>
 
 static const std::string CONFIG_PREFIX = "C";
 
@@ -467,6 +468,63 @@ _get_name_from_passwd_file (void *ctx)
     return name;
 }
 
+static char *
+_get_username_from_passwd_file (void *ctx)
+{
+    long pw_buf_size;
+    char *pw_buf;
+    struct passwd passwd, *ignored;
+    char *name;
+    int e;
+
+    pw_buf_size = sysconf (_SC_GETPW_R_SIZE_MAX);
+    if (pw_buf_size == -1) pw_buf_size = 64;
+    pw_buf = (char *)talloc_zero_size (ctx, pw_buf_size);
+
+    while ((e = getpwuid_r (getuid (), &passwd, pw_buf,
+			    pw_buf_size, &ignored)) == ERANGE) {
+	pw_buf_size = pw_buf_size * 2;
+	pw_buf = (char *)talloc_zero_size (ctx, pw_buf_size);
+    }
+
+    if (e == 0)
+	name = talloc_strdup (ctx, passwd.pw_name);
+    else
+	name = talloc_strdup (ctx, "");
+
+    talloc_free (pw_buf);
+
+    return name;
+}
+
+static const char *
+_get_email_from_passwd_file (void *ctx)
+{
+
+    char hostname[256];
+    struct hostent *hostent;
+    const char *domainname;
+    char *email;
+
+    char *username = _get_username_from_passwd_file (ctx);
+
+    gethostname (hostname, 256);
+    hostname[255] = '\0';
+
+    hostent = gethostbyname (hostname);
+    if (hostent && (domainname = strchr (hostent->h_name, '.')))
+	domainname += 1;
+    else
+	domainname = "(none)";
+
+    email = talloc_asprintf (ctx, "%s@%s.%s",
+			     username, hostname, domainname);
+
+    talloc_free (username);
+    talloc_free (email);
+    return email;
+}
+
 static const char *
 _notmuch_config_key_to_string (notmuch_config_key_t key) {
     switch (key) {
@@ -500,7 +558,7 @@ _notmuch_config_key_to_string (notmuch_config_key_t key) {
 static const char *
 _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key) {
     char *path;
-    const char* name;
+    const char *name, *email;
 
     switch (key) {
     case NOTMUCH_CONFIG_DATABASE_PATH:
@@ -526,13 +584,17 @@ _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key)
 	    name = talloc_strdup (notmuch, name);
 	else
 	    name = _get_name_from_passwd_file (notmuch);
-
 	return name;
-	break;
+    case NOTMUCH_CONFIG_PRIMARY_EMAIL:
+	email = getenv ("EMAIL");
+	if (email)
+	    email = talloc_strdup (notmuch, email);
+	else
+	    email = _get_email_from_passwd_file (notmuch);
+	return email;
     case NOTMUCH_CONFIG_HOOK_DIR:
     case NOTMUCH_CONFIG_BACKUP_DIR:
     case NOTMUCH_CONFIG_NEW_IGNORE:
-    case NOTMUCH_CONFIG_PRIMARY_EMAIL:
     case NOTMUCH_CONFIG_OTHER_EMAIL:
 	return NULL;
     default:
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 2c6e726c..292778d5 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -397,7 +397,7 @@ MAIL_DIR/.notmuch/backups
 inbox;unread
 NULL
 true
-NULL
+USERNAME@FQDN
 NULL
 USER_FULL_NAME
 == stderr ==
@@ -626,9 +626,6 @@ EOF
 
 
 test_begin_subtest "notmuch_database_get_config (ndlc)"
-echo NOTMUCH_CONFIG=$NOTMUCH_CONFIG
-echo NOTMUCH_PROFILE=$NOTMUCH_PROFILE
-echo HOME=$HOME
 cat c_head2 - c_tail <<'EOF' | test_C ${MAIL_DIR} %NULL% %NULL%
 {
    EXPECT0(notmuch_database_get_config (db, "test.key1", &val));
@@ -742,7 +739,7 @@ MAIL_DIR/.notmuch/backups
 inbox;unread
 NULL
 true
-NULL
+USERNAME@FQDN
 NULL
 USER_FULL_NAME
 == stderr ==
diff --git a/test/test-lib.sh b/test/test-lib.sh
index e881dc40..cb27cb78 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -107,6 +107,9 @@ unset GREP_OPTIONS
 # For emacsclient
 unset ALTERNATE_EDITOR
 
+# for reproducibility
+unset EMAIL
+
 add_gnupg_home ()
 {
     [ -e "${GNUPGHOME}/gpg.conf" ] && return
@@ -697,8 +700,9 @@ notmuch_built_with_sanitize ()
 notmuch_passwd_sanitize ()
 {
     local user=$(id -un)
+    local fqdn=$(hostname -f)
     local full_name=$(getent passwd $user | cut -d: -f 5 | cut -d, -f1)
-    sed "s/$full_name/USER_FULL_NAME/"
+    sed -e "s/$user/USERNAME/" -e "s/$fqdn/FQDN/" -e "s/$full_name/USER_FULL_NAME/"
 }
 
 notmuch_config_sanitize ()
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 09/27] lib/open: canonicalize relative path read from config file
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (7 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 08/27] lib/config: set default for primary user email David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 10/27] CLI: load merged config at top level David Bremner
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This matches functionality in the the CLI function
notmuch_config_get_database_path, which was previously used in the CLI
code for all calls to open a database.
---
 lib/open.cc | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/lib/open.cc b/lib/open.cc
index 58385592..737e79a7 100644
--- a/lib/open.cc
+++ b/lib/open.cc
@@ -193,9 +193,16 @@ _choose_database_path (void * ctx,
        *database_path = getenv ("NOTMUCH_DATABASE");
     }
 
-    if (! *database_path && key_file)
-	*database_path = g_key_file_get_value (key_file, "database", "path", NULL);
-
+    if (! *database_path && key_file) {
+	gchar *path = g_key_file_get_value (key_file, "database", "path", NULL);
+	if (path) {
+	    if (path[0] == '/')
+		*database_path = talloc_strdup (ctx, path);
+	    else
+		*database_path = talloc_asprintf (ctx, "%s/%s", getenv ("HOME"), path);
+	    g_free (path);
+	}
+    }
     if (! *database_path) {
 	*database_path = _xdg_dir (ctx, "XDG_DATA_HOME", ".local/share", profile);
 	*split = true;
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 10/27] CLI: load merged config at top level
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (8 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 09/27] lib/open: canonicalize relative path read from config file David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 11/27] CLI/config: use merged config for "config get" David Bremner
                   ` (17 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This paves the way for the conversion of the remaining subcommands to
the new configuration framework.
---
 notmuch-client.h |  1 +
 notmuch.c        | 29 ++++++++++++++++++++++++++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index f60f5406..db88daf8 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -258,6 +258,7 @@ typedef enum {
     NOTMUCH_COMMAND_DATABASE_EARLY	= 1 << 2,
     NOTMUCH_COMMAND_DATABASE_WRITE	= 1 << 3,
     NOTMUCH_COMMAND_DATABASE_CREATE	= 1 << 4,
+    NOTMUCH_COMMAND_CONFIG_LOAD		= 1 << 5,
 } notmuch_command_mode_t;
 
 notmuch_config_t *
diff --git a/notmuch.c b/notmuch.c
index 71482e43..d2eb5daa 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -168,7 +168,7 @@ static command_t commands[] = {
       "Compact the notmuch database." },
     { "reindex", notmuch_reindex_command, NOTMUCH_COMMAND_DATABASE_EARLY | NOTMUCH_COMMAND_DATABASE_WRITE,
       "Re-index all messages matching the search terms." },
-    { "config", notmuch_config_command, NOTMUCH_COMMAND_CONFIG_OPEN,
+    { "config", notmuch_config_command, NOTMUCH_COMMAND_CONFIG_OPEN | NOTMUCH_COMMAND_CONFIG_LOAD,
       "Get or set settings in the notmuch configuration file." },
 #if WITH_EMACS
     { "emacs-mua", NULL, 0,
@@ -460,7 +460,7 @@ main (int argc, char *argv[])
     notmuch_config_t *config = NULL;
     notmuch_database_t *notmuch = NULL;
     int opt_index;
-    int ret;
+    int ret = EXIT_SUCCESS;
 
     notmuch_opt_desc_t options[] = {
 	{ .opt_string = &config_file_name, .name = "config" },
@@ -548,7 +548,30 @@ main (int argc, char *argv[])
 		return EXIT_FAILURE;
 	    }
 	}
-    } else {
+    }
+
+    if (command->mode & NOTMUCH_COMMAND_CONFIG_LOAD) {
+	char *status_string = NULL;
+	notmuch_status_t status;
+	status = notmuch_database_load_config (NULL,
+					       config_file_name,
+					       NULL,
+					       &notmuch,
+					       &status_string);
+	if (status) {
+	    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);
+	    goto DONE;
+	}
+
+    }
+
+    if (command->mode & NOTMUCH_COMMAND_CONFIG_OPEN) {
 	config = notmuch_config_open (local, config_file_name, command->mode);
 	if (! config) {
 	    ret = EXIT_FAILURE;
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 11/27] CLI/config: use merged config for "config get"
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (9 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 10/27] CLI: load merged config at top level David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 12/27] test/setup: check file output instead of notmuch config list David Bremner
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This commit starts the conversion of notmuch-config.c
functionality (as opposed to just interface) to the new config
framework.

The change to T030-config is because of the move of the
canonicalization database paths from the notmuch_config_t accessor to
the internal function _choose_database_path.
---
 notmuch-config.c    | 92 +++++----------------------------------------
 test/T030-config.sh | 31 ++++++++++++---
 2 files changed, 36 insertions(+), 87 deletions(-)

diff --git a/notmuch-config.c b/notmuch-config.c
index 0193401f..91b9eeaf 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -862,89 +862,17 @@ _config_key_info (const char *item)
     return NULL;
 }
 
-static bool
-_stored_in_db (const char *item)
-{
-    config_key_info_t *info;
-
-    info = _config_key_info (item);
-
-    return (info && info->in_db);
-}
-
-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, &notmuch))
-	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)
+notmuch_config_command_get (notmuch_database_t *notmuch, char *item)
 {
-    if (strcmp (item, "database.path") == 0) {
-	printf ("%s\n", notmuch_config_get_database_path (config));
-    } else if (strcmp (item, "user.name") == 0) {
-	printf ("%s\n", notmuch_config_get_user_name (config));
-    } else if (strcmp (item, "user.primary_email") == 0) {
-	printf ("%s\n", notmuch_config_get_user_primary_email (config));
-    } else if (strcmp (item, "user.other_email") == 0) {
-	const char **other_email;
-	size_t i, length;
-
-	other_email = notmuch_config_get_user_other_email (config, &length);
-	for (i = 0; i < length; i++)
-	    printf ("%s\n", other_email[i]);
-    } else if (strcmp (item, "new.tags") == 0) {
-	const char **tags;
-	size_t i, length;
-
-	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 (_stored_in_db (item)) {
-	return _print_db_config (config, item);
-    } else {
-	char **value;
-	size_t i, length;
-	char *group, *key;
-
-	if (_item_split (item, &group, &key))
-	    return 1;
-
-	value = g_key_file_get_string_list (config->key_file,
-					    group, key,
-					    &length, NULL);
-	if (value == NULL) {
-	    fprintf (stderr, "Unknown configuration item: %s.%s\n",
-		     group, key);
-	    return 1;
-	}
-
-	for (i = 0; i < length; i++)
-	    printf ("%s\n", value[i]);
-
-	g_strfreev (value);
+    notmuch_config_values_t *list;
+    for (list = notmuch_config_get_values_string (notmuch, item);
+	 notmuch_config_values_valid (list);
+	 notmuch_config_values_move_to_next (list)) {
+	const char *val = notmuch_config_values_get (list);
+	puts(val);
     }
-
-    return 0;
+    return EXIT_SUCCESS;
 }
 
 static int
@@ -1105,7 +1033,7 @@ notmuch_config_command_list (notmuch_config_t *config)
 }
 
 int
-notmuch_config_command (notmuch_config_t *config, unused(notmuch_database_t *notmuch), int argc, char *argv[])
+notmuch_config_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[])
 {
     int ret;
     int opt_index;
@@ -1133,7 +1061,7 @@ notmuch_config_command (notmuch_config_t *config, unused(notmuch_database_t *not
 		     "one argument.\n");
 	    return EXIT_FAILURE;
 	}
-	ret = notmuch_config_command_get (config, argv[1]);
+	ret = notmuch_config_command_get (notmuch, argv[1]);
     } else if (strcmp (argv[0], "set") == 0) {
 	if (argc < 2) {
 	    fprintf (stderr, "Error: notmuch config set requires at least "
diff --git a/test/T030-config.sh b/test/T030-config.sh
index 67c9545c..8dff9c72 100755
--- a/test/T030-config.sh
+++ b/test/T030-config.sh
@@ -7,9 +7,12 @@ test_begin_subtest "Get string value"
 test_expect_equal "$(notmuch config get user.name)" "Notmuch Test Suite"
 
 test_begin_subtest "Get list value"
-test_expect_equal "$(notmuch config get new.tags)" "\
+cat <<EOF > EXPECTED
+inbox
 unread
-inbox"
+EOF
+notmuch config get new.tags | sort > OUTPUT
+test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "Set string value"
 notmuch config set foo.string "this is a string value"
@@ -96,14 +99,32 @@ test_expect_equal "$(notmuch --config=alt-config-link config get user.name)" \
 test_begin_subtest "Writing config file through symlink follows symlink"
 test_expect_equal "$(readlink alt-config-link)" "alt-config"
 
+test_begin_subtest "Round trip arbitrary key"
+key=g${RANDOM}.m${RANDOM}
+value=${RANDOM}
+notmuch config set ${key} ${value}
+output=$(notmuch config get ${key})
+test_expect_equal "${output}" "${value}"
+
+test_begin_subtest "Clear arbitrary key"
+notmuch config set ${key}
+output=$(notmuch config get ${key})
+test_expect_equal "${output}" ""
+
+db_path=${HOME}/database-path
+
 test_begin_subtest "Absolute database path returned"
 notmuch config set database.path ${HOME}/Maildir
 test_expect_equal "$(notmuch config get database.path)" \
 		  "${HOME}/Maildir"
 
-test_begin_subtest "Relative database path properly expanded"
+ln -s `pwd`/mail home/Maildir
+add_email_corpus
+test_begin_subtest "Relative database path expanded in open"
 notmuch config set database.path Maildir
-test_expect_equal "$(notmuch config get database.path)" \
-		  "${HOME}/Maildir"
+path=$(notmuch config get database.path)
+count=$(notmuch count '*')
+test_expect_equal "${path} ${count}" \
+		  "Maildir 52"
 
 test_done
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 12/27] test/setup: check file output instead of notmuch config list
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (10 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 11/27] CLI/config: use merged config for "config get" David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 13/27] CLI/setup: switch to new configuration framework David Bremner
                   ` (15 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This allows verification of comments added to new / updated config
file.
---
 test/T040-setup.sh                            | 17 +---
 .../config-with-comments                      | 88 +++++++++++++++++++
 2 files changed, 91 insertions(+), 14 deletions(-)
 create mode 100644 test/setup.expected-output/config-with-comments

diff --git a/test/T040-setup.sh b/test/T040-setup.sh
index 5eb281d7..daeca3e4 100755
--- a/test/T040-setup.sh
+++ b/test/T040-setup.sh
@@ -10,7 +10,7 @@ Error: cannot load config file.
 Try running 'notmuch setup' to create a configuration."
 
 test_begin_subtest "Create a new config interactively"
-notmuch --config=new-notmuch-config > /dev/null <<EOF
+notmuch --config=new-notmuch-config > log.${test_count} <<EOF
 Test Suite
 test.suite@example.com
 another.suite@example.com
@@ -20,19 +20,8 @@ foo bar
 baz
 EOF
 
-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
-user.primary_email=test.suite@example.com
-user.other_email=another.suite@example.com;
-new.tags=foo;bar;
-new.ignore=
-search.exclude_tags=baz;
-maildir.synchronize_flags=true
-built_with.compact=something
-built_with.field_processor=something
-built_with.retry_lock=something"
+expected_dir=$NOTMUCH_SRCDIR/test/setup.expected-output
+test_expect_equal_file ${expected_dir}/config-with-comments new-notmuch-config
 
 test_begin_subtest "notmuch with a config but without a database suggests notmuch new"
 notmuch 2>&1 | notmuch_dir_sanitize > OUTPUT
diff --git a/test/setup.expected-output/config-with-comments b/test/setup.expected-output/config-with-comments
new file mode 100644
index 00000000..d9f796f2
--- /dev/null
+++ b/test/setup.expected-output/config-with-comments
@@ -0,0 +1,88 @@
+# .notmuch-config - Configuration file for the notmuch mail system
+#
+# For more information about notmuch, see https://notmuchmail.org
+
+# Database configuration
+#
+# The only value supported here is 'path' which should be 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.
+# Notmuch will store its database within a sub-directory of the path
+# configured here named ".notmuch".
+#
+[database]
+path=/path/to/maildir
+
+# User configuration
+#
+# Here is where you can let notmuch know how you would like to be
+# addressed. Valid settings are
+#
+#	name		Your full name.
+#	primary_email	Your primary email address.
+#	other_email	A list (separated by ';') of other email addresses
+#			at which you receive email.
+#
+# Notmuch will use the various email addresses configured here when
+# formatting replies. It will avoid including your own addresses in the
+# recipient list of replies, and will set the From address based on the
+# address to which the original email was addressed.
+#
+[user]
+name=Test Suite
+primary_email=test.suite@example.com
+other_email=another.suite@example.com;
+
+# Configuration for "notmuch new"
+#
+# The following options are supported here:
+#
+#	tags	A list (separated by ';') of the tags that will be
+#		added to all messages incorporated by "notmuch new".
+#
+#	ignore	A list (separated by ';') of file and directory names
+#		that will not be searched for messages by "notmuch new".
+#
+#		NOTE: *Every* file/directory that goes by one of those
+#		names will be ignored, independent of its depth/location
+#		in the mail store.
+#
+[new]
+tags=foo;bar;
+ignore=
+
+# Search configuration
+#
+# The following option is supported here:
+#
+#	exclude_tags
+#		A ;-separated list of tags that will be excluded from
+#		search results by default.  Using an excluded tag in a
+#		query will override that exclusion.
+#
+[search]
+exclude_tags=baz;
+
+# Maildir compatibility configuration
+#
+# The following option is supported here:
+#
+#	synchronize_flags      Valid values are true and false.
+#
+#	If true, then the following maildir flags (in message filenames)
+#	will be synchronized with the corresponding notmuch tags:
+#
+#		Flag	Tag
+#		----	-------
+#		D	draft
+#		F	flagged
+#		P	passed
+#		R	replied
+#		S	unread (added when 'S' flag is not present)
+#
+#	The "notmuch new" command will notice flag changes in filenames
+#	and update tags, while the "notmuch tag" and "notmuch restore"
+#	commands will notice tag changes and update flags in filenames
+#
+[maildir]
+synchronize_flags=true
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 13/27] CLI/setup: switch to new configuration framework
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (11 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 12/27] test/setup: check file output instead of notmuch config list David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 14/27] CLI/config: switch "notmuch config list" to merged config David Bremner
                   ` (14 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Most of the changes are the elimination of notmuch_config_t accessor
use. We also migrate some of the diagnostics to the top level where we
are opening the files in question.
---
 notmuch-setup.c | 55 +++++++++++++++++++++++--------------------------
 notmuch.c       | 21 ++++++++++++-------
 2 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/notmuch-setup.c b/notmuch-setup.c
index 67214470..1e22412b 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -88,14 +88,17 @@ welcome_message_post_setup (void)
 }
 
 static void
-print_tag_list (const char **tags, size_t tags_len)
+print_tag_list (notmuch_config_values_t *tags)
 {
-    unsigned int i;
-
-    for (i = 0; i < tags_len; i++) {
-	if (i != 0)
-	    printf (" ");
-	printf ("%s", tags[i]);
+    bool first = false;
+
+    for (;
+	 notmuch_config_values_valid(tags);
+	 notmuch_config_values_move_to_next (tags)) {
+	if (!first)
+	    printf(" ");
+	first = false;
+	printf("%s", notmuch_config_values_get (tags));
     }
 }
 
@@ -122,19 +125,13 @@ parse_tag_list (void *ctx, char *response)
 
 int
 notmuch_setup_command (notmuch_config_t *config,
-		       unused(notmuch_database_t *notmuch),
+		       notmuch_database_t *notmuch,
 		       int argc, char *argv[])
 {
     char *response = NULL;
     size_t response_size = 0;
-    const char **old_other_emails;
-    size_t old_other_emails_len;
     GPtrArray *other_emails;
-    unsigned int i;
-    const char **new_tags;
-    size_t new_tags_len;
-    const char **search_exclude_tags;
-    size_t search_exclude_tags_len;
+    notmuch_config_values_t *new_tags, *search_exclude_tags, *emails;
 
 #define prompt(format, ...)                                     \
     do {                                                        \
@@ -157,26 +154,27 @@ notmuch_setup_command (notmuch_config_t *config,
     if (notmuch_config_is_new (config))
 	welcome_message_pre_setup ();
 
-    prompt ("Your full name [%s]: ", notmuch_config_get_user_name (config));
+    prompt ("Your full name [%s]: ", notmuch_config_get (notmuch, NOTMUCH_CONFIG_USER_NAME));
     if (strlen (response))
 	notmuch_config_set_user_name (config, response);
 
     prompt ("Your primary email address [%s]: ",
-	    notmuch_config_get_user_primary_email (config));
+	    notmuch_config_get (notmuch, NOTMUCH_CONFIG_PRIMARY_EMAIL));
     if (strlen (response))
 	notmuch_config_set_user_primary_email (config, response);
 
     other_emails = g_ptr_array_new ();
 
-    old_other_emails = notmuch_config_get_user_other_email (config,
-							    &old_other_emails_len);
-    for (i = 0; i < old_other_emails_len; i++) {
-	prompt ("Additional email address [%s]: ", old_other_emails[i]);
+    for (emails = notmuch_config_get_values (notmuch, NOTMUCH_CONFIG_OTHER_EMAIL);
+	 notmuch_config_values_valid (emails);
+	 notmuch_config_values_move_to_next (emails)) {
+	const char *email = notmuch_config_values_get (emails);
+
+	prompt ("Additional email address [%s]: ", email);
 	if (strlen (response))
 	    g_ptr_array_add (other_emails, talloc_strdup (config, response));
 	else
-	    g_ptr_array_add (other_emails, talloc_strdup (config,
-							  old_other_emails[i]));
+	    g_ptr_array_add (other_emails, talloc_strdup (config, email));
     }
 
     do {
@@ -192,7 +190,7 @@ notmuch_setup_command (notmuch_config_t *config,
     g_ptr_array_free (other_emails, true);
 
     prompt ("Top-level directory of your email archive [%s]: ",
-	    notmuch_config_get_database_path (config));
+	    notmuch_config_get (notmuch, NOTMUCH_CONFIG_DATABASE_PATH));
     if (strlen (response)) {
 	const char *absolute_path;
 
@@ -200,10 +198,10 @@ notmuch_setup_command (notmuch_config_t *config,
 	notmuch_config_set_database_path (config, absolute_path);
     }
 
-    new_tags = notmuch_config_get_new_tags (config, &new_tags_len);
+    new_tags = notmuch_config_get_values (notmuch, NOTMUCH_CONFIG_NEW_TAGS);
 
     printf ("Tags to apply to all new messages (separated by spaces) [");
-    print_tag_list (new_tags, new_tags_len);
+    print_tag_list (new_tags);
     prompt ("]: ");
 
     if (strlen (response)) {
@@ -215,11 +213,10 @@ notmuch_setup_command (notmuch_config_t *config,
 	g_ptr_array_free (tags, true);
     }
 
-
-    search_exclude_tags = notmuch_config_get_search_exclude_tags (config, &search_exclude_tags_len);
+    search_exclude_tags = notmuch_config_get_values (notmuch, NOTMUCH_CONFIG_EXCLUDE_TAGS);
 
     printf ("Tags to exclude when searching messages (separated by spaces) [");
-    print_tag_list (search_exclude_tags, search_exclude_tags_len);
+    print_tag_list (search_exclude_tags);
     prompt ("]: ");
 
     if (strlen (response)) {
diff --git a/notmuch.c b/notmuch.c
index d2eb5daa..5e2cbdc8 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -139,9 +139,11 @@ notmuch_process_shared_indexing_options (notmuch_database_t *notmuch)
 
 
 static command_t commands[] = {
-    { NULL, notmuch_command, NOTMUCH_COMMAND_CONFIG_OPEN | NOTMUCH_COMMAND_CONFIG_CREATE,
+    { NULL, notmuch_command, NOTMUCH_COMMAND_CONFIG_OPEN | NOTMUCH_COMMAND_CONFIG_CREATE
+      | NOTMUCH_COMMAND_CONFIG_LOAD,
       "Notmuch main command." },
-    { "setup", notmuch_setup_command, NOTMUCH_COMMAND_CONFIG_OPEN | NOTMUCH_COMMAND_CONFIG_CREATE,
+    { "setup", notmuch_setup_command, NOTMUCH_COMMAND_CONFIG_OPEN | NOTMUCH_COMMAND_CONFIG_CREATE
+      | NOTMUCH_COMMAND_CONFIG_LOAD,
       "Interactively set up notmuch for first use." },
     { "new", notmuch_new_command,
       NOTMUCH_COMMAND_DATABASE_EARLY | NOTMUCH_COMMAND_DATABASE_WRITE | NOTMUCH_COMMAND_DATABASE_CREATE,
@@ -364,7 +366,7 @@ notmuch_help_command (unused (notmuch_config_t *config), unused(notmuch_database
  */
 static int
 notmuch_command (notmuch_config_t *config,
-		 unused(notmuch_database_t *notmuch),
+		 notmuch_database_t *notmuch,
 		 unused(int argc), unused(char **argv))
 {
     char *db_path;
@@ -374,7 +376,7 @@ notmuch_command (notmuch_config_t *config,
      * notmuch_setup_command which will give a nice welcome message,
      * and interactively guide the user through the configuration. */
     if (notmuch_config_is_new (config))
-	return notmuch_setup_command (config, NULL, 0, NULL);
+	return notmuch_setup_command (config, notmuch, 0, NULL);
 
     /* Notmuch is already configured, but is there a database? */
     db_path = talloc_asprintf (config, "%s/%s",
@@ -558,14 +560,17 @@ main (int argc, char *argv[])
 					       NULL,
 					       &notmuch,
 					       &status_string);
-	if (status) {
+
+	if (status == NOTMUCH_STATUS_NO_CONFIG && !(command->mode & NOTMUCH_COMMAND_CONFIG_CREATE)) {
+	    fputs ("Try running 'notmuch setup' to create a configuration.", stderr);
+	    goto DONE;
+	}
+
+	if (status && (status != NOTMUCH_STATUS_NO_CONFIG)) {
 	    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);
 	    goto DONE;
 	}
 
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 14/27] CLI/config: switch "notmuch config list" to merged config
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (12 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 13/27] CLI/setup: switch to new configuration framework David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 15/27] CLI/config: migrate notmuch_config_open to new config David Bremner
                   ` (13 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Use the database opened at the top level rather than opening another
notmuch_database_t.

Test output changes because keys are now listed in alphabetical order,
and because a missing database is no longer an error.
---
 notmuch-config.c    | 69 ++++++++-------------------------------------
 test/T030-config.sh | 27 ++++++++----------
 2 files changed, 23 insertions(+), 73 deletions(-)

diff --git a/notmuch-config.c b/notmuch-config.c
index 91b9eeaf..7c7f89d9 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -969,69 +969,22 @@ _notmuch_config_list_built_with ()
 }
 
 static int
-_list_db_config (notmuch_config_t *config)
+notmuch_config_command_list (notmuch_database_t *notmuch)
 {
-    notmuch_database_t *notmuch;
-    notmuch_config_list_t *list;
-
-    if (notmuch_database_open (notmuch_config_get_database_path (config),
-			       NOTMUCH_DATABASE_MODE_READ_ONLY, &notmuch))
-	return EXIT_FAILURE;
+    notmuch_config_pairs_t *list;
 
-    /* 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_built_with ();
+    for (list = notmuch_config_get_pairs (notmuch, "");
+	 notmuch_config_pairs_valid (list);
+	 notmuch_config_pairs_move_to_next (list)) {
+	const char *value = notmuch_config_pairs_value (list);
+	if (value)
+	    printf ("%s=%s\n", notmuch_config_pairs_key (list), value);
     }
-    notmuch_config_list_destroy (list);
-
+    notmuch_config_pairs_destroy (list);
     return EXIT_SUCCESS;
 }
 
-static int
-notmuch_config_command_list (notmuch_config_t *config)
-{
-    char **groups;
-    size_t g, groups_length;
-
-    groups = g_key_file_get_groups (config->key_file, &groups_length);
-    if (groups == NULL)
-	return 1;
-
-    for (g = 0; g < groups_length; g++) {
-	char **keys;
-	size_t k, keys_length;
-
-	keys = g_key_file_get_keys (config->key_file,
-				    groups[g], &keys_length, NULL);
-	if (keys == NULL)
-	    continue;
-
-	for (k = 0; k < keys_length; k++) {
-	    char *value;
-
-	    value = g_key_file_get_string (config->key_file,
-					   groups[g], keys[k], NULL);
-	    if (value != NULL) {
-		printf ("%s.%s=%s\n", groups[g], keys[k], value);
-		free (value);
-	    }
-	}
-
-	g_strfreev (keys);
-    }
-
-    g_strfreev (groups);
-
-    _notmuch_config_list_built_with ();
-    return _list_db_config (config);
-}
-
 int
 notmuch_config_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[])
 {
@@ -1070,7 +1023,7 @@ notmuch_config_command (notmuch_config_t *config, notmuch_database_t *notmuch, i
 	}
 	ret = notmuch_config_command_set (config, argv[1], argc - 2, argv + 2);
     } else if (strcmp (argv[0], "list") == 0) {
-	ret = notmuch_config_command_list (config);
+	ret = notmuch_config_command_list (notmuch);
     } else {
 	fprintf (stderr, "Unrecognized argument for notmuch config: %s\n",
 		 argv[0]);
diff --git a/test/T030-config.sh b/test/T030-config.sh
index 8dff9c72..ef615152 100755
--- a/test/T030-config.sh
+++ b/test/T030-config.sh
@@ -46,25 +46,22 @@ notmuch config set foo.nonexistent
 test_expect_equal "$(notmuch config get foo.nonexistent)" ""
 
 test_begin_subtest "List all items"
-notmuch config list > STDOUT 2> STDERR
-printf "%s\n====\n%s\n" "$(< STDOUT)" "$(< STDERR)" | notmuch_config_sanitize > OUTPUT
-
+notmuch config list 2>&1 | notmuch_config_sanitize > OUTPUT
 cat <<EOF > EXPECTED
-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
-new.tags=unread;inbox;
-new.ignore=
-search.exclude_tags=
-maildir.synchronize_flags=true
-foo.string=this is another string value
-foo.list=this;is another;list value;
 built_with.compact=something
 built_with.field_processor=something
 built_with.retry_lock=something
-====
-Error: Cannot open database at MAIL_DIR/.notmuch: No such file or directory.
+database.mail_root=MAIL_DIR
+database.path=MAIL_DIR
+foo.list=this;is another;list value;
+foo.string=this is another string value
+maildir.synchronize_flags=true
+new.ignore=
+new.tags=unread;inbox;
+search.exclude_tags=
+user.name=Notmuch Test Suite
+user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org
+user.primary_email=test_suite@notmuchmail.org
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 15/27] CLI/config: migrate notmuch_config_open to new config
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (13 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 14/27] CLI/config: switch "notmuch config list" to merged config David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 16/27] CLI/config: use notmuch_database_reopen David Bremner
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

notmuch_config_open will be preserved in the medium term for use by
the commands that are manipulating the config file directly (config
and setup)
---
 lib/config.cc                                 |   5 +-
 notmuch-client.h                              |   2 +-
 notmuch-config.c                              | 371 +++++-------------
 notmuch.c                                     |   2 +-
 test/T030-config.sh                           |   2 +-
 test/T590-libconfig.sh                        |  12 +-
 .../config-with-comments                      |   2 -
 7 files changed, 106 insertions(+), 290 deletions(-)

diff --git a/lib/config.cc b/lib/config.cc
index cfb5bd13..855816c1 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -575,7 +575,7 @@ _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key)
     case NOTMUCH_CONFIG_EXCLUDE_TAGS:
 	return "";
     case NOTMUCH_CONFIG_NEW_TAGS:
-	return "inbox;unread";
+	return "unread;inbox";
     case NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS:
 	return "true";
     case NOTMUCH_CONFIG_USER_NAME:
@@ -592,9 +592,10 @@ _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key)
 	else
 	    email = _get_email_from_passwd_file (notmuch);
 	return email;
+    case NOTMUCH_CONFIG_NEW_IGNORE:
+	return "";
     case NOTMUCH_CONFIG_HOOK_DIR:
     case NOTMUCH_CONFIG_BACKUP_DIR:
-    case NOTMUCH_CONFIG_NEW_IGNORE:
     case NOTMUCH_CONFIG_OTHER_EMAIL:
 	return NULL;
     default:
diff --git a/notmuch-client.h b/notmuch-client.h
index db88daf8..dfdfc876 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -262,7 +262,7 @@ typedef enum {
 } notmuch_command_mode_t;
 
 notmuch_config_t *
-notmuch_config_open (void *ctx,
+notmuch_config_open (notmuch_database_t *notmuch,
 		     const char *filename,
 		     notmuch_command_mode_t config_mode);
 
diff --git a/notmuch-config.c b/notmuch-config.c
index 7c7f89d9..a46c639e 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -31,87 +31,88 @@ static const char toplevel_config_comment[] =
     "\n"
     " For more information about notmuch, see https://notmuchmail.org";
 
-static const char database_config_comment[] =
-    " Database configuration\n"
-    "\n"
-    " The only value supported here is 'path' which should be the top-level\n"
-    " directory where your mail currently exists and to where mail will be\n"
-    " delivered in the future. Files should be individual email messages.\n"
-    " Notmuch will store its database within a sub-directory of the path\n"
-    " configured here named \".notmuch\".\n";
-
-static const char new_config_comment[] =
-    " Configuration for \"notmuch new\"\n"
-    "\n"
-    " The following options are supported here:\n"
-    "\n"
-    "\ttags	A list (separated by ';') of the tags that will be\n"
-    "\t	added to all messages incorporated by \"notmuch new\".\n"
-    "\n"
-    "\tignore	A list (separated by ';') of file and directory names\n"
-    "\t	that will not be searched for messages by \"notmuch new\".\n"
-    "\n"
-    "\t	NOTE: *Every* file/directory that goes by one of those\n"
-    "\t	names will be ignored, independent of its depth/location\n"
-    "\t	in the mail store.\n";
-
-static const char user_config_comment[] =
-    " User configuration\n"
-    "\n"
-    " Here is where you can let notmuch know how you would like to be\n"
-    " addressed. Valid settings are\n"
-    "\n"
-    "\tname		Your full name.\n"
-    "\tprimary_email	Your primary email address.\n"
-    "\tother_email	A list (separated by ';') of other email addresses\n"
-    "\t		at which you receive email.\n"
-    "\n"
-    " Notmuch will use the various email addresses configured here when\n"
-    " formatting replies. It will avoid including your own addresses in the\n"
-    " recipient list of replies, and will set the From address based on the\n"
-    " address to which the original email was addressed.\n";
-
-static const char maildir_config_comment[] =
-    " Maildir compatibility configuration\n"
-    "\n"
-    " The following option is supported here:\n"
-    "\n"
-    "\tsynchronize_flags      Valid values are true and false.\n"
-    "\n"
-    "\tIf true, then the following maildir flags (in message filenames)\n"
-    "\twill be synchronized with the corresponding notmuch tags:\n"
-    "\n"
-    "\t\tFlag	Tag\n"
-    "\t\t----	-------\n"
-    "\t\tD	draft\n"
-    "\t\tF	flagged\n"
-    "\t\tP	passed\n"
-    "\t\tR	replied\n"
-    "\t\tS	unread (added when 'S' flag is not present)\n"
-    "\n"
-    "\tThe \"notmuch new\" command will notice flag changes in filenames\n"
-    "\tand update tags, while the \"notmuch tag\" and \"notmuch restore\"\n"
-    "\tcommands will notice tag changes and update flags in filenames\n";
-
-static const char search_config_comment[] =
-    " Search configuration\n"
-    "\n"
-    " The following option is supported here:\n"
-    "\n"
-    "\texclude_tags\n"
-    "\t\tA ;-separated list of tags that will be excluded from\n"
-    "\t\tsearch results by default.  Using an excluded tag in a\n"
-    "\t\tquery will override that exclusion.\n";
-
-static const char crypto_config_comment[] =
-    " Cryptography related configuration\n"
-    "\n"
-    " The following old option is now ignored:\n"
-    "\n"
-    "\tgpgpath\n"
-    "\t\tThis option was used by older builds of notmuch to choose\n"
-    "\t\tthe version of gpg to use.\n"
-    "\t\tSetting $PATH is a better approach.\n";
+struct config_group {
+    const char *group_name;
+    const char *comment;
+} group_comment_table [] = {
+    {
+	"database",
+	" Database configuration\n"
+	"\n"
+	" The only value supported here is 'path' which should be the top-level\n"
+	" directory where your mail currently exists and to where mail will be\n"
+	" delivered in the future. Files should be individual email messages.\n"
+	" Notmuch will store its database within a sub-directory of the path\n"
+	" configured here named \".notmuch\".\n"
+    },
+    {
+	"user",
+	" User configuration\n"
+	"\n"
+	" Here is where you can let notmuch know how you would like to be\n"
+	" addressed. Valid settings are\n"
+	"\n"
+	"\tname		Your full name.\n"
+	"\tprimary_email	Your primary email address.\n"
+	"\tother_email	A list (separated by ';') of other email addresses\n"
+	"\t		at which you receive email.\n"
+	"\n"
+	" Notmuch will use the various email addresses configured here when\n"
+	" formatting replies. It will avoid including your own addresses in the\n"
+	" recipient list of replies, and will set the From address based on the\n"
+	" address to which the original email was addressed.\n"
+    },
+    {
+	"new",
+	" Configuration for \"notmuch new\"\n"
+	"\n"
+	" The following options are supported here:\n"
+	"\n"
+	"\ttags	A list (separated by ';') of the tags that will be\n"
+	"\t	added to all messages incorporated by \"notmuch new\".\n"
+	"\n"
+	"\tignore	A list (separated by ';') of file and directory names\n"
+	"\t	that will not be searched for messages by \"notmuch new\".\n"
+	"\n"
+	"\t	NOTE: *Every* file/directory that goes by one of those\n"
+	"\t	names will be ignored, independent of its depth/location\n"
+	"\t	in the mail store.\n"
+    },
+    {
+	"search",
+	" Search configuration\n"
+	"\n"
+	" The following option is supported here:\n"
+	"\n"
+	"\texclude_tags\n"
+	"\t\tA ;-separated list of tags that will be excluded from\n"
+	"\t\tsearch results by default.  Using an excluded tag in a\n"
+	"\t\tquery will override that exclusion.\n"
+    },
+    {
+	"maildir",
+	" Maildir compatibility configuration\n"
+	"\n"
+	" The following option is supported here:\n"
+	"\n"
+	"\tsynchronize_flags      Valid values are true and false.\n"
+	"\n"
+	"\tIf true, then the following maildir flags (in message filenames)\n"
+	"\twill be synchronized with the corresponding notmuch tags:\n"
+	"\n"
+	"\t\tFlag	Tag\n"
+	"\t\t----	-------\n"
+	"\t\tD	draft\n"
+	"\t\tF	flagged\n"
+	"\t\tP	passed\n"
+	"\t\tR	replied\n"
+	"\t\tS	unread (added when 'S' flag is not present)\n"
+	"\n"
+	"\tThe \"notmuch new\" command will notice flag changes in filenames\n"
+	"\tand update tags, while the \"notmuch tag\" and \"notmuch restore\"\n"
+	"\tcommands will notice tag changes and update flags in filenames\n"
+    },
+};
 
 struct _notmuch_config {
     char *filename;
@@ -141,69 +142,6 @@ notmuch_config_destructor (notmuch_config_t *config)
     return 0;
 }
 
-static char *
-get_name_from_passwd_file (void *ctx)
-{
-    long pw_buf_size;
-    char *pw_buf;
-    struct passwd passwd, *ignored;
-    char *name;
-    int e;
-
-    pw_buf_size = sysconf (_SC_GETPW_R_SIZE_MAX);
-    if (pw_buf_size == -1) pw_buf_size = 64;
-    pw_buf = talloc_size (ctx, pw_buf_size);
-
-    while ((e = getpwuid_r (getuid (), &passwd, pw_buf,
-			    pw_buf_size, &ignored)) == ERANGE) {
-	pw_buf_size = pw_buf_size * 2;
-	pw_buf = talloc_zero_size (ctx, pw_buf_size);
-    }
-
-    if (e == 0) {
-	char *comma = strchr (passwd.pw_gecos, ',');
-	if (comma)
-	    name = talloc_strndup (ctx, passwd.pw_gecos,
-				   comma - passwd.pw_gecos);
-	else
-	    name = talloc_strdup (ctx, passwd.pw_gecos);
-    } else {
-	name = talloc_strdup (ctx, "");
-    }
-
-    talloc_free (pw_buf);
-
-    return name;
-}
-
-static char *
-get_username_from_passwd_file (void *ctx)
-{
-    long pw_buf_size;
-    char *pw_buf;
-    struct passwd passwd, *ignored;
-    char *name;
-    int e;
-
-    pw_buf_size = sysconf (_SC_GETPW_R_SIZE_MAX);
-    if (pw_buf_size == -1) pw_buf_size = 64;
-    pw_buf = talloc_zero_size (ctx, pw_buf_size);
-
-    while ((e = getpwuid_r (getuid (), &passwd, pw_buf,
-			    pw_buf_size, &ignored)) == ERANGE) {
-	pw_buf_size = pw_buf_size * 2;
-	pw_buf = talloc_zero_size (ctx, pw_buf_size);
-    }
-
-    if (e == 0)
-	name = talloc_strdup (ctx, passwd.pw_name);
-    else
-	name = talloc_strdup (ctx, "");
-
-    talloc_free (pw_buf);
-
-    return name;
-}
 
 static bool
 get_config_from_file (notmuch_config_t *config, bool create_new)
@@ -322,21 +260,13 @@ get_config_from_file (notmuch_config_t *config, bool create_new)
  *	user in editing the file directly.
  */
 notmuch_config_t *
-notmuch_config_open (void *ctx,
+notmuch_config_open (notmuch_database_t *notmuch,
 		     const char *filename,
 		     notmuch_command_mode_t config_mode)
 {
-    GError *error = NULL;
-    size_t tmp;
     char *notmuch_config_env = NULL;
-    int file_had_database_group;
-    int file_had_new_group;
-    int file_had_user_group;
-    int file_had_maildir_group;
-    int file_had_search_group;
-    int file_had_crypto_group;
 
-    notmuch_config_t *config = talloc_zero (ctx, notmuch_config_t);
+    notmuch_config_t *config = talloc_zero (notmuch, notmuch_config_t);
 
     if (config == NULL) {
 	fprintf (stderr, "Out of memory.\n");
@@ -368,133 +298,20 @@ notmuch_config_open (void *ctx,
 	}
     }
 
-    /* Whenever we know of configuration sections that don't appear in
-     * the configuration file, we add some comments to help the user
-     * understand what can be done.
-     *
-     * It would be convenient to just add those comments now, but
-     * apparently g_key_file will clear any comments when keys are
-     * added later that create the groups. So we have to check for the
-     * groups now, but add the comments only after setting all of our
-     * values.
-     */
-    file_had_database_group = g_key_file_has_group (config->key_file,
-						    "database");
-    file_had_new_group = g_key_file_has_group (config->key_file, "new");
-    file_had_user_group = g_key_file_has_group (config->key_file, "user");
-    file_had_maildir_group = g_key_file_has_group (config->key_file, "maildir");
-    file_had_search_group = g_key_file_has_group (config->key_file, "search");
-    file_had_crypto_group = g_key_file_has_group (config->key_file, "crypto");
-
-    if (notmuch_config_get_database_path (config) == NULL) {
-	char *path = getenv ("MAILDIR");
-	if (path)
-	    path = talloc_strdup (config, path);
-	else
-	    path = talloc_asprintf (config, "%s/mail",
-				    getenv ("HOME"));
-	notmuch_config_set_database_path (config, path);
-	talloc_free (path);
-    }
-
-    if (notmuch_config_get_user_name (config) == NULL) {
-	char *name = getenv ("NAME");
-	if (name)
-	    name = talloc_strdup (config, name);
-	else
-	    name = get_name_from_passwd_file (config);
-	notmuch_config_set_user_name (config, name);
-	talloc_free (name);
-    }
-
-    if (notmuch_config_get_user_primary_email (config) == NULL) {
-	char *email = getenv ("EMAIL");
-	if (email) {
-	    notmuch_config_set_user_primary_email (config, email);
-	} else {
-	    char hostname[256];
-	    struct hostent *hostent;
-	    const char *domainname;
-
-	    char *username = get_username_from_passwd_file (config);
-
-	    gethostname (hostname, 256);
-	    hostname[255] = '\0';
-
-	    hostent = gethostbyname (hostname);
-	    if (hostent && (domainname = strchr (hostent->h_name, '.')))
-		domainname += 1;
-	    else
-		domainname = "(none)";
-
-	    email = talloc_asprintf (config, "%s@%s.%s",
-				     username, hostname, domainname);
-
-	    notmuch_config_set_user_primary_email (config, email);
-
-	    talloc_free (username);
-	    talloc_free (email);
-	}
-    }
-
-    if (notmuch_config_get_new_tags (config, &tmp) == NULL) {
-	const char *tags[] = { "unread", "inbox" };
-	notmuch_config_set_new_tags (config, tags, 2);
-    }
-
-    if (notmuch_config_get_new_ignore (config, &tmp) == NULL) {
-	notmuch_config_set_new_ignore (config, NULL, 0);
-    }
-
-    if (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) {
-	if (config->is_new) {
-	    const char *tags[] = { "deleted", "spam" };
-	    notmuch_config_set_search_exclude_tags (config, tags, 2);
-	} else {
-	    notmuch_config_set_search_exclude_tags (config, NULL, 0);
-	}
-    }
-
-    error = NULL;
-    config->maildir_synchronize_flags =
-	g_key_file_get_boolean (config->key_file,
-				"maildir", "synchronize_flags", &error);
-    if (error) {
-	notmuch_config_set_maildir_synchronize_flags (config, true);
-	g_error_free (error);
-    }
-
-    /* Whenever we know of configuration sections that don't appear in
-     * the configuration file, we add some comments to help the user
-     * understand what can be done. */
     if (config->is_new)
 	g_key_file_set_comment (config->key_file, NULL, NULL,
 				toplevel_config_comment, NULL);
 
-    if (! file_had_database_group)
-	g_key_file_set_comment (config->key_file, "database", NULL,
-				database_config_comment, NULL);
-
-    if (! file_had_new_group)
-	g_key_file_set_comment (config->key_file, "new", NULL,
-				new_config_comment, NULL);
-
-    if (! file_had_user_group)
-	g_key_file_set_comment (config->key_file, "user", NULL,
-				user_config_comment, NULL);
-
-    if (! file_had_maildir_group)
-	g_key_file_set_comment (config->key_file, "maildir", NULL,
-				maildir_config_comment, NULL);
-
-    if (! file_had_search_group)
-	g_key_file_set_comment (config->key_file, "search", NULL,
-				search_config_comment, NULL);
-
-    if (! file_had_crypto_group)
-	g_key_file_set_comment (config->key_file, "crypto", NULL,
-				crypto_config_comment, NULL);
-
+    for (size_t i=0; i < ARRAY_SIZE (group_comment_table); i++) {
+	const char *name = group_comment_table[i].group_name;
+	if (! g_key_file_has_group (config->key_file,  name)) {
+	    /* Force group to exist before adding comment */
+	    g_key_file_set_value (config->key_file, name, "dummy_key", "dummy_val");
+	    g_key_file_remove_key (config->key_file, name, "dummy_key", NULL);
+	    g_key_file_set_comment (config->key_file, name, NULL,
+				    group_comment_table[i].comment, NULL);
+	}
+    }
     return config;
 }
 
diff --git a/notmuch.c b/notmuch.c
index 5e2cbdc8..6ff6473e 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -577,7 +577,7 @@ main (int argc, char *argv[])
     }
 
     if (command->mode & NOTMUCH_COMMAND_CONFIG_OPEN) {
-	config = notmuch_config_open (local, config_file_name, command->mode);
+	config = notmuch_config_open (notmuch, config_file_name, command->mode);
 	if (! config) {
 	    ret = EXIT_FAILURE;
 	    goto DONE;
diff --git a/test/T030-config.sh b/test/T030-config.sh
index ef615152..65cb189b 100755
--- a/test/T030-config.sh
+++ b/test/T030-config.sh
@@ -57,7 +57,7 @@ foo.list=this;is another;list value;
 foo.string=this is another string value
 maildir.synchronize_flags=true
 new.ignore=
-new.tags=unread;inbox;
+new.tags=unread;inbox
 search.exclude_tags=
 user.name=Notmuch Test Suite
 user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org
diff --git a/test/T590-libconfig.sh b/test/T590-libconfig.sh
index 292778d5..51dd29c8 100755
--- a/test/T590-libconfig.sh
+++ b/test/T590-libconfig.sh
@@ -394,8 +394,8 @@ MAIL_DIR
 MAIL_DIR/.notmuch/hooks
 MAIL_DIR/.notmuch/backups
 
-inbox;unread
-NULL
+unread;inbox
+
 true
 USERNAME@FQDN
 NULL
@@ -705,7 +705,7 @@ MAIL_DIR
 MAIL_DIR/.notmuch/hooks
 MAIL_DIR/.notmuch/backups
 foo;bar;fub
-unread;inbox;
+unread;inbox
 sekrit_junk
 true
 test_suite@notmuchmail.org
@@ -736,8 +736,8 @@ MAIL_DIR
 MAIL_DIR/.notmuch/hooks
 MAIL_DIR/.notmuch/backups
 
-inbox;unread
-NULL
+unread;inbox
+
 true
 USERNAME@FQDN
 NULL
@@ -815,7 +815,7 @@ database.path MAIL_DIR
 key with spaces value, with, spaces!
 maildir.synchronize_flags true
 new.ignore sekrit_junk
-new.tags unread;inbox;
+new.tags unread;inbox
 search.exclude_tags foo;bar;fub
 test.key1 testvalue1
 test.key2 testvalue2
diff --git a/test/setup.expected-output/config-with-comments b/test/setup.expected-output/config-with-comments
index d9f796f2..56c628e5 100644
--- a/test/setup.expected-output/config-with-comments
+++ b/test/setup.expected-output/config-with-comments
@@ -49,7 +49,6 @@ other_email=another.suite@example.com;
 #
 [new]
 tags=foo;bar;
-ignore=
 
 # Search configuration
 #
@@ -85,4 +84,3 @@ exclude_tags=baz;
 #	commands will notice tag changes and update flags in filenames
 #
 [maildir]
-synchronize_flags=true
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 16/27] CLI/config: use notmuch_database_reopen
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (14 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 15/27] CLI/config: migrate notmuch_config_open to new config David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 17/27] CLI/notmuch: switch notmuch_command to notmuch_config_get David Bremner
                   ` (11 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This allows `notmuch config` to use the common configuration
information carried by the notmuch_database_t opened at the top level.
---
 notmuch-config.c         | 16 +++++++---------
 test/T750-user-header.sh |  3 ++-
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/notmuch-config.c b/notmuch-config.c
index a46c639e..2ad3f52e 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -693,9 +693,8 @@ notmuch_config_command_get (notmuch_database_t *notmuch, char *item)
 }
 
 static int
-_set_db_config (notmuch_config_t *config, const char *key, int argc, char **argv)
+_set_db_config (notmuch_database_t *notmuch, const char *key, int argc, char **argv)
 {
-    notmuch_database_t *notmuch;
     const char *val = "";
 
     if (argc > 1) {
@@ -708,12 +707,11 @@ _set_db_config (notmuch_config_t *config, const char *key, int argc, char **argv
 	val = argv[0];
     }
 
-    if (notmuch_database_open (notmuch_config_get_database_path (config),
-			       NOTMUCH_DATABASE_MODE_READ_WRITE, &notmuch))
+    if (print_status_database ("notmuch config", notmuch,
+			       notmuch_database_reopen (notmuch,
+							NOTMUCH_DATABASE_MODE_READ_WRITE)))
 	return EXIT_FAILURE;
 
-    /* XXX Handle UUID mismatch? */
-
     if (print_status_database ("notmuch config", notmuch,
 			       notmuch_database_set_config (notmuch, key, val)))
 	return EXIT_FAILURE;
@@ -726,7 +724,7 @@ _set_db_config (notmuch_config_t *config, const char *key, int argc, char **argv
 }
 
 static int
-notmuch_config_command_set (notmuch_config_t *config, char *item, int argc, char *argv[])
+notmuch_config_command_set (notmuch_config_t *config, notmuch_database_t *notmuch, char *item, int argc, char *argv[])
 {
     char *group, *key;
     config_key_info_t *key_info;
@@ -741,7 +739,7 @@ notmuch_config_command_set (notmuch_config_t *config, char *item, int argc, char
 	return 1;
 
     if (key_info && key_info->in_db) {
-	return _set_db_config (config, item, argc, argv);
+	return _set_db_config (notmuch, item, argc, argv);
     }
 
     if (_item_split (item, &group, &key))
@@ -838,7 +836,7 @@ notmuch_config_command (notmuch_config_t *config, notmuch_database_t *notmuch, i
 		     "one argument.\n");
 	    return EXIT_FAILURE;
 	}
-	ret = notmuch_config_command_set (config, argv[1], argc - 2, argv + 2);
+	ret = notmuch_config_command_set (config, notmuch, argv[1], argc - 2, argv + 2);
     } else if (strcmp (argv[0], "list") == 0) {
 	ret = notmuch_config_command_list (notmuch);
     } else {
diff --git a/test/T750-user-header.sh b/test/T750-user-header.sh
index b19db571..586788b3 100755
--- a/test/T750-user-header.sh
+++ b/test/T750-user-header.sh
@@ -5,7 +5,8 @@ test_description='indexing user specified headers'
 test_begin_subtest "error adding user header before initializing DB"
 notmuch config set index.header.List List-Id 2>&1 | notmuch_dir_sanitize > OUTPUT
 cat <<EOF > EXPECTED
-Error: Cannot open database at MAIL_DIR/.notmuch: No such file or directory.
+notmuch config: Illegal argument for function
+Cannot reopen closed or nonexistent database
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 17/27] CLI/notmuch: switch notmuch_command to notmuch_config_get
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (15 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 16/27] CLI/config: use notmuch_database_reopen David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 18/27] CLI/config: drop obsolete notmuch_config_get_* David Bremner
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

The goal at this point is to remove the dependence on
notmuch_config_get_* without breaking any existing functionality. This
is a step towards removing notmuch_config_get_* in a future commit.
---
 notmuch.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/notmuch.c b/notmuch.c
index 6ff6473e..093af0a5 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -380,7 +380,7 @@ notmuch_command (notmuch_config_t *config,
 
     /* Notmuch is already configured, but is there a database? */
     db_path = talloc_asprintf (config, "%s/%s",
-			       notmuch_config_get_database_path (config),
+			       notmuch_config_get (notmuch, NOTMUCH_CONFIG_DATABASE_PATH),
 			       ".notmuch");
     if (stat (db_path, &st)) {
 	if (errno != ENOENT) {
@@ -411,8 +411,8 @@ notmuch_command (notmuch_config_t *config,
 	    "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),
-	    notmuch_config_get_user_primary_email (config));
+	    notmuch_config_get (notmuch, NOTMUCH_CONFIG_USER_NAME),
+	    notmuch_config_get (notmuch, NOTMUCH_CONFIG_PRIMARY_EMAIL));
 
     return EXIT_SUCCESS;
 }
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 18/27] CLI/config: drop obsolete notmuch_config_get_*
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (16 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 17/27] CLI/notmuch: switch notmuch_command to notmuch_config_get David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 19/27] CLI/config: drop cached data from notmuch_config_t David Bremner
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

These are no longer used, replaced by notmuch_config_get.
---
 notmuch-client.h |  29 ------------
 notmuch-config.c | 119 -----------------------------------------------
 2 files changed, 148 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index dfdfc876..677f2f39 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -275,70 +275,41 @@ notmuch_config_save (notmuch_config_t *config);
 bool
 notmuch_config_is_new (notmuch_config_t *config);
 
-const char *
-notmuch_config_get_database_path (notmuch_config_t *config);
-
 void
 notmuch_config_set_database_path (notmuch_config_t *config,
 				  const char *database_path);
 
-const char *
-notmuch_config_get_user_name (notmuch_config_t *config);
-
 void
 notmuch_config_set_user_name (notmuch_config_t *config,
 			      const char *user_name);
 
-const char *
-notmuch_config_get_user_primary_email (notmuch_config_t *config);
-
 void
 notmuch_config_set_user_primary_email (notmuch_config_t *config,
 				       const char *primary_email);
 
-const char **
-notmuch_config_get_user_other_email (notmuch_config_t *config,
-				     size_t *length);
-
 void
 notmuch_config_set_user_other_email (notmuch_config_t *config,
 				     const char *other_email[],
 				     size_t length);
 
-const char **
-notmuch_config_get_new_tags (notmuch_config_t *config,
-			     size_t *length);
 void
 notmuch_config_set_new_tags (notmuch_config_t *config,
 			     const char *new_tags[],
 			     size_t length);
 
-const char **
-notmuch_config_get_new_ignore (notmuch_config_t *config,
-			       size_t *length);
-
 void
 notmuch_config_set_new_ignore (notmuch_config_t *config,
 			       const char *new_ignore[],
 			       size_t length);
 
-bool
-notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config);
-
 void
 notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config,
 					      bool synchronize_flags);
 
-const char **
-notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t *length);
-
 void
 notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
 					const char *list[],
 					size_t length);
-const char *
-_notmuch_config_get_path (notmuch_config_t *config);
-
 int
 notmuch_run_hook (notmuch_database_t *notmuch, const char *hook);
 
diff --git a/notmuch-config.c b/notmuch-config.c
index 2ad3f52e..774c8936 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -327,9 +327,6 @@ notmuch_config_close (notmuch_config_t *config)
     talloc_free (config);
 }
 
-const char *_notmuch_config_get_path (notmuch_config_t *config) {
-    return config->filename;
-}
 /* Save any changes made to the notmuch configuration.
  *
  * Any comments originally in the file will be preserved.
@@ -393,22 +390,6 @@ notmuch_config_is_new (notmuch_config_t *config)
     return config->is_new;
 }
 
-static const char *
-_config_get (notmuch_config_t *config, char **field,
-	     const char *group, const char *key)
-{
-    /* read from config file and cache value, if not cached already */
-    if (*field == NULL) {
-	char *value;
-	value = g_key_file_get_string (config->key_file, group, key, NULL);
-	if (value) {
-	    *field = talloc_strdup (config, value);
-	    free (value);
-	}
-    }
-    return *field;
-}
-
 static void
 _config_set (notmuch_config_t *config, char **field,
 	     const char *group, const char *key, const char *value)
@@ -420,38 +401,6 @@ _config_set (notmuch_config_t *config, char **field,
     *field = NULL;
 }
 
-static const char **
-_config_get_list (notmuch_config_t *config,
-		  const char *section, const char *key,
-		  const char ***outlist, size_t *list_length, size_t *ret_length)
-{
-    assert (outlist);
-
-    /* read from config file and cache value, if not cached already */
-    if (*outlist == NULL) {
-
-	char **inlist = g_key_file_get_string_list (config->key_file,
-						    section, key, list_length, NULL);
-	if (inlist) {
-	    unsigned int i;
-
-	    *outlist = talloc_size (config, sizeof (char *) * (*list_length + 1));
-
-	    for (i = 0; i < *list_length; i++)
-		(*outlist)[i] = talloc_strdup (*outlist, inlist[i]);
-
-	    (*outlist)[i] = NULL;
-
-	    g_strfreev (inlist);
-	}
-    }
-
-    if (ret_length)
-	*ret_length = *list_length;
-
-    return *outlist;
-}
-
 static void
 _config_set_list (notmuch_config_t *config,
 		  const char *group, const char *key,
@@ -465,24 +414,6 @@ _config_set_list (notmuch_config_t *config,
     *config_var = NULL;
 }
 
-const char *
-notmuch_config_get_database_path (notmuch_config_t *config)
-{
-    char *db_path = (char *) _config_get (config, &config->database_path, "database", "path");
-
-    if (db_path && *db_path != '/') {
-	/* If the path in the configuration file begins with any
-	 * character other than /, presume that it is relative to
-	 * $HOME and update as appropriate.
-	 */
-	char *abs_path = talloc_asprintf (config, "%s/%s", getenv ("HOME"), db_path);
-	talloc_free (db_path);
-	db_path = config->database_path = abs_path;
-    }
-
-    return db_path;
-}
-
 void
 notmuch_config_set_database_path (notmuch_config_t *config,
 				  const char *database_path)
@@ -490,12 +421,6 @@ notmuch_config_set_database_path (notmuch_config_t *config,
     _config_set (config, &config->database_path, "database", "path", database_path);
 }
 
-const char *
-notmuch_config_get_user_name (notmuch_config_t *config)
-{
-    return _config_get (config, &config->user_name, "user", "name");
-}
-
 void
 notmuch_config_set_user_name (notmuch_config_t *config,
 			      const char *user_name)
@@ -503,12 +428,6 @@ notmuch_config_set_user_name (notmuch_config_t *config,
     _config_set (config, &config->user_name, "user", "name", user_name);
 }
 
-const char *
-notmuch_config_get_user_primary_email (notmuch_config_t *config)
-{
-    return _config_get (config, &config->user_primary_email, "user", "primary_email");
-}
-
 void
 notmuch_config_set_user_primary_email (notmuch_config_t *config,
 				       const char *primary_email)
@@ -516,30 +435,6 @@ notmuch_config_set_user_primary_email (notmuch_config_t *config,
     _config_set (config, &config->user_primary_email, "user", "primary_email", primary_email);
 }
 
-const char **
-notmuch_config_get_user_other_email (notmuch_config_t *config,   size_t *length)
-{
-    return _config_get_list (config, "user", "other_email",
-			     &(config->user_other_email),
-			     &(config->user_other_email_length), length);
-}
-
-const char **
-notmuch_config_get_new_tags (notmuch_config_t *config,   size_t *length)
-{
-    return _config_get_list (config, "new", "tags",
-			     &(config->new_tags),
-			     &(config->new_tags_length), length);
-}
-
-const char **
-notmuch_config_get_new_ignore (notmuch_config_t *config, size_t *length)
-{
-    return _config_get_list (config, "new", "ignore",
-			     &(config->new_ignore),
-			     &(config->new_ignore_length), length);
-}
-
 void
 notmuch_config_set_user_other_email (notmuch_config_t *config,
 				     const char *list[],
@@ -567,14 +462,6 @@ notmuch_config_set_new_ignore (notmuch_config_t *config,
 		      &(config->new_ignore));
 }
 
-const char **
-notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t *length)
-{
-    return _config_get_list (config, "search", "exclude_tags",
-			     &(config->search_exclude_tags),
-			     &(config->search_exclude_tags_length), length);
-}
-
 void
 notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
 					const char *list[],
@@ -849,12 +736,6 @@ notmuch_config_command (notmuch_config_t *config, notmuch_database_t *notmuch, i
 
 }
 
-bool
-notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config)
-{
-    return config->maildir_synchronize_flags;
-}
-
 void
 notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config,
 					      bool synchronize_flags)
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 19/27] CLI/config: drop cached data from notmuch_config_t
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (17 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 18/27] CLI/config: drop obsolete notmuch_config_get_* David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 20/27] CLI/config: default to storing all config in external files David Bremner
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

The idea is to preserve notmuch_config_t as a thin wrapper for GKeyFile.
---
 notmuch-config.c | 48 +++++++++---------------------------------------
 1 file changed, 9 insertions(+), 39 deletions(-)

diff --git a/notmuch-config.c b/notmuch-config.c
index 774c8936..93a1018e 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -118,19 +118,6 @@ struct _notmuch_config {
     char *filename;
     GKeyFile *key_file;
     bool is_new;
-
-    char *database_path;
-    char *user_name;
-    char *user_primary_email;
-    const char **user_other_email;
-    size_t user_other_email_length;
-    const char **new_tags;
-    size_t new_tags_length;
-    const char **new_ignore;
-    size_t new_ignore_length;
-    bool maildir_synchronize_flags;
-    const char **search_exclude_tags;
-    size_t search_exclude_tags_length;
 };
 
 static int
@@ -142,7 +129,6 @@ notmuch_config_destructor (notmuch_config_t *config)
     return 0;
 }
 
-
 static bool
 get_config_from_file (notmuch_config_t *config, bool create_new)
 {
@@ -275,9 +261,6 @@ notmuch_config_open (notmuch_database_t *notmuch,
 
     talloc_set_destructor (config, notmuch_config_destructor);
 
-    /* non-zero defaults */
-    config->maildir_synchronize_flags = true;
-
     if (filename) {
 	config->filename = talloc_strdup (config, filename);
     } else if ((notmuch_config_env = getenv ("NOTMUCH_CONFIG"))) {
@@ -391,48 +374,40 @@ notmuch_config_is_new (notmuch_config_t *config)
 }
 
 static void
-_config_set (notmuch_config_t *config, char **field,
+_config_set (notmuch_config_t *config,
 	     const char *group, const char *key, const char *value)
 {
     g_key_file_set_string (config->key_file, group, key, value);
-
-    /* drop the cached value */
-    talloc_free (*field);
-    *field = NULL;
 }
 
 static void
 _config_set_list (notmuch_config_t *config,
 		  const char *group, const char *key,
 		  const char *list[],
-		  size_t length, const char ***config_var )
+		  size_t length)
 {
     g_key_file_set_string_list (config->key_file, group, key, list, length);
-
-    /* drop the cached value */
-    talloc_free (*config_var);
-    *config_var = NULL;
 }
 
 void
 notmuch_config_set_database_path (notmuch_config_t *config,
 				  const char *database_path)
 {
-    _config_set (config, &config->database_path, "database", "path", database_path);
+    _config_set (config, "database", "path", database_path);
 }
 
 void
 notmuch_config_set_user_name (notmuch_config_t *config,
 			      const char *user_name)
 {
-    _config_set (config, &config->user_name, "user", "name", user_name);
+    _config_set (config, "user", "name", user_name);
 }
 
 void
 notmuch_config_set_user_primary_email (notmuch_config_t *config,
 				       const char *primary_email)
 {
-    _config_set (config, &config->user_primary_email, "user", "primary_email", primary_email);
+    _config_set (config, "user", "primary_email", primary_email);
 }
 
 void
@@ -440,8 +415,7 @@ notmuch_config_set_user_other_email (notmuch_config_t *config,
 				     const char *list[],
 				     size_t length)
 {
-    _config_set_list (config, "user", "other_email", list, length,
-		      &(config->user_other_email));
+    _config_set_list (config, "user", "other_email", list, length);
 }
 
 void
@@ -449,8 +423,7 @@ notmuch_config_set_new_tags (notmuch_config_t *config,
 			     const char *list[],
 			     size_t length)
 {
-    _config_set_list (config, "new", "tags", list, length,
-		      &(config->new_tags));
+    _config_set_list (config, "new", "tags", list, length);
 }
 
 void
@@ -458,8 +431,7 @@ notmuch_config_set_new_ignore (notmuch_config_t *config,
 			       const char *list[],
 			       size_t length)
 {
-    _config_set_list (config, "new", "ignore", list, length,
-		      &(config->new_ignore));
+    _config_set_list (config, "new", "ignore", list, length);
 }
 
 void
@@ -467,8 +439,7 @@ notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
 					const char *list[],
 					size_t length)
 {
-    _config_set_list (config, "search", "exclude_tags", list, length,
-		      &(config->search_exclude_tags));
+    _config_set_list (config, "search", "exclude_tags", list, length);
 }
 
 
@@ -742,5 +713,4 @@ notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config,
 {
     g_key_file_set_boolean (config->key_file,
 			    "maildir", "synchronize_flags", synchronize_flags);
-    config->maildir_synchronize_flags = synchronize_flags;
 }
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 20/27] CLI/config: default to storing all config in external files
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (18 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 19/27] CLI/config: drop cached data from notmuch_config_t David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 21/27] lib: add NOTMUCH_STATUS_NO_DATABASE David Bremner
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Previously the fact that some configuration options were only stored
in the database (and thus editing the config file had no effect) was a
source of user confusion. This was fixed with the series ending at
d9af0af1646.

On the other hand, the underlying partition of config options into
those stored by default in the database and those stored in the config
file remained. This is also confusing, since now some invocations of
"notmuch config set" modify the config file, and others silently
modify the database instead.

With this commit, it is up to the user to decide which configuration
to modify. A new "--database" option is provided for notmuch config to
enable modifying the configuration information in the database.
---
 doc/man1/notmuch-config.rst |  6 ++++-
 doc/man1/notmuch.rst        |  4 +++-
 notmuch-config.c            | 44 +++++++++++++++++++++++++++----------
 test/T030-config.sh         | 20 +++++++++++++++++
 test/T600-named-queries.sh  | 17 ++++++--------
 test/T750-user-header.sh    |  8 -------
 6 files changed, 67 insertions(+), 32 deletions(-)

diff --git a/doc/man1/notmuch-config.rst b/doc/man1/notmuch-config.rst
index 99030a41..2a155632 100644
--- a/doc/man1/notmuch-config.rst
+++ b/doc/man1/notmuch-config.rst
@@ -7,7 +7,7 @@ SYNOPSIS
 
 **notmuch** **config** **get** <*section*>.<*item*>
 
-**notmuch** **config** **set** <*section*>.<*item*> [*value* ...]
+**notmuch** **config** **set** [--database] <*section*>.<*item*> [*value* ...]
 
 **notmuch** **config** **list**
 
@@ -30,6 +30,10 @@ configuration file and corresponding database.
     If no values are provided, the specified configuration item will
     be removed from the configuration file.
 
+    With the `--database` option, updates configuration metadata
+    stored in the database, rather than the default (text)
+    configuration file.
+
 **list**
     Every configuration item is printed to stdout, each on a separate
     line of the form::
diff --git a/doc/man1/notmuch.rst b/doc/man1/notmuch.rst
index fecfd08a..48351588 100644
--- a/doc/man1/notmuch.rst
+++ b/doc/man1/notmuch.rst
@@ -48,7 +48,9 @@ Supported global options for ``notmuch`` include
 
 ``--config=FILE``
     Specify the configuration file to use. This overrides any
-    configuration file specified by ${NOTMUCH\_CONFIG}.
+    configuration file specified by ${NOTMUCH\_CONFIG}. The empty
+    string is a permitted and sometimes useful value of *FILE*, which
+    tells ``notmuch`` to use only configuration metadata from the database.
 
 ``--uuid=HEX``
     Enforce that the database UUID (a unique identifier which persists
diff --git a/notmuch-config.c b/notmuch-config.c
index 93a1018e..5ba62819 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -511,16 +511,15 @@ validate_field_name (const char *str)
 
 typedef struct config_key {
     const char *name;
-    bool in_db;
     bool prefix;
     bool (*validate)(const char *);
 } config_key_info_t;
 
 static struct config_key
     config_key_table[] = {
-    { "index.decrypt",   true,   false,  NULL },
-    { "index.header.",   true,   true,   validate_field_name },
-    { "query.",          true,   true,   NULL },
+    { "index.decrypt",   false,  NULL },
+    { "index.header.",   true,   validate_field_name },
+    { "query.",          true,   NULL },
 };
 
 static config_key_info_t *
@@ -582,10 +581,36 @@ _set_db_config (notmuch_database_t *notmuch, const char *key, int argc, char **a
 }
 
 static int
-notmuch_config_command_set (notmuch_config_t *config, notmuch_database_t *notmuch, char *item, int argc, char *argv[])
+notmuch_config_command_set (notmuch_config_t *config, notmuch_database_t *notmuch,
+			    int argc, char *argv[])
 {
     char *group, *key;
     config_key_info_t *key_info;
+    bool update_database = false;
+    int opt_index;
+    char *item;
+
+    notmuch_opt_desc_t options[] = {
+	{ .opt_bool = &update_database, .name = "database" },
+	{ }
+    };
+
+    opt_index = parse_arguments (argc, argv, options, 1);
+    if (opt_index < 0)
+	return EXIT_FAILURE;
+
+    argc -= opt_index;
+    argv += opt_index;
+
+    if (argc < 1) {
+	fprintf (stderr, "Error: notmuch config set requires at least "
+		 "one argument.\n");
+	return EXIT_FAILURE;
+    }
+
+    item = argv[0];
+    argv++;
+    argc--;
 
     if (STRNCMP_LITERAL (item, BUILT_WITH_PREFIX) == 0) {
 	fprintf (stderr, "Error: read only option: %s\n", item);
@@ -596,7 +621,7 @@ notmuch_config_command_set (notmuch_config_t *config, notmuch_database_t *notmuc
     if (key_info && key_info->validate && (! key_info->validate (item)))
 	return 1;
 
-    if (key_info && key_info->in_db) {
+    if (update_database) {
 	return _set_db_config (notmuch, item, argc, argv);
     }
 
@@ -689,12 +714,7 @@ notmuch_config_command (notmuch_config_t *config, notmuch_database_t *notmuch, i
 	}
 	ret = notmuch_config_command_get (notmuch, argv[1]);
     } else if (strcmp (argv[0], "set") == 0) {
-	if (argc < 2) {
-	    fprintf (stderr, "Error: notmuch config set requires at least "
-		     "one argument.\n");
-	    return EXIT_FAILURE;
-	}
-	ret = notmuch_config_command_set (config, notmuch, argv[1], argc - 2, argv + 2);
+	ret = notmuch_config_command_set (config, notmuch, argc, argv);
     } else if (strcmp (argv[0], "list") == 0) {
 	ret = notmuch_config_command_list (notmuch);
     } else {
diff --git a/test/T030-config.sh b/test/T030-config.sh
index 65cb189b..c7d72455 100755
--- a/test/T030-config.sh
+++ b/test/T030-config.sh
@@ -124,4 +124,24 @@ count=$(notmuch count '*')
 test_expect_equal "${path} ${count}" \
 		  "Maildir 52"
 
+test_begin_subtest "Add config to database"
+notmuch new
+key=g${RANDOM}.m${RANDOM}
+value=${RANDOM}
+notmuch config set --database ${key} ${value}
+notmuch dump --include=config > OUTPUT
+cat <<EOF > EXPECTED
+#notmuch-dump batch-tag:3 config
+#@ ${key} ${value}
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "Roundtrip config to/from database"
+notmuch new
+key=g${RANDOM}.m${RANDOM}
+value=${RANDOM}
+notmuch config set --database ${key} ${value}
+output=$(notmuch config get ${key})
+test_expect_equal "${output}" "${value}"
+
 test_done
diff --git a/test/T600-named-queries.sh b/test/T600-named-queries.sh
index 0ae8b83d..a7b84995 100755
--- a/test/T600-named-queries.sh
+++ b/test/T600-named-queries.sh
@@ -4,13 +4,13 @@ test_description='named queries'
 
 QUERYSTR="date:2009-11-18..2009-11-18 and tag:unread"
 
-test_begin_subtest "error adding named query before initializing DB"
-test_expect_code 1 "notmuch config set query.test \"$QUERYSTR\""
+test_begin_subtest "error adding named query to DB before initialization"
+test_expect_code 1 "notmuch config set --database query.test \"$QUERYSTR\""
 
 add_email_corpus
 
-test_begin_subtest "adding named query"
-test_expect_success "notmuch config set query.test \"$QUERYSTR\""
+test_begin_subtest "adding named query (database)"
+test_expect_success "notmuch config set --database query.test \"$QUERYSTR\""
 
 test_begin_subtest "adding nested named query"
 QUERYSTR2="query:test and subject:Maildir"
@@ -32,7 +32,6 @@ 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
 
@@ -40,23 +39,21 @@ test_begin_subtest 'dumping large queries'
 # This value is just large enough to trigger a limitation of gzprintf
 # to 8191 bytes in total (by default).
 repeat=1329
-notmuch config set query.big "$(seq -s' ' $repeat)"
+notmuch config set --database query.big "$(seq -s' ' $repeat)"
 notmuch dump --include=config > OUTPUT
-notmuch config set query.big ''
+notmuch config set --database query.big
 printf "#notmuch-dump batch-tag:3 config\n#@ query.big " > EXPECTED
 seq -s'%20' $repeat >> EXPECTED
 cat <<EOF >> EXPECTED
 #@ query.test date%3a2009-11-18..2009-11-18%20and%20tag%3aunread
-#@ query.test2 query%3atest%20and%20subject%3aMaildir
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
 test_begin_subtest "delete named queries"
 notmuch dump > BEFORE
-notmuch config set query.test
+notmuch config set --database query.test
 notmuch dump | grep '^#@' > OUTPUT
 cat<<EOF > EXPECTED
-#@ query.test2 query%3atest%20and%20subject%3aMaildir
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
diff --git a/test/T750-user-header.sh b/test/T750-user-header.sh
index 586788b3..05f80885 100755
--- a/test/T750-user-header.sh
+++ b/test/T750-user-header.sh
@@ -2,14 +2,6 @@
 test_description='indexing user specified headers'
 . $(dirname "$0")/test-lib.sh || exit 1
 
-test_begin_subtest "error adding user header before initializing DB"
-notmuch config set index.header.List List-Id 2>&1 | notmuch_dir_sanitize > OUTPUT
-cat <<EOF > EXPECTED
-notmuch config: Illegal argument for function
-Cannot reopen closed or nonexistent database
-EOF
-test_expect_equal_file EXPECTED OUTPUT
-
 add_email_corpus
 
 notmuch search '*' | notmuch_search_sanitize > initial-threads
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 21/27] lib: add NOTMUCH_STATUS_NO_DATABASE
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (19 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 20/27] CLI/config: default to storing all config in external files David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 22/27] CLI+lib: detect missing database in split configurations David Bremner
                   ` (6 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This will allow more precise return values from various open related functions.
---
 bindings/python-cffi/notmuch2/_build.py  | 1 +
 bindings/python-cffi/notmuch2/_errors.py | 3 +++
 lib/database.cc                          | 2 ++
 lib/notmuch-private.h                    | 1 +
 lib/notmuch.h                            | 4 ++++
 5 files changed, 11 insertions(+)

diff --git a/bindings/python-cffi/notmuch2/_build.py b/bindings/python-cffi/notmuch2/_build.py
index f67b4de6..f712b6c5 100644
--- a/bindings/python-cffi/notmuch2/_build.py
+++ b/bindings/python-cffi/notmuch2/_build.py
@@ -51,6 +51,7 @@ ffibuilder.cdef(
         NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION,
         NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL,
         NOTMUCH_STATUS_NO_CONFIG,
+        NOTMUCH_STATUS_NO_DATABASE,
         NOTMUCH_STATUS_DATABASE_EXISTS,
         NOTMUCH_STATUS_LAST_STATUS
     } notmuch_status_t;
diff --git a/bindings/python-cffi/notmuch2/_errors.py b/bindings/python-cffi/notmuch2/_errors.py
index 65064d4e..9301073e 100644
--- a/bindings/python-cffi/notmuch2/_errors.py
+++ b/bindings/python-cffi/notmuch2/_errors.py
@@ -52,6 +52,8 @@ class NotmuchError(Exception):
                 IllegalArgumentError,
             capi.lib.NOTMUCH_STATUS_NO_CONFIG:
                 NoConfigError,
+            capi.lib.NOTMUCH_STATUS_NO_DATABASE:
+                NoDatabaseError,
             capi.lib.NOTMUCH_STATUS_DATABASE_EXISTS:
                 DatabaseExistsError,
         }
@@ -99,6 +101,7 @@ class UpgradeRequiredError(NotmuchError): pass
 class PathError(NotmuchError): pass
 class IllegalArgumentError(NotmuchError): pass
 class NoConfigError(NotmuchError): pass
+class NoDatabaseError(NotmuchError): pass
 class DatabaseExistsError(NotmuchError): pass
 
 class ObjectDestroyedError(NotmuchError):
diff --git a/lib/database.cc b/lib/database.cc
index 87ad1385..4c00ff60 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -304,6 +304,8 @@ notmuch_status_to_string (notmuch_status_t status)
 	return "Unknown crypto protocol";
     case NOTMUCH_STATUS_NO_CONFIG:
 	return "No configuration file found";
+    case NOTMUCH_STATUS_NO_DATABASE:
+	return "No configuration file found";
     case NOTMUCH_STATUS_DATABASE_EXISTS:
 	return "Database exists, not recreated";
     default:
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index b884f060..483974b8 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -142,6 +142,7 @@ typedef enum _notmuch_private_status {
     NOTMUCH_PRIVATE_STATUS_FAILED_CRYPTO_CONTEXT_CREATION	= NOTMUCH_STATUS_FAILED_CRYPTO_CONTEXT_CREATION,
     NOTMUCH_PRIVATE_STATUS_UNKNOWN_CRYPTO_PROTOCOL		= NOTMUCH_STATUS_UNKNOWN_CRYPTO_PROTOCOL,
     NOTMUCH_PRIVATE_STATUS_NO_CONFIG				= NOTMUCH_STATUS_NO_CONFIG,
+    NOTMUCH_PRIVATE_STATUS_NO_DATABASE				= NOTMUCH_STATUS_NO_DATABASE,
     NOTMUCH_PRIVATE_STATUS_DATABASE_EXISTS			= NOTMUCH_STATUS_DATABASE_EXISTS,
 
     /* Then add our own private values. */
diff --git a/lib/notmuch.h b/lib/notmuch.h
index f050d2b6..2172d8c8 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -212,6 +212,10 @@ typedef enum _notmuch_status {
      * Unable to load a config file
      */
     NOTMUCH_STATUS_NO_CONFIG,
+    /**
+     * Unable to load a database
+     */
+    NOTMUCH_STATUS_NO_DATABASE,
     /**
      * Database exists, so not (re)-created
      */
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 22/27] CLI+lib: detect missing database in split configurations.
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (20 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 21/27] lib: add NOTMUCH_STATUS_NO_DATABASE David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 23/27] lib: provide notmuch_config_path David Bremner
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Eventually we want to do all opening of databases in the top
level (main function). This means that detection of missing databases
needs to move out of subcommands. It also requires updating the
library to use the new NO_DATABASE status code.
---
 lib/open.cc              | 24 ++++++++++++-------
 notmuch.c                | 52 ++++++++++++++++------------------------
 test/T040-setup.sh       |  7 ++----
 test/T055-path-config.sh | 16 +++++++++++++
 4 files changed, 54 insertions(+), 45 deletions(-)

diff --git a/lib/open.cc b/lib/open.cc
index 737e79a7..3c88ff80 100644
--- a/lib/open.cc
+++ b/lib/open.cc
@@ -209,8 +209,8 @@ _choose_database_path (void * ctx,
     }
 
     if (*database_path == NULL) {
-	*message = strdup ("Error: Cannot open a database for a NULL path.\n");
-	return NOTMUCH_STATUS_NULL_POINTER;
+	*message = strdup ("Error: could not locate database.\n");
+	return NOTMUCH_STATUS_NO_DATABASE;
     }
 
     if (*database_path[0] != '/') {
@@ -726,12 +726,12 @@ _maybe_load_config_from_database (notmuch_database_t *notmuch,
     char *message; /* ignored */
 
     if (_db_dir_exists (database_path, &message))
-	return NOTMUCH_STATUS_SUCCESS;
+	return NOTMUCH_STATUS_NO_DATABASE;
 
     _set_database_path (notmuch, database_path);
 
     if (_notmuch_choose_xapian_path (notmuch, database_path, &notmuch->xapian_path, &message))
-	return NOTMUCH_STATUS_SUCCESS;
+	return NOTMUCH_STATUS_NO_DATABASE;
 
     (void) _finish_open (notmuch, profile, NOTMUCH_DATABASE_MODE_READ_ONLY, key_file, &message);
 
@@ -774,19 +774,27 @@ notmuch_database_load_config (const char *database_path,
     status = _choose_database_path (local, profile, key_file,
 				    &database_path, &split, &message);
     switch (status) {
-	/* weirdly NULL_POINTER is what is returned if we fail to find
-	 * a database */
-    case NOTMUCH_STATUS_NULL_POINTER:
+    case NOTMUCH_STATUS_NO_DATABASE:
     case NOTMUCH_STATUS_SUCCESS:
+	if (! status2)
+	    status2 = status;
 	break;
     default:
 	goto DONE;
     }
 
+
     if (database_path) {
 	status = _maybe_load_config_from_database (notmuch, key_file, database_path, profile);
-	if (status)
+	switch (status) {
+	case NOTMUCH_STATUS_NO_DATABASE:
+	case NOTMUCH_STATUS_SUCCESS:
+	    if (! status2)
+		status2 = status;
+	    break;
+	default:
 	    goto DONE;
+	}
     }
 
     if (key_file) {
diff --git a/notmuch.c b/notmuch.c
index 093af0a5..fa6b7eaa 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -369,34 +369,12 @@ notmuch_command (notmuch_config_t *config,
 		 notmuch_database_t *notmuch,
 		 unused(int argc), unused(char **argv))
 {
-    char *db_path;
-    struct stat st;
-
     /* If the user has never configured notmuch, then run
      * notmuch_setup_command which will give a nice welcome message,
      * and interactively guide the user through the configuration. */
     if (notmuch_config_is_new (config))
 	return notmuch_setup_command (config, notmuch, 0, NULL);
 
-    /* Notmuch is already configured, but is there a database? */
-    db_path = talloc_asprintf (config, "%s/%s",
-			       notmuch_config_get (notmuch, NOTMUCH_CONFIG_DATABASE_PATH),
-			       ".notmuch");
-    if (stat (db_path, &st)) {
-	if (errno != ENOENT) {
-	    fprintf (stderr, "Error looking for notmuch database at %s: %s\n",
-		     db_path, strerror (errno));
-	    return EXIT_FAILURE;
-	}
-	printf ("Notmuch is configured, but there's not yet a database at\n\n\t%s\n\n",
-		db_path);
-	printf ("You probably want to run \"notmuch new\" now to create that database.\n\n"
-		"Note that the first run of \"notmuch new\" can take a very long time\n"
-		"and that the resulting database will use roughly the same amount of\n"
-		"storage space as the email being indexed.\n\n");
-	return EXIT_SUCCESS;
-    }
-
     printf ("Notmuch is configured and appears to have a database. Excellent!\n\n"
 	    "At this point you can start exploring the functionality of notmuch by\n"
 	    "using commands such as:\n\n"
@@ -561,19 +539,29 @@ main (int argc, char *argv[])
 					       &notmuch,
 					       &status_string);
 
-	if (status == NOTMUCH_STATUS_NO_CONFIG && !(command->mode & NOTMUCH_COMMAND_CONFIG_CREATE)) {
-	    fputs ("Try running 'notmuch setup' to create a configuration.", stderr);
-	    goto DONE;
-	}
-
-	if (status && (status != NOTMUCH_STATUS_NO_CONFIG)) {
-	    if (status_string) {
-		fputs (status_string, stderr);
-		free (status_string);
+	switch (status) {
+	case NOTMUCH_STATUS_NO_CONFIG:
+	    if (!(command->mode & NOTMUCH_COMMAND_CONFIG_CREATE)) {
+		fputs ("Try running 'notmuch setup' to create a configuration.", stderr);
+		goto DONE;
 	    }
+	    break;
+	case NOTMUCH_STATUS_NO_DATABASE:
+	    if (! command_name) {
+		printf ("Notmuch is configured, but no database was found.\n");
+		printf ("You probably want to run \"notmuch new\" now to create a database.\n\n"
+			"Note that the first run of \"notmuch new\" can take a very long time\n"
+			"and that the resulting database will use roughly the same amount of\n"
+			"storage space as the email being indexed.\n\n");
+		status = NOTMUCH_STATUS_SUCCESS;
+		goto DONE;
+	    }
+	    break;
+	case NOTMUCH_STATUS_SUCCESS:
+	    break;
+	default:
 	    goto DONE;
 	}
-
     }
 
     if (command->mode & NOTMUCH_COMMAND_CONFIG_OPEN) {
diff --git a/test/T040-setup.sh b/test/T040-setup.sh
index daeca3e4..42c621c8 100755
--- a/test/T040-setup.sh
+++ b/test/T040-setup.sh
@@ -26,11 +26,8 @@ test_expect_equal_file ${expected_dir}/config-with-comments new-notmuch-config
 test_begin_subtest "notmuch with a config but without a database suggests notmuch new"
 notmuch 2>&1 | notmuch_dir_sanitize > OUTPUT
 cat <<EOF > EXPECTED
-Notmuch is configured, but there's not yet a database at
-
-	MAIL_DIR/.notmuch
-
-You probably want to run "notmuch new" now to create that database.
+Notmuch is configured, but no database was found.
+You probably want to run "notmuch new" now to create a database.
 
 Note that the first run of "notmuch new" can take a very long time
 and that the resulting database will use roughly the same amount of
diff --git a/test/T055-path-config.sh b/test/T055-path-config.sh
index d8828342..0a34e67f 100755
--- a/test/T055-path-config.sh
+++ b/test/T055-path-config.sh
@@ -199,6 +199,22 @@ EOF
 	"$output" \
 	"Welcome to a new version of notmuch! Your database will now be upgraded."
 
+    test_begin_subtest "notmuch +config -database suggests notmuch new ($config)"
+    mv "$XAPIAN_PATH" "${XAPIAN_PATH}.bak"
+    notmuch > OUTPUT
+cat <<EOF > EXPECTED
+Notmuch is configured, but no database was found.
+You probably want to run "notmuch new" now to create a database.
+
+Note that the first run of "notmuch new" can take a very long time
+and that the resulting database will use roughly the same amount of
+storage space as the email being indexed.
+
+EOF
+    mv "${XAPIAN_PATH}.bak" "$XAPIAN_PATH"
+
+   test_expect_equal_file EXPECTED OUTPUT
+
     restore_config
 done
 
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 23/27] lib: provide notmuch_config_path
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (21 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 22/27] CLI+lib: detect missing database in split configurations David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 24/27] CLI/config: support set/get with split configuration David Bremner
                   ` (4 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

Since the library searches in several locations for a config file, the
caller does not know which of these is chosen in the usual case of
passing NULL as a config file. This changes provides an API for the
caller to retrieve the name of the config file chosen. It will be
tested in a following commit.
---
 lib/config.cc          |  5 +++++
 lib/database-private.h |  3 +++
 lib/notmuch.h          | 16 +++++++++++++++-
 lib/open.cc            | 36 +++++++++++++++++++++---------------
 4 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/lib/config.cc b/lib/config.cc
index 855816c1..8aabba5e 100644
--- a/lib/config.cc
+++ b/lib/config.cc
@@ -627,6 +627,11 @@ notmuch_config_get (notmuch_database_t *notmuch, notmuch_config_key_t key) {
     return _notmuch_string_map_get (notmuch->config, _notmuch_config_key_to_string (key));
 }
 
+const char *
+notmuch_config_path (notmuch_database_t *notmuch) {
+    return notmuch->config_path;
+}
+
 notmuch_status_t
 notmuch_config_set (notmuch_database_t *notmuch, notmuch_config_key_t key, const char *val) {
 
diff --git a/lib/database-private.h b/lib/database-private.h
index 2900382d..0d12ec1e 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -192,6 +192,9 @@ struct _notmuch_database {
     /* Path to actual database */
     const char *xapian_path;
 
+    /* Path to config loaded, if any */
+    const char *config_path;
+
     int atomic_nesting;
     /* true if changes have been made in this atomic section */
     bool atomic_dirty;
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 2172d8c8..37c42b1a 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -454,7 +454,12 @@ notmuch_database_open_with_config (const char *database_path,
  *
  * For description of arguments, @see notmuch_database_open_with_config
  *
- * @retval NOTMUCH_STATUS_SUCCESS: Successfully loaded (some) configuration.
+ * @retval NOTMUCH_STATUS_SUCCESS: Successfully loaded configuration.
+ *
+ * @retval NOTMUCH_STATUS_NO_CONFIG: No config file was loaded. Not fatal.
+ *
+ * @retval NOTMUCH_STATUS_NO_DATABASE: No config information was
+ *	loaded from a database. Not fatal.
  *
  * @retval NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory.
  *
@@ -2682,6 +2687,15 @@ notmuch_status_t
 notmuch_config_get_bool (notmuch_database_t *notmuch,
 			 notmuch_config_key_t key,
 			 notmuch_bool_t *val);
+
+/**
+ * return the path of the config file loaded, if any
+ *
+ * @retval NULL if no config file was loaded
+ */
+const char *
+notmuch_config_path (notmuch_database_t *notmuch);
+
 /**
  * get the current default indexing options for a given database.
  *
diff --git a/lib/open.cc b/lib/open.cc
index 3c88ff80..95bfadd0 100644
--- a/lib/open.cc
+++ b/lib/open.cc
@@ -113,12 +113,12 @@ _choose_dir (notmuch_database_t *notmuch,
 }
 
 static notmuch_status_t
-_load_key_file (const char *path,
+_load_key_file (notmuch_database_t *notmuch,
+		const char *path,
 		const char *profile,
 		GKeyFile **key_file)
 {
     notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;
-    void *local = talloc_new (NULL);
 
     if (path && EMPTY_STRING (path))
 	goto DONE;
@@ -126,11 +126,13 @@ _load_key_file (const char *path,
     if (! path)
 	path = getenv ("NOTMUCH_CONFIG");
 
-    if (! path) {
-	const char *dir = _xdg_dir (local, "XDG_CONFIG_HOME", ".config", profile);
+    if (path)
+	path = talloc_strdup (notmuch, path);
+    else {
+	const char *dir = _xdg_dir (notmuch, "XDG_CONFIG_HOME", ".config", profile);
 
 	if (dir) {
-	    path = talloc_asprintf (local, "%s/config", dir);
+	    path = talloc_asprintf (notmuch, "%s/config", dir);
 	    if (access (path, R_OK) !=0)
 		path = NULL;
 	}
@@ -139,13 +141,13 @@ _load_key_file (const char *path,
     if (! path) {
 	const char *home = getenv ("HOME");
 
-	path = talloc_asprintf (local, "%s/.notmuch-config", home);
+	path = talloc_asprintf (notmuch, "%s/.notmuch-config", home);
 
 	if (! profile)
 	    profile = getenv ("NOTMUCH_PROFILE");
 
 	if (profile)
-	    path = talloc_asprintf (local, "%s.%s", path, profile);
+	    path = talloc_asprintf (notmuch, "%s.%s", path, profile);
     }
 
     *key_file = g_key_file_new ();
@@ -154,7 +156,9 @@ _load_key_file (const char *path,
     }
 
 DONE:
-    talloc_free (local);
+    if (path)
+	notmuch->config_path = path;
+
     return status;
 }
 
@@ -229,6 +233,7 @@ notmuch_database_t * _alloc_notmuch() {
     notmuch->exception_reported = false;
     notmuch->status_string = NULL;
     notmuch->writable_xapian_db = NULL;
+    notmuch->config_path = NULL;
     notmuch->atomic_nesting = 0;
     notmuch->view = 1;
     return notmuch;
@@ -480,7 +485,7 @@ notmuch_database_open_with_config (const char *database_path,
 	goto DONE;
     }
 
-    status =_load_key_file (config_path, profile, &key_file);
+    status =_load_key_file (notmuch, config_path, profile, &key_file);
     if (status) {
 	message = strdup ("Error: cannot load config file.\n");
 	goto DONE;
@@ -573,7 +578,7 @@ notmuch_database_create_with_config (const char *database_path,
 	goto DONE;
     }
 
-    status =_load_key_file (config_path, profile, &key_file);
+    status =_load_key_file (notmuch, config_path, profile, &key_file);
     if (status) {
 	message = strdup ("Error: cannot load config file.\n");
 	goto DONE;
@@ -760,9 +765,10 @@ notmuch_database_load_config (const char *database_path,
 	goto DONE;
     }
 
-    status =_load_key_file (config_path, profile, &key_file);
+    status =_load_key_file (notmuch, config_path, profile, &key_file);
     switch (status) {
     case NOTMUCH_STATUS_SUCCESS:
+	break;
     case NOTMUCH_STATUS_NO_CONFIG:
 	warning = status;
 	break;
@@ -776,8 +782,8 @@ notmuch_database_load_config (const char *database_path,
     switch (status) {
     case NOTMUCH_STATUS_NO_DATABASE:
     case NOTMUCH_STATUS_SUCCESS:
-	if (! status2)
-	    status2 = status;
+	if (! warning)
+	    warning = status;
 	break;
     default:
 	goto DONE;
@@ -789,8 +795,8 @@ notmuch_database_load_config (const char *database_path,
 	switch (status) {
 	case NOTMUCH_STATUS_NO_DATABASE:
 	case NOTMUCH_STATUS_SUCCESS:
-	    if (! status2)
-		status2 = status;
+	    if (! warning)
+		warning = status;
 	    break;
 	default:
 	    goto DONE;
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 24/27] CLI/config: support set/get with split configuration
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (22 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 23/27] lib: provide notmuch_config_path David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 25/27] CLI/config: remove calls to notmuch_config_open from top level David Bremner
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

The code change is tiny, and transient, but the tests will serve as
regression tests the config file opening is moved into subcommands.
---
 notmuch.c                |  5 +++-
 test/T055-path-config.sh | 60 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/notmuch.c b/notmuch.c
index fa6b7eaa..b1dac8a7 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -443,7 +443,7 @@ main (int argc, char *argv[])
     int ret = EXIT_SUCCESS;
 
     notmuch_opt_desc_t options[] = {
-	{ .opt_string = &config_file_name, .name = "config" },
+	{ .opt_string = &config_file_name, .name = "config", .allow_empty=TRUE },
 	{ .opt_inherit = notmuch_shared_options },
 	{ }
     };
@@ -565,6 +565,9 @@ main (int argc, char *argv[])
     }
 
     if (command->mode & NOTMUCH_COMMAND_CONFIG_OPEN) {
+	if (! config_file_name)
+	    config_file_name = notmuch_config_path (notmuch);
+
 	config = notmuch_config_open (notmuch, config_file_name, command->mode);
 	if (! config) {
 	    ret = EXIT_FAILURE;
diff --git a/test/T055-path-config.sh b/test/T055-path-config.sh
index 0a34e67f..535c41e9 100755
--- a/test/T055-path-config.sh
+++ b/test/T055-path-config.sh
@@ -215,7 +215,65 @@ EOF
 
    test_expect_equal_file EXPECTED OUTPUT
 
-    restore_config
+   test_begin_subtest "Set config value ($config)"
+   name=${RANDOM}
+   value=${RANDOM}
+   notmuch config set test${test_count}.${name} ${value}
+   output=$(notmuch config get test${test_count}.${name})
+   notmuch config set test${test_count}.${name}
+   output2=$(notmuch config get test${test_count}.${name})
+   test_expect_equal "${output}+${output2}" "${value}+"
+
+   test_begin_subtest "Set config value in database ($config)"
+   name=${RANDOM}
+   value=${RANDOM}
+   notmuch config set --database test${test_count}.${name} ${value}
+   output=$(notmuch config get test${test_count}.${name})
+   notmuch config set --database test${test_count}.${name}
+   output2=$(notmuch config get test${test_count}.${name})
+   test_expect_equal "${output}+${output2}" "${value}+"
+
+   test_begin_subtest "Config list ($config)"
+   notmuch config list | notmuch_dir_sanitize | sed -e "s/^database.backup_dir=.*$/database.backup_dir/"  \
+						    -e "s/^database.hook_dir=.*$/database.hook_dir/" \
+						    -e "s/^database.path=.*$/database.path/" > OUTPUT
+   cat <<EOF > EXPECTED
+built_with.compact=true
+built_with.field_processor=true
+built_with.retry_lock=true
+database.backup_dir
+database.hook_dir
+database.mail_root=MAIL_DIR
+database.path
+maildir.synchronize_flags=true
+new.ignore=
+new.tags=unread;inbox
+search.exclude_tags=
+user.name=Notmuch Test Suite
+user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org
+user.primary_email=test_suite@notmuchmail.org
+EOF
+   test_expect_equal_file EXPECTED OUTPUT
+
+   case $config in
+       XDG*)
+	   test_begin_subtest "Set shadowed config value in database ($config)"
+	   test_subtest_known_broken
+	   name=${RANDOM}
+	   value=${RANDOM}
+	   key=test${test_count}.${name}
+	   notmuch config set --database ${key}  ${value}
+	   notmuch config set ${key} shadow${value}
+	   output=$(notmuch --config='' config get ${key})
+	   notmuch config set --database ${key}
+	   output2=$(notmuch --config='' config get ${key})
+	   notmuch config set ${key}
+	   test_expect_equal "${output}+${output2}" "${value}+"
+	   ;;
+   esac
+   restore_config
+   rm -rf home/.local
+   rm -rf home/.config
 done
 
 test_done
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 25/27] CLI/config: remove calls to notmuch_config_open from top level
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (23 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 24/27] CLI/config: support set/get with split configuration David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 26/27] CLI: drop notmuch_config_t from subcommand interface David Bremner
                   ` (2 subsequent siblings)
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

This will allow simplifying the subcommand interface. It also fixes a
previously broken test, since notmuch_config_open does not understand
the notion of the empty string as a config file name.
---
 notmuch-client.h         |  3 +--
 notmuch-config.c         | 24 +++++++++++++++---------
 notmuch-setup.c          | 11 ++++++++++-
 notmuch.c                | 40 ++++++++++++++++++----------------------
 test/T055-path-config.sh |  1 -
 5 files changed, 44 insertions(+), 35 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index 677f2f39..29b78835 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -253,7 +253,6 @@ json_quote_str (const void *ctx, const char *str);
 /* notmuch-config.c */
 
 typedef enum {
-    NOTMUCH_COMMAND_CONFIG_OPEN		= 1 << 0,
     NOTMUCH_COMMAND_CONFIG_CREATE	= 1 << 1,
     NOTMUCH_COMMAND_DATABASE_EARLY	= 1 << 2,
     NOTMUCH_COMMAND_DATABASE_WRITE	= 1 << 3,
@@ -264,7 +263,7 @@ typedef enum {
 notmuch_config_t *
 notmuch_config_open (notmuch_database_t *notmuch,
 		     const char *filename,
-		     notmuch_command_mode_t config_mode);
+		     bool create);
 
 void
 notmuch_config_close (notmuch_config_t *config);
diff --git a/notmuch-config.c b/notmuch-config.c
index 5ba62819..89813aea 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -248,7 +248,7 @@ get_config_from_file (notmuch_config_t *config, bool create_new)
 notmuch_config_t *
 notmuch_config_open (notmuch_database_t *notmuch,
 		     const char *filename,
-		     notmuch_command_mode_t config_mode)
+		     bool create)
 {
     char *notmuch_config_env = NULL;
 
@@ -272,13 +272,9 @@ notmuch_config_open (notmuch_database_t *notmuch,
 
     config->key_file = g_key_file_new ();
 
-    if (config_mode & NOTMUCH_COMMAND_CONFIG_OPEN) {
-	bool create_new = (config_mode & NOTMUCH_COMMAND_CONFIG_CREATE) != 0;
-
-	if (! get_config_from_file (config, create_new)) {
+    if (! get_config_from_file (config, create)) {
 	    talloc_free (config);
 	    return NULL;
-	}
     }
 
     if (config->is_new)
@@ -581,13 +577,14 @@ _set_db_config (notmuch_database_t *notmuch, const char *key, int argc, char **a
 }
 
 static int
-notmuch_config_command_set (notmuch_config_t *config, notmuch_database_t *notmuch,
+notmuch_config_command_set (unused(notmuch_config_t *config), notmuch_database_t *notmuch,
 			    int argc, char *argv[])
 {
     char *group, *key;
     config_key_info_t *key_info;
+    notmuch_config_t *config;
     bool update_database = false;
-    int opt_index;
+    int opt_index, ret;
     char *item;
 
     notmuch_opt_desc_t options[] = {
@@ -628,6 +625,11 @@ notmuch_config_command_set (notmuch_config_t *config, notmuch_database_t *notmuc
     if (_item_split (item, &group, &key))
 	return 1;
 
+    config = notmuch_config_open (notmuch,
+				  notmuch_config_path (notmuch), false);
+    if (! config)
+	return 1;
+
     /* With only the name of an item, we clear it from the
      * configuration file.
      *
@@ -648,7 +650,11 @@ notmuch_config_command_set (notmuch_config_t *config, notmuch_database_t *notmuc
 	break;
     }
 
-    return notmuch_config_save (config);
+    ret = notmuch_config_save (config);
+
+    notmuch_config_close (config);
+
+    return ret;
 }
 
 static
diff --git a/notmuch-setup.c b/notmuch-setup.c
index 1e22412b..c7c3ed47 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -124,7 +124,7 @@ parse_tag_list (void *ctx, char *response)
 }
 
 int
-notmuch_setup_command (notmuch_config_t *config,
+notmuch_setup_command (unused(notmuch_config_t *config),
 		       notmuch_database_t *notmuch,
 		       int argc, char *argv[])
 {
@@ -132,6 +132,7 @@ notmuch_setup_command (notmuch_config_t *config,
     size_t response_size = 0;
     GPtrArray *other_emails;
     notmuch_config_values_t *new_tags, *search_exclude_tags, *emails;
+    notmuch_config_t *config;
 
 #define prompt(format, ...)                                     \
     do {                                                        \
@@ -151,6 +152,11 @@ notmuch_setup_command (notmuch_config_t *config,
 	fprintf (stderr, "Warning: ignoring --uuid=%s\n",
 		 notmuch_requested_db_uuid);
 
+    config = notmuch_config_open (notmuch,
+				  notmuch_config_path (notmuch), true);
+    if (! config)
+	return EXIT_FAILURE;
+
     if (notmuch_config_is_new (config))
 	welcome_message_pre_setup ();
 
@@ -232,6 +238,9 @@ notmuch_setup_command (notmuch_config_t *config,
     if (notmuch_config_save (config))
 	return EXIT_FAILURE;
 
+    if (config)
+	notmuch_config_close (config);
+
     if (notmuch_config_is_new (config))
 	welcome_message_post_setup ();
 
diff --git a/notmuch.c b/notmuch.c
index b1dac8a7..1ef8f078 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -139,11 +139,9 @@ notmuch_process_shared_indexing_options (notmuch_database_t *notmuch)
 
 
 static command_t commands[] = {
-    { NULL, notmuch_command, NOTMUCH_COMMAND_CONFIG_OPEN | NOTMUCH_COMMAND_CONFIG_CREATE
-      | NOTMUCH_COMMAND_CONFIG_LOAD,
+    { NULL, notmuch_command, NOTMUCH_COMMAND_CONFIG_CREATE | NOTMUCH_COMMAND_CONFIG_LOAD,
       "Notmuch main command." },
-    { "setup", notmuch_setup_command, NOTMUCH_COMMAND_CONFIG_OPEN | NOTMUCH_COMMAND_CONFIG_CREATE
-      | NOTMUCH_COMMAND_CONFIG_LOAD,
+    { "setup", notmuch_setup_command, NOTMUCH_COMMAND_CONFIG_CREATE | NOTMUCH_COMMAND_CONFIG_LOAD,
       "Interactively set up notmuch for first use." },
     { "new", notmuch_new_command,
       NOTMUCH_COMMAND_DATABASE_EARLY | NOTMUCH_COMMAND_DATABASE_WRITE | NOTMUCH_COMMAND_DATABASE_CREATE,
@@ -170,7 +168,7 @@ static command_t commands[] = {
       "Compact the notmuch database." },
     { "reindex", notmuch_reindex_command, NOTMUCH_COMMAND_DATABASE_EARLY | NOTMUCH_COMMAND_DATABASE_WRITE,
       "Re-index all messages matching the search terms." },
-    { "config", notmuch_config_command, NOTMUCH_COMMAND_CONFIG_OPEN | NOTMUCH_COMMAND_CONFIG_LOAD,
+    { "config", notmuch_config_command, NOTMUCH_COMMAND_CONFIG_LOAD,
       "Get or set settings in the notmuch configuration file." },
 #if WITH_EMACS
     { "emacs-mua", NULL, 0,
@@ -365,15 +363,26 @@ notmuch_help_command (unused (notmuch_config_t *config), unused(notmuch_database
  * to be more clever about this in the future.
  */
 static int
-notmuch_command (notmuch_config_t *config,
+notmuch_command (unused(notmuch_config_t *config),
 		 notmuch_database_t *notmuch,
 		 unused(int argc), unused(char **argv))
 {
-    /* If the user has never configured notmuch, then run
+
+    const char *config_path;
+
+    /* If the user has not created a configuration file, then run
      * notmuch_setup_command which will give a nice welcome message,
      * and interactively guide the user through the configuration. */
-    if (notmuch_config_is_new (config))
-	return notmuch_setup_command (config, notmuch, 0, NULL);
+    config_path = notmuch_config_path (notmuch);
+    if (access (config_path, R_OK | W_OK | F_OK) == -1) {
+	if (errno != ENOENT) {
+	    fprintf (stderr, "Error: %s config file access failed: %s\n", config_path,
+		     strerror (errno));
+	    return EXIT_FAILURE;
+	} else {
+	    return notmuch_setup_command (NULL, notmuch, 0, NULL);
+	}
+    }
 
     printf ("Notmuch is configured and appears to have a database. Excellent!\n\n"
 	    "At this point you can start exploring the functionality of notmuch by\n"
@@ -564,22 +573,9 @@ main (int argc, char *argv[])
 	}
     }
 
-    if (command->mode & NOTMUCH_COMMAND_CONFIG_OPEN) {
-	if (! config_file_name)
-	    config_file_name = notmuch_config_path (notmuch);
-
-	config = notmuch_config_open (notmuch, config_file_name, command->mode);
-	if (! config) {
-	    ret = EXIT_FAILURE;
-	    goto DONE;
-	}
-    }
     ret = (command->function)(config, notmuch, argc - opt_index, argv + opt_index);
 
   DONE:
-    if (config)
-	notmuch_config_close (config);
-
     talloc_report = getenv ("NOTMUCH_TALLOC_REPORT");
     if (talloc_report && strcmp (talloc_report, "") != 0) {
 	/* this relies on the previous call to
diff --git a/test/T055-path-config.sh b/test/T055-path-config.sh
index 535c41e9..2045a555 100755
--- a/test/T055-path-config.sh
+++ b/test/T055-path-config.sh
@@ -258,7 +258,6 @@ EOF
    case $config in
        XDG*)
 	   test_begin_subtest "Set shadowed config value in database ($config)"
-	   test_subtest_known_broken
 	   name=${RANDOM}
 	   value=${RANDOM}
 	   key=test${test_count}.${name}
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 26/27] CLI: drop notmuch_config_t from subcommand interface.
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (24 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 25/27] CLI/config: remove calls to notmuch_config_open from top level David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:01 ` [PATCH 27/27] CLI: rename notmuch_config_t to notmuch_conffile_t David Bremner
  2021-03-04 13:50 ` v1: convert remaining CLI to new configuration David Bremner
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

At this point it is unused in all subcommands.
---
 notmuch-client.h  | 28 ++++++++++++++--------------
 notmuch-compact.c |  2 +-
 notmuch-config.c  |  6 +++---
 notmuch-count.c   |  2 +-
 notmuch-dump.c    |  2 +-
 notmuch-insert.c  |  2 +-
 notmuch-new.c     |  2 +-
 notmuch-reindex.c |  2 +-
 notmuch-reply.c   |  2 +-
 notmuch-restore.c |  2 +-
 notmuch-search.c  |  4 ++--
 notmuch-setup.c   |  3 +--
 notmuch-show.c    |  2 +-
 notmuch-tag.c     |  2 +-
 notmuch.c         | 16 +++++++---------
 15 files changed, 37 insertions(+), 40 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index 29b78835..1976352f 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -171,46 +171,46 @@ void
 notmuch_exit_if_unsupported_format (void);
 
 int
-notmuch_count_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_count_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_dump_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_dump_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_new_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_new_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_insert_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_insert_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_reindex_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_reindex_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_reply_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_reply_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_restore_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_restore_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_search_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_search_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_address_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_address_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_setup_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_setup_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_show_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_tag_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_tag_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_config_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_config_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 int
-notmuch_compact_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_compact_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 const char *
 notmuch_time_relative_date (const void *ctx, time_t then);
diff --git a/notmuch-compact.c b/notmuch-compact.c
index 361583db..2648434e 100644
--- a/notmuch-compact.c
+++ b/notmuch-compact.c
@@ -27,7 +27,7 @@ status_update_cb (const char *msg, unused (void *closure))
 }
 
 int
-notmuch_compact_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_compact_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     const char *backup_path = NULL;
     notmuch_status_t ret;
diff --git a/notmuch-config.c b/notmuch-config.c
index 89813aea..0fca2adc 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -577,7 +577,7 @@ _set_db_config (notmuch_database_t *notmuch, const char *key, int argc, char **a
 }
 
 static int
-notmuch_config_command_set (unused(notmuch_config_t *config), notmuch_database_t *notmuch,
+notmuch_config_command_set (notmuch_database_t *notmuch,
 			    int argc, char *argv[])
 {
     char *group, *key;
@@ -690,7 +690,7 @@ notmuch_config_command_list (notmuch_database_t *notmuch)
 }
 
 int
-notmuch_config_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_config_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     int ret;
     int opt_index;
@@ -720,7 +720,7 @@ notmuch_config_command (notmuch_config_t *config, notmuch_database_t *notmuch, i
 	}
 	ret = notmuch_config_command_get (notmuch, argv[1]);
     } else if (strcmp (argv[0], "set") == 0) {
-	ret = notmuch_config_command_set (config, notmuch, argc, argv);
+	ret = notmuch_config_command_set (notmuch, argc, argv);
     } else if (strcmp (argv[0], "list") == 0) {
 	ret = notmuch_config_command_list (notmuch);
     } else {
diff --git a/notmuch-count.c b/notmuch-count.c
index 048b1f44..6f239c7e 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -151,7 +151,7 @@ count_file (notmuch_database_t *notmuch, FILE *input, notmuch_config_values_t *e
 }
 
 int
-notmuch_count_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_count_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     char *query_str;
     int opt_index;
diff --git a/notmuch-dump.c b/notmuch-dump.c
index d7017929..928f025b 100644
--- a/notmuch-dump.c
+++ b/notmuch-dump.c
@@ -361,7 +361,7 @@ notmuch_database_dump (notmuch_database_t *notmuch,
 }
 
 int
-notmuch_dump_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch , int argc, char *argv[])
+notmuch_dump_command (notmuch_database_t *notmuch , int argc, char *argv[])
 {
     const char *query_str = NULL;
     int ret;
diff --git a/notmuch-insert.c b/notmuch-insert.c
index 38a0dfe6..00c00468 100644
--- a/notmuch-insert.c
+++ b/notmuch-insert.c
@@ -444,7 +444,7 @@ add_file (notmuch_database_t *notmuch, const char *path, tag_op_list_t *tag_ops,
 }
 
 int
-notmuch_insert_command (unused(notmuch_config_t *config),notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_insert_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     notmuch_status_t status, close_status;
     struct sigaction action;
diff --git a/notmuch-new.c b/notmuch-new.c
index 8a8ff69a..ebdda067 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -1101,7 +1101,7 @@ _maybe_upgrade (notmuch_database_t *notmuch, add_files_state_t *state) {
 }
 
 int
-notmuch_new_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_new_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     add_files_state_t add_files_state = {
 	.verbosity = VERBOSITY_NORMAL,
diff --git a/notmuch-reindex.c b/notmuch-reindex.c
index fa84d4fc..8904c1f4 100644
--- a/notmuch-reindex.c
+++ b/notmuch-reindex.c
@@ -83,7 +83,7 @@ reindex_query (notmuch_database_t *notmuch, const char *query_string,
 }
 
 int
-notmuch_reindex_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_reindex_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     char *query_string = NULL;
     struct sigaction action;
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 700f3397..ada6eda6 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -703,7 +703,7 @@ do_reply (notmuch_database_t *notmuch,
 }
 
 int
-notmuch_reply_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_reply_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     notmuch_query_t *query;
     char *query_string;
diff --git a/notmuch-restore.c b/notmuch-restore.c
index ce07f89d..fb4302a7 100644
--- a/notmuch-restore.c
+++ b/notmuch-restore.c
@@ -219,7 +219,7 @@ parse_sup_line (void *ctx, char *line,
 }
 
 int
-notmuch_restore_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_restore_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     bool accumulate = false;
     tag_op_flag_t flags = 0;
diff --git a/notmuch-search.c b/notmuch-search.c
index aba22799..832223c9 100644
--- a/notmuch-search.c
+++ b/notmuch-search.c
@@ -794,7 +794,7 @@ static const notmuch_opt_desc_t common_options[] = {
 };
 
 int
-notmuch_search_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_search_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     search_context_t *ctx = &search_context;
     int opt_index, ret;
@@ -860,7 +860,7 @@ notmuch_search_command (unused(notmuch_config_t *config), notmuch_database_t *no
 }
 
 int
-notmuch_address_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_address_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     search_context_t *ctx = &search_context;
     int opt_index, ret;
diff --git a/notmuch-setup.c b/notmuch-setup.c
index c7c3ed47..22769a5a 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -124,8 +124,7 @@ parse_tag_list (void *ctx, char *response)
 }
 
 int
-notmuch_setup_command (unused(notmuch_config_t *config),
-		       notmuch_database_t *notmuch,
+notmuch_setup_command (notmuch_database_t *notmuch,
 		       int argc, char *argv[])
 {
     char *response = NULL;
diff --git a/notmuch-show.c b/notmuch-show.c
index 4a26f8ce..bfa9548b 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1215,7 +1215,7 @@ static const notmuch_show_format_t *formatters[] = {
 };
 
 int
-notmuch_show_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_show_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     notmuch_query_t *query;
     char *query_string;
diff --git a/notmuch-tag.c b/notmuch-tag.c
index 464874b4..667a75d6 100644
--- a/notmuch-tag.c
+++ b/notmuch-tag.c
@@ -187,7 +187,7 @@ tag_file (void *ctx, notmuch_database_t *notmuch, tag_op_flag_t flags,
 }
 
 int
-notmuch_tag_command (unused(notmuch_config_t *config), notmuch_database_t *notmuch, int argc, char *argv[])
+notmuch_tag_command (notmuch_database_t *notmuch, int argc, char *argv[])
 {
     tag_op_list_t *tag_ops = NULL;
     char *query_string = NULL;
diff --git a/notmuch.c b/notmuch.c
index 1ef8f078..e0b0aaa6 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -31,7 +31,7 @@
  * Each subcommand should be passed either a config object, or an open
  * database
  */
-typedef int (*command_function_t) (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+typedef int (*command_function_t) (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 typedef struct command {
     const char *name;
@@ -41,10 +41,10 @@ typedef struct command {
 } command_t;
 
 static int
-notmuch_help_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_help_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 static int
-notmuch_command (notmuch_config_t *config, notmuch_database_t *notmuch, int argc, char *argv[]);
+notmuch_command (notmuch_database_t *notmuch, int argc, char *argv[]);
 
 static int
 _help_for (const char *topic);
@@ -339,7 +339,7 @@ _help_for (const char *topic_name)
 }
 
 static int
-notmuch_help_command (unused (notmuch_config_t *config), unused(notmuch_database_t *notmuch), int argc, char *argv[])
+notmuch_help_command (unused(notmuch_database_t *notmuch), int argc, char *argv[])
 {
     int opt_index;
 
@@ -363,8 +363,7 @@ notmuch_help_command (unused (notmuch_config_t *config), unused(notmuch_database
  * to be more clever about this in the future.
  */
 static int
-notmuch_command (unused(notmuch_config_t *config),
-		 notmuch_database_t *notmuch,
+notmuch_command (notmuch_database_t *notmuch,
 		 unused(int argc), unused(char **argv))
 {
 
@@ -380,7 +379,7 @@ notmuch_command (unused(notmuch_config_t *config),
 		     strerror (errno));
 	    return EXIT_FAILURE;
 	} else {
-	    return notmuch_setup_command (NULL, notmuch, 0, NULL);
+	    return notmuch_setup_command (notmuch, 0, NULL);
 	}
     }
 
@@ -446,7 +445,6 @@ main (int argc, char *argv[])
     const char *command_name = NULL;
     command_t *command;
     const char *config_file_name = NULL;
-    notmuch_config_t *config = NULL;
     notmuch_database_t *notmuch = NULL;
     int opt_index;
     int ret = EXIT_SUCCESS;
@@ -573,7 +571,7 @@ main (int argc, char *argv[])
 	}
     }
 
-    ret = (command->function)(config, notmuch, argc - opt_index, argv + opt_index);
+    ret = (command->function)(notmuch, argc - opt_index, argv + opt_index);
 
   DONE:
     talloc_report = getenv ("NOTMUCH_TALLOC_REPORT");
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 27/27] CLI: rename notmuch_config_t to notmuch_conffile_t
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (25 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 26/27] CLI: drop notmuch_config_t from subcommand interface David Bremner
@ 2021-03-04 13:01 ` David Bremner
  2021-03-04 13:50 ` v1: convert remaining CLI to new configuration David Bremner
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:01 UTC (permalink / raw)
  To: notmuch; +Cc: David Bremner

The name is a compromise between keeping function names from getting
too long, and avoiding confusion with the newer notmuch_config library
API. Try to make clear that the residual functionality is only about
updating configuration files.
---
 notmuch-client.h | 56 +++++++++++++++++++++++-----------------------
 notmuch-config.c | 58 ++++++++++++++++++++++++------------------------
 notmuch-setup.c  | 38 +++++++++++++++----------------
 3 files changed, 76 insertions(+), 76 deletions(-)

diff --git a/notmuch-client.h b/notmuch-client.h
index 1976352f..f071da86 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -156,7 +156,7 @@ chomp_newline (char *str)
  */
 extern int notmuch_format_version;
 
-typedef struct _notmuch_config notmuch_config_t;
+typedef struct _notmuch_conffile notmuch_conffile_t;
 
 /* Commands that support structured output should support the
  * following argument
@@ -260,55 +260,55 @@ typedef enum {
     NOTMUCH_COMMAND_CONFIG_LOAD		= 1 << 5,
 } notmuch_command_mode_t;
 
-notmuch_config_t *
-notmuch_config_open (notmuch_database_t *notmuch,
-		     const char *filename,
-		     bool create);
+notmuch_conffile_t *
+notmuch_conffile_open (notmuch_database_t *notmuch,
+		       const char *filename,
+		       bool create);
 
 void
-notmuch_config_close (notmuch_config_t *config);
+notmuch_conffile_close (notmuch_conffile_t *config);
 
 int
-notmuch_config_save (notmuch_config_t *config);
+notmuch_conffile_save (notmuch_conffile_t *config);
 
 bool
-notmuch_config_is_new (notmuch_config_t *config);
+notmuch_conffile_is_new (notmuch_conffile_t *config);
 
 void
-notmuch_config_set_database_path (notmuch_config_t *config,
-				  const char *database_path);
+notmuch_conffile_set_database_path (notmuch_conffile_t *config,
+				    const char *database_path);
 
 void
-notmuch_config_set_user_name (notmuch_config_t *config,
-			      const char *user_name);
+notmuch_conffile_set_user_name (notmuch_conffile_t *config,
+				const char *user_name);
 
 void
-notmuch_config_set_user_primary_email (notmuch_config_t *config,
-				       const char *primary_email);
+notmuch_conffile_set_user_primary_email (notmuch_conffile_t *config,
+					 const char *primary_email);
 
 void
-notmuch_config_set_user_other_email (notmuch_config_t *config,
-				     const char *other_email[],
-				     size_t length);
+notmuch_conffile_set_user_other_email (notmuch_conffile_t *config,
+				       const char *other_email[],
+				       size_t length);
 
 void
-notmuch_config_set_new_tags (notmuch_config_t *config,
-			     const char *new_tags[],
-			     size_t length);
+notmuch_conffile_set_new_tags (notmuch_conffile_t *config,
+			       const char *new_tags[],
+			       size_t length);
 
 void
-notmuch_config_set_new_ignore (notmuch_config_t *config,
-			       const char *new_ignore[],
-			       size_t length);
+notmuch_conffile_set_new_ignore (notmuch_conffile_t *config,
+				 const char *new_ignore[],
+				 size_t length);
 
 void
-notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config,
-					      bool synchronize_flags);
+notmuch_conffile_set_maildir_synchronize_flags (notmuch_conffile_t *config,
+						bool synchronize_flags);
 
 void
-notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
-					const char *list[],
-					size_t length);
+notmuch_conffile_set_search_exclude_tags (notmuch_conffile_t *config,
+					  const char *list[],
+					  size_t length);
 int
 notmuch_run_hook (notmuch_database_t *notmuch, const char *hook);
 
diff --git a/notmuch-config.c b/notmuch-config.c
index 0fca2adc..399ffccc 100644
--- a/notmuch-config.c
+++ b/notmuch-config.c
@@ -114,14 +114,14 @@ struct config_group {
     },
 };
 
-struct _notmuch_config {
+struct _notmuch_conffile {
     char *filename;
     GKeyFile *key_file;
     bool is_new;
 };
 
 static int
-notmuch_config_destructor (notmuch_config_t *config)
+notmuch_conffile_destructor (notmuch_conffile_t *config)
 {
     if (config->key_file)
 	g_key_file_free (config->key_file);
@@ -130,7 +130,7 @@ notmuch_config_destructor (notmuch_config_t *config)
 }
 
 static bool
-get_config_from_file (notmuch_config_t *config, bool create_new)
+get_config_from_file (notmuch_conffile_t *config, bool create_new)
 {
     #define BUF_SIZE 4096
     char *config_str = NULL;
@@ -245,21 +245,21 @@ get_config_from_file (notmuch_config_t *config, bool create_new)
  *	The default configuration also contains comments to guide the
  *	user in editing the file directly.
  */
-notmuch_config_t *
-notmuch_config_open (notmuch_database_t *notmuch,
-		     const char *filename,
-		     bool create)
+notmuch_conffile_t *
+notmuch_conffile_open (notmuch_database_t *notmuch,
+		       const char *filename,
+		       bool create)
 {
     char *notmuch_config_env = NULL;
 
-    notmuch_config_t *config = talloc_zero (notmuch, notmuch_config_t);
+    notmuch_conffile_t *config = talloc_zero (notmuch, notmuch_conffile_t);
 
     if (config == NULL) {
 	fprintf (stderr, "Out of memory.\n");
 	return NULL;
     }
 
-    talloc_set_destructor (config, notmuch_config_destructor);
+    talloc_set_destructor (config, notmuch_conffile_destructor);
 
     if (filename) {
 	config->filename = talloc_strdup (config, filename);
@@ -294,14 +294,14 @@ notmuch_config_open (notmuch_database_t *notmuch,
     return config;
 }
 
-/* Close the given notmuch_config_t object, freeing all resources.
+/* Close the given notmuch_conffile_t object, freeing all resources.
  *
  * Note: Any changes made to the configuration are *not* saved by this
- * function. To save changes, call notmuch_config_save before
- * notmuch_config_close.
+ * function. To save changes, call notmuch_conffile_save before
+ * notmuch_conffile_close.
  */
 void
-notmuch_config_close (notmuch_config_t *config)
+notmuch_conffile_close (notmuch_conffile_t *config)
 {
     talloc_free (config);
 }
@@ -314,7 +314,7 @@ notmuch_config_close (notmuch_config_t *config)
  * printing a description of the error to stderr).
  */
 int
-notmuch_config_save (notmuch_config_t *config)
+notmuch_conffile_save (notmuch_conffile_t *config)
 {
     size_t length;
     char *data, *filename;
@@ -364,20 +364,20 @@ notmuch_config_save (notmuch_config_t *config)
 }
 
 bool
-notmuch_config_is_new (notmuch_config_t *config)
+notmuch_conffile_is_new (notmuch_conffile_t *config)
 {
     return config->is_new;
 }
 
 static void
-_config_set (notmuch_config_t *config,
+_config_set (notmuch_conffile_t *config,
 	     const char *group, const char *key, const char *value)
 {
     g_key_file_set_string (config->key_file, group, key, value);
 }
 
 static void
-_config_set_list (notmuch_config_t *config,
+_config_set_list (notmuch_conffile_t *config,
 		  const char *group, const char *key,
 		  const char *list[],
 		  size_t length)
@@ -386,28 +386,28 @@ _config_set_list (notmuch_config_t *config,
 }
 
 void
-notmuch_config_set_database_path (notmuch_config_t *config,
+notmuch_conffile_set_database_path (notmuch_conffile_t *config,
 				  const char *database_path)
 {
     _config_set (config, "database", "path", database_path);
 }
 
 void
-notmuch_config_set_user_name (notmuch_config_t *config,
+notmuch_conffile_set_user_name (notmuch_conffile_t *config,
 			      const char *user_name)
 {
     _config_set (config, "user", "name", user_name);
 }
 
 void
-notmuch_config_set_user_primary_email (notmuch_config_t *config,
+notmuch_conffile_set_user_primary_email (notmuch_conffile_t *config,
 				       const char *primary_email)
 {
     _config_set (config, "user", "primary_email", primary_email);
 }
 
 void
-notmuch_config_set_user_other_email (notmuch_config_t *config,
+notmuch_conffile_set_user_other_email (notmuch_conffile_t *config,
 				     const char *list[],
 				     size_t length)
 {
@@ -415,7 +415,7 @@ notmuch_config_set_user_other_email (notmuch_config_t *config,
 }
 
 void
-notmuch_config_set_new_tags (notmuch_config_t *config,
+notmuch_conffile_set_new_tags (notmuch_conffile_t *config,
 			     const char *list[],
 			     size_t length)
 {
@@ -423,7 +423,7 @@ notmuch_config_set_new_tags (notmuch_config_t *config,
 }
 
 void
-notmuch_config_set_new_ignore (notmuch_config_t *config,
+notmuch_conffile_set_new_ignore (notmuch_conffile_t *config,
 			       const char *list[],
 			       size_t length)
 {
@@ -431,7 +431,7 @@ notmuch_config_set_new_ignore (notmuch_config_t *config,
 }
 
 void
-notmuch_config_set_search_exclude_tags (notmuch_config_t *config,
+notmuch_conffile_set_search_exclude_tags (notmuch_conffile_t *config,
 					const char *list[],
 					size_t length)
 {
@@ -582,7 +582,7 @@ notmuch_config_command_set (notmuch_database_t *notmuch,
 {
     char *group, *key;
     config_key_info_t *key_info;
-    notmuch_config_t *config;
+    notmuch_conffile_t *config;
     bool update_database = false;
     int opt_index, ret;
     char *item;
@@ -625,7 +625,7 @@ notmuch_config_command_set (notmuch_database_t *notmuch,
     if (_item_split (item, &group, &key))
 	return 1;
 
-    config = notmuch_config_open (notmuch,
+    config = notmuch_conffile_open (notmuch,
 				  notmuch_config_path (notmuch), false);
     if (! config)
 	return 1;
@@ -650,9 +650,9 @@ notmuch_config_command_set (notmuch_database_t *notmuch,
 	break;
     }
 
-    ret = notmuch_config_save (config);
+    ret = notmuch_conffile_save (config);
 
-    notmuch_config_close (config);
+    notmuch_conffile_close (config);
 
     return ret;
 }
@@ -734,7 +734,7 @@ notmuch_config_command (notmuch_database_t *notmuch, int argc, char *argv[])
 }
 
 void
-notmuch_config_set_maildir_synchronize_flags (notmuch_config_t *config,
+notmuch_conffile_set_maildir_synchronize_flags (notmuch_conffile_t *config,
 					      bool synchronize_flags)
 {
     g_key_file_set_boolean (config->key_file,
diff --git a/notmuch-setup.c b/notmuch-setup.c
index 22769a5a..e0afb1c4 100644
--- a/notmuch-setup.c
+++ b/notmuch-setup.c
@@ -131,7 +131,7 @@ notmuch_setup_command (notmuch_database_t *notmuch,
     size_t response_size = 0;
     GPtrArray *other_emails;
     notmuch_config_values_t *new_tags, *search_exclude_tags, *emails;
-    notmuch_config_t *config;
+    notmuch_conffile_t *config;
 
 #define prompt(format, ...)                                     \
     do {                                                        \
@@ -151,22 +151,22 @@ notmuch_setup_command (notmuch_database_t *notmuch,
 	fprintf (stderr, "Warning: ignoring --uuid=%s\n",
 		 notmuch_requested_db_uuid);
 
-    config = notmuch_config_open (notmuch,
-				  notmuch_config_path (notmuch), true);
+    config = notmuch_conffile_open (notmuch,
+				    notmuch_config_path (notmuch), true);
     if (! config)
 	return EXIT_FAILURE;
 
-    if (notmuch_config_is_new (config))
+    if (notmuch_conffile_is_new (config))
 	welcome_message_pre_setup ();
 
     prompt ("Your full name [%s]: ", notmuch_config_get (notmuch, NOTMUCH_CONFIG_USER_NAME));
     if (strlen (response))
-	notmuch_config_set_user_name (config, response);
+	notmuch_conffile_set_user_name (config, response);
 
     prompt ("Your primary email address [%s]: ",
 	    notmuch_config_get (notmuch, NOTMUCH_CONFIG_PRIMARY_EMAIL));
     if (strlen (response))
-	notmuch_config_set_user_primary_email (config, response);
+	notmuch_conffile_set_user_primary_email (config, response);
 
     other_emails = g_ptr_array_new ();
 
@@ -188,10 +188,10 @@ notmuch_setup_command (notmuch_database_t *notmuch,
 	    g_ptr_array_add (other_emails, talloc_strdup (config, response));
     } while (strlen (response));
     if (other_emails->len)
-	notmuch_config_set_user_other_email (config,
-					     (const char **)
-					     other_emails->pdata,
-					     other_emails->len);
+	notmuch_conffile_set_user_other_email (config,
+					       (const char **)
+					       other_emails->pdata,
+					       other_emails->len);
     g_ptr_array_free (other_emails, true);
 
     prompt ("Top-level directory of your email archive [%s]: ",
@@ -200,7 +200,7 @@ notmuch_setup_command (notmuch_database_t *notmuch,
 	const char *absolute_path;
 
 	absolute_path = make_path_absolute (config, response);
-	notmuch_config_set_database_path (config, absolute_path);
+	notmuch_conffile_set_database_path (config, absolute_path);
     }
 
     new_tags = notmuch_config_get_values (notmuch, NOTMUCH_CONFIG_NEW_TAGS);
@@ -212,8 +212,8 @@ notmuch_setup_command (notmuch_database_t *notmuch,
     if (strlen (response)) {
 	GPtrArray *tags = parse_tag_list (config, response);
 
-	notmuch_config_set_new_tags (config, (const char **) tags->pdata,
-				     tags->len);
+	notmuch_conffile_set_new_tags (config, (const char **) tags->pdata,
+				       tags->len);
 
 	g_ptr_array_free (tags, true);
     }
@@ -227,20 +227,20 @@ notmuch_setup_command (notmuch_database_t *notmuch,
     if (strlen (response)) {
 	GPtrArray *tags = parse_tag_list (config, response);
 
-	notmuch_config_set_search_exclude_tags (config,
-						(const char **) tags->pdata,
-						tags->len);
+	notmuch_conffile_set_search_exclude_tags (config,
+						  (const char **) tags->pdata,
+						  tags->len);
 
 	g_ptr_array_free (tags, true);
     }
 
-    if (notmuch_config_save (config))
+    if (notmuch_conffile_save (config))
 	return EXIT_FAILURE;
 
     if (config)
-	notmuch_config_close (config);
+	notmuch_conffile_close (config);
 
-    if (notmuch_config_is_new (config))
+    if (notmuch_conffile_is_new (config))
 	welcome_message_post_setup ();
 
     return EXIT_SUCCESS;
-- 
2.30.1

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: v1: convert remaining CLI to new configuration
  2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
                   ` (26 preceding siblings ...)
  2021-03-04 13:01 ` [PATCH 27/27] CLI: rename notmuch_config_t to notmuch_conffile_t David Bremner
@ 2021-03-04 13:50 ` David Bremner
  27 siblings, 0 replies; 29+ messages in thread
From: David Bremner @ 2021-03-04 13:50 UTC (permalink / raw)
  To: notmuch

David Bremner <david@tethera.net> writes:

> This completes the planned overhaul of configuration handling. It
> obsoletes [1], and needs to be applied on top of [2]. I will post a
> rebased version of [2] fairly soon.
>
> [1]: id:20210220164448.3956011-1-david@tethera.net
> [2]: id:20210208004109.1192719-1-david@tethera.net

To help people that just want to run the code, I have pushed the branch "next"
I am currently running with both remaining configuration series applied

  git clone https://git.notmuchmail.org/git/notmuch -b next

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2021-03-04 13:50 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-04 13:01 v1: convert remaining CLI to new configuration David Bremner
2021-03-04 13:01 ` [PATCH 01/27] lib: add missing status strings David Bremner
2021-03-04 13:01 ` [PATCH 02/27] test: convert random-corpus to use n_d_open_with_config David Bremner
2021-03-04 13:01 ` [PATCH 03/27] lib/open: pull _load_key_file out of _choose_database_path David Bremner
2021-03-04 13:01 ` [PATCH 04/27] lib: provide notmuch_database_load_config David Bremner
2021-03-04 13:01 ` [PATCH 05/27] lib/config: add notmuch_config_get_values_string David Bremner
2021-03-04 13:01 ` [PATCH 06/27] lib/config: add config_pairs iterators David Bremner
2021-03-04 13:01 ` [PATCH 07/27] lib/config: set defaults for user full name David Bremner
2021-03-04 13:01 ` [PATCH 08/27] lib/config: set default for primary user email David Bremner
2021-03-04 13:01 ` [PATCH 09/27] lib/open: canonicalize relative path read from config file David Bremner
2021-03-04 13:01 ` [PATCH 10/27] CLI: load merged config at top level David Bremner
2021-03-04 13:01 ` [PATCH 11/27] CLI/config: use merged config for "config get" David Bremner
2021-03-04 13:01 ` [PATCH 12/27] test/setup: check file output instead of notmuch config list David Bremner
2021-03-04 13:01 ` [PATCH 13/27] CLI/setup: switch to new configuration framework David Bremner
2021-03-04 13:01 ` [PATCH 14/27] CLI/config: switch "notmuch config list" to merged config David Bremner
2021-03-04 13:01 ` [PATCH 15/27] CLI/config: migrate notmuch_config_open to new config David Bremner
2021-03-04 13:01 ` [PATCH 16/27] CLI/config: use notmuch_database_reopen David Bremner
2021-03-04 13:01 ` [PATCH 17/27] CLI/notmuch: switch notmuch_command to notmuch_config_get David Bremner
2021-03-04 13:01 ` [PATCH 18/27] CLI/config: drop obsolete notmuch_config_get_* David Bremner
2021-03-04 13:01 ` [PATCH 19/27] CLI/config: drop cached data from notmuch_config_t David Bremner
2021-03-04 13:01 ` [PATCH 20/27] CLI/config: default to storing all config in external files David Bremner
2021-03-04 13:01 ` [PATCH 21/27] lib: add NOTMUCH_STATUS_NO_DATABASE David Bremner
2021-03-04 13:01 ` [PATCH 22/27] CLI+lib: detect missing database in split configurations David Bremner
2021-03-04 13:01 ` [PATCH 23/27] lib: provide notmuch_config_path David Bremner
2021-03-04 13:01 ` [PATCH 24/27] CLI/config: support set/get with split configuration David Bremner
2021-03-04 13:01 ` [PATCH 25/27] CLI/config: remove calls to notmuch_config_open from top level David Bremner
2021-03-04 13:01 ` [PATCH 26/27] CLI: drop notmuch_config_t from subcommand interface David Bremner
2021-03-04 13:01 ` [PATCH 27/27] CLI: rename notmuch_config_t to notmuch_conffile_t David Bremner
2021-03-04 13:50 ` v1: convert remaining CLI to new configuration David Bremner

unofficial mirror of notmuch@notmuchmail.org

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://yhetil.org/notmuch/0 notmuch/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 notmuch notmuch/ https://yhetil.org/notmuch \
		notmuch@notmuchmail.org
	public-inbox-index notmuch

Example config snippet for mirrors.
Newsgroups are available over NNTP:
	nntp://news.yhetil.org/yhetil.mail.notmuch.general
	nntp://news.gmane.io/gmane.mail.notmuch.general


code repositories for project(s) associated with this inbox:

	notmuch.git.git (no URL configured)

AGPL code for this site: git clone http://ou63pmih66umazou.onion/public-inbox.git