mirror of https://github.com/djcb/mu.git
mu-init: guess maildir when --maildir is missing
Re-instate the guessing that's in the manpage. Add unit tests. Update documentation. Fixes #2616.
This commit is contained in:
parent
8366e009cb
commit
b4c768e6d0
|
@ -35,12 +35,12 @@ namespace Mu {
|
||||||
* Check if the directory has the given attributes
|
* Check if the directory has the given attributes
|
||||||
*
|
*
|
||||||
* @param path path to dir
|
* @param path path to dir
|
||||||
* @param readable is it readable?
|
* @param readable is it readable? false means "don't care"
|
||||||
* @param writeable is it writable?
|
* @param writeable is it writable? false means "don't care"
|
||||||
*
|
*
|
||||||
* @return true if is is a directory with given attributes; false otherwise.
|
* @return true if is is a directory with given attributes; false otherwise.
|
||||||
*/
|
*/
|
||||||
bool check_dir(const std::string& path, bool readable, bool writeable);
|
bool check_dir(const std::string& path, bool readable=false, bool writeable=false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See g_canonicalize_filename
|
* See g_canonicalize_filename
|
||||||
|
@ -233,8 +233,9 @@ Result<void> remove_directory(const std::string& path);
|
||||||
* @param try_setsid whether to try setsid(2) (see its manpage for details) if this
|
* @param try_setsid whether to try setsid(2) (see its manpage for details) if this
|
||||||
* system supports it.
|
* system supports it.
|
||||||
*
|
*
|
||||||
* @return Ok(exit code) or an error. Note that exit-code != 0 is _not_ considered an error from the
|
* @return Ok(exit code) or an error. Note that exit-code != 0 is _not_
|
||||||
* perspective of run_command, but is for run_command0
|
* considered an error from the perspective of run_command, but is for
|
||||||
|
* run_command0
|
||||||
*/
|
*/
|
||||||
struct CommandOutput {
|
struct CommandOutput {
|
||||||
int exit_code;
|
int exit_code;
|
||||||
|
|
|
@ -18,9 +18,11 @@ has completed, you can run *mu index*
|
||||||
|
|
||||||
** -m, --maildir=<maildir>
|
** -m, --maildir=<maildir>
|
||||||
|
|
||||||
starts searching at =<maildir>=. By default, *mu* uses whatever the *MAILDIR*
|
use =<maildir>= as the root-maildir.
|
||||||
environment variable is set to; if it is not set, it tries =~/Maildir= if it
|
|
||||||
already exists.
|
By default, *mu* uses the *MAILDIR* environment; if it is not set, it uses =~/Maildir=
|
||||||
|
if it is an existing directory. If neither of those can be used, the ~--maildir~
|
||||||
|
option is required.
|
||||||
|
|
||||||
** --my-address=<email-address-or-regex>
|
** --my-address=<email-address-or-regex>
|
||||||
|
|
||||||
|
@ -37,8 +39,8 @@ argument may need to be quoted.
|
||||||
|
|
||||||
** --ignored-address=<email-address-or-regex>
|
** --ignored-address=<email-address-or-regex>
|
||||||
|
|
||||||
specifies that some e-mail address is to be ignored from the contacts-cache
|
specifies that some e-mail address is to be ignored from the contacts-cache (the
|
||||||
(the option can be used multiple times). Such address then cannot be found with
|
option can be used multiple times). Such addresses then cannot be found with
|
||||||
*mu-cfind(1)* or in the Mu4e contacts cache.
|
*mu-cfind(1)* or in the Mu4e contacts cache.
|
||||||
|
|
||||||
=<my-email-address>= can be either a plain e-mail address or a regexp, just like
|
=<my-email-address>= can be either a plain e-mail address or a regexp, just like
|
||||||
|
@ -51,9 +53,9 @@ specifies the maximum size for an e-mail message. Usually, the default of
|
||||||
|
|
||||||
** --batch-size=<size>
|
** --batch-size=<size>
|
||||||
|
|
||||||
number of changes after which they are committed to the database; decreasing
|
the number of changes after which they are committed to the database; decreasing
|
||||||
this reduces the memory requirements, but make indexing substantially slows (and
|
the value reduces the memory requirements, at the cost of make indexing
|
||||||
vice-versa for increasing). Usually, the default of 250000 should be fine.
|
substantially slower. Usually, the default of 250000 should be fine.
|
||||||
|
|
||||||
Batch-size 0 is interpreted as 'use the default'.
|
Batch-size 0 is interpreted as 'use the default'.
|
||||||
|
|
||||||
|
@ -61,7 +63,7 @@ Batch-size 0 is interpreted as 'use the default'.
|
||||||
|
|
||||||
whether to enable support for using ngrams in indexing and query parsing; this
|
whether to enable support for using ngrams in indexing and query parsing; this
|
||||||
can be useful for languages without explicit word breaks, such as
|
can be useful for languages without explicit word breaks, such as
|
||||||
Chinese/Japanese/Korean. See *NGRAM SUPPORT* below.
|
Chinese/Japanese/Korean. See *NGRAM SUPPORT* below for details.
|
||||||
|
|
||||||
** --reinit
|
** --reinit
|
||||||
|
|
||||||
|
@ -75,9 +77,9 @@ options.
|
||||||
|
|
||||||
*mu*'s underlying Xapian database supports 'ngrams', which improve searching for
|
*mu*'s underlying Xapian database supports 'ngrams', which improve searching for
|
||||||
languages/scripts that do not have explicit word breaks, such as Chinese,
|
languages/scripts that do not have explicit word breaks, such as Chinese,
|
||||||
Japanese and Korean. It is fairly intrusive, and influence both indexing and
|
Japanese and Korean. It is fairly intrusive, and influences both indexing and
|
||||||
query-parsing; it is not enabled by default, and is recommended only if you need
|
query-parsing; it is not enabled by default, and is recommended only if you need
|
||||||
to search in such languages.
|
to search for messages written in such languages.
|
||||||
|
|
||||||
When enabled, *mu* automatically uses ngrams automatically. Xapian environment
|
When enabled, *mu* automatically uses ngrams automatically. Xapian environment
|
||||||
variables such as ~XAPIAN_CJK_NGRAM~ are ignored.
|
variables such as ~XAPIAN_CJK_NGRAM~ are ignored.
|
||||||
|
|
|
@ -77,6 +77,13 @@ test('test-cmd-index',
|
||||||
cpp_args: ['-DBUILD_TESTS'],
|
cpp_args: ['-DBUILD_TESTS'],
|
||||||
dependencies: [glib_dep, lib_mu_dep]))
|
dependencies: [glib_dep, lib_mu_dep]))
|
||||||
|
|
||||||
|
test('test-cmd-init',
|
||||||
|
executable('test-cmd-init',
|
||||||
|
'mu-cmd-init.cc',
|
||||||
|
install: false,
|
||||||
|
cpp_args: ['-DBUILD_TESTS'],
|
||||||
|
dependencies: [glib_dep, lib_mu_dep]))
|
||||||
|
|
||||||
test('test-cmd-mkdir',
|
test('test-cmd-mkdir',
|
||||||
executable('test-cmd-mkdir',
|
executable('test-cmd-mkdir',
|
||||||
'mu-cmd-mkdir.cc',
|
'mu-cmd-mkdir.cc',
|
||||||
|
@ -105,7 +112,6 @@ test('test-cmd-verify',
|
||||||
cpp_args: ['-DBUILD_TESTS'],
|
cpp_args: ['-DBUILD_TESTS'],
|
||||||
dependencies: [glib_dep, lib_mu_dep]))
|
dependencies: [glib_dep, lib_mu_dep]))
|
||||||
|
|
||||||
|
|
||||||
test('test-cmd-view',
|
test('test-cmd-view',
|
||||||
executable('test-cmd-view',
|
executable('test-cmd-view',
|
||||||
'mu-cmd-view.cc',
|
'mu-cmd-view.cc',
|
||||||
|
|
|
@ -152,11 +152,11 @@ test_mu_index(size_t batch_size=0)
|
||||||
auto res1 = run_command({MU_PROGRAM, "--quiet", "init", "--batch-size",
|
auto res1 = run_command({MU_PROGRAM, "--quiet", "init", "--batch-size",
|
||||||
mu_format("{}", batch_size == 0 ? 10000 : batch_size),
|
mu_format("{}", batch_size == 0 ? 10000 : batch_size),
|
||||||
"--muhome", mu_home, "--maildir" , MU_TESTMAILDIR2});
|
"--muhome", mu_home, "--maildir" , MU_TESTMAILDIR2});
|
||||||
assert_valid_result(res1);
|
assert_valid_command(res1);
|
||||||
|
|
||||||
auto res2 = run_command({MU_PROGRAM, "--quiet", "index",
|
auto res2 = run_command({MU_PROGRAM, "--quiet", "index",
|
||||||
"--muhome", mu_home});
|
"--muhome", mu_home});
|
||||||
assert_valid_result(res2);
|
assert_valid_command(res2);
|
||||||
|
|
||||||
auto&& store = unwrap(Store::make(join_paths(temp_dir.path(), "xapian")));
|
auto&& store = unwrap(Store::make(join_paths(temp_dir.path(), "xapian")));
|
||||||
g_assert_cmpuint(store.size(),==,14);
|
g_assert_cmpuint(store.size(),==,14);
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
using namespace Mu;
|
using namespace Mu;
|
||||||
|
|
||||||
|
#ifndef BUILD_TESTS
|
||||||
|
|
||||||
Result<void>
|
Result<void>
|
||||||
Mu::mu_cmd_init(const Options& opts)
|
Mu::mu_cmd_init(const Options& opts)
|
||||||
{
|
{
|
||||||
|
@ -79,3 +81,61 @@ Mu::mu_cmd_init(const Options& opts)
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else /* BUILD_TESTS */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <config.h>
|
||||||
|
#include <mu-store.hh>
|
||||||
|
#include "utils/mu-test-utils.hh"
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_mu_init_basic()
|
||||||
|
{
|
||||||
|
TempDir temp_dir{};
|
||||||
|
|
||||||
|
const auto mu_home{temp_dir.path()};
|
||||||
|
|
||||||
|
auto res1 = run_command({MU_PROGRAM, "--quiet", "init",
|
||||||
|
"--muhome", mu_home, "--maildir" , MU_TESTMAILDIR2});
|
||||||
|
assert_valid_command(res1);
|
||||||
|
|
||||||
|
auto&& store = unwrap(Store::make(join_paths(temp_dir.path(), "xapian")));
|
||||||
|
g_assert_true(store.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_mu_init_maildir()
|
||||||
|
{
|
||||||
|
TempDir temp_dir{};
|
||||||
|
|
||||||
|
const auto mu_home{temp_dir.path()};
|
||||||
|
|
||||||
|
g_setenv("MAILDIR", MU_TESTMAILDIR2, 1);
|
||||||
|
auto res1 = run_command({MU_PROGRAM, "--quiet", "init",
|
||||||
|
"--muhome", mu_home});
|
||||||
|
assert_valid_command(res1);
|
||||||
|
|
||||||
|
auto&& store = unwrap(Store::make(join_paths(temp_dir.path(), "xapian")));
|
||||||
|
g_assert_true(store.empty());
|
||||||
|
assert_equal(store.root_maildir(), MU_TESTMAILDIR2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
mu_test_init(&argc, &argv);
|
||||||
|
|
||||||
|
g_test_add_func("/cmd/init/basic", test_mu_init_basic);
|
||||||
|
g_test_add_func("/cmd/init/maildir", test_mu_init_maildir);
|
||||||
|
|
||||||
|
return g_test_run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*BUILD_TESTS*/
|
||||||
|
|
|
@ -184,20 +184,16 @@ options_map(const IE& ie)
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// transformers
|
// transformers
|
||||||
|
|
||||||
|
|
||||||
// Expand the path using wordexp
|
// Expand the path using wordexp
|
||||||
static const std::function ExpandPath = [](std::string filepath)->std::string {
|
static const std::function ExpandPath = [](std::string filepath)->std::string {
|
||||||
if (auto&& res{expand_path(filepath)}; !res)
|
if (auto&& res{expand_path(filepath)}; !res)
|
||||||
throw CLI::ValidationError{res.error().what()};
|
throw CLI::ValidationError{res.error().what()};
|
||||||
else
|
else
|
||||||
return filepath = std::move(res.value());
|
return res.value();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Canonicalize path
|
// Canonicalize path
|
||||||
static const std::function CanonicalizePath = [](std::string filepath)->std::string {
|
static const std::function CanonicalizePath = [](std::string filepath)->std::string {
|
||||||
return filepath = canonicalize_filename(filepath);
|
return filepath = canonicalize_filename(filepath);
|
||||||
|
@ -289,7 +285,7 @@ sub_extract(CLI::App& sub, Options& opts)
|
||||||
sub.add_option("--target-dir", opts.extract.targetdir,
|
sub.add_option("--target-dir", opts.extract.targetdir,
|
||||||
"Target directory for saving")
|
"Target directory for saving")
|
||||||
->type_name("<dir>")
|
->type_name("<dir>")
|
||||||
->transform(ExpandPath, "expand path")
|
->transform(ExpandPath, "expand target path")
|
||||||
->default_str("<current>")
|
->default_str("<current>")
|
||||||
->default_val(".");
|
->default_val(".");
|
||||||
sub.add_flag("--uncooked,-u", opts.extract.uncooked,
|
sub.add_flag("--uncooked,-u", opts.extract.uncooked,
|
||||||
|
@ -403,7 +399,7 @@ sub_find(CLI::App& sub, Options& opts)
|
||||||
sub.add_option("--linksdir", opts.find.linksdir,
|
sub.add_option("--linksdir", opts.find.linksdir,
|
||||||
"Use bookmarked query")
|
"Use bookmarked query")
|
||||||
->type_name("<dir>")
|
->type_name("<dir>")
|
||||||
->transform(ExpandPath, "expand path");
|
->transform(ExpandPath, "expand linksdir path");
|
||||||
|
|
||||||
sub.add_option("--summary-len", opts.find.summary_len,
|
sub.add_option("--summary-len", opts.find.summary_len,
|
||||||
"Use up to so many lines for the summary")
|
"Use up to so many lines for the summary")
|
||||||
|
@ -448,10 +444,20 @@ sub_info(CLI::App& sub, Options& opts)
|
||||||
static void
|
static void
|
||||||
sub_init(CLI::App& sub, Options& opts)
|
sub_init(CLI::App& sub, Options& opts)
|
||||||
{
|
{
|
||||||
sub.add_option("--maildir,-m", opts.init.maildir,
|
const auto default_mdir = std::invoke([]()->std::string {
|
||||||
"Top of the maildir")
|
if (const auto mdir_env{::getenv("MAILDIR")}; mdir_env)
|
||||||
|
return mdir_env;
|
||||||
|
else if (const auto mdir_home = ::join_paths(g_get_home_dir(), "Maildir");
|
||||||
|
check_dir(mdir_home))
|
||||||
|
return mdir_home;
|
||||||
|
else
|
||||||
|
return {};
|
||||||
|
});
|
||||||
|
|
||||||
|
sub.add_option("--maildir,-m", opts.init.maildir, "Top of the maildir")
|
||||||
->type_name("<maildir>")
|
->type_name("<maildir>")
|
||||||
->transform(ExpandPath, "expand path");
|
->default_val(default_mdir)
|
||||||
|
->transform(ExpandPath, "expand maildir path");
|
||||||
sub.add_option("--my-address", opts.init.my_addresses,
|
sub.add_option("--my-address", opts.init.my_addresses,
|
||||||
"Personal e-mail address or regexp")
|
"Personal e-mail address or regexp")
|
||||||
->type_name("<address>");
|
->type_name("<address>");
|
||||||
|
@ -503,8 +509,8 @@ sub_move(CLI::App& sub, Options& opts)
|
||||||
|
|
||||||
sub.add_option("source", opts.move.src, "Message file to move")
|
sub.add_option("source", opts.move.src, "Message file to move")
|
||||||
->type_name("<message-path>")
|
->type_name("<message-path>")
|
||||||
->transform(ExpandPath, "expand path")
|
->transform(ExpandPath, "expand source path")
|
||||||
->transform(CanonicalizePath, "canonicalize path")
|
->transform(CanonicalizePath, "canonicalize source path")
|
||||||
->required();
|
->required();
|
||||||
sub.add_option("destination", opts.move.dest,
|
sub.add_option("destination", opts.move.dest,
|
||||||
"Destination maildir")
|
"Destination maildir")
|
||||||
|
@ -813,7 +819,7 @@ There is NO WARRANTY, to the extent permitted by law.
|
||||||
opts.muhome, "Specify alternative mu directory")
|
opts.muhome, "Specify alternative mu directory")
|
||||||
->envname("MUHOME")
|
->envname("MUHOME")
|
||||||
->type_name("<dir>")
|
->type_name("<dir>")
|
||||||
->transform(ExpandPath, "expand path");
|
->transform(ExpandPath, "expand muhome path");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add scripts (if supported) as semi-subcommands as well */
|
/* add scripts (if supported) as semi-subcommands as well */
|
||||||
|
|
Loading…
Reference in New Issue