aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2022-12-08 10:52:04 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2022-12-08 10:52:04 +0200
commit393ab18520eb5019d00822ae744a4d4e65304226 (patch)
treebbc3f7a6b504d63a2c1dd134627c890ba5fe297c
parent180fdc20372d6501b8fcabb66e1d3cbda02b35c9 (diff)
Add --[no]diag-color options (infrastructure only)
-rw-r--r--bpkg/bpkg.cxx85
-rw-r--r--bpkg/common.cli12
-rw-r--r--bpkg/utility.cxx3
-rw-r--r--bpkg/utility.hxx12
-rw-r--r--bpkg/utility.txx8
5 files changed, 97 insertions, 23 deletions
diff --git a/bpkg/bpkg.cxx b/bpkg/bpkg.cxx
index 2a9fb6d..3ede99e 100644
--- a/bpkg/bpkg.cxx
+++ b/bpkg/bpkg.cxx
@@ -2,6 +2,8 @@
// license : MIT; see accompanying LICENSE file
#include <limits>
+#include <cstdlib> // getenv()
+#include <cstring> // strcmp()
#include <iostream>
#include <exception> // set_terminate(), terminate_handler
#include <type_traits> // enable_if, is_base_of
@@ -161,12 +163,15 @@ namespace bpkg
init_diag (bc.verbosity,
bo.silent (),
- (bc.progress ? bc.progress :
- co.progress () ? optional<bool> (true) :
- co.no_progress () ? optional<bool> (false) : nullopt),
+ (bc.progress ? bc.progress :
+ co.progress () ? optional<bool> (true) :
+ co.no_progress () ? optional<bool> (false) : nullopt),
+ (bc.diag_color ? bc.diag_color :
+ co.diag_color () ? optional<bool> (true) :
+ co.no_diag_color () ? optional<bool> (false) : nullopt),
bo.no_line (),
bo.no_column (),
- bpkg::stderr_term);
+ bpkg::stderr_term.has_value ());
// Note that we pretend to be in the serial-stop mode even though we may
// build build system modules in parallel in order to get better
@@ -465,31 +470,48 @@ init (const common_options& co,
// Verify common options.
//
- // Also merge the --progress/--no-progress options, overriding a less
- // specific flag with a more specific.
+ // Also merge the --*/--no-* options, overriding a less specific flag with
+ // a more specific.
//
- optional<bool> progress;
- auto merge_progress = [&progress]
- (const O& o,
- const default_options_entry<O>* e = nullptr)
+ //
+ optional<bool> progress, diag_color;
+ auto merge_no = [&progress, &diag_color] (
+ const O& o,
+ const default_options_entry<O>* e = nullptr)
{
- if (o.progress () && o.no_progress ())
{
- diag_record dr;
- (e != nullptr ? dr << fail (e->file) : dr << fail)
+ if (o.progress () && o.no_progress ())
+ {
+ diag_record dr;
+ (e != nullptr ? dr << fail (e->file) : dr << fail)
<< "both --progress and --no-progress specified";
+ }
+
+ if (o.progress ())
+ progress = true;
+ else if (o.no_progress ())
+ progress = false;
}
- if (o.progress ())
- progress = true;
- else if (o.no_progress ())
- progress = false;
+ {
+ if (o.diag_color () && o.no_diag_color ())
+ {
+ diag_record dr;
+ (e != nullptr ? dr << fail (e->file) : dr << fail)
+ << "both --diag-color and --no-diag-color specified";
+ }
+
+ if (o.diag_color ())
+ diag_color = true;
+ else if (o.no_diag_color ())
+ diag_color = false;
+ }
};
for (const default_options_entry<O>& e: dos)
- merge_progress (e.options, &e);
+ merge_no (e.options, &e);
- merge_progress (o);
+ merge_no (o);
o = merge_options (dos, o);
@@ -498,6 +520,12 @@ init (const common_options& co,
o.progress (*progress);
o.no_progress (!*progress);
}
+
+ if (diag_color)
+ {
+ o.diag_color (*diag_color);
+ o.no_diag_color (!*diag_color);
+ }
}
catch (const invalid_argument& e)
{
@@ -544,7 +572,24 @@ try
default_terminate = set_terminate (custom_terminate);
- stderr_term = fdterm (stderr_fd ());
+ if (fdterm (stderr_fd ()))
+ {
+ stderr_term = std::getenv ("TERM");
+
+ stderr_term_color =
+#ifdef _WIN32
+ // For now we disable color on Windows since it's unclear if/where/how
+ // it is supported. Maybe one day someone will figure this out.
+ //
+ false
+#else
+ // This test was lifted from GCC (Emacs shell sets TERM=dumb).
+ //
+ *stderr_term != nullptr && strcmp (*stderr_term, "dumb") != 0
+#endif
+ ;
+ }
+
exec_dir = path (argv[0]).directory ();
build2_argv0 = argv[0];
diff --git a/bpkg/common.cli b/bpkg/common.cli
index ac045d0..d870a8d 100644
--- a/bpkg/common.cli
+++ b/bpkg/common.cli
@@ -134,6 +134,18 @@ namespace bpkg
network transfers, building, etc."
}
+ bool --diag-color
+ {
+ "Use color in diagnostics. If printing to a terminal the color is used
+ by default provided the terminal is not dumb. Use \cb{--no-diag-color}
+ to suppress."
+ }
+
+ bool --no-diag-color
+ {
+ "Don't use color in diagnostics."
+ }
+
path --build
{
"<path>",
diff --git a/bpkg/utility.cxx b/bpkg/utility.cxx
index 68d79ad..467e01f 100644
--- a/bpkg/utility.cxx
+++ b/bpkg/utility.cxx
@@ -161,7 +161,8 @@ namespace bpkg
}
}
- bool stderr_term;
+ optional<const char*> stderr_term = nullopt;
+ bool stderr_term_color = false;
bool
yn_prompt (const string& p, char d)
diff --git a/bpkg/utility.hxx b/bpkg/utility.hxx
index 342d608..1f5c725 100644
--- a/bpkg/utility.hxx
+++ b/bpkg/utility.hxx
@@ -152,9 +152,17 @@ namespace bpkg
dir_path
current_directory ();
- // Progress.
+ // Diagnostics.
//
- extern bool stderr_term; // True if stderr is a terminal.
+ // If stderr is not a terminal, then the value is absent (so can be used as
+ // bool). Otherwise, it is the value of the TERM environment variable (which
+ // can be NULL).
+ //
+ extern optional<const char*> stderr_term;
+
+ // True if the color can be used on the stderr terminal.
+ //
+ extern bool stderr_term_color;
// Y/N prompt. See butl::yn_prompt() for details (this is a thin wrapper).
//
diff --git a/bpkg/utility.txx b/bpkg/utility.txx
index 47619c6..6113e4e 100644
--- a/bpkg/utility.txx
+++ b/bpkg/utility.txx
@@ -74,6 +74,14 @@ namespace bpkg
if (no_progress)
ops.push_back ("--no-progress");
+ // Forward our --[no]diag-color options.
+ //
+ if (co.diag_color ())
+ ops.push_back ("--diag-color");
+
+ if (co.no_diag_color ())
+ ops.push_back ("--no-diag-color");
+
return process_start_callback (
[] (const char* const args[], size_t n)
{