mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-22 02:48:08 +01:00
add support for user-specified files & directories to ignore
A new configuration key 'new.ignore' is used to determine which files and directories user wants not to be scanned as new mails. Mark the corresponding test as no longer broken. This work merges my previous attempts and Andreas Amann's work in id:"ylp7hi23mw8.fsf@tyndall.ie"
This commit is contained in:
parent
863c149514
commit
ce1e720de6
4 changed files with 71 additions and 14 deletions
|
@ -250,6 +250,15 @@ notmuch_config_set_new_tags (notmuch_config_t *config,
|
||||||
const char *new_tags[],
|
const char *new_tags[],
|
||||||
size_t length);
|
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);
|
||||||
|
|
||||||
notmuch_bool_t
|
notmuch_bool_t
|
||||||
notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config);
|
notmuch_config_get_maildir_synchronize_flags (notmuch_config_t *config);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,10 @@ static const char new_config_comment[] =
|
||||||
" The following options are supported here:\n"
|
" The following options are supported here:\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\ttags A list (separated by ';') of the tags that will be\n"
|
"\ttags A list (separated by ';') of the tags that will be\n"
|
||||||
"\t added to all messages incorporated by \"notmuch new\".\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";
|
||||||
|
|
||||||
static const char user_config_comment[] =
|
static const char user_config_comment[] =
|
||||||
" User configuration\n"
|
" User configuration\n"
|
||||||
|
@ -105,6 +108,8 @@ struct _notmuch_config {
|
||||||
size_t user_other_email_length;
|
size_t user_other_email_length;
|
||||||
const char **new_tags;
|
const char **new_tags;
|
||||||
size_t new_tags_length;
|
size_t new_tags_length;
|
||||||
|
const char **new_ignore;
|
||||||
|
size_t new_ignore_length;
|
||||||
notmuch_bool_t maildir_synchronize_flags;
|
notmuch_bool_t maildir_synchronize_flags;
|
||||||
const char **search_exclude_tags;
|
const char **search_exclude_tags;
|
||||||
size_t search_exclude_tags_length;
|
size_t search_exclude_tags_length;
|
||||||
|
@ -264,6 +269,8 @@ notmuch_config_open (void *ctx,
|
||||||
config->user_other_email_length = 0;
|
config->user_other_email_length = 0;
|
||||||
config->new_tags = NULL;
|
config->new_tags = NULL;
|
||||||
config->new_tags_length = 0;
|
config->new_tags_length = 0;
|
||||||
|
config->new_ignore = NULL;
|
||||||
|
config->new_ignore_length = 0;
|
||||||
config->maildir_synchronize_flags = TRUE;
|
config->maildir_synchronize_flags = TRUE;
|
||||||
config->search_exclude_tags = NULL;
|
config->search_exclude_tags = NULL;
|
||||||
config->search_exclude_tags_length = 0;
|
config->search_exclude_tags_length = 0;
|
||||||
|
@ -361,6 +368,10 @@ notmuch_config_open (void *ctx,
|
||||||
notmuch_config_set_new_tags (config, tags, 2);
|
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 (notmuch_config_get_search_exclude_tags (config, &tmp) == NULL) {
|
||||||
if (is_new) {
|
if (is_new) {
|
||||||
const char *tags[] = { "deleted", "spam" };
|
const char *tags[] = { "deleted", "spam" };
|
||||||
|
@ -609,6 +620,14 @@ notmuch_config_get_new_tags (notmuch_config_t *config, size_t *length)
|
||||||
&(config->new_tags_length), length);
|
&(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
|
void
|
||||||
notmuch_config_set_user_other_email (notmuch_config_t *config,
|
notmuch_config_set_user_other_email (notmuch_config_t *config,
|
||||||
const char *list[],
|
const char *list[],
|
||||||
|
@ -627,6 +646,15 @@ notmuch_config_set_new_tags (notmuch_config_t *config,
|
||||||
&(config->new_tags));
|
&(config->new_tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
const char **
|
const char **
|
||||||
notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t *length)
|
notmuch_config_get_search_exclude_tags (notmuch_config_t *config, size_t *length)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,6 +39,8 @@ typedef struct {
|
||||||
int verbose;
|
int verbose;
|
||||||
const char **new_tags;
|
const char **new_tags;
|
||||||
size_t new_tags_length;
|
size_t new_tags_length;
|
||||||
|
const char **new_ignore;
|
||||||
|
size_t new_ignore_length;
|
||||||
|
|
||||||
int total_files;
|
int total_files;
|
||||||
int processed_files;
|
int processed_files;
|
||||||
|
@ -181,6 +183,20 @@ _entries_resemble_maildir (struct dirent **entries, int count)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Test if the file/directory is to be ignored.
|
||||||
|
*/
|
||||||
|
static notmuch_bool_t
|
||||||
|
_entry_in_ignore_list (const char *entry, add_files_state_t *state)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < state->new_ignore_length; i++)
|
||||||
|
if (strcmp (entry, state->new_ignore[i]) == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Examine 'path' recursively as follows:
|
/* Examine 'path' recursively as follows:
|
||||||
*
|
*
|
||||||
* o Ask the filesystem for the mtime of 'path' (fs_mtime)
|
* o Ask the filesystem for the mtime of 'path' (fs_mtime)
|
||||||
|
@ -320,15 +336,15 @@ add_files_recursive (notmuch_database_t *notmuch,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore special directories to avoid infinite recursion.
|
/* Ignore special directories to avoid infinite recursion.
|
||||||
* Also ignore the .notmuch directory and any "tmp" directory
|
* Also ignore the .notmuch directory, any "tmp" directory
|
||||||
* that appears within a maildir.
|
* that appears within a maildir and files/directories
|
||||||
|
* the user has configured to be ignored.
|
||||||
*/
|
*/
|
||||||
/* XXX: Eventually we'll want more sophistication to let the
|
|
||||||
* user specify files to be ignored. */
|
|
||||||
if (strcmp (entry->d_name, ".") == 0 ||
|
if (strcmp (entry->d_name, ".") == 0 ||
|
||||||
strcmp (entry->d_name, "..") == 0 ||
|
strcmp (entry->d_name, "..") == 0 ||
|
||||||
(is_maildir && strcmp (entry->d_name, "tmp") == 0) ||
|
(is_maildir && strcmp (entry->d_name, "tmp") == 0) ||
|
||||||
strcmp (entry->d_name, ".notmuch") ==0)
|
strcmp (entry->d_name, ".notmuch") == 0 ||
|
||||||
|
_entry_in_ignore_list (entry->d_name, state))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -369,6 +385,10 @@ add_files_recursive (notmuch_database_t *notmuch,
|
||||||
|
|
||||||
entry = fs_entries[i];
|
entry = fs_entries[i];
|
||||||
|
|
||||||
|
/* Ignore files & directories user has configured to be ignored */
|
||||||
|
if (_entry_in_ignore_list (entry->d_name, state))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* Check if we've walked past any names in db_files or
|
/* Check if we've walked past any names in db_files or
|
||||||
* db_subdirs. If so, these have been deleted. */
|
* db_subdirs. If so, these have been deleted. */
|
||||||
while (notmuch_filenames_valid (db_files) &&
|
while (notmuch_filenames_valid (db_files) &&
|
||||||
|
@ -650,7 +670,7 @@ add_files (notmuch_database_t *notmuch,
|
||||||
* initialized to zero by the top-level caller before calling
|
* initialized to zero by the top-level caller before calling
|
||||||
* count_files). */
|
* count_files). */
|
||||||
static void
|
static void
|
||||||
count_files (const char *path, int *count)
|
count_files (const char *path, int *count, add_files_state_t *state)
|
||||||
{
|
{
|
||||||
struct dirent *entry = NULL;
|
struct dirent *entry = NULL;
|
||||||
char *next;
|
char *next;
|
||||||
|
@ -672,13 +692,13 @@ count_files (const char *path, int *count)
|
||||||
entry = fs_entries[i++];
|
entry = fs_entries[i++];
|
||||||
|
|
||||||
/* Ignore special directories to avoid infinite recursion.
|
/* Ignore special directories to avoid infinite recursion.
|
||||||
* Also ignore the .notmuch directory.
|
* Also ignore the .notmuch directory and files/directories
|
||||||
|
* the user has configured to be ignored.
|
||||||
*/
|
*/
|
||||||
/* XXX: Eventually we'll want more sophistication to let the
|
|
||||||
* user specify files to be ignored. */
|
|
||||||
if (strcmp (entry->d_name, ".") == 0 ||
|
if (strcmp (entry->d_name, ".") == 0 ||
|
||||||
strcmp (entry->d_name, "..") == 0 ||
|
strcmp (entry->d_name, "..") == 0 ||
|
||||||
strcmp (entry->d_name, ".notmuch") == 0)
|
strcmp (entry->d_name, ".notmuch") == 0 ||
|
||||||
|
_entry_in_ignore_list (entry->d_name, state))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -699,7 +719,7 @@ count_files (const char *path, int *count)
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
} else if (S_ISDIR (st.st_mode)) {
|
} else if (S_ISDIR (st.st_mode)) {
|
||||||
count_files (next, count);
|
count_files (next, count, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (next);
|
free (next);
|
||||||
|
@ -841,6 +861,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length);
|
add_files_state.new_tags = notmuch_config_get_new_tags (config, &add_files_state.new_tags_length);
|
||||||
|
add_files_state.new_ignore = notmuch_config_get_new_ignore (config, &add_files_state.new_ignore_length);
|
||||||
add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
|
add_files_state.synchronize_flags = notmuch_config_get_maildir_synchronize_flags (config);
|
||||||
db_path = notmuch_config_get_database_path (config);
|
db_path = notmuch_config_get_database_path (config);
|
||||||
|
|
||||||
|
@ -856,7 +877,7 @@ notmuch_new_command (void *ctx, int argc, char *argv[])
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
count_files (db_path, &count);
|
count_files (db_path, &count, &add_files_state);
|
||||||
if (interrupted)
|
if (interrupted)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
1
test/new
1
test/new
|
@ -167,7 +167,6 @@ Note: Ignoring non-mail file: ${MAIL_DIR}/ignored_file
|
||||||
Added 1 new message to the database."
|
Added 1 new message to the database."
|
||||||
|
|
||||||
test_begin_subtest "Ignore files and directories specified in new.ignore"
|
test_begin_subtest "Ignore files and directories specified in new.ignore"
|
||||||
test_subtest_known_broken
|
|
||||||
generate_message
|
generate_message
|
||||||
notmuch config set new.ignore .git ignored_file .ignored_hidden_file
|
notmuch config set new.ignore .git ignored_file .ignored_hidden_file
|
||||||
touch "${MAIL_DIR}"/.git # change .git's mtime for notmuch new to rescan.
|
touch "${MAIL_DIR}"/.git # change .git's mtime for notmuch new to rescan.
|
||||||
|
|
Loading…
Reference in a new issue