From f813498f4daaa2a29509b3ef431dd91b82a960a7 Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Fri, 5 Apr 2024 21:17:55 +0300 Subject: [PATCH] mu: add --reindex option for mu index I.e. without having to reinit explicitly. --- man/mu-index.1.org | 4 ++++ mu/mu-cmd-index.cc | 28 ++++++++++++++++++++-------- mu/mu-cmd.cc | 8 +++++--- mu/mu-cmd.hh | 3 +-- mu/mu-options.cc | 4 +++- mu/mu-options.hh | 1 + mu/mu.cc | 8 ++++++-- 7 files changed, 40 insertions(+), 16 deletions(-) diff --git a/man/mu-index.1.org b/man/mu-index.1.org index 7fab422a..80452e07 100644 --- a/man/mu-index.1.org +++ b/man/mu-index.1.org @@ -78,6 +78,10 @@ messages. disable the database cleanup that *mu* does by default after indexing. +** --reindex + +perform a complete reindexing of all the messages in the maildir. + #+include: "muhome.inc" :minlevel 2 #+include: "common-options.inc" :minlevel 1 diff --git a/mu/mu-cmd-index.cc b/mu/mu-cmd-index.cc index 0d65a653..6b3b2558 100644 --- a/mu/mu-cmd-index.cc +++ b/mu/mu-cmd-index.cc @@ -78,9 +78,21 @@ print_stats(const Indexer::Progress& stats, bool color) } Result -Mu::mu_cmd_index(Store& store, const Options& opts) +Mu::mu_cmd_index(const Options& opts) { - const auto mdir{store.root_maildir()}; + auto store = std::invoke([&]{ + if (opts.index.reindex) + return Store::make(opts.runtime_path(RuntimePath::XapianDb), + Store::Options::ReInit|Store::Options::Writable); + else + return Store::make(opts.runtime_path(RuntimePath::XapianDb), + Store::Options::Writable); + }); + + if (!store) + return Err(store.error()); + + const auto mdir{store->root_maildir()}; if (G_UNLIKELY(::access(mdir.c_str(), R_OK) != 0)) return Err(Error::Code::File, "'{}' is not readable: {}", mdir, g_strerror(errno)); @@ -93,19 +105,19 @@ Mu::mu_cmd_index(Store& store, const Options& opts) mu_println("indexing maildir {}{}{} -> " "store {}{}{}", - col.fg(Color::Green), store.root_maildir(), col.reset(), - col.fg(Color::Blue), store.path(), col.reset()); + col.fg(Color::Green), store->root_maildir(), col.reset(), + col.fg(Color::Blue), store->path(), col.reset()); } Mu::Indexer::Config conf{}; conf.cleanup = !opts.index.nocleanup; conf.lazy_check = opts.index.lazycheck; // ignore .noupdate with an empty store. - conf.ignore_noupdate = store.empty(); + conf.ignore_noupdate = store->empty(); install_sig_handler(); - auto& indexer{store.indexer()}; + auto& indexer{store->indexer()}; indexer.start(conf); while (!caught_signal && indexer.is_running()) { if (!opts.quiet) @@ -119,10 +131,10 @@ Mu::mu_cmd_index(Store& store, const Options& opts) } } - store.indexer().stop(); + indexer.stop(); if (!opts.quiet) { - print_stats(store.indexer().progress(), !opts.nocolor); + print_stats(indexer.progress(), !opts.nocolor); mu_print("\n"); ::fflush({}); } diff --git a/mu/mu-cmd.cc b/mu/mu-cmd.cc index 62e67913..bcdca985 100644 --- a/mu/mu-cmd.cc +++ b/mu/mu-cmd.cc @@ -142,10 +142,12 @@ Mu::mu_cmd_execute(const Options& opts) try { return with_writable_store(mu_cmd_remove, opts); case Options::SubCommand::Move: return with_writable_store(mu_cmd_move, opts); - case Options::SubCommand::Index: - return with_writable_store(mu_cmd_index, opts); - /* commands instantiate store themselves */ + /* + * commands instantiate store themselves + */ + case Options::SubCommand::Index: + return mu_cmd_index(opts); case Options::SubCommand::Init: return mu_cmd_init(opts); case Options::SubCommand::Server: diff --git a/mu/mu-cmd.hh b/mu/mu-cmd.hh index 3a4214fb..7b591f8f 100644 --- a/mu/mu-cmd.hh +++ b/mu/mu-cmd.hh @@ -92,12 +92,11 @@ Result mu_cmd_find(const Store& store, const Options& opts); /** * execute the 'index' command * - * @param store store object to use * @param opts configuration options * * @return Ok() or some error */ -Result mu_cmd_index(Store& store, const Options& opt); +Result mu_cmd_index(const Options& opt); /** * execute the 'info' command diff --git a/mu/mu-options.cc b/mu/mu-options.cc index 2a1288ed..9533e9cc 100644 --- a/mu/mu-options.cc +++ b/mu/mu-options.cc @@ -1,5 +1,5 @@ /* -** Copyright (C) 2022-2023 Dirk-Jan C. Binnema +** Copyright (C) 2022-2024 Dirk-Jan C. Binnema ** ** This program is free software; you can redistribute it and/or modify it ** under the terms of the GNU General Public License as published by the @@ -430,6 +430,8 @@ sub_index(CLI::App& sub, Options& opts) "Skip based on dir-timestamps"); sub.add_flag("--nocleanup", opts.index.nocleanup, "Don't clean up database after indexing"); + sub.add_flag("--reindex", opts.index.reindex, + "Perform a complete reindexing"); } diff --git a/mu/mu-options.hh b/mu/mu-options.hh index 58eecfa1..fa440bf4 100644 --- a/mu/mu-options.hh +++ b/mu/mu-options.hh @@ -172,6 +172,7 @@ struct Options { struct Index { bool nocleanup; /**< don't cleanup del'd mails */ bool lazycheck; /**< don't check uptodate dirs */ + bool reindex; /**< do a full re-index */ } index; diff --git a/mu/mu.cc b/mu/mu.cc index 8bb6dfd9..69d3c485 100644 --- a/mu/mu.cc +++ b/mu/mu.cc @@ -67,8 +67,12 @@ handle_result(const Result& res, const Mu::Options& opts) col.fg(Color::Blue), col.reset(), col.fg(Color::Green), res.error().hint(), col.reset()); - if (res.error().exit_code() != 0 && !res.error().is_soft_error()) - mu_warning("mu finishing with error: {}", format_as(res.error())); + if (res.error().exit_code() != 0 && !res.error().is_soft_error()) { + mu_warning("mu finishing with error: {}", + format_as(res.error())); + if (const auto& hint = res.error().hint(); !hint.empty()) + mu_info("hint: {}", hint); + } return res.error().exit_code(); }