CLI/config: migrate notmuch_config_open to new config

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)
This commit is contained in:
David Bremner 2021-02-14 09:32:41 -04:00
parent 3787fe6c84
commit b76da87d29
7 changed files with 106 additions and 290 deletions

View file

@ -598,7 +598,7 @@ _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key)
case NOTMUCH_CONFIG_EXCLUDE_TAGS: case NOTMUCH_CONFIG_EXCLUDE_TAGS:
return ""; return "";
case NOTMUCH_CONFIG_NEW_TAGS: case NOTMUCH_CONFIG_NEW_TAGS:
return "inbox;unread"; return "unread;inbox";
case NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS: case NOTMUCH_CONFIG_SYNC_MAILDIR_FLAGS:
return "true"; return "true";
case NOTMUCH_CONFIG_USER_NAME: case NOTMUCH_CONFIG_USER_NAME:
@ -615,9 +615,10 @@ _notmuch_config_default (notmuch_database_t *notmuch, notmuch_config_key_t key)
else else
email = _get_email_from_passwd_file (notmuch); email = _get_email_from_passwd_file (notmuch);
return email; return email;
case NOTMUCH_CONFIG_NEW_IGNORE:
return "";
case NOTMUCH_CONFIG_HOOK_DIR: case NOTMUCH_CONFIG_HOOK_DIR:
case NOTMUCH_CONFIG_BACKUP_DIR: case NOTMUCH_CONFIG_BACKUP_DIR:
case NOTMUCH_CONFIG_NEW_IGNORE:
case NOTMUCH_CONFIG_OTHER_EMAIL: case NOTMUCH_CONFIG_OTHER_EMAIL:
return NULL; return NULL;
default: default:

View file

@ -276,7 +276,7 @@ typedef enum {
} notmuch_command_mode_t; } notmuch_command_mode_t;
notmuch_config_t * notmuch_config_t *
notmuch_config_open (void *ctx, notmuch_config_open (notmuch_database_t *notmuch,
const char *filename, const char *filename,
notmuch_command_mode_t config_mode); notmuch_command_mode_t config_mode);

View file

@ -31,31 +31,22 @@ static const char toplevel_config_comment[] =
"\n" "\n"
" For more information about notmuch, see https://notmuchmail.org"; " For more information about notmuch, see https://notmuchmail.org";
static const char database_config_comment[] = struct config_group {
const char *group_name;
const char *comment;
} group_comment_table [] = {
{
"database",
" Database configuration\n" " Database configuration\n"
"\n" "\n"
" The only value supported here is 'path' which should be the top-level\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" " directory where your mail currently exists and to where mail will be\n"
" delivered in the future. Files should be individual email messages.\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" " Notmuch will store its database within a sub-directory of the path\n"
" configured here named \".notmuch\".\n"; " configured here named \".notmuch\".\n"
},
static const char new_config_comment[] = {
" Configuration for \"notmuch new\"\n" "user",
"\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" " User configuration\n"
"\n" "\n"
" Here is where you can let notmuch know how you would like to be\n" " Here is where you can let notmuch know how you would like to be\n"
@ -69,9 +60,37 @@ static const char user_config_comment[] =
" Notmuch will use the various email addresses configured here when\n" " Notmuch will use the various email addresses configured here when\n"
" formatting replies. It will avoid including your own addresses in the\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" " recipient list of replies, and will set the From address based on the\n"
" address to which the original email was addressed.\n"; " address to which the original email was addressed.\n"
},
static const char maildir_config_comment[] = {
"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" " Maildir compatibility configuration\n"
"\n" "\n"
" The following option is supported here:\n" " The following option is supported here:\n"
@ -91,27 +110,9 @@ static const char maildir_config_comment[] =
"\n" "\n"
"\tThe \"notmuch new\" command will notice flag changes in filenames\n" "\tThe \"notmuch new\" command will notice flag changes in filenames\n"
"\tand update tags, while the \"notmuch tag\" and \"notmuch restore\"\n" "\tand update tags, while the \"notmuch tag\" and \"notmuch restore\"\n"
"\tcommands will notice tag changes and update flags in filenames\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 _notmuch_config { struct _notmuch_config {
char *filename; char *filename;
@ -141,69 +142,6 @@ notmuch_config_destructor (notmuch_config_t *config)
return 0; 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 static bool
get_config_from_file (notmuch_config_t *config, bool create_new) 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. * user in editing the file directly.
*/ */
notmuch_config_t * notmuch_config_t *
notmuch_config_open (void *ctx, notmuch_config_open (notmuch_database_t *notmuch,
const char *filename, const char *filename,
notmuch_command_mode_t config_mode) notmuch_command_mode_t config_mode)
{ {
GError *error = NULL;
size_t tmp;
char *notmuch_config_env = NULL; 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) { if (config == NULL) {
fprintf (stderr, "Out of memory.\n"); 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) if (config->is_new)
g_key_file_set_comment (config->key_file, NULL, NULL, g_key_file_set_comment (config->key_file, NULL, NULL,
toplevel_config_comment, NULL); toplevel_config_comment, NULL);
if (! file_had_database_group) for (size_t i = 0; i < ARRAY_SIZE (group_comment_table); i++) {
g_key_file_set_comment (config->key_file, "database", NULL, const char *name = group_comment_table[i].group_name;
database_config_comment, NULL); if (! g_key_file_has_group (config->key_file, name)) {
/* Force group to exist before adding comment */
if (! file_had_new_group) g_key_file_set_value (config->key_file, name, "dummy_key", "dummy_val");
g_key_file_set_comment (config->key_file, "new", NULL, g_key_file_remove_key (config->key_file, name, "dummy_key", NULL);
new_config_comment, NULL); g_key_file_set_comment (config->key_file, name, NULL,
group_comment_table[i].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);
return config; return config;
} }

View file

@ -588,7 +588,7 @@ main (int argc, char *argv[])
} }
if (command->mode & NOTMUCH_COMMAND_CONFIG_OPEN) { 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) { if (! config) {
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
goto DONE; goto DONE;

View file

@ -57,7 +57,7 @@ foo.list=this;is another;list value;
foo.string=this is another string value foo.string=this is another string value
maildir.synchronize_flags=true maildir.synchronize_flags=true
new.ignore= new.ignore=
new.tags=unread;inbox; new.tags=unread;inbox
search.exclude_tags= search.exclude_tags=
user.name=Notmuch Test Suite user.name=Notmuch Test Suite
user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org user.other_email=test_suite_other@notmuchmail.org;test_suite@otherdomain.org

View file

@ -394,8 +394,8 @@ MAIL_DIR
MAIL_DIR/.notmuch/hooks MAIL_DIR/.notmuch/hooks
MAIL_DIR/.notmuch/backups MAIL_DIR/.notmuch/backups
inbox;unread unread;inbox
NULL
true true
USERNAME@FQDN USERNAME@FQDN
NULL NULL
@ -705,7 +705,7 @@ MAIL_DIR
MAIL_DIR/.notmuch/hooks MAIL_DIR/.notmuch/hooks
MAIL_DIR/.notmuch/backups MAIL_DIR/.notmuch/backups
foo;bar;fub foo;bar;fub
unread;inbox; unread;inbox
sekrit_junk sekrit_junk
true true
test_suite@notmuchmail.org test_suite@notmuchmail.org
@ -736,8 +736,8 @@ MAIL_DIR
MAIL_DIR/.notmuch/hooks MAIL_DIR/.notmuch/hooks
MAIL_DIR/.notmuch/backups MAIL_DIR/.notmuch/backups
inbox;unread unread;inbox
NULL
true true
USERNAME@FQDN USERNAME@FQDN
NULL NULL
@ -815,7 +815,7 @@ database.path MAIL_DIR
key with spaces value, with, spaces! key with spaces value, with, spaces!
maildir.synchronize_flags true maildir.synchronize_flags true
new.ignore sekrit_junk new.ignore sekrit_junk
new.tags unread;inbox; new.tags unread;inbox
search.exclude_tags foo;bar;fub search.exclude_tags foo;bar;fub
test.key1 testvalue1 test.key1 testvalue1
test.key2 testvalue2 test.key2 testvalue2

View file

@ -49,7 +49,6 @@ other_email=another.suite@example.com;
# #
[new] [new]
tags=foo;bar; tags=foo;bar;
ignore=
# Search configuration # Search configuration
# #
@ -85,4 +84,3 @@ exclude_tags=baz;
# commands will notice tag changes and update flags in filenames # commands will notice tag changes and update flags in filenames
# #
[maildir] [maildir]
synchronize_flags=true