diff --git a/lib/utils/mu-utils-file.hh b/lib/utils/mu-utils-file.hh index 503de33c..7eb3ba55 100644 --- a/lib/utils/mu-utils-file.hh +++ b/lib/utils/mu-utils-file.hh @@ -35,12 +35,12 @@ namespace Mu { * Check if the directory has the given attributes * * @param path path to dir - * @param readable is it readable? - * @param writeable is it writable? + * @param readable is it readable? false means "don't care" + * @param writeable is it writable? false means "don't care" * * @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 @@ -233,8 +233,9 @@ Result remove_directory(const std::string& path); * @param try_setsid whether to try setsid(2) (see its manpage for details) if this * system supports it. * - * @return Ok(exit code) or an error. Note that exit-code != 0 is _not_ considered an error from the - * perspective of run_command, but is for run_command0 + * @return Ok(exit code) or an error. Note that exit-code != 0 is _not_ + * considered an error from the perspective of run_command, but is for + * run_command0 */ struct CommandOutput { int exit_code; diff --git a/man/mu-init.1.org b/man/mu-init.1.org index 60509165..d0342d9c 100644 --- a/man/mu-init.1.org +++ b/man/mu-init.1.org @@ -18,9 +18,11 @@ has completed, you can run *mu index* ** -m, --maildir= -starts searching at ==. By default, *mu* uses whatever the *MAILDIR* -environment variable is set to; if it is not set, it tries =~/Maildir= if it -already exists. +use == as the root-maildir. + +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= @@ -37,8 +39,8 @@ argument may need to be quoted. ** --ignored-address= -specifies that some e-mail address is to be ignored from the contacts-cache -(the option can be used multiple times). Such address then cannot be found with +specifies that some e-mail address is to be ignored from the contacts-cache (the +option can be used multiple times). Such addresses then cannot be found with *mu-cfind(1)* or in the Mu4e contacts cache. == 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= -number of changes after which they are committed to the database; decreasing -this reduces the memory requirements, but make indexing substantially slows (and -vice-versa for increasing). Usually, the default of 250000 should be fine. +the number of changes after which they are committed to the database; decreasing +the value reduces the memory requirements, at the cost of make indexing +substantially slower. Usually, the default of 250000 should be fine. 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 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 @@ -75,9 +77,9 @@ options. *mu*'s underlying Xapian database supports 'ngrams', which improve searching for 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 -to search in such languages. +to search for messages written in such languages. When enabled, *mu* automatically uses ngrams automatically. Xapian environment variables such as ~XAPIAN_CJK_NGRAM~ are ignored. diff --git a/mu/meson.build b/mu/meson.build index 3c27f0ad..cdb9c72a 100644 --- a/mu/meson.build +++ b/mu/meson.build @@ -77,6 +77,13 @@ test('test-cmd-index', cpp_args: ['-DBUILD_TESTS'], 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', executable('test-cmd-mkdir', 'mu-cmd-mkdir.cc', @@ -105,7 +112,6 @@ test('test-cmd-verify', cpp_args: ['-DBUILD_TESTS'], dependencies: [glib_dep, lib_mu_dep])) - test('test-cmd-view', executable('test-cmd-view', 'mu-cmd-view.cc', diff --git a/mu/mu-cmd-index.cc b/mu/mu-cmd-index.cc index 0fd50455..0d65a653 100644 --- a/mu/mu-cmd-index.cc +++ b/mu/mu-cmd-index.cc @@ -152,11 +152,11 @@ test_mu_index(size_t batch_size=0) auto res1 = run_command({MU_PROGRAM, "--quiet", "init", "--batch-size", mu_format("{}", batch_size == 0 ? 10000 : batch_size), "--muhome", mu_home, "--maildir" , MU_TESTMAILDIR2}); - assert_valid_result(res1); + assert_valid_command(res1); auto res2 = run_command({MU_PROGRAM, "--quiet", "index", "--muhome", mu_home}); - assert_valid_result(res2); + assert_valid_command(res2); auto&& store = unwrap(Store::make(join_paths(temp_dir.path(), "xapian"))); g_assert_cmpuint(store.size(),==,14); diff --git a/mu/mu-cmd-init.cc b/mu/mu-cmd-init.cc index 51769c00..210ead5c 100644 --- a/mu/mu-cmd-init.cc +++ b/mu/mu-cmd-init.cc @@ -23,6 +23,8 @@ using namespace Mu; +#ifndef BUILD_TESTS + Result Mu::mu_cmd_init(const Options& opts) { @@ -79,3 +81,61 @@ Mu::mu_cmd_init(const Options& opts) return Ok(); } + + + +#else /* BUILD_TESTS */ + +/* + * Tests. + * + */ +#include +#include +#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*/ diff --git a/mu/mu-options.cc b/mu/mu-options.cc index abdd9b0a..2a1288ed 100644 --- a/mu/mu-options.cc +++ b/mu/mu-options.cc @@ -184,20 +184,16 @@ options_map(const IE& ie) return map; } - - // transformers - // Expand the path using wordexp static const std::function ExpandPath = [](std::string filepath)->std::string { if (auto&& res{expand_path(filepath)}; !res) throw CLI::ValidationError{res.error().what()}; else - return filepath = std::move(res.value()); + return res.value(); }; - // Canonicalize path static const std::function CanonicalizePath = [](std::string filepath)->std::string { return filepath = canonicalize_filename(filepath); @@ -289,7 +285,7 @@ sub_extract(CLI::App& sub, Options& opts) sub.add_option("--target-dir", opts.extract.targetdir, "Target directory for saving") ->type_name("") - ->transform(ExpandPath, "expand path") + ->transform(ExpandPath, "expand target path") ->default_str("") ->default_val("."); 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, "Use bookmarked query") ->type_name("") - ->transform(ExpandPath, "expand path"); + ->transform(ExpandPath, "expand linksdir path"); sub.add_option("--summary-len", opts.find.summary_len, "Use up to so many lines for the summary") @@ -448,10 +444,20 @@ sub_info(CLI::App& sub, Options& opts) static void sub_init(CLI::App& sub, Options& opts) { - sub.add_option("--maildir,-m", opts.init.maildir, - "Top of the maildir") + const auto default_mdir = std::invoke([]()->std::string { + 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("") - ->transform(ExpandPath, "expand path"); + ->default_val(default_mdir) + ->transform(ExpandPath, "expand maildir path"); sub.add_option("--my-address", opts.init.my_addresses, "Personal e-mail address or regexp") ->type_name("
"); @@ -503,8 +509,8 @@ sub_move(CLI::App& sub, Options& opts) sub.add_option("source", opts.move.src, "Message file to move") ->type_name("") - ->transform(ExpandPath, "expand path") - ->transform(CanonicalizePath, "canonicalize path") + ->transform(ExpandPath, "expand source path") + ->transform(CanonicalizePath, "canonicalize source path") ->required(); sub.add_option("destination", opts.move.dest, "Destination maildir") @@ -813,7 +819,7 @@ There is NO WARRANTY, to the extent permitted by law. opts.muhome, "Specify alternative mu directory") ->envname("MUHOME") ->type_name("") - ->transform(ExpandPath, "expand path"); + ->transform(ExpandPath, "expand muhome path"); } /* add scripts (if supported) as semi-subcommands as well */