mu: allow color in early command errors
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright (C) 2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
** Copyright (C) 2022-2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
**
|
**
|
||||||
** This program is free software; you can redistribute it and/or modify it
|
** 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
|
** under the terms of the GNU General Public License as published by the
|
||||||
@ -594,24 +594,29 @@ cmd_help(const CLI::App& app, Options& opts)
|
|||||||
"no help available for '%s'", opts.help.command.c_str());
|
"no help available for '%s'", opts.help.command.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Options::default_no_color()
|
||||||
|
{
|
||||||
|
static const auto no_color =
|
||||||
|
!::isatty(::fileno(stdout)) ||
|
||||||
|
!::isatty(::fileno(stderr)) ||
|
||||||
|
::getenv("NO_COLOR") != NULL;
|
||||||
|
|
||||||
|
return no_color;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_global_options(CLI::App& cli, Options& opts)
|
add_global_options(CLI::App& cli, Options& opts)
|
||||||
{
|
{
|
||||||
static const auto default_no_color =
|
opts.nocolor = Options::default_no_color();
|
||||||
!::isatty(::fileno(stdout)) ||
|
|
||||||
!::isatty(::fileno(stderr)) ||
|
|
||||||
::getenv("NO_COLOR") != NULL;
|
|
||||||
opts.nocolor = default_no_color;
|
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
cli.add_flag("-q,--quiet", opts.quiet, "Hide non-essential output");
|
cli.add_flag("-q,--quiet", opts.quiet, "Hide non-essential output");
|
||||||
cli.add_flag("-v,--verbose", opts.verbose, "Show verbose 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");
|
||||||
cli.add_flag("--nocolor", opts.nocolor, "Don't show ANSI colors")
|
cli.add_flag("--nocolor", opts.nocolor, "Don't show ANSI colors")
|
||||||
->default_val(default_no_color)
|
->default_val(Options::default_no_color())
|
||||||
->default_str(default_no_color ? "<true>" : "<false>");
|
->default_str(Options::default_no_color() ? "<true>" : "<false>");
|
||||||
cli.add_flag("-d,--debug", opts.debug, "Run in debug mode")
|
cli.add_flag("-d,--debug", opts.debug, "Run in debug mode")
|
||||||
->group(""/*always hide*/);
|
->group(""/*always hide*/);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,13 @@ struct Options {
|
|||||||
bool verbose; /**< verbose output */
|
bool verbose; /**< verbose output */
|
||||||
std::string muhome; /**< alternative mu dir */
|
std::string muhome; /**< alternative mu dir */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether by default, we should show color
|
||||||
|
*
|
||||||
|
* @return true or false
|
||||||
|
*/
|
||||||
|
static bool default_no_color();
|
||||||
|
|
||||||
enum struct SubCommand {
|
enum struct SubCommand {
|
||||||
Add, Cfind, Extract, Fields, Find, Help, Index,Info, Init, Mkdir,
|
Add, Cfind, Extract, Fields, Find, Help, Index,Info, Init, Mkdir,
|
||||||
Remove, Script, Server, Verify, View/*must be last*/
|
Remove, Script, Server, Verify, View/*must be last*/
|
||||||
@ -274,7 +281,6 @@ struct Options {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namepace Mu
|
} // namepace Mu
|
||||||
|
|
||||||
#endif /* MU_OPTIONS_HH__ */
|
#endif /* MU_OPTIONS_HH__ */
|
||||||
|
|||||||
32
mu/mu.cc
32
mu/mu.cc
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright (C) 2008-2022 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
** Copyright (C) 2008-2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
|
||||||
**
|
**
|
||||||
** This program is free software; you can redistribute it and/or modify it
|
** 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
|
** under the terms of the GNU General Public License as published by the
|
||||||
@ -33,6 +33,19 @@
|
|||||||
|
|
||||||
using namespace Mu;
|
using namespace Mu;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
output_error(const std::string& what, bool use_color)
|
||||||
|
{
|
||||||
|
using Color = MaybeAnsi::Color;
|
||||||
|
MaybeAnsi col{use_color};
|
||||||
|
|
||||||
|
std::cerr << col.fg(Color::Red) << "error" << col.reset() << ": "
|
||||||
|
<< col.fg(Color::BrightYellow)
|
||||||
|
<< what << "\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
handle_result(const Result<void>& res, const Mu::Options& opts)
|
handle_result(const Result<void>& res, const Mu::Options& opts)
|
||||||
{
|
{
|
||||||
@ -43,11 +56,9 @@ handle_result(const Result<void>& res, const Mu::Options& opts)
|
|||||||
MaybeAnsi col{!opts.nocolor};
|
MaybeAnsi col{!opts.nocolor};
|
||||||
|
|
||||||
// show the error and some help, but not if it's only a softerror.
|
// show the error and some help, but not if it's only a softerror.
|
||||||
if (!res.error().is_soft_error()) {
|
if (!res.error().is_soft_error())
|
||||||
std::cerr << col.fg(Color::Red) << "error" << col.reset() << ": "
|
output_error(res.error().what(), !opts.nocolor);
|
||||||
<< col.fg(Color::BrightYellow)
|
else
|
||||||
<< res.error().what() << "\n";
|
|
||||||
} else
|
|
||||||
std::cerr << col.fg(Color::BrightBlue) << res.error().what() << '\n';
|
std::cerr << col.fg(Color::BrightBlue) << res.error().what() << '\n';
|
||||||
|
|
||||||
std::cerr << col.fg(Color::Green);
|
std::cerr << col.fg(Color::Green);
|
||||||
@ -82,13 +93,18 @@ main(int argc, char* argv[])
|
|||||||
*/
|
*/
|
||||||
const auto opts{Options::make(argc, argv)};
|
const auto opts{Options::make(argc, argv)};
|
||||||
if (!opts) {
|
if (!opts) {
|
||||||
std::cerr << "error: " << opts.error().what() << "\n";
|
output_error(opts.error().what(), !Options::default_no_color());
|
||||||
return opts.error().exit_code();
|
return opts.error().exit_code();
|
||||||
} else if (!opts->sub_command) {
|
} else if (!opts->sub_command) {
|
||||||
// nothing more to do.
|
// nothing more to do.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* there's a subcommand
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set up logging
|
* set up logging
|
||||||
*/
|
*/
|
||||||
@ -101,7 +117,7 @@ main(int argc, char* argv[])
|
|||||||
const auto logger = Logger::make(opts->runtime_path(RuntimePath::LogFile),
|
const auto logger = Logger::make(opts->runtime_path(RuntimePath::LogFile),
|
||||||
lopts);
|
lopts);
|
||||||
if (!logger) {
|
if (!logger) {
|
||||||
std::cerr << "error:" << logger.error().what() << "\n";
|
output_error(logger.error().what(), !opts->nocolor);
|
||||||
return logger.error().exit_code();
|
return logger.error().exit_code();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user