mu-labels: improve command-line handling
Esp., better handle the 'no subcommand' case: give the user some more useful help.
This commit is contained in:
@ -168,7 +168,10 @@ label_import(Mu::Store& store, const Options& opts)
|
|||||||
Result<void>
|
Result<void>
|
||||||
Mu::mu_cmd_labels(Mu::Store &store, const Options &opts)
|
Mu::mu_cmd_labels(Mu::Store &store, const Options &opts)
|
||||||
{
|
{
|
||||||
switch (opts.labels.sub) {
|
if (!opts.labels.sub)
|
||||||
|
return Ok(); // nothing to do.
|
||||||
|
|
||||||
|
switch (*opts.labels.sub) {
|
||||||
case Options::Labels::Sub::List:
|
case Options::Labels::Sub::List:
|
||||||
return label_list(store, opts);
|
return label_list(store, opts);
|
||||||
case Options::Labels::Sub::RestoreList:
|
case Options::Labels::Sub::RestoreList:
|
||||||
@ -181,7 +184,6 @@ Mu::mu_cmd_labels(Mu::Store &store, const Options &opts)
|
|||||||
return label_export(store, opts);
|
return label_export(store, opts);
|
||||||
case Options::Labels::Sub::Import:
|
case Options::Labels::Sub::Import:
|
||||||
return label_import(store, opts);
|
return label_import(store, opts);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Err(Error{Error::Code::Internal,
|
return Err(Error{Error::Code::Internal,
|
||||||
"invalid sub-command"});
|
"invalid sub-command"});
|
||||||
@ -191,7 +193,7 @@ Mu::mu_cmd_labels(Mu::Store &store, const Options &opts)
|
|||||||
#ifdef BUILD_TESTS
|
#ifdef BUILD_TESTS
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tests.
|
* Tests...
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|||||||
@ -496,9 +496,8 @@ sub_init(CLI::App& sub, Options& opts)
|
|||||||
static void
|
static void
|
||||||
sub_labels(CLI::App& sub, Options& opts)
|
sub_labels(CLI::App& sub, Options& opts)
|
||||||
{
|
{
|
||||||
sub.require_subcommand(0);
|
sub.require_subcommand(0, 1);
|
||||||
|
|
||||||
// update
|
|
||||||
auto update{sub.add_subcommand("update", "update labels")};
|
auto update{sub.add_subcommand("update", "update labels")};
|
||||||
update->add_option("--labels", opts.labels.delta_labels,
|
update->add_option("--labels", opts.labels.delta_labels,
|
||||||
"One or more comma-separated +label,-label")
|
"One or more comma-separated +label,-label")
|
||||||
@ -506,12 +505,11 @@ sub_labels(CLI::App& sub, Options& opts)
|
|||||||
->type_name("<delta-label>")
|
->type_name("<delta-label>")
|
||||||
->required();
|
->required();
|
||||||
update->add_flag("-n,--dry-run", opts.labels.dry_run,
|
update->add_flag("-n,--dry-run", opts.labels.dry_run,
|
||||||
"Output what would change without changing anything");
|
"Output what would change without changing anything");
|
||||||
update->add_option("query", opts.labels.query, "Query for messages to update")
|
update->add_option("query", opts.labels.query, "Query for messages to update")
|
||||||
->required();
|
->required();
|
||||||
add_muhome_option(*update, opts);
|
add_muhome_option(*update, opts);
|
||||||
|
|
||||||
// clear
|
|
||||||
auto clear = sub.add_subcommand("clear", "clear all labels from matched messages");
|
auto clear = sub.add_subcommand("clear", "clear all labels from matched messages");
|
||||||
clear ->add_option("query", opts.labels.query, "Query for messages to clear of labels")
|
clear ->add_option("query", opts.labels.query, "Query for messages to clear of labels")
|
||||||
->required();
|
->required();
|
||||||
@ -519,22 +517,18 @@ sub_labels(CLI::App& sub, Options& opts)
|
|||||||
"Output what would change without changing anything");
|
"Output what would change without changing anything");
|
||||||
add_muhome_option(*clear, opts);
|
add_muhome_option(*clear, opts);
|
||||||
|
|
||||||
// list
|
|
||||||
[[maybe_unused]] auto list = sub.add_subcommand("list", "list labels in the store");
|
[[maybe_unused]] auto list = sub.add_subcommand("list", "list labels in the store");
|
||||||
add_muhome_option(*list, opts);
|
add_muhome_option(*list, opts);
|
||||||
|
|
||||||
// restore-list
|
|
||||||
[[maybe_unused]] auto restore_list = sub.add_subcommand(
|
[[maybe_unused]] auto restore_list = sub.add_subcommand(
|
||||||
"restore-list", "restore the labels cache");
|
"restore-list", "restore the labels cache");
|
||||||
add_muhome_option(*restore_list, opts);
|
add_muhome_option(*restore_list, opts);
|
||||||
|
|
||||||
// export
|
|
||||||
[[maybe_unused]] auto exportsub = sub.add_subcommand("export", "export labels to a file");
|
[[maybe_unused]] auto exportsub = sub.add_subcommand("export", "export labels to a file");
|
||||||
add_muhome_option(*exportsub, opts);
|
add_muhome_option(*exportsub, opts);
|
||||||
exportsub->add_option("output", opts.labels.file, "File to export labels to")
|
exportsub->add_option("output", opts.labels.file, "File to export labels to")
|
||||||
->type_name("<file>");
|
->type_name("<file>");
|
||||||
|
|
||||||
// import
|
|
||||||
auto importsub = sub.add_subcommand("import", "import labels from a file");
|
auto importsub = sub.add_subcommand("import", "import labels from a file");
|
||||||
importsub->add_flag("-n,--dry-run", opts.labels.dry_run,
|
importsub->add_flag("-n,--dry-run", opts.labels.dry_run,
|
||||||
"Output what would change without changing anything");
|
"Output what would change without changing anything");
|
||||||
@ -543,12 +537,6 @@ sub_labels(CLI::App& sub, Options& opts)
|
|||||||
->type_name("<file>");
|
->type_name("<file>");
|
||||||
add_muhome_option(*importsub, opts);
|
add_muhome_option(*importsub, opts);
|
||||||
|
|
||||||
// XXX: it'd be nice to make "update" the default command, such that
|
|
||||||
// mu label foo --labels +a,-b
|
|
||||||
// would be interpreted as
|
|
||||||
// mu label update foo --labels +a,-b
|
|
||||||
// but no succeeded yet; CLI11 treats 'foo' as unknown sub-command
|
|
||||||
|
|
||||||
sub.final_callback([&](){
|
sub.final_callback([&](){
|
||||||
if (sub.got_subcommand("list")) {
|
if (sub.got_subcommand("list")) {
|
||||||
opts.labels.sub = Options::Labels::Sub::List;
|
opts.labels.sub = Options::Labels::Sub::List;
|
||||||
@ -568,6 +556,9 @@ sub_labels(CLI::App& sub, Options& opts)
|
|||||||
} else if (sub.got_subcommand("import")){
|
} else if (sub.got_subcommand("import")){
|
||||||
opts.labels.sub = Options::Labels::Sub::Import;
|
opts.labels.sub = Options::Labels::Sub::Import;
|
||||||
opts.labels.read_only = opts.labels.dry_run;
|
opts.labels.read_only = opts.labels.dry_run;
|
||||||
|
} else {
|
||||||
|
mu_println("{}", sub.help());
|
||||||
|
opts.labels.read_only = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -905,8 +896,8 @@ Copyright (C) 2008-2025 Dirk-Jan C. Binnema
|
|||||||
|
|
||||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
|
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
|
||||||
This is free software: you are free to change and redistribute it.
|
This is free software: you are free to change and redistribute it.
|
||||||
There is NO WARRANTY, to the extent permitted by law.
|
There is NO WARRANTY, to the extent permitted by law.)");
|
||||||
)");
|
|
||||||
app.set_version_flag("-V,--version", PACKAGE_VERSION);
|
app.set_version_flag("-V,--version", PACKAGE_VERSION);
|
||||||
app.set_help_flag("-h,--help", "Show help information");
|
app.set_help_flag("-h,--help", "Show help information");
|
||||||
app.set_help_all_flag("--help-all");
|
app.set_help_all_flag("--help-all");
|
||||||
|
|||||||
@ -220,7 +220,7 @@ struct Options {
|
|||||||
Export, // export labels
|
Export, // export labels
|
||||||
Import, // import labels
|
Import, // import labels
|
||||||
};
|
};
|
||||||
Sub sub;
|
Option<Sub> sub; // the chosen sub-command
|
||||||
} labels;
|
} labels;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user