diff options
Diffstat (limited to 'bpkg/utility.txx')
-rw-r--r-- | bpkg/utility.txx | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/bpkg/utility.txx b/bpkg/utility.txx new file mode 100644 index 0000000..f830478 --- /dev/null +++ b/bpkg/utility.txx @@ -0,0 +1,98 @@ +// file : bpkg/utility.txx -*- C++ -*- +// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <libbutl/small-vector.mxx> + +#include <bpkg/diagnostics.hxx> + +namespace bpkg +{ + // *_b() + // + template <typename O, typename E, typename... A> + process + start_b (const common_options& co, + O&& out, + E&& err, + verb_b v, + A&&... args) + { + const char* b (name_b (co)); + + try + { + // Use our executable directory as a fallback search since normally the + // entire toolchain is installed into one directory. This way, for + // example, if we installed into /opt/build2 and run bpkg with absolute + // path (and without PATH), then bpkg will be able to find "its" b. + // + process_path pp (process::path_search (b, exec_dir)); + + butl::small_vector<const char*, 1> ops; + + // Map verbosity level. If we are running quiet or at level 1, + // then run build2 quiet. Otherwise, run it at the same level + // as us. + // + string vl; + + if (verb == 0) + ops.push_back ("-q"); + else if (verb == 1) + { + if (v != verb_b::normal) + { + ops.push_back ("-q"); + + if (v == verb_b::progress && stderr_term) + ops.push_back ("--progress"); + } + } + else if (verb == 2) + ops.push_back ("-v"); + else + { + vl = to_string (verb); + ops.push_back ("--verbose"); + ops.push_back (vl.c_str ()); + } + + return process_start_callback ( + [] (const char* const args[], size_t n) + { + if (verb >= 2) + print_process (args, n); + }, + 0 /* stdin */, + forward<O> (out), + forward<E> (err), + pp, + ops, + co.build_option (), + forward<A> (args)...); + } + catch (const process_error& e) + { + fail << "unable to execute " << b << ": " << e << endf; + } + } + + template <typename... A> + void + run_b (const common_options& co, verb_b v, A&&... args) + { + process pr ( + start_b (co, 1 /* stdout */, 2 /* stderr */, v, forward<A> (args)...)); + + if (!pr.wait ()) + { + const process_exit& e (*pr.exit); + + if (e.normal ()) + throw failed (); // Assume the child issued diagnostics. + + fail << "process " << name_b (co) << " " << e; + } + } +} |