mu-move: add new move sub command

Add sub-command to move messages; add tests and docs.

Fixes #157
This commit is contained in:
Dirk-Jan C. Binnema
2023-09-13 23:54:45 +03:00
parent 1a3dc46866
commit 2d20074b99
14 changed files with 597 additions and 90 deletions

View File

@ -197,6 +197,12 @@ static const std::function ExpandPath = [](std::string filepath)->std::string {
return filepath = std::move(res.value());
};
// Canonicalize path
static const std::function CanonicalizePath = [](std::string filepath)->std::string {
return filepath = canonicalize_filename(filepath);
};
/*
* common
*/
@ -481,6 +487,31 @@ sub_mkdir(CLI::App& sub, Options& opts)
->required();
}
static void
sub_move(CLI::App& sub, Options& opts)
{
sub.add_flag("--change-name", opts.move.change_name,
"Change name of target file");
sub.add_flag("--update-dups", opts.move.update_dups,
"Update duplicate messages too");
sub.add_flag("--dry-run,-n", opts.move.dry_run,
"Print target name, but do not change anything");
sub.add_option("--flags", opts.move.flags, "Target flags")
->type_name("<flags>");
sub.add_option("source", opts.move.src, "Message file to move")
->type_name("<message-path>")
->transform(ExpandPath, "expand path")
->transform(CanonicalizePath, "canonicalize path")
->required();
sub.add_option("destination", opts.move.dest,
"Destination maildir")
->type_name("<maildir>");
}
static void
sub_remove(CLI::App& sub, Options& opts)
{
@ -602,7 +633,7 @@ AssocPairs<SubCommand, CommandInfo, Options::SubCommandNum> SubCommandInfos= {{
},
{ SubCommand::Info,
{Category::NeedsReadOnlyStore,
"info", "Show information about the message store database", sub_info }
"info", "Show information", sub_info }
},
{ SubCommand::Init,
{Category::NeedsWritableStore,
@ -612,6 +643,10 @@ AssocPairs<SubCommand, CommandInfo, Options::SubCommandNum> SubCommandInfos= {{
{Category::None,
"mkdir", "Create a new Maildir", sub_mkdir }
},
{ SubCommand::Move,
{Category::NeedsWritableStore,
"move", "Move a message or change flags", sub_move }
},
{ SubCommand::Remove,
{Category::NeedsWritableStore,
"remove", "Remove message from file-system and database", sub_remove }
@ -718,7 +753,8 @@ add_global_options(CLI::App& cli, Options& opts)
cli.add_flag("-q,--quiet", opts.quiet, "Hide non-essential output");
cli.add_flag("-v,--verbose", opts.verbose, "Show verbose output");
cli.add_flag("--log-stderr", opts.log_stderr, "Log to stderr");
cli.add_flag("--log-stderr", opts.log_stderr, "Log to stderr")
->group(""/*always hide*/);
cli.add_flag("--nocolor", opts.nocolor, "Don't show ANSI colors")
->default_val(Options::default_no_color())
->default_str(Options::default_no_color() ? "<true>" : "<false>");
@ -780,7 +816,7 @@ There is NO WARRANTY, to the extent permitted by law.
->transform(ExpandPath, "expand path");
}
/* add scripts (if supported) as semi-subscommands as well */
/* add scripts (if supported) as semi-subcommands as well */
const auto scripts = add_scripts(app, opts);
try {
@ -842,6 +878,11 @@ Options::category(Options::SubCommand sub)
static constexpr bool
validate_subcommand_ids()
{
size_t val{};
for (auto& cmd: Options::SubCommands)
if (static_cast<size_t>(cmd) != val++)
return false;
for (auto u = 0U; u != SubCommandInfos.size(); ++u)
if (static_cast<size_t>(SubCommandInfos.at(u).first) != u)
return false;